Copied to clipboard!

API Documentation

Welcome to the Rwanda Pay API. Our REST API allows you to integrate mobile money payments into your application seamlessly. Accept payments from MTN MoMo and Airtel Money customers across Rwanda.

Lightning Fast

Average response time < 200ms

Secure

PCI DSS compliant, SSL encrypted

99.9% Uptime

Enterprise-grade reliability

Authentication

All API requests require authentication using your API key. Include your API key in the Authorization header.

Your API Credentials:

Test PK: pk_test_xxxxx
Test SK: sk_test_xxxxx
Authentication Header
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Idempotency-Key: UNIQUE_KEY_32_CHARS

Getting your API keys

Log in to your merchant dashboard → Developer → API Keys to generate your test and live API keys.

Base URL

Sandbox (Testing)
https://sandbox-api.rwandapay.rw/v1
Production (Live)
https://api.rwandapay.rw/v1

Rate Limits

PlanRate LimitBurst
Sandbox100 requests/minute200 requests/minute
Production (Basic)500 requests/minute1000 requests/minute
Production (Premium)2000 requests/minute5000 requests/minute
POST /payments/collect

Collect Payment

Initiate a mobile money payment collection from a customer. Supports MTN MoMo and Airtel Money.

Request Parameters

ParameterTypeRequiredDescription
amountdecimal*Amount in RWF (min: 100, max: 1,000,000)
phonestring*Customer phone number (e.g., 0788123456)
providerstringoptionalMTN or Airtel (auto-detected if not provided)
referencestringoptionalYour unique reference ID
callback_urlstringoptionalWebhook URL for payment notifications
metadataobjectoptionalCustom data to store with payment

Code Examples

cURL
PHP
JavaScript
Python
Java
C#
Ruby
Go
Request
curl -X POST https://api.rwandapay.rw/v1/payments/collect \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: UNIQUE_KEY_32_CHARS" \
  -d '{
    "amount": 5000,
    "phone": "0788123456",
    "provider": "MTN",
    "reference": "INV-001",
    "callback_url": "https://yourdomain.com/webhook",
    "metadata": {
      "customer_name": "John Doe",
      "product_id": "123"
    }
  }'
PHP (cURL)
<?php
$apiKey = 'YOUR_API_KEY';

$ch = curl_init('https://api.rwandapay.rw/v1/payments/collect');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $apiKey,
    'Content-Type: application/json',
    'Idempotency-Key: ' . uniqid(),
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'amount' => 5000,
    'phone' => '0788123456',
    'provider' => 'MTN',
    'reference' => 'INV-001',
]));

$response = curl_exec($ch);
$result = json_decode($response, true);
print_r($result);
?>
JavaScript (Fetch)
const apiKey = 'YOUR_API_KEY';

const response = await fetch('https://api.rwandapay.rw/v1/payments/collect', {
    method: 'POST',
    headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': crypto.randomUUID(),
    },
    body: JSON.stringify({
        amount: 5000,
        phone: '0788123456',
        provider: 'MTN',
        reference: 'INV-001',
    })
});

const data = await response.json();
console.log(data);
Python (requests)
import requests
import uuid

api_key = "YOUR_API_KEY"
url = "https://api.rwandapay.rw/v1/payments/collect"

headers = {
    "Authorization": f"Bearer {api_key}",
    "Content-Type": "application/json",
    "Idempotency-Key": str(uuid.uuid4())
}

payload = {
    "amount": 5000,
    "phone": "0788123456",
    "provider": "MTN",
    "reference": "INV-001"
}

response = requests.post(url, headers=headers, json=payload)
print(response.json())
Java (OkHttp)
import okhttp3.*;
import java.io.IOException;

public class PaymentRequest {
    public static void main(String[] args) throws IOException {
        OkHttpClient client = new OkHttpClient();
        
        String json = "{\n" +
            "  \"amount\": 5000,\n" +
            "  \"phone\": \"0788123456\",\n" +
            "  \"provider\": \"MTN\",\n" +
            "  \"reference\": \"INV-001\"\n" +
            "}";
        
        Request request = new Request.Builder()
            .url("https://api.rwandapay.rw/v1/payments/collect")
            .post(RequestBody.create(json, MediaType.parse("application/json")))
            .addHeader("Authorization", "Bearer YOUR_API_KEY")
            .addHeader("Content-Type", "application/json")
            .build();
        
        Response response = client.newCall(request).execute();
        System.out.println(response.body().string());
    }
}
C# (HttpClient)
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using var client = new HttpClient();
        client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_API_KEY");
        
        var payload = new
        {
            amount = 5000,
            phone = "0788123456",
            provider = "MTN",
            reference = "INV-001"
        };
        
        var json = Newtonsoft.Json.JsonConvert.SerializeObject(payload);
        var content = new StringContent(json, Encoding.UTF8, "application/json");
        
        var response = await client.PostAsync("https://api.rwandapay.rw/v1/payments/collect", content);
        var result = await response.Content.ReadAsStringAsync();
        Console.WriteLine(result);
    }
}
Ruby
require 'net/http'
require 'json'

uri = URI('https://api.rwandapay.rw/v1/payments/collect')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer YOUR_API_KEY'
request['Content-Type'] = 'application/json'

