Bonum Gateway APIs
1. Орчны Тохиргоо
Үндсэн URL & Хувьсагчид
| Хувьсагч | Тест Орчин | Продакшн Орчин |
|---|---|---|
API_BASE_URL |
https://testapi.bonum.mn |
https://apis.bonum.mn |
APP_SECRET |
Мерчант бүртгэлийн үед өгөгдсөн | Bonum-тай холбогдоно уу |
DEFAULT_TERMINAL_ID
|
Мерчант Порталд үүсгэсэн | Bonum-тай холбогдоно уу |
Хэлний Дэмжлэг
Accept-Language толгой ашиглан хариуг хүссэн хэлээрээ
хүлээн авна:
| Толгой | Утга | Тайлбар |
|---|---|---|
Accept-Language |
mn |
Монгол хэлээр хариу |
Accept-Language |
en |
Англи хэлээр хариу |
2. Нэвтрэлт
GET Токен Авах
/bonum-gateway/ecommerce/auth/create
API нэвтрэлтийн access token болон refresh token авна.
APP_SECRET-г мерчант порталд үүсгэнэ. Мерчант порталд
терминал үүсгэж, түүний terminalId утгыг ашиглана.
Анхааруулга: Энэ endpoint нь хязгаарлалттай. Хэт олон удаа
хүсэлт илгээвэл TOO_MANY_REQUESTS алдаа гарна.
Хүсэлтийн Толгой
| Толгой | Утга | Тайлбар |
|---|---|---|
Authorization |
AppSecret {APP_SECRET} |
Таны аппликейшны нууц түлхүүр |
X-TERMINAL-ID |
{DEFAULT_TERMINAL_ID} |
Таны терминалын ID |
Хариу 200 OK
{
"tokenType": "Bearer",
"accessToken": "eyJhbGciOiJIUzI1...",
"expiresIn": 1800,
"refreshToken": "eyJhbGciOiJIUzI1...",
"refreshExpiresIn": 2000,
"unit": "SECONDS"
}
Алдааны Хариу 429 Too Many Requests
{
"traceId": "695cbcbce9d3faa6...",
"errorCode": null,
"error": null,
"message": "Rate-Limit: Use previous token. Do not get token too frequently.",
"data": null,
"detail": null,
"duration": 452,
"status": 429
}
GET Токен Шинэчлэх
/bonum-gateway/ecommerce/auth/refresh
Хугацаа дууссан access token-г refresh token ашиглан шинэчилнэ.
Хүсэлтийн Толгой
| Толгой | Утга | Тайлбар |
|---|---|---|
Authorization |
Bearer {refreshToken} |
Таны refresh token |
Хариу 200 OK
Токен Авах хариутай ижил бүтэцтэй шинэ access token буцаана.
3. Вэб Төлбөр / Нэгдсэн
GET 3.1 Төлбөрийн Провайдерууд
/bonum-gateway/ecommerce/invoices/payment-providers
Таны хэрэглэгчдэд боломжтой идэвхтэй төлбөрийн сонголтуудыг буцаана. Энэ жагсаалтыг өөрчлөх боломжтой.
Боломжтой Провайдерууд
| Провайдер | Тайлбар |
|---|---|
QPAY |
QR суурьтай төлбөр. Бүх банк болон fintech апп-ууд QPAY дэмждэг |
E_COMMERCE |
Онлайн картын төлбөр |
WE_CHAT |
Хятад хэрэглэгчдэд зориулсан WeChat хэтэвчний төлбөр |
SONO_SHOP |
SonoShop зээлээр одоо авч дараа төлөх |
Хүсэлтийн Толгой
| Толгой | Утга |
|---|---|
Authorization |
Bearer {accessToken} |
Хариу 200 OK
[
{
"provider": "QPAY",
"enabled": true
},
{
"provider": "E_COMMERCE",
"enabled": true
},
{
"provider": "SONO_SHOP",
"enabled": true
}
]
POST 3.2 Нэхэмжлэл Үүсгэх
/bonum-gateway/ecommerce/invoices
Нэхэмжлэл үүсгэж, дагах линк буцаана. Хөтөч эсвэл клиент нь хэрэглэгчийг төлбөр хийхийн тулд дагах линк рүү чиглүүлэх ёстой.
Төлбөр дууссан эсвэл цуцлагдсан тохиолдолд callback (webhook) URL руу мэдэгдэл илгээгдэнэ. Callback нь Bonum-д урьдчилан тохируулсан HTTP(S) endpoint байх ёстой.
Хүсэлтийн Толгой
| Толгой | Утга |
|---|---|
Authorization |
Bearer {accessToken} |
Accept-Language |
mn or en |
Content-Type |
application/json |
Хүсэлтийн Бие
{
"amount": 1,
"callback": "https://your-domain.com/payment-callback?txn=c22765536",
"transactionId": "aa22765536",
"expiresIn": 23000, // seconds
"providers": ["QPAY"], // optional, see "Get Payment Providers"
"items": [ // optional
{
"image": "https://example.com/product.png",
"title": "Product Name",
"remark": "Product Description",
"amount": 1,
"count": 1
}
],
"extras": [ // optional
{
"placeholder": "Enter details",
"type": "TEXT", // NUMBER, PHONE, EMAIL, TEXT, ALL
"required": true
}
]
}
Хүсэлтийн Талбарууд
| Талбар | Төрөл | Шаардлагатай | Тайлбар |
|---|---|---|---|
amount |
Number | Тийм | Нийт төлбөрийн дүн |
callback |
String | Тийм | Төлбөрийн дараа чиглүүлэх URL |
transactionId |
String | Тийм | Таны давтагдашгүй гүйлгээний тодорхойлогч |
expiresIn |
Number | Үгүй | Дуусах хугацаа секундээр |
providers |
Array | Үгүй | Төлбөрийн провайдеруудыг шүүх |
items |
Array | Үгүй | Нэхэмжлэлийн бараа зүйлс |
extras |
Array | Үгүй | Хэрэглэгчийн нэмэлт оруулах талбарууд |
Хариу 200 OK
{
"invoiceId": "8cf2c49d200f049f2b384f0adf42b981...",
"followUpLink": "https://ecommerce.bonum.mn/ecommerce?invoiceId=c511ea63..."
}
GET 3.3 Нэхэмжлэлийн Төлөв (Зөвхөн Тест)
/bonum-gateway/ecommerce/invoices/{invoiceId}
АНХААРУУЛГА: ЭНЭ СЕРВИСИЙГ ПРОДАКШН ОРЧИНД АШИГЛАХГҮЙ.
"Нэхэмжлэл Үүсгэх"-ээр үүсгэсэн нэхэмжлэлийн төлбөрийн төлөвийг буцаана. Продакшн орчинд өөрийн локал өгөгдөл болон webhook мессежийг ашиглана: нэхэмжлэлийн бүртгэлийг өөрийн талд хадгалж, webhook хүлээн авсны дараа шинэчилнэ.
Хүсэлтийн Толгой
| Толгой | Утга |
|---|---|
Authorization |
Bearer {accessToken} |
Accept |
application/json |
3.4 Нэхэмжлэлийн Webhook
Хэрэглэгч төлбөрөө дуусгасны дараа мерчантын бүртгүүлсэн webhook URL руу POST хүсэлтээр webhook мессеж илгээгдэнэ.
Амжилттай Төлбөрийн Webhook
{
"type": "PAYMENT",
"status": "SUCCESS",
"message": "",
"body": {
"amount": 10000.00,
"currency": "MNT",
"completedAt": "2026-01-29 11:20:33",
"terminalId": "17171994",
"invoiceId": "8eff7d69001c03f486f64410f9daa82c",
"paymentVendor": "QPAY",
"initType": "ECOMMERCE",
"status": "PAID",
"respCode": "",
"transactionId": "N998921",
"extras-inputs": [],
"extras": []
}
}
Амжилтгүй Төлбөрийн Webhook
{
"type": "PAYMENT",
"status": "FAILED",
"message": "",
"body": {
"transactionId": "B347699",
"amount": 15000.00,
"currency": "MNT",
"updatedAt": 1769657291559,
"terminalId": "17171994",
"invoiceStatus": "EXPIRED"
}
}
4. Картын Токенжуулалт
Хүсэлтийн Толгойн Тэмдэглэл:
X-CARD-TOKEN-г хүсэлтийн толгойд хавсаргах ёстой.
Түүний утга нь кредит картын токен амжилттай үүссэний дараа
мерчантын webhook endpoint руу илгээгдэнэ.
POST 4.1 Картын Токен Үүсгэх
/mpay-service/merchant/cards/tokenize/request
Кредит картын токенжуулалтын хүсэлт үүсгэж, дагах линк буцаана. Линк нь хэрэглэгчийг шаардлагатай алхмуудаар дамжуулна. Дууссаны дараа мерчантын бүртгүүлсэн URL руу webhook мэдэгдэл илгээгдэнэ.
Хүсэлтийн Толгой
| Толгой | Утга |
|---|---|
Authorization |
Bearer {accessToken} |
Accept-Language |
mn or en |
Content-Type |
application/json |
Хүсэлтийн Бие
{
"callback": "https://merchant-web/card-token-callback?id=20250512180511001",
"transactionId": "15za20250512180511006",
"payment": {
"amount": 100.00
},
"subscription": { // optional
"planId": 1,
"cycleValue": "5",
"cycles": 5,
"payNow": false,
"custEmail": "customer@example.com"
},
"items": [ // optional
{
"image": "https://example.com/item.png",
"title": "Item title",
"remark": "Item description",
"amount": 1,
"count": 10
}
]
}
Хүсэлтийн Талбарууд
| Талбар | Төрөл | Шаардлагатай | Тайлбар |
|---|---|---|---|
callback |
String | Тийм | Токенжуулалтын дараа хэрэглэгчийг чиглүүлэх URL |
transactionId |
String | Тийм | Энэ токенжуулалтын хүсэлтийн давтагдашгүй ID |
payment.amount |
Number | Үгүй | Төлбөрийн дүн (токенжуулалтын үед төлбөр хийх бол) |
subscription.planId |
Number | Үгүй | Төлбөрийн төлөвлөгөөний ID (Төлбөрийн Төлөвлөгөөний Жагсаалт харна уу) |
subscription.cycleValue |
String | Үгүй | Төлбөрийн өдөр: 1-7 (долоо хоног), 1-31 (сар), 1-366 (жил) |
subscription.cycles |
Number | Үгүй | Төлбөрийн мөчлөгийн тоо. Null бол цуцлах хүртэл идэвхтэй |
subscription.payNow |
Boolean | Үгүй | True бол одоогийн огноо эхний төлбөрийн огноо болно |
subscription.custEmail |
String | Үгүй | Захиалгын мэдэгдэл авах хэрэглэгчийн имэйл |
Хариу 200 OK
{
"followUpLink": "https://ecommerce.bonum.mn/tokenize?id=73c642ec1df9ca...",
"id": "73c642ec1df9ca..."
}
Картын Токен Webhook Мессеж
Токен амжилттай үүссэний дараа мерчантын бүртгүүлсэн URL руу webhook мессеж илгээгдэнэ:
{
"type": "CARD-TOKEN",
"status": "SUCCESS",
"message": "",
"body": {
"token": "1fc53f9389f489ff6e04617bd6338a71...",
"mask": "5150 23** **** 4778",
"expiry": "2026/11",
"bank": {
"id": 19,
"code": "150000",
"name": "Golomt Bank",
"icon": "https://bonum-prod-resource.s3.us-east-2.amazonaws.com/golomt.png"
},
"transactionId": "6ab20250512180511006",
"completedAt": "2026-01-26 12:58:03",
"amounts": [
{ "amount": 5.00, "currency": "MNT" }
],
"subscriptions": [
{
"subscriptionId": 1,
"planId": 1,
"nextBillingDate": "2026-02-02 00:00:00"
}
]
}
}
Webhook Толгой
| Толгой | Тайлбар |
|---|---|
X-CARD-TOKEN |
Үүсгэгдсэн картын токены утга |
POST 4.2 Худалдан авалт (Картын Токеноор Төлөх)
/mpay-service/merchant/transaction/purchase
Өмнө үүсгэсэн картын токен ашиглан төлбөр хийнэ.
Тэмдэглэл: Ачаалал ихтэй үед төлбөрүүд дараалалд орж болно. Дараалалд орсон төлбөрүүд асинхрон байдлаар гүйцэтгэгдэж, үр дүнг webhook-ээр дамжуулна.
errorCode талбарыг ашиглах эсвэл харуулахгүй байна
уу. Энэ нь зөвхөн дотоод хэрэглээнд зориулагдсан.
Хүсэлтийн Толгой
| Толгой | Утга |
|---|---|
Authorization |
Bearer {accessToken} |
X-CARD-TOKEN |
Картын токены утга |
Accept-Language |
mn or en |
Content-Type |
application/json |
Хүсэлтийн Бие
{
"amount": 15,
"currency": "MNT",
"transactionId": "your-unique-transaction-id"
}
Амжилттай Хариу 200 OK
{
"traceId": "6965c23f4a88878d...",
"errorCode": "${invalid.bonum.response.00}",
"error": null,
"message": "Payment successful (00)",
"data": {
"id": 172345,
"completedAt": "2026-01-13 11:55:44",
"status": "SUCCESS",
"description": "",
"cardStatus": "ACTIVE"
},
"detail": null,
"duration": 759,
"status": 200
}
Алдааны Хариу 400 Bad Request
{
"traceId": "6965b3f57a560ad2...",
"errorCode": "${invalid.bonum.response.56}",
"error": null,
"message": "Card payment not possible (56)",
"data": {
"id": 171044,
"completedAt": "2026-01-13 10:54:46",
"status": "FAILED",
"description": "",
"cardStatus": "INACTIVE"
},
"detail": null,
"duration": 635,
"status": 400
}
Дараалалд Орсон Хариу 201 Created
{
"traceId": "697088018770d01b...",
"errorCode": "QUEUED",
"error": null,
"message": "bonum.token.invoice.queued",
"data": {
"id": 662,
"completedAt": "2026-01-21 16:02:10",
"status": "QUEUED",
"description": "",
"cardStatus": null,
"respCode": null
},
"detail": null,
"duration": 1192,
"status": 201
}
GET 4.3 Буцаалт
/mpay-service/merchant/transaction/rollback/{id}
Өмнө дууссан худалдан авалтын гүйлгээг буцаана.
Хүсэлтийн Толгой
| Толгой | Утга |
|---|---|
Authorization |
Bearer {accessToken} |
X-CARD-TOKEN |
Картын токены утга |
Замын Параметрүүд
| Параметр | Тайлбар |
|---|---|
id |
Буцаах гүйлгээний ID |
5. Захиалгын Төлөвлөгөө
GET 5.1 Төлбөрийн Төлөвлөгөөний Жагсаалт
/mpay-service/merchant/values/payment-plans
Мерчантын төлбөрийн төлөвлөгөөнүүдийн (захиалгын төлөвлөгөө) жагсаалтыг буцаана. Төлбөрийн төлөвлөгөөг Мерчант Порталд үүсгэх, унших, засах, устгах боломжтой.
Хүсэлтийн Толгой
| Толгой | Утга |
|---|---|
Authorization |
Bearer {accessToken} |
Хариу 200 OK
{
"traceId": "6960b2d3ec9f9d4a...",
"data": [
{
"planId": 1,
"name": "Test Weekly Plan 1",
"remark": "Weekly payment plan",
"createdAt": "2025-03-20 15:53:51",
"recurringType": "WEEKLY",
"amount": 5.00,
"status": "ACTIVE",
"cardCount": 0,
"retryCount": 3
},
{
"planId": 21,
"name": "Monthly Plan",
"remark": "Monthly payment plan",
"createdAt": "2026-01-08 16:21:30",
"recurringType": "MONTHLY",
"amount": 9.00,
"status": "ACTIVE",
"cardCount": 0,
"retryCount": 3
}
],
"status": 200
}
POST 5.2 Захиалга Хийх
/mpay-service/merchant/subscriptions/subscribe
Кредит картын токеныг төлбөрийн төлөвлөгөөнд захиалга хийнэ.
Хүсэлтийн Толгой
| Толгой | Утга |
|---|---|
Authorization |
Bearer {accessToken} |
X-CARD-TOKEN |
Картын токены утга |
Content-Type |
application/json |
Хүсэлтийн Бие
{
"planId": 30,
"cycleValue": 10,
"cycles": 3,
"payNow": false,
"custEmail": "customer@example.com"
}
Хүсэлтийн Талбарууд
| Талбар | Төрөл | Шаардлагатай | Тайлбар |
|---|---|---|---|
planId |
Number | Тийм | "Төлбөрийн Төлөвлөгөөний Жагсаалт"-аас авсан төлбөрийн төлөвлөгөөний ID |
cycleValue |
Number | Тийм | Төлбөрийн өдөр: WEEKLY 1-7 (Дав-Ням), MONTHLY 1-31, YEARLY 1-366 |
cycles |
Number | Үгүй | Мөчлөгийн тоо. Null бол цуцлах хүртэл идэвхтэй |
payNow |
Boolean | Үгүй | True бол cycleValue-г үл тоомсорлоно; эхний төлбөр шууд хийгдэнэ |
custEmail |
String | Үгүй | Мэдэгдэл авах хэрэглэгчийн имэйл |
Тэмдэглэл: Захиалгын огноо нь төлбөрийн
төлөвлөгөөний cycleValue-тай таарвал, захиалга хийх
үед төлбөр шууд хийгдэнэ.
Амжилттай Хариу 201 Created
{
"traceId": "6976ca6cbdfca1fc...",
"data": {
"subscriptionId": 41,
"subscribedAt": "2026-01-26 09:59:11",
"cardMask": "9496 43** **** 2727",
"plan": {
"planId": 4,
"name": "Monthly Plan",
"recurringType": "MONTHLY",
"amount": 3,
"status": "ACTIVE",
"retryCount": 3
},
"nextBillAt": "2026-01-27 00:00:00",
"lastBilledAt": "2026-01-26 09:59:11",
"status": "ACTIVE"
},
"status": 201
}
Алдаа: Давхар Захиалга 429 Too Many Requests
// If one subscription process is not finished and another is issued for the same card
{
"traceId": "6960ba5dc45779dd...",
"message": "subscription.process.waiting",
"data": null,
"status": 429
}
Алдаа: Картын Төлбөр Татгалзсан 400 Bad Request
// Card system denies the payment request
{
"traceId": "6960bb4080c62f87...",
"errorCode": "${invalid.bonum.response.89}",
"message": "Payment not possible (89)",
"data": null,
"status": 400
}
5.3 Захиалга Удирдах
PUT Захиалгын Токен Солих (Шинэ Токен Үүсгэх)
/mpay-service/merchant/subscriptions/{subscriptionId}/change/create-new-token
Шинэ токен үүсгэн захиалгын картын токеныг солино.
{
"callback": "https://merchant-web/card-token-callback?id=something",
"transactionId": "123456000",
"items": [ // optional
{
"image": "https://example.com/item.png",
"title": "Item title",
"remark": "Item description",
"amount": 1,
"count": 10
}
]
}
PUT Захиалгын Токен Солих (Одоо байгаа Токен)
/mpay-service/merchant/subscriptions/{subscriptionId}/change
Одоо байгаа токен ашиглан захиалгын картын токеныг солино.
| Толгой | Утга |
|---|---|
X-CARD-TOKEN |
Шинэ картын токены утга |
GET Захиалгууд Авах
/mpay-service/merchant/subscriptions
Картын токены захиалгуудыг буцаана.
| Толгой | Утга |
|---|---|
X-CARD-TOKEN |
Картын токены утга |
DELETE Захиалга Цуцлах
/mpay-service/merchant/subscriptions/{subscriptionId}
Картын токеныг төлбөрийн төлөвлөгөөнөөс захиалга цуцална. Дараагийн төлбөрийн мөчлөгийн төлбөр дараагийн төлбөрийн огноонд хийгдсээр байна.
| Толгой | Утга |
|---|---|
X-CARD-TOKEN |
Картын токены утга |
DELETE Захиалга Устгах
/mpay-service/merchant/subscriptions/{subscriptionId}/delete
Захиалгыг бүрмөсөн устгана. Дараагийн төлбөрийн мөчлөгт төлбөр үүсэхгүй.
| Толгой | Утга |
|---|---|
X-CARD-TOKEN |
Картын токены утга |
Захиалгын Автомат Төлбөрийн Webhook
Картын токен Төлбөрийн Төлөвлөгөөнд захиалга хийсний дараа, төлбөр нь төлбөрийн огноонд автоматаар хийгдэнэ. Мерчантын бүртгүүлсэн URL руу webhook мессеж илгээгдэнэ:
{
"type": "SUBSCRIPTION-PAYMENT",
"status": "SUCCESS", // SUCCESS | FAILED
"message": "",
"body": {
"subscriptionId": 41,
"invoiceId": 786,
"planId": 4,
"transactionId": "20000007",
"completedAt": "2026-01-27 02:00:08",
"amount": 3,
"currency": "MNT"
}
}
6. QR Код / Deeplink Төлбөр
POST 6.1 QR Код Үүсгэх
/mpay-service/merchant/transaction/qr/create
QPAY-г дэмждэг банк болон fintech апп-уудаар төлбөр хийх QR код үүсгэнэ.
Хүсэлтийн Толгой
| Толгой | Утга |
|---|---|
Authorization |
Bearer {accessToken} |
Content-Type |
application/json |
Хүсэлтийн Бие
{
"amount": 10,
"transactionId": "3ba1234567890a",
"expiresIn": 600 // 10 minutes, in seconds
}
Хариу 200 OK
{
"traceId": "69b76ea35599c03c...",
"status": 200,
"data": {
"invoiceId": "1234bacd123",
"qrCode": "12345...abc",
"qrImage": "[base64 encoded QR image]",
"links": [
{
"name": "Khan bank",
"description": "Khan bank",
"logo": "https://qpay.mn/q/logo/khanbank.png",
"link": "khanbank://q?qPay_QRcode=...",
"appStoreId": "1555908766",
"androidPackageName": "com.khanbank.retail"
},
{
"name": "Social Pay",
"description": "Golomt bank",
"logo": "https://qpay.mn/q/logo/socialpay.png",
"link": "socialpay-payment://q?qPay_QRcode=...",
"appStoreId": "1152919460",
"androidPackageName": "mn.egolomt.socialpay"
},
{
"name": "Trade and Development bank",
"description": "TDB online",
"logo": "https://qpay.mn/q/logo/tdbbank.png",
"link": "tdbbank://q?qPay_QRcode=...",
"appStoreId": "1458831706",
"androidPackageName": "mn.tdb.pay"
}
]
}
}
POST 6.2 QR Нэхэмжлэл
/mpay-service/merchant/transaction/qr
QR кодоор (QPAY QR Code) нэхэмжлэлийн мэдээлэл авна.
Хүсэлтийн Бие
{
"qrCode": "0002010102121531279404962794049600..."
}
PUT Картын Токеноор Төлөх
/merchant/transaction/qr/pay
Картын токен ашиглан QR нэхэмжлэл төлнө.
Хүсэлтийн Толгой
| Толгой | Утга |
|---|---|
Authorization |
Bearer {accessToken} |
X-CARD-TOKEN |
Картын токены утга |
Accept-Language |
mn or en |
Хүсэлтийн Бие
{
"qrCode": "0002010102121531279404962794049600...",
"transactionId": "f123456789"
}
7. Webhook Дамжуулалт & Баталгаажуулалт
Webhook Хэрхэн Ажилладаг
Төлбөрийн Gateway нь гүйлгээ болон картын токены мэдээллийг
мерчантын бүртгүүлсэн webhook URL руу HTTP POST-оор илгээдэг.
Мессежийн баталгаажуулалтад x-checksum-v2 толгой
хавсаргагдана.
Төлбөрийн Webhook Мессеж
{
"type": "PAYMENT",
"status": "SUCCESS", // SUCCESS | FAILED
"message": "Successful",
"body": {
"invoiceId": "abc....xyz....",
"transactionId": "your-transaction-id"
}
}
Картын Токен Webhook Мессеж
{
"type": "CARD-TOKEN",
"status": "SUCCESS", // SUCCESS | FAILED
"message": "Successful",
"body": {
"token": "abc....xyz....",
"transactionId": "your-transaction-id"
}
}
Checksum Баталгаажуулалт
Ирж буй webhook мессежийг x-checksum-v2 толгой
ашиглан баталгаажуулна. MERCHANT_CHECKSUM_KEY-г Bonum
аюулгүй байдлаар өгнө.
Энэ түлхүүрийг найдвартай хадгална уу.
// Kotlin Example
fun checksumValidation(httpRequest: HttpRequest): Boolean {
// This key will be provided by Bonum — keep it secure
val MERCHANT_CHECKSUM_KEY = ""
val raw = JSON.toJson(
value = httpRequest.requestBody,
prettyPrint = false // no indentation
)
val checksumValue = checksum(raw, MERCHANT_CHECKSUM_KEY)
val checksumHeaderValue = httpRequest.headers.get("x-checksum-v2")
return Objects.equals(checksumValue, checksumHeaderValue)
}
fun checksum(value: String, key: String): String {
val secretKey = SecretKeySpec(
key.toByteArray(Charsets.UTF_8),
"HmacSHA256"
)
val mac = Mac.getInstance("HmacSHA256")
mac.init(secretKey)
val hmacArray = mac.doFinal(
value.toByteArray(Charsets.UTF_8)
)
return hex(hmacArray)
}
private fun hex(vl: ByteArray): String {
val sb = StringBuilder(vl.size * 2)
for (b in vl) {
sb.append(String.format("%02x", b.toInt() and 0xff))
}
return sb.toString()
}
8. Дэмжлэг & Холбоо Барих
Лавлагаа:
Мерчант Портал -
https://merchant.bonum.mn/
Postman Цуглуулга -
Postman дээр харах
Нэмэлт тусламж хэрэгтэй бол манай багтай холбогдоно уу:
- Имэйл: info@bonum.mn
- Утас: +976 7200-5000
1. Environment Setup
Base URLs & Variables
| Variable | Testing Environment | Production Environment |
|---|---|---|
API_BASE_URL |
https://testapi.bonum.mn |
https://apis.bonum.mn |
APP_SECRET |
Provided during merchant setup | Contact Bonum |
DEFAULT_TERMINAL_ID |
Created on Merchant Portal | Contact Bonum |
Language Support
Use the Accept-Language header to receive responses
in your preferred language:
| Header | Value | Description |
|---|---|---|
Accept-Language |
mn |
Mongolian responses |
Accept-Language |
en |
English responses |
2. Authentication
GET Get Token
/bonum-gateway/ecommerce/auth/create
Obtain an access token and refresh token for API authentication.
The APP_SECRET is created on the merchant portal.
Create a terminal on the merchant portal and use its
terminalId value.
Caution: This endpoint is protected by rate limiting. Excessive
or too frequent requests will result in a
TOO_MANY_REQUESTS error.
Request Headers
| Header | Value | Description |
|---|---|---|
Authorization |
AppSecret {APP_SECRET} |
Your application secret key |
X-TERMINAL-ID |
{DEFAULT_TERMINAL_ID} |
Your terminal ID |
Response 200 OK
{
"tokenType": "Bearer",
"accessToken": "eyJhbGciOiJIUzI1...",
"expiresIn": 1800,
"refreshToken": "eyJhbGciOiJIUzI1...",
"refreshExpiresIn": 2000,
"unit": "SECONDS"
}
Error Response 429 Too Many Requests
{
"traceId": "695cbcbce9d3faa6...",
"errorCode": null,
"error": null,
"message": "Rate-Limit: Use previous token. Do not get token too frequently.",
"data": null,
"detail": null,
"duration": 452,
"status": 429
}
GET Refresh Token
/bonum-gateway/ecommerce/auth/refresh
Refresh an expired access token using the refresh token.
Request Headers
| Header | Value | Description |
|---|---|---|
Authorization |
Bearer {refreshToken} |
Your refresh token |
Response 200 OK
Returns a new access token with the same structure as the Get Token response.
3. Web Payment / All in One
GET 3.1 Get Payment Providers
/bonum-gateway/ecommerce/invoices/payment-providers
Returns the active payment options available for your customers. This list can be modified.
Available Providers
| Provider | Description |
|---|---|
QPAY |
QR-based payment. All banks and fintech apps support QPAY |
E_COMMERCE |
Online card payment |
WE_CHAT |
WeChat wallet payment for Chinese customers |
SONO_SHOP |
Buy Now, Pay Later via SonoShop loan |
Request Headers
| Header | Value |
|---|---|
Authorization |
Bearer {accessToken} |
Response 200 OK
[
{
"provider": "QPAY",
"enabled": true
},
{
"provider": "E_COMMERCE",
"enabled": true
},
{
"provider": "SONO_SHOP",
"enabled": true
}
]
POST 3.2 Create Invoice
/bonum-gateway/ecommerce/invoices
Creates an invoice and returns a follow-up link. The browser or client must redirect to the follow-up link for the user to proceed with payment.
Once payment is completed or cancelled, a notification will be sent to the callback (webhook) URL. The callback must be an HTTP(S) endpoint pre-configured on the Bonum side.
Request Headers
| Header | Value |
|---|---|
Authorization |
Bearer {accessToken} |
Accept-Language |
mn or en |
Content-Type |
application/json |
Request Body
{
"amount": 1,
"callback": "https://your-domain.com/payment-callback?txn=c22765536",
"transactionId": "aa22765536",
"expiresIn": 23000, // seconds
"providers": ["QPAY"], // optional, see "Get Payment Providers"
"items": [ // optional
{
"image": "https://example.com/product.png",
"title": "Product Name",
"remark": "Product Description",
"amount": 1,
"count": 1
}
],
"extras": [ // optional
{
"placeholder": "Enter details",
"type": "TEXT", // NUMBER, PHONE, EMAIL, TEXT, ALL
"required": true
}
]
}
Request Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
amount |
Number | Yes | Total payment amount |
callback |
String | Yes | URL to redirect after payment |
transactionId |
String | Yes | Your unique transaction identifier |
expiresIn |
Number | No | Expiry time in seconds |
providers |
Array | No | Filter payment providers |
items |
Array | No | Line items for the invoice |
extras |
Array | No | Extra input fields for customer |
Response 200 OK
{
"invoiceId": "8cf2c49d200f049f2b384f0adf42b981...",
"followUpLink": "https://ecommerce.bonum.mn/ecommerce?invoiceId=c511ea63..."
}
GET 3.3 Get Invoice Status (Testing Only)
/bonum-gateway/ecommerce/invoices/{invoiceId}
CAUTION: DO NOT USE THIS SERVICE ON PRODUCTION.
Returns the payment status of an invoice created by "Create Invoice". For production, use your local data and webhook message delivery: store the invoice record on your side and update it once a webhook is received.
Request Headers
| Header | Value |
|---|---|
Authorization |
Bearer {accessToken} |
Accept |
application/json |
3.4 Invoice Webhook Messages
After the user completes a payment, a webhook message is sent to the merchant's registered webhook URL via POST.
Successful Payment Webhook
{
"type": "PAYMENT",
"status": "SUCCESS",
"message": "",
"body": {
"amount": 10000.00,
"currency": "MNT",
"completedAt": "2026-01-29 11:20:33",
"terminalId": "17171994",
"invoiceId": "8eff7d69001c03f486f64410f9daa82c",
"paymentVendor": "QPAY",
"initType": "ECOMMERCE",
"status": "PAID",
"respCode": "",
"transactionId": "N998921",
"extras-inputs": [],
"extras": []
}
}
Failed Payment Webhook
{
"type": "PAYMENT",
"status": "FAILED",
"message": "",
"body": {
"transactionId": "B347699",
"amount": 15000.00,
"currency": "MNT",
"updatedAt": 1769657291559,
"terminalId": "17171994",
"invoiceStatus": "EXPIRED"
}
}
4. Card Tokenization
Request Header Note:
X-CARD-TOKEN must be attached to request headers. Its
value is sent to the merchant's webhook endpoint once the credit
card token is generated successfully.
POST 4.1 Create Card Token
/mpay-service/merchant/cards/tokenize/request
Creates a credit card tokenization request and returns a follow-up link. The link takes the user through the necessary steps. Once done, a webhook notification will be sent to the merchant's registered URL.
Request Headers
| Header | Value |
|---|---|
Authorization |
Bearer {accessToken} |
Accept-Language |
mn or en |
Content-Type |
application/json |
Request Body
{
"callback": "https://merchant-web/card-token-callback?id=20250512180511001",
"transactionId": "15za20250512180511006",
"payment": {
"amount": 100.00
},
"subscription": { // optional
"planId": 1,
"cycleValue": "5",
"cycles": 5,
"payNow": false,
"custEmail": "customer@example.com"
},
"items": [ // optional
{
"image": "https://example.com/item.png",
"title": "Item title",
"remark": "Item description",
"amount": 1,
"count": 10
}
]
}
Request Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
callback |
String | Yes | URL to redirect user after tokenization |
transactionId |
String | Yes | Your unique ID for this tokenization request |
payment.amount |
Number | No | Payment amount (if making a payment during tokenization) |
subscription.planId |
Number | No | Payment plan ID (see List of Payment Plans) |
subscription.cycleValue |
String | No | Billing day: 1-7 (weekly), 1-31 (monthly), 1-366 (yearly) |
subscription.cycles |
Number | No | Number of billing cycles. If null, active until cancelled |
subscription.payNow |
Boolean | No | If true, current date becomes first billing date |
subscription.custEmail |
String | No | Customer email for subscription notifications |
Response 200 OK
{
"followUpLink": "https://ecommerce.bonum.mn/tokenize?id=73c642ec1df9ca...",
"id": "73c642ec1df9ca..."
}
Card Token Webhook Message
On successful token generation, a webhook message is sent to the merchant's registered URL:
{
"type": "CARD-TOKEN",
"status": "SUCCESS",
"message": "",
"body": {
"token": "1fc53f9389f489ff6e04617bd6338a71...",
"mask": "5150 23** **** 4778",
"expiry": "2026/11",
"bank": {
"id": 19,
"code": "150000",
"name": "Golomt Bank",
"icon": "https://bonum-prod-resource.s3.us-east-2.amazonaws.com/golomt.png"
},
"transactionId": "6ab20250512180511006",
"completedAt": "2026-01-26 12:58:03",
"amounts": [
{ "amount": 5.00, "currency": "MNT" }
],
"subscriptions": [
{
"subscriptionId": 1,
"planId": 1,
"nextBillingDate": "2026-02-02 00:00:00"
}
]
}
}
Webhook Headers
| Header | Description |
|---|---|
X-CARD-TOKEN |
The generated card token value |
POST 4.2 Purchase (Pay with Card Token)
/mpay-service/merchant/transaction/purchase
Initiates a payment using a previously generated card token.
Note: During high traffic, payments may be queued. Queued payments are executed asynchronously and the result is delivered via webhook.
Do not rely on or expose the errorCode field. It
is for internal use only.
Request Headers
| Header | Value |
|---|---|
Authorization |
Bearer {accessToken} |
X-CARD-TOKEN |
Card token value |
Accept-Language |
mn or en |
Content-Type |
application/json |
Request Body
{
"amount": 15,
"currency": "MNT",
"transactionId": "your-unique-transaction-id"
}
Successful Response 200 OK
{
"traceId": "6965c23f4a88878d...",
"errorCode": "${invalid.bonum.response.00}",
"error": null,
"message": "Payment successful (00)",
"data": {
"id": 172345,
"completedAt": "2026-01-13 11:55:44",
"status": "SUCCESS",
"description": "",
"cardStatus": "ACTIVE"
},
"detail": null,
"duration": 759,
"status": 200
}
Failed Response 400 Bad Request
{
"traceId": "6965b3f57a560ad2...",
"errorCode": "${invalid.bonum.response.56}",
"error": null,
"message": "Card payment not possible (56)",
"data": {
"id": 171044,
"completedAt": "2026-01-13 10:54:46",
"status": "FAILED",
"description": "",
"cardStatus": "INACTIVE"
},
"detail": null,
"duration": 635,
"status": 400
}
Queued Response 201 Created
{
"traceId": "697088018770d01b...",
"errorCode": "QUEUED",
"error": null,
"message": "bonum.token.invoice.queued",
"data": {
"id": 662,
"completedAt": "2026-01-21 16:02:10",
"status": "QUEUED",
"description": "",
"cardStatus": null,
"respCode": null
},
"detail": null,
"duration": 1192,
"status": 201
}
GET 4.3 Rollback Purchase
/mpay-service/merchant/transaction/rollback/{id}
Rolls back a previously completed purchase transaction.
Request Headers
| Header | Value |
|---|---|
Authorization |
Bearer {accessToken} |
X-CARD-TOKEN |
Card token value |
Path Parameters
| Parameter | Description |
|---|---|
id |
The transaction ID to rollback |
5. Subscription Plans
GET 5.1 List of Payment Plans
/mpay-service/merchant/values/payment-plans
Returns the list of payment plans (subscription plans) of the merchant. Payment plans can be created, read, updated, and deleted on the Merchant Portal.
Request Headers
| Header | Value |
|---|---|
Authorization |
Bearer {accessToken} |
Response 200 OK
{
"traceId": "6960b2d3ec9f9d4a...",
"data": [
{
"planId": 1,
"name": "Test Weekly Plan 1",
"remark": "Weekly payment plan",
"createdAt": "2025-03-20 15:53:51",
"recurringType": "WEEKLY",
"amount": 5.00,
"status": "ACTIVE",
"cardCount": 0,
"retryCount": 3
},
{
"planId": 21,
"name": "Monthly Plan",
"remark": "Monthly payment plan",
"createdAt": "2026-01-08 16:21:30",
"recurringType": "MONTHLY",
"amount": 9.00,
"status": "ACTIVE",
"cardCount": 0,
"retryCount": 3
}
],
"status": 200
}
POST 5.2 Subscribe
/mpay-service/merchant/subscriptions/subscribe
Subscribes a credit card token to a payment plan.
Request Headers
| Header | Value |
|---|---|
Authorization |
Bearer {accessToken} |
X-CARD-TOKEN |
Card token value |
Content-Type |
application/json |
Request Body
{
"planId": 30,
"cycleValue": 10,
"cycles": 3,
"payNow": false,
"custEmail": "customer@example.com"
}
Request Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
planId |
Number | Yes | Payment plan ID from "List of Payment Plans" |
cycleValue |
Number | Yes | Billing day: WEEKLY 1-7 (Mon-Sun), MONTHLY 1-31, YEARLY 1-366 |
cycles |
Number | No | Number of cycles. If null, active until cancelled |
payNow |
Boolean | No | If true, ignores cycleValue; first payment is immediate |
custEmail |
String | No | Customer email for notifications |
Note: If the subscription date matches the
payment plan's cycleValue, the payment is processed
immediately during subscription.
Successful Response 201 Created
{
"traceId": "6976ca6cbdfca1fc...",
"data": {
"subscriptionId": 41,
"subscribedAt": "2026-01-26 09:59:11",
"cardMask": "9496 43** **** 2727",
"plan": {
"planId": 4,
"name": "Monthly Plan",
"recurringType": "MONTHLY",
"amount": 3,
"status": "ACTIVE",
"retryCount": 3
},
"nextBillAt": "2026-01-27 00:00:00",
"lastBilledAt": "2026-01-26 09:59:11",
"status": "ACTIVE"
},
"status": 201
}
Error: Multiple Subscription 429 Too Many Requests
// If one subscription process is not finished and another is issued for the same card
{
"traceId": "6960ba5dc45779dd...",
"message": "subscription.process.waiting",
"data": null,
"status": 429
}
Error: Card Payment Denied 400 Bad Request
// Card system denies the payment request
{
"traceId": "6960bb4080c62f87...",
"errorCode": "${invalid.bonum.response.89}",
"message": "Payment not possible (89)",
"data": null,
"status": 400
}
5.3 Manage Subscriptions
PUT Change Subscription Token (Create New Token)
/mpay-service/merchant/subscriptions/{subscriptionId}/change/create-new-token
Changes the card token for a subscription by creating a new token.
{
"callback": "https://merchant-web/card-token-callback?id=something",
"transactionId": "123456000",
"items": [ // optional
{
"image": "https://example.com/item.png",
"title": "Item title",
"remark": "Item description",
"amount": 1,
"count": 10
}
]
}
PUT Change Subscription Token (Existing Token)
/mpay-service/merchant/subscriptions/{subscriptionId}/change
Changes the card token for a subscription using an existing token.
| Header | Value |
|---|---|
X-CARD-TOKEN |
The new card token value |
GET Get Subscriptions
/mpay-service/merchant/subscriptions
Returns the subscriptions of a card token.
| Header | Value |
|---|---|
X-CARD-TOKEN |
Card token value |
DELETE Unsubscribe
/mpay-service/merchant/subscriptions/{subscriptionId}
Unsubscribes a card token from a payment plan. The next billing cycle payment will still be executed at the next billing date.
| Header | Value |
|---|---|
X-CARD-TOKEN |
Card token value |
DELETE Delete Subscription
/mpay-service/merchant/subscriptions/{subscriptionId}/delete
Deletes a subscription entirely. No payment is created for the next billing cycle.
| Header | Value |
|---|---|
X-CARD-TOKEN |
Card token value |
Subscription Automatic Payment Webhook
Once a card token is subscribed to a Payment Plan, payments are processed automatically on billing dates. A webhook message is sent to the merchant's registered URL:
{
"type": "SUBSCRIPTION-PAYMENT",
"status": "SUCCESS", // SUCCESS | FAILED
"message": "",
"body": {
"subscriptionId": 41,
"invoiceId": 786,
"planId": 4,
"transactionId": "20000007",
"completedAt": "2026-01-27 02:00:08",
"amount": 3,
"currency": "MNT"
}
}
6. QR Code / Deeplink Payment
POST 6.1 Create QR Code
/mpay-service/merchant/transaction/qr/create
Creates a QR code for payment via QPAY-supported bank and fintech apps.
Request Headers
| Header | Value |
|---|---|
Authorization |
Bearer {accessToken} |
Content-Type |
application/json |
Request Body
{
"amount": 10,
"transactionId": "3ba1234567890a",
"expiresIn": 600 // 10 minutes, in seconds
}
Response 200 OK
{
"traceId": "69b76ea35599c03c...",
"status": 200,
"data": {
"invoiceId": "1234bacd123",
"qrCode": "12345...abc",
"qrImage": "[base64 encoded QR image]",
"links": [
{
"name": "Khan bank",
"description": "Khan bank",
"logo": "https://qpay.mn/q/logo/khanbank.png",
"link": "khanbank://q?qPay_QRcode=...",
"appStoreId": "1555908766",
"androidPackageName": "com.khanbank.retail"
},
{
"name": "Social Pay",
"description": "Golomt bank",
"logo": "https://qpay.mn/q/logo/socialpay.png",
"link": "socialpay-payment://q?qPay_QRcode=...",
"appStoreId": "1152919460",
"androidPackageName": "mn.egolomt.socialpay"
},
{
"name": "Trade and Development bank",
"description": "TDB online",
"logo": "https://qpay.mn/q/logo/tdbbank.png",
"link": "tdbbank://q?qPay_QRcode=...",
"appStoreId": "1458831706",
"androidPackageName": "mn.tdb.pay"
}
]
}
}
POST 6.2 Get Invoice by QR Code
/mpay-service/merchant/transaction/qr
Gets QR invoice information by qrCode (QPAY QR Code).
Request Body
{
"qrCode": "0002010102121531279404962794049600..."
}
PUT Pay by Card Token
/merchant/transaction/qr/pay
Pays a QR invoice using a card token.
Request Headers
| Header | Value |
|---|---|
Authorization |
Bearer {accessToken} |
X-CARD-TOKEN |
Card token value |
Accept-Language |
mn or en |
Request Body
{
"qrCode": "0002010102121531279404962794049600...",
"transactionId": "f123456789"
}
7. Webhook Delivery & Validation
How Webhooks Work
The Payment Gateway sends transaction and card token information
to the merchant's registered webhook URL via HTTP POST. A
x-checksum-v2 header is included for message
validation.
Payment Webhook Message
{
"type": "PAYMENT",
"status": "SUCCESS", // SUCCESS | FAILED
"message": "Successful",
"body": {
"invoiceId": "abc....xyz....",
"transactionId": "your-transaction-id"
}
}
Card Token Webhook Message
{
"type": "CARD-TOKEN",
"status": "SUCCESS", // SUCCESS | FAILED
"message": "Successful",
"body": {
"token": "abc....xyz....",
"transactionId": "your-transaction-id"
}
}
Checksum Validation
Validate incoming webhook messages using the
x-checksum-v2 header. The
MERCHANT_CHECKSUM_KEY will be provided by Bonum
securely. Keep this key safe.
// Kotlin Example
fun checksumValidation(httpRequest: HttpRequest): Boolean {
// This key will be provided by Bonum — keep it secure
val MERCHANT_CHECKSUM_KEY = ""
val raw = JSON.toJson(
value = httpRequest.requestBody,
prettyPrint = false // no indentation
)
val checksumValue = checksum(raw, MERCHANT_CHECKSUM_KEY)
val checksumHeaderValue = httpRequest.headers.get("x-checksum-v2")
return Objects.equals(checksumValue, checksumHeaderValue)
}
fun checksum(value: String, key: String): String {
val secretKey = SecretKeySpec(
key.toByteArray(Charsets.UTF_8),
"HmacSHA256"
)
val mac = Mac.getInstance("HmacSHA256")
mac.init(secretKey)
val hmacArray = mac.doFinal(
value.toByteArray(Charsets.UTF_8)
)
return hex(hmacArray)
}
private fun hex(vl: ByteArray): String {
val sb = StringBuilder(vl.size * 2)
for (b in vl) {
sb.append(String.format("%02x", b.toInt() and 0xff))
}
return sb.toString()
}
8. Support & Contact
References:
Merchant Portal -
https://merchant.bonum.mn/
Postman Collection -
View on Postman
If you need further assistance, please contact our team:
- Email: info@bonum.mn
- Phone: +976 7200-5000