SSkilltecabyclaudinhocode
Enviar skill
← Voltar para o catálogo

bml-connect

Automação

BML Connect (Bank of Maldives) payment API integration guide. Use this skill whenever the user mentions BML Connect, Bank of Maldives payments, MVR transactions, MobilePay integration, Maldivian payment processing, laari currency, or wants to accept payments in the Maldives. Also trigger when you see BML API keys, `/public/v2/transactions`, `/public-customers`, or any reference to merchants.bankof

10estrelas
Ver no GitHub ↗Autor: umarey

BML Connect Integration

BML Connect is the Bank of Maldives merchant payment platform — the primary way to accept online payments in the Maldives. This skill contains everything needed to integrate with the BML Connect API.


Authentication

Every API call uses a static API key in the Authorization header. No OAuth, no token exchange, no expiry.

Authorization: YOUR_SECRET_API_KEY

Two types of API keys exist per app:

  • API Key (secret) — long JWT-like string. Used for all server-to-server calls. Never expose publicly.
  • API Key Publicpk_ prefixed. Only for client-side card tokenization (PomeloJS). Not needed for server-side operations.

The merchant also has an Application ID (UUID format) which may be needed for some SDK-based calls.


Environments

EnvironmentBase URLDashboard
Productionhttps://api.merchants.bankofmaldives.com.mv/publicdashboard.merchants.bankofmaldives.com.mv
Sandbox (UAT)https://api.uat.merchants.bankofmaldives.com.mv/publicdashboard.uat.merchants.bankofmaldives.com.mv

Default to sandbox when writing integration code unless the user specifies production. This prevents accidental real charges during development.


API Endpoints Quick Reference

OperationMethodEndpoint
Create transactionPOST/public/v2/transactions
Get transactionGET/public/v2/transactions/{id}
Update transactionPATCH/public/v2/transactions/{id}
Send payment SMSPOST/public/transactions/{id}/sms
Send payment EmailPOST/public/transactions/{id}/email
Create customerPOST/public-customers
Get customerGET/public-customers/{id}
List customersGET/public-customers
Get customer tokensGET/public-customers/{id}/tokens
Charge tokenPOST/public-customers/charge
Create shopPOST/public/shops
Get shopsGET/public/shops
Update shopPATCH/public/shops/{id}

Critical URL quirk: Customer endpoints use /public-customers (dash), not /public/customers (slash). This is the most common integration mistake — getting this wrong produces confusing 404 errors.


Creating a Transaction

This is the most common operation. Send amount in laari (smallest currency unit — 100 laari = MVR 1.00).

POST /public/v2/transactions

{
    "amount": 15000,
    "currency": "MVR",
    "localId": "your-internal-id",
    "customerReference": "Human-readable description",
    "webhook": "https://your-domain.com/webhooks/bml",
    "redirectUrl": "https://your-domain.com/payment/complete"
}

Response contains:

  • id — BML transaction ID
  • url — full payment page URL (redirect the customer here or embed in iframe)
  • shortUrl — short URL (useful for SMS)
  • qr.url — QR code image URL
  • stateQR_CODE_GENERATED initially

The localId field is your internal reference — use it to match BML transactions back to your orders/invoices.


Transaction States

StateMeaning
QR_CODE_GENERATEDTransaction created, QR ready, awaiting payment
CONFIRMEDPayment received — money is in
CANCELLEDTransaction cancelled
FAILEDPayment failed
EXPIREDTransaction timed out

Only CONFIRMED means money received. Always verify via webhook or polling before marking anything as paid. Never trust client-side redirects alone — a user can manipulate the redirect URL.


Payment Methods Supported

  • Card (Visa/Mastercard via MPGS) — customer scans QR or opens link, enters card details
  • BML MobilePay — customer scans QR in MobilePay app
  • Alipay / WeChat Pay / UnionPay — tourist payments
  • Apple Pay / Google Pay — via QR flow

