Full Flow
Payment Flow
Complete payment flow for SuperQi miniapps
This guide walks you through the complete payment flow for SuperQi miniapps. Before implementing payment functionality, ensure you have completed the authentication flow to obtain the user's access token.
Overview
The payment process consists of two main steps:
- Backend: Create a payment request and obtain a payment URL
- Frontend: Use the payment URL to initiate the payment process
Prerequisites: You must have a valid
accessToken from the authentication flow before proceeding with payments.Step 1: Backend - Create Payment Request
API Endpoint
URL: POST /v1/payments/pay
Request Body
{
"productCode": "51051000101000000011",
"paymentRequestId": "your_unique_order_id",
"paymentAmount": {
"currency": "IQD",
"value": "150000"
},
"order": {
"orderDescription": "Product purchase description",
"buyer": {
"referenceBuyerId": "user_access_token"
}
},
"paymentExpiryTime": "2024-01-18T16:10:36+03:00",
"paymentRedirectUrl": "https://your-domain.com/payment-success",
"paymentNotifyUrl": "https://your-domain.com/api/payment-notification",
"voidNotifyUrl": "https://your-domain.com/api/void-notification",
"extendInfo": "Additional payment information"
}
Request Parameters
productCode (String, Required)
- Defines the payment type. Choose from:
- Online Purchase:
"51051000101000000011" - Online Purchase (Auth Capture):
"51051000101000000012" - Agreement Payment:
"51051000101000100031"
- Online Purchase:
paymentRequestId (String, Required)
- Your unique order ID from your database
- Used for idempotence control
- Max length: 64 characters
paymentAuthCode (String, Optional)
- Payment authorization code
- Max length: 128 characters
paymentAmount (Object, Required)
currency: Always"IQD"value: Amount in fils (multiply IQD by 1000)- Example: 1000 IQD =
"1000000"fils
- Example: 1000 IQD =
order (Object, Required)
orderDescription: Description of the purchasebuyer.referenceBuyerId: The user's access token from authentication
paymentExpiryTime (String, Optional)
- Payment expiration time in ISO 8601 format
- If empty, wallet will set default expiry
paymentRedirectUrl (String, Optional)
- URL to redirect user after payment completion
- Max length: 1024 characters
paymentNotifyUrl (String, Optional)
- Your backend endpoint to receive payment success notifications
- Max length: 1024 characters
voidNotifyUrl (String, Optional)
- Your backend endpoint to receive payment void notifications
- Max length: 1024 characters
extendInfo (String, Optional)
- Additional information in JSON format
- Max length: 2048 characters
Expected Response
{
"result": {
"resultCode": "ACCEPT",
"resultStatus": "A",
"resultMessage": "accept"
},
"paymentId": "2023120611121280010016600090000xxxx",
"redirectActionForm": {
"redirectionUrl": "https://www.wallet.com/cashier?orderId=xxxxxxx"
}
}
For detailed request/response specifications, see the payment API documentation.
Step 2: Frontend - Initiate Payment
Implementation
After receiving the payment URL from your backend, use the my.tradePay method to initiate the payment:
my.tradePay({
paymentUrl: String(redirectionUrl), // URL from backend response
success: (res) => {
// Handle successful payment
console.log("Payment successful:", res);
// TODO: Implement success actions (redirect, show success message, etc.)
},
fail: (res) => {
// Handle payment failure
console.error("Payment failed:", res);
// TODO: Implement error handling (show error message, retry option, etc.)
},
});
Payment Flow Example
1. User Initiates Payment
// Frontend: User clicks "Pay Now" button
function initiatePayment(amount, orderDescription) {
// Send payment request to your backend
// TODO: Implement your backend API call
console.log(`Initiating payment for ${amount} IQD`);
}
2. Backend Creates Payment Request
// Backend: Create payment request
const paymentRequest = {
productCode: "51051000101000000011", // Online Purchase
paymentRequestId: generateUniqueOrderId(),
paymentAmount: {
currency: "IQD",
value: String(amount * 1000), // Convert IQD to fils
},
order: {
orderDescription: orderDescription,
buyer: {
referenceBuyerId: userAccessToken, // From authentication flow
},
},
paymentNotifyUrl: "https://your-domain.com/api/payment-notification",
};
// TODO: Send request to SuperQi API with proper headers and signature
3. Frontend Processes Payment
// Frontend: Use the payment URL from backend response
my.tradePay({
paymentUrl: paymentResponse.redirectActionForm.redirectionUrl,
success: (res) => {
// Payment completed successfully
window.location.href = "/payment-success";
},
fail: (res) => {
// Payment failed
alert("Payment failed. Please try again.");
},
});
Important Notes
Payment Amount Calculation
- Always multiply IQD amount by 1000 to convert to fils
- Example: 150 IQD = 150,000 fils =
"150000"::
Payment Notifications
- Set up
paymentNotifyUrlto receive payment success notifications - Set up
voidNotifyUrlto handle payment cancellations - These endpoints should be secured and validate the incoming requests ::
Order ID Management
- Use
paymentRequestIdfor idempotence control - Ensure each payment request has a unique order ID
- Store the mapping between your order ID and SuperQi's
paymentId::
Additional Resources
- Authentication Flow: Complete Authentication Guide
- Backend Implementation: Backend Documentation
- Frontend Implementation: Frontend Documentation
- API Reference: Payment API Documentation