Payments

pay

Create wallet payment orders for cashier and agreement scenarios.

Overview

POST /v1/payments/pay creates payment orders within the wallet. The endpoint supports three flows:

  • Cashier payment (standard commerce) – redirect the Mini Program to the wallet cashier where users approve each payment.
  • Agreement payment (auto-debit) – reuse a previously signed agreement (paymentAuthCode) to charge the user without presenting the cashier.
  • Escrow payment – funds are held securely in escrow until the merchant accepts and fulfills the order, protecting both buyer and seller.

All monetary amounts in requests and responses must be expressed in the smallest currency unit (IQD fils). For example, 100 IQD equals 100000.

A payment which takes place at wallets. The merchant/partner initiates a payment request to wallet through this interface, and the wallet will handle different payment scenarios based on the parameters in the request.

Endpoint

MethodPath
POST/v1/payments/pay

API Structure

A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see: OpenAPIs Overview.

Shared Request Fields

FieldTypeRequiredDescription
productCodestringYesDefined 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"
paymentRequestIdstringYesThe 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.
paymentAuthCodestringNo*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.
paymentAmountobjectYesThe 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.currencystringYesCurrency code (e.g., "IQD").
paymentAmount.valuestringYesAmount value in smallest currency unit (fils).
orderobjectYesThe 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.orderDescriptionstringYesDescription of the order.
order.buyerobjectNo*Buyer information.

*Optional in Agreement Payment, required in Cashier Payment.
order.buyer.referenceBuyerIdstringYesThe 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.
paymentExpiryTimestring/datetimeNoThe 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.
paymentRedirectUrlstringNoThe redirect URL defined by merchants. Max. length: 1024 characters.
paymentNotifyUrlstringNoThe payment success notification URL defined by merchants. Max. length: 1024 characters.
voidNotifyUrlstringNoThe url that void notification will be sent to. Max. length: 1024 characters.
extendInfostringNoThe extensive information. The wallet and merchant can put extensive information in this property. The format should be JSON format. Max. length: 2048 characters.
Ensure referenceBuyerId in order.buyer matches the customerId retrieved from applyToken.

Cashier Payment

In this mode the merchant redirects the user to the wallet cashier embedded in the Mini Program.

Flow Overview

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.

To view the end-to-end diagram, see the Cashier Payment flow.

Cashier Payment Request Additional Fields

FieldTypeRequiredDescription
paymentRedirectUrlstringNoMerchant URL displayed when the user finishes or cancels the payment. Max 1024 characters.
order.buyerobjectYesRequired for cashier payment.

Sample Cashier Payment Request

{
  "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"
}

Key Points for Cashier Payment

  • 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.

Sample Cashier Payment Response

{
  "result": {
    "resultCode": "ACCEPT",
    "resultStatus": "A",
    "resultMessage": "accept"
  },
  "paymentId": "2023120611121280010016600900000xxxx",
  "redirectActionForm": {
    "redirectionUrl": "https://www.wallet.com/cashier?orderId=xxxxxxx"
  }
}

Response Field Details

  • 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 Payment

Agreement payments charge the user using an existing contract established via qicardSignContract.

Flow Overview

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.

To view the end-to-end diagram, see the Agreement Payment flow.

Agreement Payment Request Additional Fields

FieldTypeRequiredDescription
paymentAuthCodestringYesAuthorization 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.referenceBuyerIdstringNoOptional 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.

Ensure the payer represented by referenceBuyerId matches the user who signed the agreement; mismatches are rejected.

Sample Agreement Payment Request

{
  "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"
}

Key Points for Agreement Payment

  • 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.

Sample Agreement Payment Response

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"
}

Response Field Details

  • 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 Payment

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.

Flow Overview

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.

To view the complete escrow flow, see the escrow payment APIs: merchantAccept, confirmOrder, cancelPayment, and voidPayment.

Escrow Payment Request Additional Fields