Known limitation: MIB (Maldives Islamic Bank) customers cannot pay through BML Connect. MIB transfers must be handled manually outside of BML Connect. If the user's product serves MIB customers, suggest adding a manual bank transfer option alongside BML Connect.


Webhook Handling

BML sends a POST request to your webhook URL when a transaction state changes. This is the most reliable way to confirm payments.

Webhook Signature Verification

BML sends three headers for signature verification:

  • X-Signature-Nonce
  • X-Signature-Timestamp
  • X-Signature

Verify by generating sha256(nonce + timestamp + apiKey) and comparing to the signature header using a timing-safe comparison (to prevent timing attacks):

generated = sha256(nonce + timestamp + your_api_key)
valid = timing_safe_equals(generated, X-Signature)

Use the language-appropriate timing-safe comparison:

  • Node.js: crypto.timingSafeEqual()
  • Python: hmac.compare_digest()
  • PHP: hash_equals()
  • Go: subtle.ConstantTimeCompare()

Webhook Event Types

EventWhen it fires
NOTIFY_TRANSACTION_CHANGEAny state change on a transaction
NOTIFY_TOKENISATION_STATUSCard saved successfully (tokenization)

Webhook Payload

The payload includes eventType, state, transactionId, and other transaction details. Only process CONFIRMED state to mark payments as complete.

Important: Your webhook endpoint must be excluded from CSRF protection. BML cannot send a CSRF token. Framework-specific examples:

  • Laravel: Add the route to $except in VerifyCsrfToken middleware
  • Express: Use express.raw() or express.json() on the webhook route specifically
  • Django: Use @csrf_exempt decorator

Webhook Best Practices

  1. Return 200 immediately, process asynchronously — BML may retry on slow responses
  2. Make webhook processing idempotent — you may receive the same event multiple times
  3. Always verify the signature before trusting the payload
  4. Log the raw payload for debugging

Sending Payment Links

Via SMS

POST /public/transactions/{transactionId}/sms

{
    "phoneNumber": "9607771234"
}

Via Email

POST /public/transactions/{transactionId}/email

{
    "email": "customer@example.com"
}

Known issue: SMS and Email sending may fail with AWS authentication errors on BML's side. This is a BML infrastructure issue, not your code. If this happens, use the shortUrl from the transaction response and send it yourself via your own SMS/email provider. Always implement this fallback — don't rely solely on BML's SMS/email.


Tokenization (Card-on-File)

BML supports saving customer cards for one-click future payments.

Flow

  1. Create a customer in BML's system first
  2. First payment: Create transaction with tokenizationDetails — BML saves card, returns token
  3. Future payments: Call charge token endpoint with customerId + tokenId — charged instantly, no card re-entry

Create Customer

POST /public-customers

{
    "name": "Customer Name",
    "email": "customer@example.com",
    "phone": "9607771234"
}

First Payment (Tokenize)

POST /public/v2/transactions

{
    "amount": 15000,
    "currency": "MVR",
    "customerId": "bml-customer-id",
    "tokenizationDetails": {
        "tokenize": true,
        "paymentType": "UNSCHEDULED",
        "recurringFrequency": "UNSCHEDULED"
    },
    "webhook": "https://your-domain.com/webhooks/bml"
}

Charge Saved Card

POST /public-customers/charge

{
    "customerId": "bml-customer-id",
    "transactionId": "new-transaction-id",
    "tokenId": "saved-card-token-id"
}

Note: You must first create a new transaction (to get a transactionId), then charge the token against it. The token charge is a two-step process.

Webhook event NOTIFY_TOKENISATION_STATUS fires when a card is saved successfully.


Money Handling

  • Currency: MVR (Maldivian Rufiyaa)
  • Smallest unit: laari (100 laari = MVR 1.00)
  • Always send amounts to BML in laari (integer). MVR 150.00 = 15000.
  • **Never use floating point for mone

Como adicionar

/plugin marketplace add umarey/BML-Connect-Claude-Code-skill

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Comentários · Nenhum comentário

Entre para comentar. Entrar

  • Ainda não há comentários. Seja o primeiro.