Receber por email
← Voltar para o catálogo

bml-connect

Esta skill é um guia de integração da API de pagamentos BML Connect (Bank of Maldives). Ative-a para tópicos como pagamentos BML Connect, transações MVR, processamento de pagamentos nas Maldivas, ou ao aceitar pagamentos nas Maldivas, incluindo referências a chaves API BML.

10estrelas
Atualizado há 6 meses

Ver no GitHub ↗

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.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/bml-connect/svg)](https://www.skillteca.com.br/skills/bml-connect)

Skills relacionadas

Ver todas de Automação →

Alerta por categoria

Receba novas skills de Automação toda segunda

1 email curto, só com as skills novas de Automação. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

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 Public — pk_ 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

| Environment | Base URL | Dashboard | |---|---|---| | Production | https://api.merchants.bankofmaldives.com.mv/public | dashboard.merchants.bankofmaldives.com.mv | | Sandbox (UAT) | https://api.uat.merchants.bankofmaldives.com.mv/public | dashboard.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

| Operation | Method | Endpoint | |---|---|---| | Create transaction | POST | /public/v2/transactions | | Get transaction | GET | /public/v2/transactions/{id} | | Update transaction | PATCH | /public/v2/transactions/{id} | | Send payment SMS | POST | /public/transactions/{id}/sms | | Send payment Email | POST | /public/transactions/{id}/email | | Create customer | POST | /public-customers | | Get customer | GET | /public-customers/{id} | | List customers | GET | /public-customers | | Get customer tokens | GET | /public-customers/{id}/tokens | | Charge token | POST | /public-customers/charge | | Create shop | POST | /public/shops | | Get shops | GET | /public/shops | | Update shop | PATCH | /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
  • state — QR_CODE_GENERATED initially

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

Transaction States

| State | Meaning | |---|---| | QR_CODE_GENERATED | Transaction created, QR ready, awaiting payment | | CONFIRMED | Payment received — money is in | | CANCELLED | Transaction cancelled | | FAILED | Payment failed | | EXPIRED | Transaction 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

| Event | When it fires | |---|---| | NOTIFY_TRANSACTION_CHANGE | Any state change on a transaction | | NOTIFY_TOKENISATION_STATUS | Card 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
Compartilhar X LinkedIn