USSD payment
Accept Scan to Pay payments from feature-phone customers via USSD short code. No smartphone required.
USSD payment lets customers without smartphones pay you using a short code on any GSM phone. They dial *120*...#, navigate a menu, enter a payment reference or amount, and confirm with a PIN. The transaction routes through the same card-payment rails as every other Scan to Pay payment — the customer's experience just looks different.
This is the channel that puts Scan to Pay within reach of the millions of South Africans on feature phones. If financial inclusion is part of your business case, USSD is essential.
For the API endpoints, see USSD purchase API.
When to use USSD
| ✅ Good fit | ❌ Wrong fit |
|---|---|
| Your customer base includes feature phones (rural retail, micro-merchants, informal trade) | Smartphone-only customer base |
| You can't rely on customers having data or installing apps | You already have a smartphone touchpoint |
| You're integrating with a USSD aggregator or mobile network operator | You don't have a USSD short-code arrangement |
| Bill payment for utility / telco use cases | E-commerce checkouts (use Bluebox hosted checkout instead) |
USSD requires a separate operational arrangement (the short code, the gateway) on top of your Scan to Pay integration. It's not as plug-and-play as QR — but where it fits, nothing else reaches the same audience.
The customer experience
☎ Customer's feature phone
──────────────────────────
1. Dials short code: *120*your-code#
2. USSD menu appears: ┌─────────────────────────┐
│ Merchant Name │
│ │
│ 1. Pay R 50.00 │
│ 2. Pay other amount │
│ 3. Buy airtime │
│ 0. Exit │
└─────────────────────────┘
3. Customer picks option,
enters amount if variable
4. PIN prompt: ┌─────────────────────────┐
│ Enter your PIN to pay │
│ R 50.00 to ACME COFFEE │
│ │
│ PIN: **** │
└─────────────────────────┘
5. Confirmation message: ┌─────────────────────────┐
│ Payment successful │
│ Ref: 6321400012 │
└─────────────────────────┘
What's happening behind the menu:
- Step 1. The mobile network operator's USSD gateway routes the customer's session to your USSD application.
- Step 2. Your USSD app calls Scan to Pay APIs to fetch merchant info, present the menu options.
- Step 3. Your USSD app builds (or looks up) a payment code for the chosen amount.
- Step 4. The Scan to Pay platform pushes a PIN-entry request to the customer's phone via the Wallet Initiation Gateway (WIG). The customer enters their PIN.
- Step 5. Scan to Pay authorises against the issuing bank, settles via the acquirer, and notifies you via webhook.
Who's involved
USSD has more moving parts than QR-based flows. Four parties each play a role:
| Party | Responsibility |
|---|---|
| Mobile network operator | Owns the short code and the GSM-level USSD session routing. You typically lease the short code from an aggregator who has the MNO relationship. |
| You (merchant or PSP) | Operate the USSD application that presents the menu, builds the payment code, and calls the Scan to Pay API. |
| Scan to Pay | Translates payment codes into PIN prompts on the customer's phone, routes the auth to the bank, manages settlement. |
| Issuing bank | Authorises the PIN-protected transaction against the customer's linked card. |
If you don't already have a USSD gateway or short-code arrangement, get one in place before you start integrating. The Scan to Pay-specific work is straightforward; the USSD plumbing is the longer lead-time item.
Two integration modes
Depending on the mobile network operator and the type of customer, Scan to Pay supports two USSD payment patterns:
Pattern A — Code-based purchase. Your USSD app generates a Scan to Pay code (same POST /code/create endpoint as everywhere else) and the customer's USSD session triggers payment of that code. Use this when the customer is paying a specific item (a bill, a fixed product, a known cart).
Pattern B — Network/WIG purchase. Your USSD app initiates the payment directly via the network purchase endpoints. Use this when the customer is buying airtime, data bundles, or other network-operator-sold products.
Both patterns end in the same webhook with the same payload shape. The difference is which endpoint you call.
See USSD purchase API for the full endpoint reference and cartItems rules for airtime / data bundle baskets.
Transaction states for USSD
USSD payments produce all the same TxState values as QR payments, plus a richer set of timeout-specific states for each step of the customer interaction:
END_TIMEOUT_PURCHASE— customer didn't respond at the PIN promptEND_TIMEOUT_CARD_DETAILS— customer added a card but timed out before completingEND_TIMEOUT_INVALID_PIN,END_TIMEOUT_INVALID_CVV,END_TIMEOUT_INVALID_CARD_NUMBER— input validation failuresEND_CLIENT_CANCEL,END_CLIENT_TIMEOUT— customer cancelled or session expired
These are normal — USSD sessions are short (typically 60–120 seconds total) and customers do drop out of the flow more often than on QR. Design your customer-facing copy to handle these gracefully.
See Transaction states for the full list.
Limits
USSD payments are most often used for airtime and data bundle purchases. The platform applies daily and monthly per-MSISDN limits to these basket types to prevent fraud rings:
| Item type | Daily | Monthly |
|---|---|---|
AIRTIME | R1 000 | R2 000 |
AIRTIME_BUNDLE (SMS / data) | R2 000 | R5 000 |
A blocked transaction surfaces as LIMIT_FAILED on the webhook (END_LIMIT_FAILED as TxState). See QR Code Payments — business rules for full limit-basket rules.
Testing
USSD test scenarios are documented under Sandbox and test cards. The same test card prefixes apply (success / insufficient funds / switch inoperative), plus the amount-cents trick lets you simulate any ISO response code.
For sandbox USSD sessions specifically, you'll need to coordinate with your USSD aggregator — sandbox short codes are typically separate from production short codes.
What's next
- The detailed API for USSD payments → USSD purchase API
- Same code-create endpoint as QR → Dynamic QR
- Receive the payment notification → Webhooks
- Transaction states including USSD-specific timeouts → Transaction states
- Refund a USSD transaction → Refunds and reversals
- Sandbox testing → Sandbox and test cards
Updated 4 days ago
