V2 API Reference

Authentication

Required Headers
HeaderValueDescription
x-merchant-keyYour API keyAuthentication. Required on all protected endpoints.
Content-Typeapplication/jsonRequired on POST requests with a body.
Endpoints Overview
MethodPathDescription
POST/api/v2/payment/processSubmit an Apple Pay payment
POST/api/v2/payment/process/googleSubmit a Google Pay payment
GET/api/v2/payments/{paymentId}Get payment status by payment ID
GET/api/v2/payments/{paymentId}/awaitWait for a payment to reach a terminal status (recommended for wallet sessions)
GET/api/v2/payments/lookup/by-order-idGet payment status by your order ID

POST /api/v2/payment/process

POST /api/v2/payment/process

Submit an Apple Pay payment for processing. The token object is the raw PKPaymentToken from the Apple Pay framework.

Request Headers
HeaderRequiredValue
x-merchant-keyRequiredYour merchant API key
Content-TypeRequiredapplication/json
Request Body
FieldTypeRequiredDescription
order_idstringRequiredYour unique order ID. Max 128 characters. Duplicate order_id per merchant returns the existing payment.
amountnumberOptionalMajor currency units. Min: 0.01. Max 2 decimal places. Overrides token amount if provided.
tokenobjectRequiredApple Pay PKPaymentToken object
token.paymentData.datastringRequiredBase64-encoded encrypted payment data
token.paymentData.signaturestringRequiredPKCS #7 detached signature
token.paymentData.versionstringRequirede.g. "EC_v1"
token.paymentData.headerobjectRequiredpublicKeyHash, ephemeralPublicKey, transactionId
token.paymentMethodobjectRequireddisplayName, network, type
token.transactionIdentifierstringRequiredApple's unique transaction identifier
Example Request
curl -X POST https://<your-domain>/api/v2/payment/process \
  -H "Content-Type: application/json" \
  -H "x-merchant-key: mk_live_xxxxxxxxxxxxxxxxxxxx" \
  -d '{
    "order_id": "ORDER-2024-00123",
    "amount": 150.50,
    "token": {
      "paymentData": {
        "data": "aGVsbG8gd29ybGQ...",
        "signature": "MIAGCSqGSIb3DQ...",
        "header": {
          "publicKeyHash": "Hmng9JBG...",
          "ephemeralPublicKey": "MFkwEwYH...",
          "transactionId": "9AFDA47D..."
        },
        "version": "EC_v1"
      },
      "paymentMethod": {
        "displayName": "Visa 4242",
        "network": "Visa",
        "type": "debit"
      },
      "transactionIdentifier": "9AFDA47D..."
    }
  }'
Response Body (200 OK)
FieldTypeDescription
paymentIdstring (UUID)Bonum payment identifier. Use for polling or webhook matching.
orderIdstringYour order_id echoed back
statusstringAlways "PENDING" — final result delivered via webhook
acceptedAtstring (ISO 8601)Time the request was accepted
statusUrlstringFull URL (including PSP domain) to check current status at any time
awaitUrlstringFull URL (including PSP domain) to block and wait for the final status. Use directly — do not prepend a domain. Recommended for closing wallet sessions.
{
  "paymentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "orderId": "ORD-20240521-001",
  "status": "PENDING",
  "acceptedAt": "2026-05-21T14:30:00.000+08:00",
  "statusUrl": "https://psp.bonum.mn/api/v2/payments/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "awaitUrl": "https://psp.bonum.mn/api/v2/payments/a1b2c3d4-e5f6-7890-abcd-ef1234567890/await"
}
Error Codes
HTTP StatusCondition
400Missing order_id, missing token, amount < 0.01
401Missing or invalid x-merchant-key
429Rate limit exceeded

POST /api/v2/payment/process/google

POST /api/v2/payment/process/google

Submit a Google Pay payment for processing.

Request Body
FieldTypeRequiredDescription
order_idstringRequiredYour unique order ID
tokenstringRequiredEncrypted Google Pay token string from PaymentData.paymentMethodData.tokenizationData.token
currency_codestringRequiredOne of: MNT, USD, EUR, JPY
amountnumberOptionalAmount in major currency units. Min: 0.01.
Example Request
curl -X POST https://<your-domain>/api/v2/payment/process/google \
  -H "Content-Type: application/json" \
  -H "x-merchant-key: mk_live_xxxxxxxxxxxxxxxxxxxx" \
  -d '{
    "order_id": "ORDER-2024-00124",
    "token": "eyJzaWduYXR1cmUiOiJNRUlDSVFDa...",
    "currency_code": "MNT",
    "amount": 150.50
  }'
Response Body (200 OK)

Identical structure to the Apple Pay response, including awaitUrl.

{
  "paymentId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "orderId": "ORD-20240521-002",
  "status": "PENDING",
  "acceptedAt": "2026-05-21T14:31:00.000+08:00",
  "statusUrl": "https://psp.bonum.mn/api/v2/payments/b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "awaitUrl": "https://psp.bonum.mn/api/v2/payments/b2c3d4e5-f6a7-8901-bcde-f12345678901/await"
}

GET /api/v2/payments/{paymentId}

GET /api/v2/payments/{paymentId}

Retrieve the current status and details of a payment by its paymentId.

