Post payments
After making a payment, further actions might be required, such as inquiry, cancellation, and refund.
Payment result notification
When a payment reaches a final state of success or failure, Mobile Payment Partner sends payment result notification to Alipay+.
Process flow
The following figure illustrates the service flow:
Figure 1. Payment result notification flow
The interface request contains the following fields:
No. | Field | Remarks |
1 | paymentResult | The paymentResult.resultStatus field reflects the payment status, with |
2 | paymentRequestId | / |
3 | paymentId Optional | This field is required when paymentResult.resultStatus is |
4 | paymentAmount Optional | This field is required when paymentResult.resultStatus is |
5 | payToAmount Optional | This field is required when paymentResult.resultStatus is |
6 | paymentTime Optional | This field is required when paymentResult.resultStatus is |
7 | customerId Optional | This field is required when paymentResult.resultStatus is |
8 | passThroughInfo Optional | / |
The interface response contains the following field:
No. | Field |
1 | result |
Processing logic
If Alipay+ provides the address to receive payment result notification, Mobile Payment Partner must send notifications to the specified address.
When sending the payment notification request, Mobile Payment Partner must pay attention to the following items:
- When a payment reaches a final state of success or failure, Mobile Payment Partner must send payment result notification to Alipay+.
- Mobile Payment Partner needs to detect whether Alipay+ failed to send the acknowledgment, and has the capability to retry the notification sending. The retry rule is suggested as below:
- Retry 1~2 times within 5 seconds.
- The subsequent intervals increase consecutively. For example, 30s, 1m, 2m, ...
- A total of 15 retries is suggested.
- If the payment failed, Mobile Payment Partner must send a paymentResult.resultStatus of
F
and an error code that is corresponding to a specific reason.
- If the balance is not enough, return a paymentResult.resultCode of
USER_BALANCE_NOT_ENOUGH
- If the user does not exist, or if the status is abnormal, return a paymentResult.resultCode of
USER_NOT_EXIST
/USER_STATUS_ABNORMAL
- Optional: If the payment is declined for risk reasons, return a paymentResult.resultCode of
RISK_REJECT
- Optional: If the payment failed because the payment method used by the Mobile Payment Partner is not available, return a paymentResult.resultCode of
UNAVAILABLE_PAYMENT_METHOD
- Optional: If all payment methods are unavailable, return a paymentResult.resultCode of
NO_PAY_OPTION
- Optional: If the payment is declined because the payment verification is failed, return a paymentResult.resultCode of
USER_PAYMENT_VERIFICATION_FAILED
- Optional: If the payment is declined because the user KYC is failed, return a paymentResult.resultCode of
USER_KYC_NOT_QUALIFIED
- Optional: If the payment is declined because the merchant verification is failed, return a paymentResult.resultCode of
PAYMENT_NOT_QUALIFIED
Mobile Payment Partner might return payment result in one of the following methods:
- The response of the Payment interface
- The request of the notifyPayment interface to send asynchronize notification
- The response of the inquiryPayment interface
No matter which method is used, Mobile Payment Partner must ensure that resultCode and resultStatus are the same. However, one exception is allowed: the payment succeeds (Payment.resultCode is SUCCESS
and Payment.resultStatus is S
), and then the payment is successfully cancelled. In this case, when the inquiryPayment interface is called, the result reads Payment.resultCode is ORDER_IS_CLOSED
and Payment.resultStatus is F
.
Sample
Sample request
{
"paymentResult": {
"resultCode":"SUCCESS",
"resultStatus":"S",
"resultMessage":"success"
},
"paymentRequestId":"2020010123456789****",
"paymentId":"202001012345678901322222",
"paymentTime": "2020-01-01T12:01:01+08:30",
"paymentAmount":{
"value":"100",
"currency":"JPY"
},
"payToAmount":{
"value":"1000",
"currency":"KRW"
},
"customerId":"1234567"
}
Sample response
{
"result": {
"resultCode":"SUCCESS",
"resultStatus":"S",
"resultMessage":"Success"
}
}
More information
See notifyPayment for details.
Query the payment result
Alipay+ can call the inquiryPayment interface to query the payment result of Mobile Payment Partner (MPP) when the payment result notification is not returned timely because of network or system problems.
Process flow
The following figure illustrates the payment status inquiry flow:
Figure 2. Payment status inquiry flow
The interface request contains the following fields:
No. | Field | Remarks |
1 | acquirerId | / |
2 | pspId | / |
3 | paymentRequestId | / |
The interface response contains the following fields:
No. | Field | Remarks |
1 | result | If result.resultStatus is |
2 | paymentResult Optional | The payment result, which is returned only when result.resultStatus is |
3 | paymentRequestId Optional | This field must be returned when the refund is successful. |
4 | paymentId Optional | Must be returned for successful payments when paymentResult.resultStatus is |
5 | paymentAmount Optional | Must be returned for successful payments when paymentResult.resultStatus is |
6 | payToAmount Optional | Must be returned for successful payments when paymentResult.resultStatus is |
7 | paymentTime Optional | Must be returned for successful payments when paymentResult.resultStatus is |
8 | customerId Optional | Must be returned for successful payments when paymentResult.resultStatus is |
9 | passThroughInfo Optional | / |
Processing logic
When processing payment result inquiry requests, Mobile Payment Partner must pay attention to the following items:
- If the payment doesn't exist, return a result.resultStatus of
F
and a result.resultCode ofORDER_NOT_EXIST
. - If the payment exists and is successful, return a result.resultStatus of
S
and a paymentResult.resultStatus ofS
. - If the payment exists but is failed, return a result.resultStatus of
S
and paymentResult.resultStatus ofF
. - If the payment is cancelled, return a result.resultStatus of
S
and paymentResult.resultStatus ofF
. In addition, specify the failure reasons in result.resultCode. - If the payment failed, Mobile Payment Partner must return a result.resultStatus of
S
and an error code that is corresponding to a specific reason.
- If the balance is not enough, return a paymentResult.resultCode of
USER_BALANCE_NOT_ENOUGH
- Optional: If the user does not exist, or if the status is abnormal, return a paymentResult.resultCode of
USER_NOT_EXIST
/USER_STATUS_ABNORMAL
- Optional: If the payment is declined for risk reasons, return a paymentResult.resultCode of
RISK_REJECT
- Optional: If the payment failed because the payment method used by the Mobile Payment Partner is not available, return a paymentResult.resultCode of
UNAVAILABLE_PAYMENT_METHOD
- Optional: If all payment methods are unavailable, return a paymentResult.resultCode of
NO_PAY_OPTION
- Optional: If the payment is declined because the user verification is failed, return a paymentResult.resultCode of
USER_PAYMENT_VERIFICATION_FAILED
- Optional: If the payment is declined because the user KYC is failed, return a paymentResult.resultCode of
USER_KYC_NOT_QUALIFIED
- Optional: If the payment is declined because the merchant verification is failed, return a paymentResult.resultCode of
MERCHANT_NOT_REGISTERED
- When no response is received, Alipay+ retries the request at incremental time intervals for about 10 minutes.
Sample
Sample request:
{
"acquirerId": "102218800000000****",
"pspId":"102217200000000****",
"paymentRequestId":"2020010123456789****"
}
Sample response:
{
"result": {
"resultCode":"SUCCESS",
"resultStatus":"S",
"resultMessage":"Success"
},
"paymentResult": {
"resultCode":"SUCCESS",
"resultStatus":"S",
"resultMessage":"Success"
},
"paymentId":"2020010123456789013****",
"paymentTime": "2020-01-01T12:01:01+08:30",
"paymentAmount":{
"value":"100",
"currency":"JPY"
},
"payToAmount":{
"value":"1000",
"currency":"KRW"
},
"customerId":"123****"
}
More information
See inquiryPayment for details.
Cancel the transaction
When Alipay+ does not receive the payment result from MPP within 1 minute after the payment is initiated, or when the inquiry of the payment result remains unknown within 1 minute after the payment is initiated, Alipay+ closes the transaction and initiates the cancellation request to MPP.
Process flow
The following figure illustrates the flow of payment cancellation initiated by Alipay+:
Figure 3. Flow of payment cancellation initiated by Alipay+
The interface request contains the following fields:
No. | Field | Remarks |
1 | acquirerId | / |
2 | pspId | / |
3 | paymentRequestId | MPP uses this field for the idempotence control. For cancellation requests which are initiated with the same |
The interface response contains the following field:
No. | Field |
1 | result |
Processing logic
When cancel a payment, MPP must pay attention to the following items:
- The payment can only be cancelled within the agreed cancellable period, which is from the time when the transaction is initiated to 00:30 UTC+8 of T+1 day. The cancellable period is extended to T+1 day so that MPP can cancel payments for transactions that are initiated at around 24:00 UTC+8 of T day.
- When the cancellation request is initiated within the agreed time window, the MPP needs to ensure that the cancellation is successful and return a response that indicates successful cancellation to Alipay+, regardless of the payment status (success, failure or in process). This prevents complaints from users when an order is successfully canceled at the merchant side but no refund is received due to cancellation failures at the MPP side. In detail, the MPP needs to process the cancellation request as below.
- If the payment is successful, cancel the payment.
- If the payment does not exist or is failed, return cancellation success. When a payment request that has the same paymentRequestId with the non-existent payment is sent to MPP, MPP must reject the request.
- If the payment is being processed, close the transaction and ensure that no payment occurs for the order.
- When no response is received, Alipay+ retries the request at incremental time intervals for about 2 hours.
Sample
Sample request:
{
"acquirerId": "1022188000000000001",
"pspId":"1022172000000000001",
"paymentRequestId":"20200101234567890132"
}
Sample response:
{
"result": {
"resultCode":"SUCCESS",
"resultStatus":"S",
"resultMessage":"Success"
}
}
More information
See cancelPayment for details.
Refund the payment
The refund interface can be used to return funds to users based on successful payment transactions. When the foreign exchange process is involved in the payment process, Alipay+ performs the refund based on the original payment rate or market rate according to the contract.
Process flow
The following figure illustrates the refund flow:
Figure 4. Refund flow
The interface request contains the following fields:
No. | Field | Remarks |
1 | acquirerId | / |
2 | pspId | / |
3 | paymentRequestId | / |
4 | refundRequestId | This field is used for the idempotence control. For the refund requests with the same refundRequestId and reach a final status ( |
5 | refundAmount | The value of refundAmount.currency and payAmount.currency must be the same. If multiple refunds exist for a particular PaymentOrder, the total successful refunded amount must not exceed the value of paymentAmount in paymentOrder. |
6 | refundFromAmount | The value of refundFromAmount.currency and payToAmount.currency must be the same. In the guaranteed price model, if multiple refunds exist for a particular PaymentOrder, the total successful refunded amount must not exceed the value of paymentAmount in paymentOrder. |
7 | refundQuote Optional | This field is required if the value of refundAmount.currency isn't equal to that of refundFromAmount.currency. The value of this field is the same as that of paymentQuote for the guaranteed price model. |
8 | refundPromoInfo Optional | This field is required when the promotion is applied. |
9 | surchargeInfo Optional | Specify this field if surcharge information exists in the payment that is related to this refund request. |
The interface response contains the following fields:
No. | Field | Remarks |
1 | result | If result.resultStatus is |
2 | refundId Optional | This field must be returned when the refund result is successful. |
3 | refundTime Optional | This field must be returned when the refund is successful. |
Processing logic
General refund
When processing refund requests, MPP must pay attention to the following items:
- You must ensure that the refund is successful and refund funds to the user as soon as possible. This prevents complaints from users when a transaction is successfully refunded at the merchant side but no refund is received by the user due to failures at your side.
- Support full refund, partial refund, and multiple partial refunds. The total amount of multiple partial refunds cannot exceed the original amount paid by the user.
- The refund time window should be at least 366 days.
- Support refund requests with the same refundRequestId by performing idempotence control.
- When no response is received, Alipay+ retries the request at incremental time intervals for about 2 hours.
Unable to process refund disputes
If the MPP is unable to process refund disputes, it's suggested that the MPP returns Success for all refund requests.
Promotion exists
If promotion exists, refund according to the refundFromAmount field.
Surcharge exists
If surcharge exists, pay attention to the surchargeAmount field when you perform the refund.
Sample
Sample request:
{
"acquirerId": "102218800000000****",
"pspId":"102217200000000****",
"paymentRequestId":"20181129190741010007000000****",
"refundRequestId":"20181129190741020007000000****",
"refundAmount":{
"value":"90",
"currency":"JPY"
},
"refundFromAmount":{
"value":"900",
"currency":"KRW"
},
"refundQuote":{
"quoteId":"123****",
"quoteCurrencyPair":"JPY/KRW",
"quotePrice":"10.0000"
}
}
Sample response:
{
"result": {
"resultCode":"SUCCESS",
"resultStatus":"S",
"resultMessage":"Success"
},
"refundId":"20181129190741020007000000****",
"refundTime": "2020-10-10T12:01:01+08:30"
}
More information
See refund for details.
Inquiry user information
Merchants can use the access token to retrieve the user information to display on merchant pages such as the receipt page. The MPP must verify the corresponding scope of the access token in the request.
Process flow
The interface request contains the following fields:
No. | Field |
1 | pspId |
2 | acquirerId |
3 | accessToken |
The interface response contains the following fields:
No. | Field | Remarks |
3 | result | / |
4 | userInfo Optional | Hash that uses MD5 to describe the user login ID. When the user login ID is a phone number, the number is expressed as an E.164 number. The format is +{country code}{area code with leading 0 removed}{number}. For example, +14154567899 is a US mobile phone number with country code as 1, area code as 415, and the local number as 4567899. The UK mobile phone number (020) 4455 5666 transformed into E.164 is +442044555666, where 44 is the country code, 20 is the area code. |
5 | passThroughInfo Optional | / |
Processing logic
Requirements
- The MPP must verify whether the access token is correct. If not, return a result.resultCode of
INVALID_TOKEN
- The MPP must verify whether the access token is within the expiry date. If not, return a result.resultCode of
INVALID_TOKEN/EXPIRED_ACCESS_TOKEN
The MPP returns different user information according to the scope value:
- When the scope is
BASE_USER_INFO
, the MPP returns userId. - When the scope is
USER_LOGIN_ID
, the MPP returns userLoginId. - When the scope is
HASH_LOGIN_ID
, the MPP returns hashLoginId. - When multiple scopes are specified for the same access token, the MPP returns all information of the corresponding scopes.
- When the scope does not contain user information related values, for example, if the scope value is
AGREEMENT_PAY
, the resultStatus must beF
, and the MPP must return anINVALID_TOKEN
error.
Note: In certain country/region, per regulation requirements, when the value of the scopes field in the prepare API request includes
USER_LOGIN_ID
, the MPP must mask the user login ID to protect sensitive information when handling the inquireUserInfo API requests.
Sample
Request sample:
{
"acquirerId": "102218800000000****",
"pspId":"102217200000000****",
"accessToken":"2810060320191123miS088290002****",
}
Response sample:
{
"result": {
"resultCode": "SUCCESS",
"resultMessage": "Success",
"resultStatus": "S"
},
"userInfo":{
"userId":"0b9e3097157587196046311763****",
"userLoginId":"+44205666****",
"hashUserLoginId":"87e8429bfd31541acb1156e3bb35****"
}
}
More information
See inquiryUserInfo for details.
Optional: Query the user ID
The merchant customer service can use the inquiryCustomerId interface to verify whether the user identity is valid. This interface is only applicable to some special scenarios. For example, the user contacts the merchant customer service for help or complaint about one payment. However, the MPP does not return the plaintext user login ID in the inquireUserInfo interface response for security reasons. The merchant customer service will ask the user to provide the login ID, then uses the login ID to query the user ID to verify the user identity.
Sample
Sample request:
{
"acquirerId": "102218800000000****",
"pspId":"102217200000000****",
"inquiryType": "BY_LOGIN_ID",
"plaintextUserLoginId": "+44204455****"
}
Sample response:
{
"result": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "Success"
},
"customerId": "0b9fc028157180258292517484****"
}
More information
See inquiryCustomerId for details.