Migrating from V1 to V2
1. What Changed
| Aspect | V1 (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-key — unchanged |
| 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_id — unchanged |
| Payment result | In the HTTP response body | Via webhook or GET /api/v2/payments/{paymentId} |
2. New Response Structure
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
}
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"
}
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
# 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
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"
}
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();
}
# Your webhook URL must be HTTPS and return 2xx within 10 seconds
https://your-store.mn/webhooks/bonum-payment
curl https://<your-domain>/api/v2/payments/550e8400-e29b-41d4-a716-446655440000 \
-H "x-merchant-key: mk_live_xxxxxxxxxxxxxxxxxxxx"
4. What Stays the Same
The following are identical in V2 and require no code changes on your side:
| Item | Notes |
|---|---|
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 token | Pass the same encrypted string from the Google Pay API |
The order_id field | Same field name, same behavior |
The amount field | Same format (major currency units, 2 decimal places) |
| Domain verification & Apple Pay merchant setup | No changes to certificates or domain files |
5. Backwards Compatibility
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/process | Same as POST /api/v2/payment/process |
POST /payment/process/google | Same as POST /api/v2/payment/process/google |
status: "PENDING" instead of a final result. The migration to async behavior affects all paths.
Contact your Bonum account manager for the deprecation schedule for V1 paths. We recommend completing migration before the announced deprecation date to avoid disruption.
AUTHORIZED or FAILED event before going live.
Contact Bonum developer support if you have questions about the migration or need assistance testing your integration.