Virtual Terminal
Take a payment when the customer is in front of you but you have no physical reader. Create a session, then either show the customer a QR / hosted checkout link for card payments, or push a mobile money prompt to their phone.
Endpoints
All routes live under /v1/merchant/virtual-terminal and require an authenticated merchant with approved KYC.
| Method | Path | Purpose |
|---|---|---|
| GET | /v1/merchant/virtual-terminal/sessions | List sessions (paginated, filterable) |
| POST | /v1/merchant/virtual-terminal/sessions | Create a collection session |
| GET | /v1/merchant/virtual-terminal/sessions/:id | Retrieve a session (with QR for pending) |
| POST | /v1/merchant/virtual-terminal/sessions/:id/charge | Charge the session |
| DELETE | /v1/merchant/virtual-terminal/sessions/:id | Cancel a pending session |
Create a session
Supply the amount, currency, and a payment_method (card is the default). The response includes a hosted payment_url and a ready-to-display QR code.
POST /v1/merchant/virtual-terminal/sessions
Authorization: Bearer sk_test_...
Content-Type: application/json
Idempotency-Key: vt-2026-06-001
{
"amount": "25.00",
"currency": "USD",
"description": "Counter sale",
"payment_method": "card",
"expires_in_minutes": 30
}{
"success": true,
"data": {
"session": {
"id": "vts_01HQXYZ",
"status": "pending",
"amount": "25.0000",
"currency": "USD",
"description": "Counter sale",
"payment_method": "card",
"expires_at": "2026-06-03T11:00:00.000Z",
"payment_url": "https://pay.watenga.africa/abc12xyz",
"slug": "abc12xyz",
"qr": { "svg": "<svg ...>" }
}
}
}Card payments via QR / link
For card and zimswitch methods, present the payment_url or QR code to the customer — they complete payment on the hosted checkout. Calling charge without a saved token simply returns the link to display.
Charge a mobile money session
For mobile money methods, call charge with the customer's phone number to push a USSD prompt. Then poll the session (or listen for the payment webhook) until it is paid.
POST /v1/merchant/virtual-terminal/sessions/vts_01HQXYZ/charge
Authorization: Bearer sk_test_...
Content-Type: application/json
{
"customer_phone": "+263771234567"
}{
"success": true,
"data": {
"session_id": "vts_01HQXYZ",
"transaction_id": "txn_01HQ",
"checkout_id": "chk_01HQ",
"requires_polling": true,
"message": "Payment request sent to customer phone"
}
}expires_in_minutes). Pass an Idempotency-Key on create and charge to safely retry.