Using Alipay in the Android SDK

    Allow customers to pay using Alipay's Android tools.

    This guide takes you through building a Source-generation flow that works with Alipay's app-to-app and app-to-web flows for creating reusable and one-time payment sources.

    Download and integrate the Alipay API

    To do in-app payments using Alipay's app-to-app redirect flow, you must first download the Alipay SDK.

    After unzipping the archive, find the file named alipaySdk-20170725.jar and add it to the libs directory of your project. Then add the dependency to your build.gradle file:

    dependencies {
      // ... other dependencies
      compile files('libs/alipaySdk-20170725.jar')
    }
    

    Prepare your activity for redirects

    Before adding code to generate Alipay sources and work with the Alipay application and web endpoints, first prepare the application manifest for redirects. This allows Alipay to return users to your application when verification is complete. This is done via an intent filter in the application manifest entry for the activity that users should go back to.

    <activity
      android:name=".activity.MyAlipayActivity"
      android:theme="@style/SampleThemeDefault">
      <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
    
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
    
        <!--corresponds to a redirect URL of "mycompany://alipay" -->
        <data
            android:host="alipay"
            android:scheme="mycompany"/>
      </intent-filter>
    </activity>
    

    Create the Stripe Alipay source

    In the activity code itself, first generate a Stripe source using the Stripe Android SDK. There are two types of Alipay sources: one-time and reusable. Factory-style functions are provided for both types.

    SourceParams alipaySingleUseParams = SourceParams.createAlipaySingleUseParams(
      50L, // Amount is a long int in the lowest denomination. 50 cents in USD is the minimum
      "USD",
      "Mr. Sample", // customer name
      "sample@sample.smp", // customer email
      "mycompany://alipay"); // a redirect address to get the user back into your app
    
    // Note that this call performs I/O on the thread on which it is called, and crashes
    // if you do not have it on a background thread. For more information on
    // handling threading, see https://stripe.com/docs/mobile/android/sources#create-source-object
    stripe.createSourceSynchronous(alipayParams, "pk_test_6pRNASCoBOKtIshFeQd4XMUh");
    

    The parameters necessary to create a reusable source are similar to a one-time source. They lack the fixed payment amount, since this can be charged multiple times for different amounts.

    SourceParams alipayReusableParams = SourceParams.createAlipayReusableParams(
      "USD", // Currency code
      "Mr. Sample", // customer name
      "sample@sample.smp", // customer email
      "mycompany://alipay"); // a redirect address to get the user back into your app
    

    Use the Source fields with Alipay

    The returned Stripe Source object contains fields to give to the Alipay SDK to complete the transaction. Which field to use depends on the desired Alipay functionality and whether the source is a one-time source or reusable.

    App-to-App Single-Use Source

    For app-to-app connection (if the user has the Alipay app installed), you first need a way to communicate the asynchronous result from the SDK. The following code demonstrates how to use a Handler to receive the result.

    private Handler mHandler = new Handler(Looper.getMainLooper()) {
      @Override
      public void handleMessage(Message msg) {
        switch (msg.what) {
          case SDK_PAY_FLAG:
            @SuppressWarnings("unchecked")
            Map<String, String> answer = (Map<String, String>) msg.obj;
            // The result info contains other information about the transaction
            String resultInfo = answer.get("result");
            String resultStatus = answer.get("resultStatus");
            if (TextUtils.equals(resultStatus, "9000")) {
                Toast.makeText(AlipayActivity.this, "success", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(AlipayActivity.this, "failed", Toast.LENGTH_SHORT).show();
            }
            break;
          default:
            break;
        }
      }
    };
    

    Once a method of communicating the result to the main thread has been established, you can invoke the Alipay SDK using the data contained in the "alipay" section of the Source hash, which can be retrieved by looking at the getSourceTypeData() function on the source. In that sub-hash, there is a "data_string" field, which contains the information the Alipay SDK needs to complete the transaction.

    private void invokeAlipayNative(Source source) {
      Map<String, Object> alipayParams = source.getSourceTypeData();
      final String dataString = (String) alipayParams.get("data_string");
    
      Runnable payRunnable = new Runnable() {
        @Override
        public void run() {
          // The PayTask class is from the Alipay SDK. Do not run this function
          // on the main thread.
          PayTask alipay = new PayTask(MyAlipayActivity.this);
          // Invoking this function immediately takes the user to the Alipay
          // app, if in stalled. If not, the user is sent to the browser.
          Map<String, String> result = alipay.payV2(dataString, true);
    
          // Once you get the result, communicate it back to the main thread
          Message msg = new Message();
          msg.what = SDK_PAY_FLAG;
          msg.obj = result;
          mHandler.sendMessage(msg);
        }
      };
    
      Thread payThread = new Thread(payRunnable);
      payThread.start();
    }
    

    App-to-App Reusable Source

    For a reusable source, the flow is shorter. The required parameter is stored in the "native_url" field of the sub-hash returned from getSourceTypeData(). Use this value as the data of an ACTION_VIEW intent, and invoke startActivityForResult.

    private void invokeAlipayNativeReusable(Source source) {
      Map<String, Object> alipayParams = source.getSourceTypeData();
      String dataString = (String) alipayParams.get("native_url");
      Intent intent = new Intent(Intent.ACTION_VIEW);
      intent.setData(Uri.parse(dataString));
      // Start the activity with your choice of integer request code,
      // here denoted as START_ALIPAY_REQUEST
      startActivityForResult(intent, START_ALIPAY_REQUEST);
    }
    

    When Alipay returns the user to your activity, you can check for failure. Note that RESULT_OK is not always returned for success, but RESULT_CANCELED is always returned by the user backing out.

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      if (requestCode == START_ALIPAY_REQUEST) {
        if (resultCode == Activity.RESULT_CANCELED) {
          // Do not use the source
        } else {
          // The source was approved.
        }
      }
    }
    

    Use web redirects

    If you don't wish to use the app-to-app functionality of the Alipay SDK, you can also allow the user to confirm on the web directly. This method can be done whether or not you have installed the Alipay SDK in your application, though you do still need to set up your activity manifest entry to accept redirect requests. For web-only Alipay access, you can use the getRedirect() sub-hash of the source. From that sub-hash, give the value returned from getUrl() to an ACTION_VIEW intent, and the user is launched directly to a browser, similar to a standard 3DS flow.

    private void invokeAlipayWeb(Source source) {
      String redirectUrl = source.getRedirect().getUrl();
      Intent intent = new Intent(Intent.ACTION_VIEW);
      intent.setData(Uri.parse(redirectUrl));
      startActivity(intent);
    }