/v1/payments/refund
POST /v1/payments/refund
The refund
Ā API is used to initiate a refund of a successful payment, refund a transaction and return money to the payer. The transaction can be refunded partially or fully. This API returns SUCCESS
Ā when deducting money from the merchant is successful.
Note:
1) The merchant/partner submits a refund request to wallets directly
2) Wallets determines whether the refund is successful based on its own payment status and respond to merchants/partners.
3) Multiple refund requests are supported for one successful payment, but the total refund amount can not be greater than the payment amount.
4) This API returns SUCCESS
only means deducting money from the merchant is successful. The merchant can use the inquiryRefund API to determine the refund to payer status in the asynchronous refund processing scenario.
Note: All monetary values in the fields of request and response in their smallest currency units, and for IQD, the smallest unit is fils. Thus, if a transaction amount is 150 IQD, the value will be gaven as 150000.
Message structure
A message consists of a header and body. The following sections are focused on the body structure. For the header structure, seeļ¼
Request
Property | Data type | Required | Description | Example |
refundRequestId | StringĀ | Yes | The unqiue ID of a refund generated by merchants.
| "2023112719074101000700000088881xxxx" |
paymentId | StringĀ | No | TheĀ unqiueĀ ID of the corresponding original payment. Max. length: 64 characters. | "2023120611121280010016600090000xxxx" |
paymentRequestId | StringĀ | No | The paymentRequestId for the corresponding original payment. Max. length: 64 characters. | "20230101234567890133333xxxx" |
captureId | String | No | The unique ID for a capture request generated by the wallet. Max. length: 64 characters | "202311271907410100070000007776xxxx" |
refundAmount | Amount | Yes | Refund amount. | { Ā Ā "currency": "IQD", Ā Ā "value": "10000" Ā } |
refundReason | StringĀ | No | Refund reason. Max. length: 256 characters. | "have returned goods to the shop" |
extendInfo | StringĀ | No | The extend information, wallets and merchants can put extending information in this property.Ā The format shoud be JSON format. Max. length: 2048 characters. | "extendInfo: This is additional information" |
Response
Property | Data type | Required | Description | Example |
result | Yes | The request result, which contains information such as status and error codes. | { Ā Ā "resultCode": "SUCCESS", Ā Ā "resultStatus": "S", Ā Ā "resultMessage": "Success." Ā } | |
refundId | StringĀ | No | Unique refund order number. It isĀ generated by Wallet, which uniquely identifies the refund. It is mandatory when the result.resultStatus is S.Max. length: 64 characters. | "2023120611121280130016600090000xxxx" |
refundTime | String/Datetime | No | Deduct money from merchant success time, after then will start to refund money to user.Ā which follows theĀ ISO 8601Ā standard.Ā It is mandatory when the result.resultStatus is S. | "2023-11-27T12:01:01+08:30" |
Result Process Logic
In the response, the result.resultStatus
field indicates the result of processing a request as follows.
resultStatus | DecriptionĀ |
S | The corresponding It means thatĀ deducting money from the merchant is successful, the merchant/partner can process as success. |
U | The corresponding It means that when handling the refund request, an unknown exception occurs. The merchant/partner can call the Refund Inquiry ( What needs to note is as follow:
If other response (almost never occur), the merchant/partner should process like U. |
F | That means this transaction is failed.Ā The corresponding It means that the refund is failed. The failure reasons can be the followings, but not limited to:Ā Ā
For details, see the followingĀ Error codes section. |
Error codes
Error codes are usually classified into the following categories:
- Common error codes: are common for all Mini Program OpenAPIs. Ā
- API-specific error codes: are listed in the following table.
resultStatus | resultCode | resultMessage |
U | REFUND_IN_PROCESS | Refund is under processing. |
F | MULTI_REFUND_NOT_ALLOWED | Multiple refund not allowed in agreement. |
F | REFUND_NOT_ALLOWED | Refund not allowed in agreement. |
F | REPEAT_REQ_INCONSISTENT | Repeated submit, and requests are inconsistent. |
F | PARTNER_STATUS_ABNORMAL | The partner status is abnormal. |
F | ORDER_NOT_EXIST | The order does not exist. |
F | ORDER_STATUS_INVALID | The order status is invalid, such as CLOSED |
F | REFUND_WINDOW_EXCEED | Exceed Refund window. |
F | REFUND_AMOUNT_EXCEED | The total refund amount has exceed the payment amount. |
F | PARTNER_BALANCE_NOT_ENOUGH | The partner balance is not enough. |
F | CURRENCY_NOT_SUPPORT | The currency is not supported. |
F | USER_NOT_EXIST | The user does not exist. |
F | USER_STATUS_ABNORMAL | The user status is abnormal. |
Sample
For example, a wallet user applies for refund of 100 IQD of a successful payment at the merchant/partner. So the merchant/partner will call this refund API to the wallet to refund money to users.
- The Mini ProgramĀ calls this my.getAuthCode JSAPI with specific scopes(USER_ID) to request an authorization code.
- The E-wallet App service calls authorization service to processes the authorization information.
- The E-wallet backend verifies the authorization information, generates the authCode and returns.
- The E-wallet App service returns the authCode to the Mini Program.
- The Mini Program sends the authCode to the merchant backend.
- The merchant backend calls theĀ applyTokenĀ APIĀ withĀ authCodeĀ to apply theĀ accessToken.
- The E-Wallet backend returnsĀ accessTokenĀ information to the merchant backend, such asĀ customerId, accessToken, refreshToken, etc.
- The Mini Program creates an order with customerId.
- The merchant backend calls the payment API to initialte payment flow, including customerId as referenceBuyerId, paymentNotifyUrl(optional), etc.
- The E-Wallet backend returns payment detail information the merchant backend, such as redirectionUrl.
- The merchant backend passes the payment detail information to the Mini Program.
- The Mini Program calls the my.tradePay JSAPI with redirectionUrl to conduct the payment.
- The E-Wallet App Service displays the cashier page with order information, such as amount, order details, etc.
- The user confirms the payment in the cashier page.
- The E-Wallet App Service calls payment service and execute the payment process.
- When the payment reaches the final status, the E-wallet backend returns the payment result to the Mini Program (Step 18).
- Also the E-wallet backend notifies the merchant backend of the payment result with paymentNotifyUrl provided in Step 10(Step 19).
- Finally, E-wallet backend notifies the user of the payment result via SMS/Email/Inbox message (Step 20).
- After the service or goods has been delivered, the user could start a fully refund or partial refund in the Mini Program or the merchant cashier (Step 21).
- The Mini Program sends the refund request to merchant backend, and the merchant backend calls the refund API to refund the money(Step 23).
- The E-Wallet backend returns the refund result to the merchant backend.
- And the Mini Program displays the refund result to the user(Step 26).
- When the E-Wallet backend returns the resultCode as REFUND_IN_PROCESS, the merchant can call
inquiryRefund
API to query refund result (Step 27).
Request
{
"refundRequestId": "2023112719074101000700000088881xxxx",
"paymentId": "2023120611121280010016600090000xxxx",
"refundAmount": {
"currency": "IQD",
"value": "10000"
}
}
- refundRequestId is the unique ID of this refund request, generated by merchant/partner, merchant/partner should make sure it is unique, because wallet will use refundRequestId to do idempotent process.
- paymentIdĀ is the payment ID generated by Wallet, which is the unique payment identifier associated with this refund.
- refundAmountĀ describes 100 IQD should refund to user, refund amount should less than origin payment amount. The amount to pay out for this refund.refundAmount.currency and paymentAmount.currency in payment request are the same. And if there are multiple refunds for a particular payment, the total successful refunded amount cannot exceed the payment amount in the payment transaction.
Note:
- paymentId and paymentRequestId and captureId can not both empty, wallet has to find out the origin payment order based on paymentId or paymentRequestId or captureId.
Response
{
"result": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "Success."
},
"refundId": "2023120611121280130016600090000xxxx",
"refundTime": "2023-11-27T12:01:01+08:30"
}
- result.resultStatus==S shows that the Wallet refund is successful.
- refundId is generated by Wallet, uniquely identifies the refund.
- refundTime describes the success date time of this refund.