Status and reconciliation
Read payment status without creating another payment.
Status checks
Card: GET /api/v1/payments/card/{identifier}/status.
Wallet: GET /api/v1/payments/wallet/{identifier}/status.
Both require HMAC and return the stored gateway transaction in data; they do not synchronously query the bank. The identifier may be transactionId, orderId, referenceId, or externalRef. Prefer transactionId because an order may have multiple attempts. Sign an empty body and empty idempotency line for GET.
For QR, use signed callbacks and Transactions. A recorded bank reference can be looked up with HMAC POST /api/v1/transactions/bank-reference/inquire:
{ "referenceCode": "BANK_REFERENCE_FROM_RECEIPT", "paymentMethod": "LDB_QR" }The other supported method is INDOCHINA_BANK_QR. This searches previously recorded callback evidence; a missing record returns 404. The simulator does not generate real bank callback evidence.
Status meanings
| Status | Merchant action |
|---|---|
PENDING | Wait; creation is not settlement. |
SUCCESS | Verify environment, amount, currency, and order, then fulfill once. |
FAILED | Do not fulfill; investigate before another attempt. |
CANCELLED | Do not fulfill. |
EXPIRED | Stop presenting expired instructions; reconcile any later live settlement evidence. |
AMOUNT_MISMATCH | Hold fulfillment for reconciliation. |
The live transition logic can process later evidence for expired payments; do not assume every expired payment can never settle. TEST final outcomes cannot be changed through simulation.
Cancellation
- LDB QR: HMAC
DELETE /api/v1/payments/ldb-qr/{orderId}/cancel, optional JSON{ "reason": "Customer cancelled" }. - Wallet: HMAC
DELETE /api/v1/payments/wallet/cancel.service, JSON{ "paymentMethod": "ALIPAY", "orderId": "order-20261110-0001", "reason": "Customer cancelled" }. UseWECHAT_PAYfor WeChat.
TEST cancellation simulates CANCELLED; LIVE cancellation is currently blocked by bank verification. There is no merchant card-cancel or Indochina-QR-cancel route in this controller. Cancellation is not a refund API.
Hosted status
LIVE creation does not return statusAccessToken. Check status through your server using the authenticated status endpoints above. Previously issued hosted tokens remain supported until expiry; no merchant API secret should be sent to a browser.
Server-side status example
These calls belong in your authenticated server. Replace card with wallet for wallet payments. Verify order ownership before exposing results to a browser. Download the helpers linked in the authentication guide.
import { gatewayRequest } from './vantra-client.mjs';
const transactionId = 'SAVED_TRANSACTION_ID';
const payment = await gatewayRequest({
origin: process.env.VANTRA_API_ORIGIN,
apiKey: process.env.VANTRA_API_KEY,
secret: process.env.VANTRA_API_SECRET,
method: 'GET',
path: `/api/v1/payments/card/${encodeURIComponent(transactionId)}/status`,
});
console.log(payment.status);The Express/Next.js orders module is an application adapter: implement authentication and ownership checks before exposing this endpoint.
New LIVE payments use TXN-<base36 timestamp>-<8 uppercase hex characters> and INV-YYYYMM-XXXXX (Asia/Vientiane month). Existing identifiers remain unchanged.