# Reload (Easy TopUp, paid by BML card) Top up a Dhiraagu prepaid number through the dhiraagu.com.mv **Easy TopUp** page. Dhiraagu only builds the order: the money moves on a **BML Merchant Services transaction** that Dhiraagu creates for it, which is then paid exactly like any card-only BML merchant link ([BML API → Merchant Card Payment](../bmlapi/16-card-payment.md)). Reconstructed from `docs/dhiraaguapi/tmp/dhiraagu_reload_gateway.md` (a Firefox HAR). --- ## Flow overview ``` GET /services/easy-topup → nonce #1 POST cart&act=recharge (nonce #1) → cartId GET /services/payment-v2?cartid= → nonce #2 POST merchant&act=form (nonce #2) → BML gateway's merchantId POST payment&act=create (nonce #2) → paymentId, oid POST bml&act=createV2 (nonce #2) → BML transaction url ──┐ │ ── from here: the BML card-only merchant flow ── │ GET transaction.merchants…//paynow ←─────────────────────────────┘ … Pomelo tokenise, next-action, Wibmo 3-D Secure, MPGS … → TRANSACTION_CONFIRMED GET transaction.merchants…/?wait=1 → 302 dhiraagu-bml-response.aspx (tops up) → 302 /services/reload-receipt ``` After the payment the browser is sent `transaction…/?wait=1` → `dhiraagu-bml-response.aspx?transactionId=&state=CONFIRMED&signature=…` → `/services/reload-receipt?pyid=`. **This is what makes Dhiraagu top up the number** — a payment that stopped at BML's `TRANSACTION_CONFIRMED` was charged but not delivered until that URL was opened. The card flow follows it for every merchant, see [BML API → Return to the merchant](../bmlapi/16-card-payment.md#7-return-to-the-merchant). **Recovering a stuck reload:** open `https://transaction.merchants.bankofmaldives.com.mv/?wait=1` in a browser. BML signs the callback, so the transaction id is all that's needed. (`curl` gets a Cloudflare 403 on the Dhiraagu hop; a browser works.) --- ## Common All API calls are `POST https://www.dhiraagu.com.mv/api/sdk-dhr-webapi.ashx?website_id=CA2BB809-3A22-485B-A518-DA6B6DE653A5&sub=&act=` with a JSON body and these headers: | Header | Value | |---|---| | `User-Agent` | a browser UA (same as [Number Lookup](01-number-lookup.md)) | | `Content-Type` | `application/json` | | `X-Requested-With` | `XMLHttpRequest` | | `Origin` | `https://www.dhiraagu.com.mv` | | `nonce` | `var nonce = "…"` from the page that makes the call | Every response is `{"respStatus":"OK","resp":…}` on success. Each page has its own nonce: the cart call uses the Easy TopUp page's, the rest use the payment page's. --- ## 1. Settings (optional) `GET …&sub=setting&act=reload` — the page reads its limits from here. Thijooree hardcodes them. ```json {"gstRate":0.08,"dailyLimit":3000, "amountLimit":{"min":20,"max":1080,"message":"Enter a whole number amount between MVR 20 and 1000"}, "reloadPerDay":{"easyTopUp":4,"myAccount":6}, …} ``` | Rule | Value | |---|---| | Amount | whole MVR, **20 – 1000** (the message says 1000; `max` says 1080 — Thijooree uses 1000) | | GST | 8%, **included** in the amount | | Per day | MVR 3000, 4 Easy TopUps | GST, as the page works it out: `gst = round2(amount × 0.08 / 1.08)`, credited `amount − gst` (MVR 20 → GST 1.48, credited 18.52). --- ## 2. Cart `sub=cart&act=recharge`, nonce from `GET /services/easy-topup`. ```json {"formId":2,"serviceNumber":"7XXXXXX","amount":20,"amountGST":1.48,"amountRecharge":18.52, "gstRate":0.08,"memberId":"","memberName":"","memberNId":"","customerId":"","customerCode":"","version":2} ``` ```json {"cartId":"002773ed-…","formId":2,"cartAmount":20.00,"cartExpiry":"…", "paymentUrl":"https://www.dhiraagu.com.mv/services/payment-v2?cartid=002773ed-…", …} ``` The page also calls `sub=dhiraaguIO&act=infoSubscriberStatus` (`{"number"}`) before this, to show the number's status and balance. Thijooree skips it — [Number Lookup](01-number-lookup.md) has already confirmed a prepaid number. --- ## 3. Payment gateway `sub=merchant&act=form`, `{"formId":2}`, nonce from `GET /services/payment-v2?cartid=`. Lists the gateways; **`gatewayId: 1` is Bank of Maldives** (2 = MIB, 3 = DhiraaguPay). ```json [{"merchantId":"98de333c-…","merchantId2":"3f5cf6b7-…","formId":2,"gatewayId":1, "gatewayName":"Bank of Maldives", …}, …] ``` --- ## 4. Payment `sub=payment&act=create` ```json {"formId":2,"cartId":"","gatewayId":1,"dhiraaguPayNumber":"","amount":"20.00", "paymentMerchantId":"","memberId":"","tokenize":"","paymentType":"", "recurringFrequency":"","bmlTokenId":""} ``` ```json {"paymentId":"3ea4351b-…","oid":"ET20260006911381","gatewayId":1,"amount":20.00,"paymentStatus":0, …} ``` --- ## 5. BML transaction `sub=bml&act=createV2`, `{"paymentId":""}`. Returns the BML Merchant Services transaction (amounts in cents): ```json {"state":"INITIATED","amount":2000,"currency":"MVR","localId":"ET20260006911381", "url":"https://transaction.merchants.bankofmaldives.com.mv/6abfec7afd7f4a4360fc1df4", "redirectUrl":"https://www.dhiraagu.com.mv/api/dhiraagu-bml-response.aspx", "expires":"…(10 min)…","customerReference":"WebApp - Topup", …} ``` The 24-hex id at the end of `url` is the transaction. Its `/paynow` page offers **UnionPay + MPGS cards only, no BML Pay**, so it's paid by card + 3-D Secure. --- ## Reload record `sub=reload&act=list`, `{"paymentId"}`, nonce from the receipt page — what the receipt page shows: ```json {"oid":"ET20260006911381","transId":"","serviceNumber":"7XXXXXX", "amountPay":20.00,"amountTopup":18.52,"amountGST":1.48, "paidStatus":1,"topupStatus":1,"reloadStatusDesc":"Successful", …} ``` Not used by Thijooree yet. --- ## Cloudflare `www.dhiraagu.com.mv` is behind Cloudflare. The browser capture carries a `cf_clearance` cookie, but [Number Lookup](01-number-lookup.md) already works from the app with plain okhttp and a browser UA, so these calls are made the same way. ---   --- **Related:** [Number Lookup](01-number-lookup.md) · [BML Merchant Card Payment](../bmlapi/16-card-payment.md) · App side: [Transfer Flows](../thijooree/20-transfer-flows.md#carrier-services-by-bml-card) [← Number Lookup](01-number-lookup.md) · [Bill Pay →](03-bill-pay.md)