Skip to main content

3.1 Create deposit

POST /api/v2/deposits

Send one JSON object with the v2 authentication headers. Send no query string. The successful response is HTTP 200, including when the operation already has a failed result; always retrieve its status.

FieldTypeRequiredDescription
order_idstring, max 255 charactersYesYour deposit identifier. Unique per merchant and operation type for idempotency.
amountJSON numberYesPositive amount, at most two decimal places. Do not send a quoted string.
currencystring, 3 lettersYesUse VND for this guide; it must match the selected shop's currency.
methodstringNoExact active shop code. Omit to use your default active shop. Do not add surrounding spaces.
customer_account_idJSON integerNoYour customer's account identifier used by the shared payment checks. Send an integer, not a quoted number; 0 is preserved. Omit or use null when unavailable.
callback_urlHTTPS URLYesAbsolute callback URL without embedded credentials.
success_urlHTTP(S) URLYesBrowser return destination when the current v2 status is SUCCESS.
pending_urlHTTP(S) URLYesBrowser return destination when the current v2 status is PENDING.
fail_urlHTTP(S) URLYesBrowser return destination when the current v2 status is FAILED.
fieldsJSON objectNo*Additional data defined by the selected shop's PayIn schema. See shop fields.
fields.merchant_user_ipstring (IPv4 or IPv6)Shop-dependentCustomer IP address. Supported for every shop; required only when the selected shop's input schema requires it. Omit or use null when optional and unavailable.

All four URL fields must be non-empty strings containing absolute URLs without embedded credentials, whitespace, or control characters. callback_url must use HTTPS; browser return URLs accept HTTP or HTTPS. Do not send a separate return_user_url: v2 selects among the three supplied destinations.

The v2 protocol does not require fields, but the selected shop may require individual keys. fields must be a JSON object, not an array. It cannot override protocol fields such as method, customer_account_id, success_url, pending_url, fail_url, or return_user_url.

Example for an active VND EPT PayIn shop configured with payer account details. Replace your_vnd_shop with your actual shop code and use the field schema assigned to that shop:

{
"order_id": "DEP-VND-1001",
"amount": 250000,
"currency": "VND",
"method": "your_vnd_shop",
"customer_account_id": 77,
"callback_url": "https://merchant.example.com/webhooks/payfield",
"success_url": "https://merchant.example.com/payment/success",
"pending_url": "https://merchant.example.com/payment/pending",
"fail_url": "https://merchant.example.com/payment/fail",
"fields": {
"account_number": "0123456789",
"holder": "Nguyen Van An",
"merchant_user_ip": "203.0.113.10"
}
}

Response 200:

{
"transaction_id": "12346",
"redirect_url": "https://pay.example.com/payin-pages/12346?expires=1801227600&signature=example-signature"
}

Treat redirect_url as the full URL returned by the API; do not build it from transaction_id. Store transaction_id and check its status. A retry with the same order_id and equivalent request returns the same operation. Reusing that ID with different request data returns 409. Idempotency is scoped to the merchant and deposit type, across shops; an existing v1 deposit with the same ID also conflicts. See API errors.

Customer page and preparation​

The returned URL opens a signed Payfield page. If payment preparation is still in progress, it shows a preparation message and refreshes approximately every two seconds. Once ready, it opens the configured payment page or displays payment instructions. Reopening the URL does not create another deposit.

If preparation stops while the financial result is still unknown, the page may show a waiting message and a return option. Keep the order pending and retrieve its status; a delay is not proof of failure. When the operation already has a terminal v2 result, opening the Payfield entry page follows the corresponding return destination instead of offering an old payment artifact.

Returning to your site​

Your configured payment page or provider return link sends the customer through a signed Payfield return URL. At that moment Payfield reads the current status and selects:

Current statusSaved destination
SUCCESSsuccess_url
FAILEDfail_url
PENDINGpending_url

Confirm that this return link is enabled for your shop's payment page/provider flow. Return handling is a browser navigation action: it neither confirms a payment nor changes its result. Use the authenticated status endpoint to decide whether to fulfill the order. To correlate browser returns, include your own order reference in the three merchant URLs when creating the deposit.

Keep signed Payfield URLs unchanged, including their query parameters. The example signature above is illustrative, not usable. Links expire according to the configured payment-page access window; an expired or altered signature is refused with HTTP 403. Repeating create does not renew that window. A page-link expiry does not by itself mean that the deposit failed: continue to use the status API. Previously issued provider links may retain their earlier return behavior; confirm compatibility during onboarding.