Alipay+ DocsAlipay+ Docs

Accept payments

This chapter goes through the process of integrating the capability of accepting payments by using Alipay+ client SDK and Alipay+ APIs.

To make a payment, the MPP needs to take the following steps:

The process is used in the scenario where a user uses an MPP app to present a payment code to the merchant.

Workflow

To accept a payment, the MPP must obtain the payment code before proceeding with the payment process.

The following figure illustrates the payment flow:

标准SDK见码可付反扫时序图.png

Figure 1: Payment workflow

The payment flow consists of the following steps:

  1. The user opens the Payment Code page in the MPP app (Step 1).
  2. The MPP app calls the getAcceptanceMarkLogos API from Alipay+ client SDK to obtain the logos of acceptance marks (Step 2).
  3. The MPP app obtains the logos of acceptance marks and displays them on the Payment Code page (Steps 3-4).
  4. When the user opens the payment code page, the MPP app also initiates a request for a payment code (Step 5).
  5. The MPP app calls the getPaymentCode API to request the payment code from Alipay+ client SDK (Step 6).
  6. Alipay+ client SDK creates a session with Alipay+ . If a session already exists, this step is skipped (Step 7).
  7. Alipay+ client SDK obtains the payment code from Alipay+ and returns it to the MPP app (Steps 8-10).
  8. The MPP app displays the payment code (Step 11).
  9. The merchant scans the payment code and then sends a request to initiate a payment (Steps 12-14).
  10. Alipay+ decodes the payment code to obtain customerId and calls the pay API to send the order information with customerId to the MPP server (Steps 15-16).
  11. The MPP server processes the payment and returns the payment result to Alipay+ (Steps 17-18).
  12. Alipay+ returns the payment result to the merchant (Steps 19-20).
  13. The MPP server sends the payment result notification to the MPP app, which then displays the payment result page to the user (Steps 21-22).

Before you begin

Before you start the integration with Alipay+ User-presented Mode Payment product, ensure that you integrate Alipay+ client SDK. See Alipay+ client SDK integration guide for details.

Step 1: Establish a session between Alipay+ client SDK and Alipay+

Note: Skip this step if the session is already created.

To ensure secure communication between Alipay+ and Alipay+ client SDK, a session is created.

The following figure illustrates the workflow of establishing a session:

workflow of establishing a session(标准SDK).png

Figure 2. Workflow of establishing a session

Complete the following steps to establish a session:

  1. Alipay+ client SDK calls the getAuthCode API to obtain the authorization code from MPP app (Step 1).
  2. The MPP app obtains the authorization code from its server and then returns it to Alipay+ client SDK (Steps 2-4).
  3. Alipay+ client SDK sends the authorization code to Alipay+(Step 5).
  4. Alipay+ calls the applyToken API to obtain the access token from the MPP server and the MPP server returns the access token and customer ID to Alipay+ (Steps 6-8).
  5. Alipay+ creates the session ID (Step 9).
  6. Alipay+ returns the session ID to Alipay+ client SDK and the session is created (Step 10).

Read the following sections for the main steps:

Step 1.1: Call the getAuthCode API to obtain the authorization code

Alipay+ client SDK calls the getAuthCode API to obtain the authorization code from MPP. The value of scopes is BASE_USER_INFO. MPP returns the authorization code by authCallback. For the samples for Android and iOS, see Alipay+ client SDK integration guide.

Step 1.2: Obtain the access token and customer ID from the MPP

Alipay+ client SDK sends the authorization code to Alipay+. With the authorization code received, Alipay+ calls the applyToken API to request an access token. In this case, the value of acquirerId is fixed as 2052666000000000, which represents Alipay+.

Alipay+ can request an access token with the authCode received.

Process flow

The API request contains the following fields:

No.

Field

Remarks

1

pspId

/

2

acquirerId

/

3

grantType

Specify the value as AUTHORIZATION_CODE

4

authCode

The authCode generated by MPP must be within 32 bits. The first 8 digits of the authorization code must be in the format of 281***13. The fourth to sixth digits are assigned by Alipay+. An authCode can only be used once, and if an authCode is used for a second time, an INVALID_AUTHCODE error will be returned.

5

refreshToken

Optional

Required when grantType is REFRESH_TOKEN. When grantType is REFRESH_TOKEN,,, refreshToken is used to retrieve accessToken. MPP uses this field for the idempotence control. For the requests of retrieving a new access token with the same refreshToken, MPP must return the same values for the required fields.

