Payments
Payments
Accept one-time payments across Africa with cards, mobile money, bank transfer, and USSD.
Overview
Xtopay processes one-time payments through a two-step flow:
- Create a payment — your server sends the amount, currency, and customer details to Xtopay
- Customer completes payment — redirect your customer to the
checkout_url, or use the Xtopay SDK to embed checkout in your UI
When payment completes (or fails), Xtopay fires a webhook to your configured endpoint.
Payment lifecycle
created → pending → processing → succeeded
↘ failed
↘ cancelled| Status | Meaning |
|---|---|
created | Payment object exists, customer not yet redirected |
pending | Customer is on the checkout page |
processing | Payment submitted to the payment network |
succeeded | Money collected — safe to fulfil the order |
failed | Payment declined or timed out |
cancelled | Customer closed checkout without paying |
Only fulfil orders on succeeded. Never fulfil on processing.
Create a payment
const payment = await xtopay.payments.create({
amount: 25000, // GHS 250.00
currency: "GHS",
customer: {
email: "ama@example.com",
name: "Ama Owusu",
phone: "+233244000000",
},
redirect_url: "https://yourapp.com/order/success",
cancel_url: "https://yourapp.com/order/cancelled",
metadata: {
order_id: "ord_abc123",
},
});
// Redirect customer
redirect(payment.checkout_url);Payment object
{
"id": "pay_a1b2c3d4e5f6",
"amount": 25000,
"currency": "GHS",
"status": "succeeded",
"customer": {
"id": "cus_xyz789",
"email": "ama@example.com",
"name": "Ama Owusu"
},
"payment_method": {
"type": "mobile_money",
"network": "mtn",
"phone": "+233244000000"
},
"checkout_url": "https://checkout.xtopay.co/pay/tok_...",
"redirect_url": "https://yourapp.com/order/success",
"metadata": { "order_id": "ord_abc123" },
"created_at": "2026-05-24T10:00:00Z",
"paid_at": "2026-05-24T10:02:14Z"
}