request.body = {
  amount: 5000,
  phone: '0788123456',
  provider: 'MTN',
  reference: 'INV-001'
}.to_json

response = http.request(request)
puts JSON.parse(response.body)
Go
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
)

func main() {
    payload := map[string]interface{}{
        "amount":   5000,
        "phone":    "0788123456",
        "provider": "MTN",
        "reference": "INV-001",
    }
    
    jsonData, _ := json.Marshal(payload)
    
    req, _ := http.NewRequest("POST", "https://api.rwandapay.rw/v1/payments/collect", bytes.NewBuffer(jsonData))
    req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
    req.Header.Set("Content-Type", "application/json")
    
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    
    var result map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&result)
    fmt.Println(result)
}

Response

Success Response (201 Created)
{
  "status": "success",
  "data": {
    "reference": "PAY-20241215-ABC123",
    "status": "pending",
    "amount": 5000,
    "fee": 175,
    "net_amount": 4825,
    "currency": "RWF",
    "payment_url": "https://pay.rwandapay.rw/pay/ABC123",
    "expires_at": "2024-12-15T14:30:00Z"
  }
}
GET /payments/{reference}

Check Payment Status

Get the current status of a payment transaction.

cURL Example
curl -X GET https://api.rwandapay.rw/v1/payments/PAY-20241215-ABC123 \
  -H "Authorization: Bearer YOUR_API_KEY"
Response
{
  "status": "success",
  "data": {
    "reference": "PAY-20241215-ABC123",
    "status": "successful",
    "amount": 5000,
    "fee": 175,
    "net_amount": 4825,
    "provider": "MTN",
    "customer_phone": "0788123456",
    "paid_at": "2024-12-15T14:25:30Z"
  }
}
POST /payments/{reference}/refund

Refund Payment

Process a refund for a completed payment. Refunds can be full or partial.

cURL Example
curl -X POST https://api.rwandapay.rw/v1/payments/PAY-20241215-ABC123/refund \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 5000,
    "reason": "Customer requested refund"
  }'
POST /checkout/initialize

Initialize Checkout

Create a hosted payment page session (like Flutterwave). Returns a payment URL to redirect your customer.

Request Example
{
  "amount": 5000,
  "currency": "RWF",
  "customer": {
    "name": "John Doe",
    "email": "john@example.com",
    "phone": "0788123456"
  },
  "tx_ref": "UNIQUE_REFERENCE",
  "redirect_url": "https://yourdomain.com/callback",
  "webhook_url": "https://yourdomain.com/webhook",
  "meta": {
    "order_id": "ORD-12345"
  }
}
Response
{
  "status": "success",
  "data": {
    "session_id": "CHK-ABC123DEF456",
    "reference": "UNIQUE_REFERENCE",
    "payment_url": "https://pay.rwandapay.rw/checkout/CHK-ABC123DEF456",
    "expires_at": "2024-12-15T15:00:00Z",
    "amount": 5000
  }
}
POST /withdrawals

Withdraw Funds

Withdraw funds from your merchant wallet to your mobile money account. Minimum withdrawal: 10,000 RWF.

cURL Example
curl -X POST https://api.rwandapay.rw/v1/withdrawals \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 10000,
    "phone": "0788123456",
    "provider": "MTN",
    "pin": "1234"
  }'
GET /balance

Check Balance

Get your current merchant wallet balance.

cURL Example
curl -X GET https://api.rwandapay.rw/v1/balance \
  -H "Authorization: Bearer YOUR_API_KEY"
Response
{
  "status": "success",
  "data": {
    "balance": 1250000.00,
    "currency": "RWF",
    "available_balance": 1200000.00,
    "pending_balance": 50000.00
  }
}

Webhooks

Configure webhook endpoints to receive real-time event notifications about payment status changes.

Webhook Payload Example
{
  "event": "payment.successful",
  "data": {
    "reference": "PAY-20241215-ABC123",
    "amount": 5000,
    "currency": "RWF",
    "status": "successful",
    "customer": {
      "name": "John Doe",
      "phone": "0788123456",
      "email": "john@example.com"
    },
    "paid_at": "2024-12-15T14:25:30Z",
    "fee": 175,
    "net_amount": 4825,
    "metadata": {
      "order_id": "ORD-12345"
    }
  }
}

Event Types

  • payment.pending - Payment initiated
  • payment.successful - Payment completed
  • payment.failed - Payment failed
  • payment.refunded - Payment refunded

Best Practices

  • Return 200 OK quickly
  • Verify signatures
  • Handle idempotency
  • Implement retry logic

SDKs & Libraries

Official SDKs to help you integrate Rwanda Pay faster.

PHP SDK

composer require rwandapay/php-sdk

JavaScript SDK

npm install rwandapay-js

Python SDK

pip install rwandapay

Java SDK

Maven: com.rwandapay

Error Codes

CodeMessageResolution
400Bad RequestCheck request parameters
401UnauthorizedInvalid or missing API key
402Insufficient BalanceAdd funds to your wallet
404Not FoundResource not found
422Validation ErrorInvalid input data
429Too Many RequestsRate limit exceeded (100/min in sandbox)
500Internal Server ErrorContact support