6

passThroughInfo

Optional

/

The API response contains the following fields:

No.

Field

Remarks

3

result

If result.resultStatus is F or U, the AuthClient can guide the user to try again.

4

accessToken

Optional

Required when the authorization token application request is successful, the AuthClient can use accessToken to access the corresponding user's resource scope. This token must be within 128 bits. 

5

accessTokenExpiryTime

Optional

Must be returned when the authorization token application request is successful.

6

refreshToken

Optional

Must be returned when the authorization token application request is successful. This token must be within 128 bits. 

7

refreshTokenExpiryTime

Optional

Must be returned when the authorization token application request is successful.

8

customerId

Optional

Must be returned when the authorization token application request is successful.

9

passThroughInfo

Optional

/

Processing logic

If the value of scopes is BASE_USER_INFO, it is recommended that you set the validity period of the access token to 10 minutes when generating the access token.

Sample

Request sample

copy
{
  "acquirerId":"10221880000000****",
  "pspId":"10220880000000****",
  "authCode": "281010133AB2F588D14B43231234****",
  "grantType": "AUTHORIZATION_CODE",
}

Response sample

copy
{
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "Success",
    "resultStatus": "S"
  },
  "accessToken": "281010033AB2F588D14B43238637264FCA5A****",
  "accessTokenExpiryTime": "2019-06-06T12:12:12+08:00",
  "refreshToken": "2810100334F62CBC577F468AAC87CFC6C910****",
  "refreshTokenExpiryTime": "2019-06-08T12:12:12+08:00",
  "customerId":"278980891233213455671****"
}

For more information about how to use the API (such as the parameter description), see applyToken for details.

Step 1.3: Alipay+ creates the session and returns the session ID to Alipay+ client SDK

Alipay+ creates the session, and associates sessionId with the returned customerId and accessToken. Alipay+ returns the session ID to Alipay+ client SDK. The session is created between Alipay+ and Alipay+ client SDK.

By default, the validity period of the session is 30 minutes (set by Alipay+ for security reasons). Auth login is normally valid for 360 hours unless the user logout.

Step 2: Obtain logos of acceptance marks and payment code

To render the payment code page, the MPP needs to obtain both the logos of the acceptance marks and the payment code.

Obtain logos of acceptance marks

To obtain the logos of the acceptance marks, the MPP client needs to call the acceptanceMarkLogos API from Alipay+ client SDK. The following figure illustrates the workflow of obtaining logos of acceptance marks.

正扫见码可付(标准SDK).png

Figure 3. The workflow of obtaining logos of acceptance marks

The process of obtaining the logos of acceptance marks consists of the following steps:

  1. The user opens the Payment Code page in the MPP app (Step 1).
  2. The MPP app calls the getAcceptanceMarkLogos API from Alipay+ client SDK to obtain the logos of acceptance marks. The MPP can determine whether to pass in the region parameter in the API request (Step 2).
  3. (Optional) If the configuration information is not cached locally or if more than 60 minutes are elapsed since Alipay+ client SDK last pulls the configuration information, Alipay+ client SDK calls the fetchConfig API to obtain the configuration information from the Alipay+ server (Steps 3-4).

Note:

The time interval between two pulls is configurable and the default time interval is 60 minutes.

  1. The MPP app obtains the logos of acceptance marks in either of the following ways: (Steps 5-9)
    • If the region parameter is not passed in by the MPP, Alipay+ client SDK determines the user's current location based on the cellular service provider information and/or the time zone obtained from the MPP app. Alipay+ client SDK then retrieves the logos of acceptance marks from the configuration information and returns them to the MPP app.
    • If the region parameter is passed in by the MPP, Alipay+ client SDK directly obtains the logos of acceptance marks from the configuration information and returns them to the MPP app.

Note:

    • If Alipay+ is not supported in the user's current location, Alipay+ client SDK returns an empty array.
    • Since the Alipay+ logo is mandatory to be displayed on the Payment Code page, the MPP needs to configure the Alipay+ logo in advance and Alipay+ client SDK does NOT return the Alipay+ logo.
  1. The MPP app displays the logos of acceptance marks accordingly on the Payment Code page (Step 10).

Obtain the payment code

Complete the following steps to obtain the payment code fromAlipay+ client SDK:

  1. Initialize Alipay+ client SDK
  2. Call the getPaymenCode API to obtain the payment code

