DGS-Pay API v2
Dashboard
Collections

Mobile Money API

Collect payments directly from MTN or Airtel Money wallets in Rwanda. When you initiate a charge, the customer receives an STK push prompt on their handset — they enter their PIN to approve, and your webhook is notified of the outcome. No card details or card infrastructure needed.

Mobile Money payments are currently limited to Rwanda (RWF). Multi-currency and additional country support is planned for API v3.

Rwanda Only The currency field must be RWF. Any other currency will return a validation error (90).

Initiate a Mobile Money Payment

Send a POST /charges request with the customer and payment details. DGS-Pay forwards the STK push to the customer's phone and returns a pending status while waiting for the customer's approval.

POST/charges
ParameterTypeRequiredDescription
amountnumberRequiredPayment amount. Must be a positive number.
currencystringRequiredISO 4217 code. Must be RWF.
payment_typestringRequiredMust be mobile_money.
customer_emailstringRequiredCustomer's email address.
customer_first_namestringRequiredCustomer's first name.
customer_last_namestringRequiredCustomer's last name.
customer_phonestringRequiredPhone number without country code, e.g. 789654321.
customer_phone_country_codestringRequiredCountry code without +, e.g. 250.
redirect_urlstringRequiredURL to redirect the customer to after payment completes.
mobile_money_networkstringRequiredMTN or Airtel.
mobile_money_phonestringRequiredPhone number that will receive the STK push.
narrationstringOptionalShort description shown to the customer, e.g. Invoice #5678.
cURL
curl -X POST \
  https://pay.digitalservicescenter.rw/generation/v2/charges \
  -H "X-DGS-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 2000,
    "currency": "RWF",
    "payment_type": "mobile_money",
    "customer_email": "jane.doe@example.com",
    "customer_first_name": "Jane",
    "customer_last_name": "Doe",
    "customer_phone": "789654321",
    "customer_phone_country_code": "250",
    "redirect_url": "https://yourdomain.com/payment-success",
    "narration": "Payment for Invoice #5678",
    "mobile_money_network": "MTN",
    "mobile_money_phone": "789654321"
  }'
JSON
{
  "amount": 2000,
  "currency": "RWF",
  "payment_type": "mobile_money",
  "customer_email": "jane.doe@example.com",
  "customer_first_name": "Jane",
  "customer_last_name": "Doe",
  "customer_phone": "789654321",
  "customer_phone_country_code": "250",
  "redirect_url": "https://yourdomain.com/payment-success",
  "narration": "Payment for Invoice #5678",
  "mobile_money_network": "MTN",
  "mobile_money_phone": "789654321"
}

Response Format

DGS-Pay returns one of three states. The initial response is almost always pending — the payment completes asynchronously when the customer approves or rejects the STK push.

JSON — STK Push sent, awaiting customer approval
{
  "status": "success",
  "message": "Charge initiated",
  "transaction_id": "123456789",
  "dgs_reference": "dgs_123456789",
  "amount": 2000,
  "currency": "RWF",
  "transaction_status": "pending",
  "payment_method_type": "mobile_money",
  "next_action_type": "redirect_url",
  "next_action_redirect_url": "https://provider.com/authorize",
  "display_text": "Complete payment on your mobile device"
}
JSON — Payment completed successfully (via webhook)
{
  "status": "success",
  "message": "Payment completed",
  "transaction_id": "987654321",
  "dgs_reference": "dgs_987654321",
  "amount": 2000,
  "currency": "RWF",
  "transaction_status": "successful",
  "payment_method_type": "mobile_money",
  "mobile_money_network": "MTN",
  "mobile_money_phone": "789654321",
  "mobile_money_country_code": "250"
}
JSON — Payment declined or cancelled
{
  "status": "failed",
  "message": "Charge failed",
  "transaction_id": "123456789",
  "dgs_reference": "dgs_123456789",
  "amount": 2000,
  "currency": "RWF",
  "transaction_status": "failed",
  "payment_method_type": "mobile_money",
  "issuer_response_type": "declined",
  "issuer_response_code": "05",
  "processor_response": "Insufficient funds"
}
Best Practice Because the customer approves asynchronously, always use a webhook to get notified of the final outcome rather than polling. Do not mark an order as paid based on the pending response alone.

Need Help?

Our technical team is ready to assist with integration questions, testing, and go-live checks.

Contact Support