Path Parameters
ParameterTypeDescription
paymentIdstring (UUID)The paymentId returned when the payment was submitted
Example Request
curl https://<your-domain>/api/v2/payments/550e8400-e29b-41d4-a716-446655440000 \
  -H "x-merchant-key: mk_live_xxxxxxxxxxxxxxxxxxxx"
Response Body (200 OK)
FieldTypeDescription
paymentIdstring (UUID)Bonum payment identifier
orderIdstringYour order ID
amountstringAmount in major currency units as a decimal string (e.g. "150.50")
currencystringISO 4217 numeric currency code (e.g. 496 for MNT)
walletTypestringAPPLE_PAY or GOOGLE_PAY
statusstringPENDING, AUTHORIZED, or FAILED
providerReferencestring | nullBank/acquirer reference number. Present when AUTHORIZED.
failureReasonstring | nullReason for failure. Present when FAILED.
createdAtstring (ISO 8601)When the payment was created
updatedAtstring (ISO 8601)When the payment was last updated
{
  "paymentId": "550e8400-e29b-41d4-a716-446655440000",
  "orderId": "ORDER-2024-00123",
  "amount": "150.50",
  "currency": "496",
  "walletType": "APPLE_PAY",
  "status": "AUTHORIZED",
  "providerReference": "GBK20240415001234",
  "failureReason": null,
  "createdAt": "2024-04-15T10:30:00.000Z",
  "updatedAt": "2024-04-15T10:30:04.000Z"
}
Error Codes
HTTP StatusCondition
401Missing or invalid x-merchant-key
404Payment ID does not exist or belongs to a different merchant

GET /api/v2/payments/{paymentId}/await

GET /api/v2/payments/{paymentId}/await

Blocks until the payment reaches a terminal status (AUTHORIZED or FAILED), then returns immediately. Designed for closing Apple Pay and Google Pay wallet sessions — call it with the awaitUrl from the submission response.

Unlike GET /api/v2/payments/{paymentId} which always returns the current state immediately, this endpoint holds the connection open on the server side and responds only when the bank has replied or the timeout is reached.

Path Parameters
ParameterTypeDescription
paymentIdstring (UUID)The paymentId returned when the payment was submitted
Query Parameters
ParameterTypeDefaultMaxDescription
timeoutMsnumber2500028000How long to wait (milliseconds) before returning a timeout response. Capped at 28 000ms to leave buffer before Apple Pay's 30-second hard limit.
Example Request
curl "https://<your-domain>/api/v2/payments/550e8400-e29b-41d4-a716-446655440000/await?timeoutMs=25000" \
  -H "x-merchant-key: mk_live_xxxxxxxxxxxxxxxxxxxx"
Response Body (200 OK)

Returns only what is needed to close the wallet session. Full payment details are delivered via webhook.

FieldTypeDescription
paymentIdstring (UUID)Bonum payment identifier
statusstringAUTHORIZED, FAILED, or PENDING (only when timedOut)
failureReasonstring | nullReason for failure. Non-null when status is FAILED.
timedOutbooleanPresent and true only when the wait window expired before the bank responded. Absent on success.
// Authorized
{
  "paymentId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "AUTHORIZED",
  "failureReason": null
}

// Failed
{
  "paymentId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "FAILED",
  "failureReason": "Insufficient funds"
}

// Timed out — bank still processing, rely on webhook for final result
{
  "paymentId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "PENDING",
  "failureReason": null,
  "timedOut": true
}
Error Codes
HTTP StatusCondition
400paymentId is not a valid UUID
401Missing or invalid x-merchant-key
404Payment ID does not exist

GET /api/v2/payments/lookup/by-order-id

GET /api/v2/payments/lookup/by-order-id

Look up a payment using your own order_id. Returns the same payment detail object as the paymentId lookup.

Query Parameters
ParameterTypeRequiredDescription
orderIdstringRequiredYour order ID used when submitting the payment
Example Request
curl "https://<your-domain>/api/v2/payments/lookup/by-order-id?orderId=ORDER-2024-00123" \
  -H "x-merchant-key: mk_live_xxxxxxxxxxxxxxxxxxxx"
Error Codes
HTTP StatusCondition
400orderId query parameter is missing or empty
401Missing or invalid x-merchant-key
404No payment found for this order ID under your merchant account

Object Reference

PaymentStatus
ValueDescription
PENDINGPayment is queued and awaiting bank response. Do not mark as complete.
AUTHORIZEDBank approved the payment. Funds are reserved. Safe to fulfill order.
FAILEDBank declined the payment or a processing error occurred. Check failureReason.
WalletType
ValueDescription
APPLE_PAYPayment submitted via Apple Pay
GOOGLE_PAYPayment submitted via Google Pay
Currency Codes
CodeCurrency
MNTMongolian Tögrög
USDUS Dollar
EUREuro
JPYJapanese Yen
Amount Units

The API accepts amounts in major currency units (e.g. 150.50 MNT).
The API returns amounts as a decimal string in major currency units (e.g. "150.50"). No conversion needed.

Rate Limits

API requests are rate-limited per merchant. Exceeding the limit returns 429 Too Many Requests. Wait before retrying or contact Bonum support if you need a higher limit.