1. Initialize Alipay+ client SDK

Before Mobile Payment Provider uses the features provided by Alipay+ client SDK, call the init API that is for Android or the initWithContext API that is for iOS to initialize the Alipay+ client SDK first.

For more information about the samples for initializing the Alipay+ Android client SDK, see Step 3: Initialize SDK in your app.

For more information about the samples for initializing the Alipay+ iOS client SDK, see Step 3: Initialize SDK in your app.

2. Call the getPaymenCode API to obtain the payment code

The Mobile Payment Provider app calls the getPaymentCode API to obtain the payment code from Alipay+ client SDK.

Note: When calling the getPaymentCode API, the MPP app must pass in information about the region that is selected by the user. The region list that is displayed for selection must be configurable at the MPP server side.

Processing logic

If the getPaymentCode call succeeds, Mobile Payment Provider must display the payment code. And, if the call fails, Mobile Payment Provider must be able to automatically retry. In addition, Mobile Payment Provider should be able to manually switch the region.

Sample

Android:

copy
String region = "CN";
IAPConnect.getPaymentCode(region, new IPaymentCodeListener() {
    @Override
    public void onPaymentCodeUpdated(String paymentCode) {
        // handle the payment code
    }

    @Override
    public void onPaymentCodeUpdateFailed(String errorCode, String errorMessage) {
        // handle the error information
    }
});

iOS:

copy
[AlipayConnect getPaymentCode:@"CN" paymentCodeListener:self];

After the getPaymentCode API is called, Alipay+ client SDK sends the request of obtaining the payment code to Alipay+ by using sessionId. Alipay+ returns the payment code to Alipay+ client SDK. After that, Alipay+ client SDK returns the payment code to Mobile Payment Provider app by paymentCodeListener (TheMobile Payment Provider app must implement the IAPConnectPaymentCodeListener protocol to obtain the code).

copy
#pragma mark - IAPConnectPaymentCodeListener

- (void)onPaymentCodeUpdateFailed:(IAPConnectResultCode)resultCode resultMessage:(NSString *)resultMessage {
    
}

- (void)onPaymentCodeUpdated:(NSString *)paymentCode {
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.mixedCodeView updatePaymentCode:paymentCode];
    });
}

Step 3: Process the payment

Mobile Payment Provider needs to process the payment requests sent from Alipay+ by using the pay API.

Process flow

The API request contains the following fields:

No.

Field

Remarks

1

acquirerId

/

2

pspId

/

3

order

In User-presented Mode PaymentisInStorePayment is true, and merchant.store must be provided.

4

paymentRequestId

This field is used for the idempotence control. For the payment requests which are initiated with the same paymentRequestId and reach a final status (S or F), MPP must return the unique result.

5

paymentAmount

The amount that Mobile Payment Provider requests to receive in the currency that A+ uses to create the payment order. If promotion exists, this is the amount that excludes the promotion amount.

6

payToAmount

The amount that Mobile Payment Provider settles to Alipay+ in Mobile Payment Provider's currency. When Mobile Payment Provider's currency is different from the merchant's currency, the following equation applies:

payToAmount.value=paymentAmount.value*paymentQuote.quotePrice.

7

paymentMethod

For User-presented Mode Payment, isInStorePayment is true and isCashierPayment is falsepaymentMethodType (value is CONNECT_WALLET), paymentMethodId (value is same as that of paymentCode), and customerId (when the paymentCode is generated by Alipay+) must be provided.

8

paymentFactor

The following rules apply:

  • needSurcharge must be true if surcharge function is used. 
  • For User-presented Mode Payment, isInStorePayment must be provided as true.
  • For the payment that requires cross-border settlement, isCrossborderSettlement must be true.

9

paymentQuote

Optional

Required when paymentAmount is not equal to payToAmount. The value of payToAmount is computed based on values of paymentAmount and paymentQuote, by using a rounding mode of HALF_EVEN.

This field is only used when payToAmount.currency is not the same as paymentAmount.currency.

10

paymentExpiryTime

Required when payment is required to be successful before the expiration time.  

11

paymentNotifyUrl

Optional

/

12

paymentRedirectUrl

Optional

/

13

paymentPromoInfo

Optional

Required when the promotion is applied to the payment.

14

surchargeInfo

Optional

Required when paymentFactor.needSurcharge is true.

17

passThroughInfo

Optional

/

The API response contains the following field:

No.

Field

Remarks

1

result

