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.
Average response time < 200ms
PCI DSS compliant, SSL encrypted
Enterprise-grade reliability
All API requests require authentication using your API key. Include your API key in the Authorization header.
Your API Credentials:
pk_test_xxxxx
sk_test_xxxxx
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.
https://sandbox-api.rwandapay.rw/v1
https://api.rwandapay.rw/v1
| Plan | Rate Limit | Burst |
|---|---|---|
| Sandbox | 100 requests/minute | 200 requests/minute |
| Production (Basic) | 500 requests/minute | 1000 requests/minute |
| Production (Premium) | 2000 requests/minute | 5000 requests/minute |
/payments/collect
Initiate a mobile money payment collection from a customer. Supports MTN MoMo and Airtel Money.
| Parameter | Type | Required | Description |
|---|---|---|---|
| amount | decimal | * | Amount in RWF (min: 100, max: 1,000,000) |
| phone | string | * | Customer phone number (e.g., 0788123456) |
| provider | string | optional | MTN or Airtel (auto-detected if not provided) |
| reference | string | optional | Your unique reference ID |
| callback_url | string | optional | Webhook URL for payment notifications |
| metadata | object | optional | Custom data to store with payment |
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
$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);
?>
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);
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())
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());
}
}
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);
}
}
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)
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)
}
{
"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"
}
}
/payments/{reference}
Get the current status of a payment transaction.
curl -X GET https://api.rwandapay.rw/v1/payments/PAY-20241215-ABC123 \
-H "Authorization: Bearer YOUR_API_KEY"
{
"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"
}
}
/payments/{reference}/refund
Process a refund for a completed payment. Refunds can be full or partial.
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"
}'
/checkout/initialize
Create a hosted payment page session (like Flutterwave). Returns a payment URL to redirect your customer.
{
"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"
}
}
{
"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
}
}
/withdrawals
Withdraw funds from your merchant wallet to your mobile money account. Minimum withdrawal: 10,000 RWF.
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"
}'
/balance
Get your current merchant wallet balance.
curl -X GET https://api.rwandapay.rw/v1/balance \
-H "Authorization: Bearer YOUR_API_KEY"
{
"status": "success",
"data": {
"balance": 1250000.00,
"currency": "RWF",
"available_balance": 1200000.00,
"pending_balance": 50000.00
}
}
Configure webhook endpoints to receive real-time event notifications about payment status changes.
{
"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
Best Practices
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
| Code | Message | Resolution |
|---|---|---|
| 400 | Bad Request | Check request parameters |
| 401 | Unauthorized | Invalid or missing API key |
| 402 | Insufficient Balance | Add funds to your wallet |
| 404 | Not Found | Resource not found |
| 422 | Validation Error | Invalid input data |
| 429 | Too Many Requests | Rate limit exceeded (100/min in sandbox) |
| 500 | Internal Server Error | Contact support |