Migrating from V1 to V2

1. What Changed

V1 vs V2 Comparison
AspectV1 (old)V2 (new)
Response timing Synchronous — the HTTP response contains the final bank result Asynchronous — HTTP response returns PENDING immediately; final result delivered via webhook
Apple Pay endpoint /payment/process /api/v2/payment/process
Google Pay endpoint /payment/process/google /api/v2/payment/process/google
Auth header x-merchant-key x-merchant-keyunchanged
Apple Pay token format PKPaymentToken object PKPaymentToken object — unchanged
Google Pay token format Encrypted token string Encrypted token string — unchanged
order_id field order_id order_idunchanged
Payment result In the HTTP response body Via webhook or GET /api/v2/payments/{paymentId}

2. New Response Structure

V1 Response (Synchronous)

In V1, the payment result was returned directly in the HTTP response — your code could read status and immediately know the outcome.

// V1 — Final result in the HTTP response
{
  "success": true,                      // Indicates if the payment was successful
  "status_code": 200,                   // PSP's status code for the operation
  "orderId": "ORDER-2024-00123",        // The order ID provided in the request
  "description": "Payment successful"   // Additional information about the payment
}
V2 Response (Asynchronous)

In V2, the HTTP response only confirms the request was accepted. The response always has status: "PENDING"this is not a failure.

// V2 — Acceptance acknowledgment (NOT the final result)
{
  "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"
}
Key change: Do not check status in the submission response to determine success or failure. Store the paymentId and wait for the webhook event (or poll the status URL) to get the final outcome.

3. Step-by-Step Migration

1
Update the endpoint paths
Change the URL in your payment submission code:
# Apple Pay
# Before:
POST /payment/process

# After:
POST /api/v2/payment/process

# Google Pay
# Before:
POST /payment/process/google

# After:
POST /api/v2/payment/process/google
2
Store the paymentId from the response
The V2 response no longer contains the final result. Store paymentId so you can match it to the incoming webhook event.
// Save this to your database when the response arrives:
{
  "orderId": "ORDER-2024-00123",
  "paymentId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "PENDING"
}
3
Do not treat PENDING as a failure
Update any code that checks the submission response for success. PENDING is the expected and correct status at this stage — not an error.
// WRONG — don't do this in V2:
if (response.status !== 'AUTHORIZED') { showError(); }

// CORRECT — V2 pattern:
if (response.status === 'PENDING') {
  savePendingOrder(response.paymentId, response.orderId);
  showWaitingScreen();
}
4
Implement a webhook endpoint
Create an HTTPS endpoint on your server that Bonum will call when the payment completes. See the Webhook Guide for full implementation details including signature verification.
# Your webhook URL must be HTTPS and return 2xx within 10 seconds
https://your-store.mn/webhooks/bonum-payment
5
Register your webhook URL with Bonum
Contact Bonum support or use the merchant dashboard to register your webhook endpoint URL and receive your webhook signing secret.
6
(Optional) Add status polling as a fallback
For extra resilience, poll the status URL if your webhook has not fired within an expected window (e.g. 30 seconds for most payments).
curl https://<your-domain>/api/v2/payments/550e8400-e29b-41d4-a716-446655440000 \
  -H "x-merchant-key: mk_live_xxxxxxxxxxxxxxxxxxxx"

4. What Stays the Same

No Changes Required

The following are identical in V2 and require no code changes on your side:

ItemNotes
Authentication header (x-merchant-key)Same header name and format
Apple Pay token structure (PKPaymentToken)Pass the same object from the Apple Pay framework
Google Pay tokenPass the same encrypted string from the Google Pay API
The order_id fieldSame field name, same behavior
The amount fieldSame format (major currency units, 2 decimal places)
Domain verification & Apple Pay merchant setupNo changes to certificates or domain files

5. Backwards Compatibility

V1 Endpoints During Transition

The original V1 paths remain active and continue to work during the migration period. They now route to the same underlying V2 processing pipeline:

V1 Path (still works)Routes to
POST /payment/processSame as POST /api/v2/payment/process
POST /payment/process/googleSame as POST /api/v2/payment/process/google
Note: Even when called via the old V1 paths, the response is now V2-style — you will receive status: "PENDING" instead of a final result. The migration to async behavior affects all paths.
Migration Timeline

Contact your Bonum account manager for the deprecation schedule for V1 paths. We recommend completing migration before the announced deprecation date to avoid disruption.

Tip: Test your migration in the sandbox environment first. Submit a test payment and confirm your webhook endpoint receives the AUTHORIZED or FAILED event before going live.
Need Help?

Contact Bonum developer support if you have questions about the migration or need assistance testing your integration.