By using Tokenization for payments, with just one click, customers can quickly and easily complete their orders. All transactions with token, after the first payment do not require customers to re-enter payment card information.
A. Process flow

B. Explanation
First time payment & card saving
Step 1: The customer makes a payment for the order on the merchant's website.
When the customer proceeds with the payment of the order, the merchant's website interface may or may not display the domestic card payment method.
If the customer selects the domestic card method on the merchant's website, there is no need to select the domestic card method on the 9Pay Payment Gateway.
Steps 2 and 3: The merchant generates a payment link with the order information and a unique invoice_no. Then, the merchant's website redirects the customer to the created payment URL.
Steps 4 and 5: The customer enters payment information and verifies the payment.
Step 6: After the customer completes the payment steps on the 9Pay Payment Gateway, if the transaction is successful, 9Pay will send IPN (Instant Payment Notification) transaction status information to the merchant's website, as registered with 9Pay.
Step 7: The customer is redirected back to the merchant's website using the return_url provided by the merchant in step 2.
Step 8: The merchant displays the transaction result to the customer.
Step 9: Approximately 20 minutes after creating the payment URL, if the IPN is not received, the merchant proactively queries the transaction status to update the transaction result.
Not receiving IPN may be due to network issues, service unavailability, or other technical problems.
Nextime payments
Step 10: The customer adds products to the shopping cart and selects card payment.
Step 11: The merchant generates a payment link with order information via token. Subsequently, the merchant's website redirects the customer to the created payment URL.
Step 12+13+14: 9Pay processes the payment using encrypted tokens. 9Pay sends IPN and redirects the customer back to the merchant's website.
Step 15: The merchant checks the payment result and displays the transaction outcome to the customer.
C. API configuration
1. Create a payment token
At the merchant's website, after the customer agrees to save payment information, the merchant's system will create a payment URL with the parameter save_token = 1. Then, it redirects the customer to the payment page.
You only need to build the Merchant signature without constructing the entire header.
| Language | Reference link |
| PHP | https://gitlab.com/9pay-sample/sample-php |
| JAVA | https://gitlab.com/9pay-sample/sample-java |
| NodeJS | https://gitlab.com/9pay-sample/sample-javascript |
Required parameters
| Attribute | Type | Required | Description |
| invoice_no | String (30) | yes | Order Id of merchant, unique for each request |
| amount | Number | yes |
Amount needs to be paid Min: 10,000 VND Max: 200,000,000 VND Curency: VND |
| description | String(255) | yes | Description of order information. |
| method | String | no | By default, redirect customers to 9Pay to select their payment method. If you pass "method = ATM_CARD," then redirect to 9Pay to enter payment information. |
| return_url | String | yes | A merchant's URL. This URL is used to redirect from 9Pay page to merchant's page after customer's payment |
| currency | String (10) | no | Currency. Default is VND. Support as USD, EUR, GBP, CNY, JPY |
| time | Int (10) | yes | Example : 1335939007 (UTC+0, length=10) |
| merchantKey | String | yes | The merchant identification string provided by 9Pay. |
| lang | String | no | The language displayed on transaction screens for customers. (vi and en). Default is vi |
| save_token | Number | no |
Determine token creation for subsequent transactions using tokens. With 0: Do not save, 1: Save token. Default is 0. |
| bank_code | String | no | Pass the bank code if you want to go directly to the bank's card input form. |
| profile_id | Int | no | Retrieve from the "Profile" list. In the case of wanting to update payment information for each profile. |
| is_customer_pay_fee | Int | no |
Determine the entity responsible for transaction fees. 0: Merchant bears the transaction fees., 1: Customers bear the transaction fees. Default is 0 |
2. Processing payment result
Pay attention to duplicate handling when receiving results for a transaction using both methods.
Return
After the payment process is completed, the customer is redirected to the return_url provided by the merchant when creating the payment URL.
The merchant uses this result to display a notification of the successful/failed transaction to the customer (contained within the query string when returning to the merchant's link).
IPN - Instant Payment Notification
After a successful payment transaction, 9Pay will send a POST request (x-www-form-data) to the merchant's registered IPN_url address.
Data reponse
| Attribute | Type | Required | Description |
| result | String | yes | Transaction information |
| checksum | String | yes | The checksum code generated using the merchant's result and checksum key |
| version | String | IPN version |
The value in the result after decoding:
| Attribute | Type | Required | Description |
| payment_no | Number | yes | 9Pay's transaction id |
| invoice_no | String | yes | Order id of merchant, unique for each request |
| amount | Number | yes | Payment amount |
| description | String (255) | yes | Order's information |
| method | String | yes | ATM_CARD |
| currency | String (10) | yes | Currency |
| created_at | Array | yes | Example : 1335939007 (UTC+0, length=10) |
| card_brand | String | yes | Bank name |
| status | Number | yes | Transaction status |
| failure_reason | String | yes | Error description |
| card_info | Array | yes | Payment information data |
| card_info.card_name | String | yes | The name of the cardholder printed on the card |
| card_info.card_brand | String | yes | The issuing bank of the card |
| card_info.card_number | String | yes | The card number in the format 123456xxxxxx6789 |
| card_info.token | String | yes | The token is encrypted corresponding to the card information |
3. Pay using token
The merchant creates a payment URL with the card_token parameter received in the payment token creation step.
Required parameters
| Attribute | Type | Required | Description |
| invoice_no | String (30) | yes | Order Id of merchant, unique for each request |
| amount | Number | yes |
Amount needs to be paid Min: 10,000 VND Max: 200,000,000 VND Curency: VND |
| description | String(255) | yes | Description of order information. |
| method | String | no | By default, redirect customers to 9Pay to select their payment method. If you pass "method = ATM_CARD," then redirect to 9Pay to enter payment information. |
| return_url | String | yes | A merchant's URL. This URL is used to redirect from 9Pay page to merchant's page after customer's payment |
| currency | String (10) | no | Currency. Default is VND. Support as USD, EUR, GBP, CNY, JPY |
| time | Int (10) | yes | Example : 1335939007 (UTC+0, length=10) |
| merchantKey | String | yes | The merchant identification string provided by 9Pay. |
| lang | String | no | The language displayed on transaction screens for customers. (vi and en). Default is vi |
| card_token | Number | no | The token is encrypted with card information provided by 9Pay to the merchant. |
| profile_id | Int | no | Retrieve from the "Profile" list. In the case of wanting to update payment information for each profile. |
| is_customer_pay_fee | Int | no |
Determine the entity responsible for transaction fees. 0: Merchant bears the transaction fees., 1: Customers bear the transaction fees. Default is 0 |