Card Payments Overview
Accept Visa and Mastercard across East Africa via 3D Secure authentication.
Overview
RohoPay supports Visa and Mastercard payments. All card transactions go through 3D Secure (3DS) authentication — the bank's hosted verification page — for maximum approval rates and chargeback protection.
How Card Payments Work
1. Your app calls POST /api/v1/checkout with card details + return_url
2. RohoPay creates a card order → returns payment_url
3. Your app redirects the user to the 3DS authentication page
4. User enters their 3DS OTP/PIN on their bank's page
5. Provider redirects the user back to your return_url
6. Provider webhook confirms status (HMAC-verified)
7. RohoPay confirms status and credits the wallet
Endpoint
POST /api/v1/checkout
Content-Type: application/json
Unlike mobile money endpoints, the card checkout endpoint authenticates via api_key in the request body rather than the Authorization header. This allows client-side checkout flows.
Request Body
stringRequiredYour RohoPay API key (test or live). Provided in the body to support browser-side checkout forms.
integerRequiredAmount in smallest currency unit (e.g., 10000 for UGX 10,000).
stringRequiredCurrency code (e.g. UGX, USD, KES, NGN). Currency is request-driven; the API no longer rejects non-UGX currencies. Mobile-money charge routing currently defaults to Uganda — widening to other countries depends on the provider country table.
stringRequiredCardholder's full name.
stringRequiredCardholder's email address.
stringPayment description for the merchant dashboard.
stringRequiredURL the user is redirected to after 3DS completes (success or failure).
stringRequired16-digit card number without spaces or dashes.
stringRequiredCard expiry in MM/YY format (e.g., 10/26).
stringRequired3-digit CVV / security code on the back of the card.
Example Request
curl -X POST https://api.rohopay.com/api/v1/checkout \
-H "Content-Type: application/json" \
-d '{
"api_key": "live_YOUR_KEY",
"amount": 75000,
"currency": "UGX",
"customer_name": "Jane Mukasa",
"customer_email": "jane@example.com",
"description": "Premium subscription",
"return_url": "https://your-app.com/payment/return",
"card_number": "4111111111111111",
"card_expiry": "10/26",
"card_cvv": "123"
}'
const res = await fetch("https://api.rohopay.com/api/v1/checkout", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
api_key: process.env.ROHOPAY_API_KEY,
amount: 75000,
currency: "UGX",
customer_name: "Jane Mukasa",
customer_email: "jane@example.com",
description: "Premium subscription",
return_url: "https://your-app.com/payment/return",
card_number: "4111111111111111",
card_expiry: "10/26",
card_cvv: "123",
}),
});
const { data } = await res.json();
// Redirect user to data.payment_url
window.location.href = data.payment_url;
import httpx, os
def initiate_card_payment(card_number: str, expiry: str, cvv: str, amount: int) -> str:
res = httpx.post(
"https://api.rohopay.com/api/v1/checkout",
json={
"api_key": os.environ["ROHOPAY_API_KEY"],
"amount": amount,
"currency": "UGX",
"customer_name": "Jane Mukasa",
"customer_email": "jane@example.com",
"return_url": "https://your-app.com/payment/return",
"card_number": card_number,
"card_expiry": expiry,
"card_cvv": cvv,
},
)
res.raise_for_status()
return res.json()["data"]["payment_url"] # redirect user here
Successful Response
{
"success": true,
"data": {
"transaction_id": "01j5m6n7p8q9r0s1t2u3vwxy",
"reference": "RHP-2024-CARD001",
"payment_url": "https://payments.relworx.com/merchant-payment/abc123xyz",
"status": "pending",
"amount": 75000,
"currency": "UGX",
"commission": 750,
"net_amount": 74250
}
}
Redirect the user to payment_url immediately. Do not store or display this URL — it is a one-time-use 3DS session link.
Supported Card Brands
| Brand | Prefix | Notes |
|---|---|---|
| Visa | 4 | Visa Verified (3DS) |
| Mastercard | 51–55 / 2221–2720 | Mastercard SecureCode (3DS) |