If result.resultCode is UNKNOWN_EXCEPTION, all optional response fields are not required.

4

paymentId

Must be returned when the payment is successful.

5

paymentUrl

/

6

paymentTime

Must be returned when the payment is successful.

7

paymentAmount

Optional

/

8

payToAmount

Optional

/

9

customerId

Optional

Must be returned when the payment is successful.

11

passThroughInfo

Optional

Processing logic

When processing payment requests, Mobile Payment Provider must pay attention to the following items:

  • Use the timeout value assigned by Alipay+, if Alipay+ does not provide the timeout value, for User-presented Mode Payment, set the timeout value as 1 minute at most. When timeout occurs, Mobile Payment Provider closes the payment order and returns an error code ORDER_IS_CLOSED.
  • Mobile Payment Provider must be able to handle payment requests with specified customerId (paymentMethod.customerId).
  • Mobile Payment Provider must be able to check the idempotency of payment requests by using paymentRequestId.
  • Support all the currencies as defined in ISO 4217.
  • Mobile Payment Provider must be able to synchronously return the payment result.
  • Exceptional case:
    • Check whether the balance is enough. If not, return a result.resultCode of USER_BALANCE_NOT_ENOUGH.
    • Mobile Payment Provider must verify the user status (especially, if user is allowed to login when the account is frozen). if the status is abnormal, return a result.resultCode of USER_STATUS_ABNORMAL.  
    • Optional: If the payment is declined for risk reasons, return a result.resultCode of RISK_REJECT.
    • Optional: If the payment failed because the payment method used by the Mobile Payment Provider is not available, return a result.resultCode of UNAVAILABLE_PAYMENT_METHOD.
    • Optional: If the payment is declined because the payment verification is failed, return a result.resultCode of  USER_PAYMENT_VERIFICATION_FAILED.
    • Optional: If the payment is declined because the user KYC is failed, return a result.resultCode of  USER_KYC_NOT_QUALIFIED.
    • Optional: If the payment is declined because the merchant verification is failed, return a result.resultCode of MERCHANT_NOT_REGISTERED.

Payment amount limitation exists

If payment amount limitation exists, Mobile Payment Provider must pay attention to the following items:

  • Check whether the amount exceeds the payment amount limit of a single transaction. If yes, return an error code PAYMENT_AMOUNT_EXCEED_LIMIT
  • Check whether the accumulated amount exceeds the limit. If yes, return an error code USER_AMOUNT_EXCEED_LIMIT
  • Check whether the payment times exceed the limit. If yes, return an error code PAYMENT_COUNT_EXCEED_LIMIT

Promotion exists

If a promotion exists, the amount user actually pays is specified in the payToAmount field.

Sample

Request:

copy
{
  "order": {
    "referenceOrderId": "OrderID_010101****",
    "orderDescription": "SHOES",
    "orderAmount": {
      "value": "100",
      "currency": "JPY"
    },
    "merchant": {
      "referenceMerchantId": "M00xxxxx0001",
      "merchantMCC": "1405",
      "merchantName": "UGG",
      "merchantAddress": {
        "region": "JP",
        "city": "xxx"
      },
      "store": {
        "referenceStoreId": "S00xxxx0001",
        "storeName": "UGG-2",
        "storeMCC": "1405"
      }
    }
  },
  "acquirerId": "102218800000000****",
  "pspId": "102217200000000****",
  "paymentRequestId": "201811291907410100070000007****",
  "paymentAmount": {
    "value": "100",
    "currency": "JPY"
  },
  "paymentMethod": {
    "paymentMethodType": "CONNECT_WALLET",
    "paymentMethodId": "281006050000000000125733DAHJ****",
    "customerId":"2160xxxxxxxxxxx1"
  },
  "payToAmount": {
    "value": "1000",
    "currency": "KRW"
  },
  "paymentQuote": {
    "quoteId": "1234567",
    "quoteCurrencyPair": "JPY/KRW",
    "quotePrice": "10.0000"
  },
  "paymentFactor": {
    "isInStorePayment": "true"
  }
}

Response:

copy
{
 "result": {
    "resultCode":"SUCCESS",
    "resultStatus":"S",
    "resultMessage":"Success"
 },
 "paymentId":"201xxxxxxxxxxxxxxxxxxxxxxx4444",
 "paymentTime": "2020-01-01T12:01:01+08:30",
 "customerId":"1234567"
}

For more information about how to use the API (such as the parameter description), see pay for details.