This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
# 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=<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…/<id>/paynow ←─────────────────────────────┘
|
||||
… Pomelo tokenise, next-action, Wibmo 3-D Secure, MPGS … → TRANSACTION_CONFIRMED
|
||||
GET transaction.merchants…/<id>?wait=1 → 302 dhiraagu-bml-response.aspx (tops up)
|
||||
→ 302 /services/reload-receipt
|
||||
```
|
||||
|
||||
After the payment the browser is sent `transaction…/<id>?wait=1` →
|
||||
`dhiraagu-bml-response.aspx?transactionId=<id>&state=CONFIRMED&signature=…` →
|
||||
`/services/reload-receipt?pyid=<paymentId>`. **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/<id>?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=<sub>&act=<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=<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":"<cartId>","gatewayId":1,"dhiraaguPayNumber":"","amount":"20.00",
|
||||
"paymentMerchantId":"<BML merchantId>","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":"<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":"<BML txn id>","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)
|
||||
@@ -96,6 +96,7 @@ The API only returns a valid result for numbers currently on the Dhiraagu networ
|
||||
| # | File | Description |
|
||||
|---|---|---|
|
||||
| 1 | [Number Lookup](01-number-lookup.md) | Validate a Dhiraagu number and determine account type |
|
||||
| 2 | [Reload](02-reload.md) | Easy TopUp order → BML merchant transaction, paid by card |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user