FieldTypeRequiredDescription
productCodestringYesMust be "51051000101000100008" for escrow payments.
paymentRedirectUrlstringNoMerchant URL displayed when the user finishes or cancels the payment. Max 1024 characters.
order.buyerobjectYesRequired for escrow payment.
paymentExpiryTimestringNoPayment expiry time. If not provided, wallet defines the expiry time.

Sample Escrow Payment Request

{
  "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"
}

Key Points for Escrow Payment

  • productCode must be "51051000101000100008" for escrow payments.
  • After payment, funds are held in escrow.
  • Merchant must call merchantAccept to accept the order.
  • After fulfillment, customer calls confirmOrder to release funds.
  • Merchant can cancel before acceptance using cancelPayment.
  • After acceptance, merchant can use voidPayment to void if fulfillment cannot be completed.

Sample Escrow Payment Response

{
  "result": {
    "resultCode": "ACCEPT",
    "resultStatus": "A",
    "resultMessage": "accept"
  },
  "paymentId": "2023120611121280010016600900000xxxx",
  "redirectActionForm": {
    "redirectionUrl": "https://www.wallet.com/cashier?orderId=xxxxxxx"
  }
}

Alternative Flows

  • Early Cancellation: Merchant can call cancelPayment if they cannot fulfill before accepting
  • Void After Acceptance: Merchant can call voidPayment if fulfillment cannot be completed after acceptance
  • Fulfillment Issues: Merchant can call voidPayment if goods cannot be delivered
  • Post-Completion Refund: After completion, merchant can issue refund if needed

Response

FieldTypeRequiredDescription
resultobjectYesThe request result, which contains information related to the request result, such as status and error codes.
result.resultCodestringYesResult code (e.g., "SUCCESS", "ACCEPT", "UNKNOWN_EXCEPTION").
result.resultStatusstringYesResult status: S (Success), A (Accepted), U (Unknown), F (Failed).
result.resultMessagestringYesResult message description.
paymentIdstringNoThe unique ID of a payment generated by Wallet. Max. length: 64 characters. Present when payment is accepted or successful.
paymentTimestring/datetimeNoPayment success time, which follows the ISO 8601 standard. Present when resultStatus is S.
redirectActionFormobjectNoIndicates a redirect URL for cashier payment. Present when resultStatus is A.
redirectActionForm.redirectionUrlstringNoThe wallet cashier page URL.

Result Processing Logic

In the response, the result.resultStatus field indicates the result of processing a request as follows:

resultStatusDescription
SSuccess – 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.
AAccepted – 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.
UUnknown – 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).
FFailed – 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.

Result Status Reference

resultStatusMeaningMerchant Action
SPayment succeeded.Mark order as paid; expect notification at paymentNotifyUrl.
AAccepted; further action required (cashier flow).Redirect user using redirectActionForm.
UUnknown exception.Retry later or wait for notifications; do not duplicate charges immediately.
FFailed.Inspect resultCode and decide whether to retry or alert the user.

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.
resultStatusresultCoderesultMessage
UPAYMENT_IN_PROCESSThe payment is still under process.
FREPEAT_REQ_INCONSISTENTRepeated submission, and requests are inconsistent.
FPAYMENT_AMOUNT_EXCEED_LIMITPayment amount exceeds limit.
FUSER_NOT_EXISTThe user does not exist.
FUSER_STATUS_ABNORMALThe user status is abnormal.
FUSER_BALANCE_NOT_ENOUGHThe user balance is not enough for this payment.
FPARTNER_NOT_EXISTThe partner does not exist.
FPARTNER_STATUS_ABNORMALThe partner status is abnormal.
FRISK_REJECTRisk reject.
FCURRENCY_NOT_SUPPORTThe currency is not supported.
FORDER_STATUS_INVALIDOrder is in invalid status such closed.
FINVALID_ACCESS_TOKENInvalid accesstoken.
FUSER_AMOUNT_EXCEED_LIMITPayment amount exceeds user's amount limit.
FAUTH_CODE_ALREADY_USEDAuth code already used.
FINVALID_CODEAuth code illegal.