POST /v1/payments/pay creates payment orders within the wallet. The endpoint supports three flows:
paymentAuthCode) to charge the user without presenting the cashier.All monetary amounts in requests and responses must be expressed in the smallest currency unit (IQD fils). For example, 100 IQD equals 100000.
| Method | Path |
|---|---|
POST | /v1/payments/pay |
A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see: OpenAPIs Overview.
| Field | Type | Required | Description |
|---|---|---|---|
productCode | string | Yes | Defined by wallets. The wallet uses the productCode to get the contract configuration which includes fee, limitation information, and so on. Max. length: 32 characters. Examples: • Online Purchase: "51051000101000000011"• Online Purchase (Auth Capture): "51051000101000000012"• Agreement Payment: "51051000101000100031"• Escrow Payment: "51051000101000100008" |
paymentRequestId | string | Yes | The unique ID of a payment generated by merchants. • Max. length: 64 characters. • This field is used for idempotence control. For the payment requests which are initiated with the same paymentRequestId and reach a final status (S or F), the wallet must return the unique result. |
paymentAuthCode | string | No* | The payment auth code generated by the wallet, such as the accessToken in the agreement pay scenario. Max. length: 128 characters.*Required for Agreement Payment scenario only. |
paymentAmount | object | Yes | The order amount, displaying users' consumption records, payment results page. Note: The monetary unit of value is fils, e.g. if the price is 100 IQD, then the paymentAmount.value should be "100000". |
paymentAmount.currency | string | Yes | Currency code (e.g., "IQD"). |
paymentAmount.value | string | Yes | Amount value in smallest currency unit (fils). |
order | object | Yes | The purchase order details, such as Merchant, Buyer, Goods, etc. The information in the Order is only used to display user's payment result page and transactions history, regulation reporting, etc. It will not make use of the amount in the order for fund operation. Note: The buyer field is optional only in the Agreement Payment scenario. |
order.orderDescription | string | Yes | Description of the order. |
order.buyer | object | No* | Buyer information. *Optional in Agreement Payment, required in Cashier Payment. |
order.buyer.referenceBuyerId | string | Yes | The unique userId, which can be the customerId obtained from accessToken information in applyToken API. It must not be default.️ Important: Please make sure the buyer and the payer is the same person. |
paymentExpiryTime | string/datetime | No | The payment order close time defined by merchant, which means the payment order will be closed automatically after paymentExpiryTime. If empty, the expiryTime will be defined by E-wallet. It follows the ISO 8601 standard. |
paymentRedirectUrl | string | No | The redirect URL defined by merchants. Max. length: 1024 characters. |
paymentNotifyUrl | string | No | The payment success notification URL defined by merchants. Max. length: 1024 characters. |
voidNotifyUrl | string | No | The url that void notification will be sent to. Max. length: 1024 characters. |
extendInfo | string | No | The extensive information. The wallet and merchant can put extensive information in this property. The format should be JSON format. Max. length: 2048 characters. |
In this mode the merchant redirects the user to the wallet cashier embedded in the Mini Program.
For example, a user purchases a 100 IQD good at the merchant/partner (online merchant usually), the merchant/partner calls this API to create the payment order first, the wallet will return the payment order ID and wallet cashier page URL to the merchant/partner, then merchant/partner can redirect user to wallet cashier page with the my.tradePay API.
| Field | Type | Required | Description |
|---|---|---|---|
paymentRedirectUrl | string | No | Merchant URL displayed when the user finishes or cancels the payment. Max 1024 characters. |
order.buyer | object | Yes | Required for cashier payment. |
{
"productCode": "51051000101000000011",
"paymentRequestId": "UDQzzvxwvyvUDxGqhMHUlIBpGkydOQC6",
"paymentAmount": {
"currency": "IQD",
"value": "100000"
},
"order": {
"orderDescription": "order_description",
"buyer": {
"referenceBuyerId": "216610000000003660xxxx"
}
},
"paymentExpiryTime": "2024-01-18T16:10:36+03:00",
"paymentNotifyUrl": "https://www.merchant.com/paymentNotifyxxxx"
}
paymentRequestId is generated by the merchant/partner, which uniquely identifies the payment. Wallet must make use of paymentRequestId for idempotent control. For example, if a payment with paymentRequestId=2023112719074101000700000077771 has been processed successfully by Wallet, when the merchant/partner uses the same paymentRequestId for payment, Wallet will respond with successful payment.productCode is the product code. The wallet uses the productCode to get the contract configuration which includes fee, limitation information, and so on.paymentNotifyUrl is the URL defined by the merchant/partner. In the cashier payment scenario, after the user finished payment in the wallet cashier page, the wallet will notify the merchant of the payment result based on this URL.paymentAmount describes the amount of 100 IQD to be collected by Wallet from user's account for this payment.order describes the order details of the purchase of the 100 IQD merchandise by the user at the merchant. Such as Merchant, Buyer, Goods, etc are included in order. The information in the Order is only used to display user's payment result page and transactions history, regulation reporting, etc.referenceBuyerId is the unique userID, which can be the customerId obtained from accessToken information in applyToken API. It must not be default. Please make sure the buyer and the payer is the same person.paymentExpiryTime is the payment order close time defined by merchant, which means the payment order will be closed automatically after paymentExpiryTime. If empty, the expiryTime will be defined by E-wallet.{
"result": {
"resultCode": "ACCEPT",
"resultStatus": "A",
"resultMessage": "accept"
},
"paymentId": "2023120611121280010016600900000xxxx",
"redirectActionForm": {
"redirectionUrl": "https://www.wallet.com/cashier?orderId=xxxxxxx"
}
}
result.resultStatus == A shows that the payment is accept success. After user finish payment in cashier page, payment will change to success.paymentId is generated by Wallet, uniquely identifies the payment.redirectActionForm returns the cashier page URL to the merchant/partner. After the merchant/partner receives the accept result, which will be redirected to this URL.Agreement payments charge the user using an existing contract established via qicardSignContract.
For example, a user authorizes an AgreementPay contract at the merchant/partner (online merchant usually), such as monthly subscription, the merchant/partner can call this API to automatically deduct money from the user's wallet without user's operation.
| Field | Type | Required | Description |
|---|---|---|---|
paymentAuthCode | string | Yes | Authorization token obtained during agreement signing (e.g., from qicardSignContract + applyToken). Max 128 characters. This was generated by the wallet as the accessToken in the agreement pay scenario. |
order.buyer.referenceBuyerId | string | No | Optional in agreement payment, but if provided must match the customerId associated with the agreement. |
Other fields (such as paymentRedirectUrl) are optional and often unused because no cashier is displayed.
referenceBuyerId matches the user who signed the agreement; mismatches are rejected.{
"productCode": "51051000101000100031",
"paymentRequestId": "UDQzzvxwvyvUDxGqhMHUlIBpGKydOQC6",
"paymentAuthCode": "0000000002202310013fQ6vpiUNV79nT00006725",
"paymentAmount": {
"currency": "IQD",
"value": "100000"
},
"order": {
"orderDescription": "order_description"
},
"paymentExpiryTime": "2024-01-18T16:10:36+03:00",
"paymentNotifyUrl": "https://www.merchant.com/paymentNotifyxxxx"
}
paymentRequestId is generated by the merchant/partner, which uniquely identifies the payment. Wallet must make use of paymentRequestId for idempotent control. For example, if a payment with paymentRequestId=2023112719074101000700000077771 has been processed successfully by Wallet, when the merchant/partner uses the same paymentRequestId for payment, Wallet will respond with successful payment.productCode is the product code. The wallet uses the productCode to get the contract configuration which includes fee, limitation information, and so on.paymentNotifyUrl is the URL defined by the merchant/partner. In the cashier payment scenario, after the user finished payment in the wallet cashier page, the wallet will notify the merchant of the payment result based on this URL.paymentAmount describes the amount of 100 IQD to be collected by Wallet from user's account for this payment.order describes the order details of the purchase of the 100 IQD merchandise by the user at the merchant. Such as Merchant, Buyer, Goods, etc are included in order. The information in the Order is only used to display user's payment result page and transactions history, regulation reporting, etc.paymentAuthCode was generated by the wallet as the accessToken in the agreement pay scenario.paymentExpiryTime is the payment order close time defined by merchant, which means the payment order will expire automatically after paymentExpiryTime. If empty, the expiryTime will be defined by E-wallet.Agreement payments usually complete synchronously. The wallet returns the payment result without a redirect form.
{
"result": {
"resultStatus": "S",
"resultCode": "SUCCESS",
"resultMessage": "Success."
},
"paymentId": "2023103011121280010016679410005274x",
"paymentTime": "2023-10-30T09:17:13+03:00"
}
result.resultStatus == S shows that the payment is success.paymentId is generated by Wallet, uniquely identifies the payment.paymentTime is generated by Wallet, it shows the payment finish time.Escrow payments hold funds securely until the merchant accepts and fulfills the order, protecting both buyer and seller. The buyer pays upfront, but funds remain in escrow until the merchant completes delivery and the buyer confirms receipt.
For example, a user purchases a 100 IQD product from a merchant. The merchant creates an escrow payment, and the user completes payment through the cashier. The funds are held in escrow until the merchant accepts the order, ships the product, and the customer confirms receipt.
merchantAccept, confirmOrder, cancelPayment, and voidPayment.| Field | Type | Required | Description |
|---|---|---|---|
productCode | string | Yes | Must be "51051000101000100008" for escrow payments. |
paymentRedirectUrl | string | No | Merchant URL displayed when the user finishes or cancels the payment. Max 1024 characters. |
order.buyer | object | Yes | Required for escrow payment. |
paymentExpiryTime | string | No | Payment expiry time. If not provided, wallet defines the expiry time. |
{
"productCode": "51051000101000100008",
"paymentRequestId": "ESCROW-PAY-550e8400-1702123456",
"paymentAmount": {
"currency": "IQD",
"value": "100000"
},
"order": {
"orderDescription": "Premium Cotton T-Shirt",
"buyer": {
"referenceBuyerId": "216610000000003660xxxx"
}
},
"paymentExpiryTime": "2024-01-18T16:10:36+03:00",
"paymentRedirectUrl": "http://merchant.com/order-tracking",
"paymentNotifyUrl": "https://www.merchant.com/paymentNotifyxxxx"
}
productCode must be "51051000101000100008" for escrow payments.merchantAccept to accept the order.confirmOrder to release funds.cancelPayment.voidPayment to void if fulfillment cannot be completed.{
"result": {
"resultCode": "ACCEPT",
"resultStatus": "A",
"resultMessage": "accept"
},
"paymentId": "2023120611121280010016600900000xxxx",
"redirectActionForm": {
"redirectionUrl": "https://www.wallet.com/cashier?orderId=xxxxxxx"
}
}
cancelPayment if they cannot fulfill before acceptingvoidPayment if fulfillment cannot be completed after acceptancevoidPayment if goods cannot be deliveredrefund if needed| Field | Type | Required | Description |
|---|---|---|---|
result | object | Yes | The request result, which contains information related to the request result, such as status and error codes. |
result.resultCode | string | Yes | Result code (e.g., "SUCCESS", "ACCEPT", "UNKNOWN_EXCEPTION"). |
result.resultStatus | string | Yes | Result status: S (Success), A (Accepted), U (Unknown), F (Failed). |
result.resultMessage | string | Yes | Result message description. |
paymentId | string | No | The unique ID of a payment generated by Wallet. Max. length: 64 characters. Present when payment is accepted or successful. |
paymentTime | string/datetime | No | Payment success time, which follows the ISO 8601 standard. Present when resultStatus is S. |
redirectActionForm | object | No | Indicates a redirect URL for cashier payment. Present when resultStatus is A. |
redirectActionForm.redirectionUrl | string | No | The wallet cashier page URL. |
In the response, the result.resultStatus field indicates the result of processing a request as follows:
| resultStatus | Description |
|---|---|
S | Success – The corresponding result.resultCode is "SUCCESS" and the result.resultMessage is "Success.". That means that this transaction is successful. The merchant/partner can update transaction to success. |
A | Accepted – The corresponding result.resultCode is "ACCEPT", and the result.resultMessage varies based on different situations. That means that the transaction is already accepted by wallets. The merchant/partner needs to continue the next operation according to the redirectActionForm response, such as display the order code to users or redirect to the wallet cashier page. |
U | Unknown – The corresponding result.resultCode is "UNKNOWN_EXCEPTION" and result.resultMessage is "An API calling is failed, which is caused by unknown reasons.". For details, see the Common error codes section.That means that unknown exception occurs on the wallet side. The merchant/partner can inquiry the payment result or wait for the payment status notification to get the real payment result. What needs to do is: • Payment evaluation scenario can not be inquired. • U status can not set to fail or success on the merchant/partner system.• U status can not refund to users by offline (Maybe will make fund loss). |
F | Failed – That means this transaction is failed. The corresponding result.resultCode and result.resultMessage vary based on different situations. For details, see the following Error codes section.Usually the F transactions can not be successful again if use the same payment request to call wallets. |
| resultStatus | Meaning | Merchant Action |
|---|---|---|
S | Payment succeeded. | Mark order as paid; expect notification at paymentNotifyUrl. |
A | Accepted; further action required (cashier flow). | Redirect user using redirectActionForm. |
U | Unknown exception. | Retry later or wait for notifications; do not duplicate charges immediately. |
F | Failed. | Inspect resultCode and decide whether to retry or alert the user. |
Error codes are usually classified into the following categories:
| resultStatus | resultCode | resultMessage |
|---|---|---|
U | PAYMENT_IN_PROCESS | The payment is still under process. |
F | REPEAT_REQ_INCONSISTENT | Repeated submission, and requests are inconsistent. |
F | PAYMENT_AMOUNT_EXCEED_LIMIT | Payment amount exceeds limit. |
F | USER_NOT_EXIST | The user does not exist. |
F | USER_STATUS_ABNORMAL | The user status is abnormal. |
F | USER_BALANCE_NOT_ENOUGH | The user balance is not enough for this payment. |
F | PARTNER_NOT_EXIST | The partner does not exist. |
F | PARTNER_STATUS_ABNORMAL | The partner status is abnormal. |
F | RISK_REJECT | Risk reject. |
F | CURRENCY_NOT_SUPPORT | The currency is not supported. |
F | ORDER_STATUS_INVALID | Order is in invalid status such closed. |
F | INVALID_ACCESS_TOKEN | Invalid accesstoken. |
F | USER_AMOUNT_EXCEED_LIMIT | Payment amount exceeds user's amount limit. |
F | AUTH_CODE_ALREADY_USED | Auth code already used. |
F | INVALID_CODE | Auth code illegal. |