Accepting USSD Payments Through Paystack
To accept USSD payments through Paystack, initialize an NGN transaction with the ussd channel enabled. The checkout page shows a bank-specific USSD code. The customer dials the code on their phone, confirms the payment via USSD prompts, and Paystack fires a charge.success webhook. USSD works on feature phones without internet, making it accessible to customers without smartphones.
How USSD Payments Work
USSD (Unstructured Supplementary Service Data) is a protocol that lets mobile phones communicate with a service provider through short codes. Nigerian banks use USSD to let customers perform banking operations (check balance, transfer money, pay bills) by dialing codes from any phone.
When a customer selects USSD at Paystack checkout:
- The customer selects their bank from a list
- Paystack generates a USSD code specific to that bank and transaction
- The customer dials the code on their phone (e.g., *737*000*5000# for GTBank)
- The bank's USSD system prompts the customer to confirm the payment amount
- The customer confirms (usually by entering their PIN)
- The bank deducts the amount and notifies Paystack
- Paystack fires a
charge.successwebhook
This works on any phone. No smartphone, no app, no internet connection needed. Just the ability to make a phone call. This makes USSD the most accessible payment channel for reaching customers in areas with limited smartphone penetration or unreliable data connectivity.
USSD via Hosted Checkout
var response = await fetch('https://api.paystack.co/transaction/initialize', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: 'customer@example.com',
amount: 500000, // 5,000 NGN
currency: 'NGN',
channels: ['ussd'],
callback_url: 'https://yoursite.com/payment/callback',
}),
});
var data = await response.json();
// Redirect to data.data.authorization_url
Paystack's checkout page handles bank selection, USSD code generation, and the waiting screen while the customer dials and confirms. The checkout updates automatically when the payment is confirmed.
USSD via the Charge API
For custom checkout flows, use the Charge API with a USSD object:
async function chargeViaUssd(email, amount, bankType) {
var response = await fetch('https://api.paystack.co/charge', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: email,
amount: amount,
currency: 'NGN',
ussd: {
type: bankType, // e.g., '737' for GTBank
},
}),
});
var data = await response.json();
// data.data.status will be 'pay_offline'
// data.data.display_text contains the USSD code to show the customer
return {
status: data.data.status,
ussdCode: data.data.display_text,
reference: data.data.reference,
};
}
// Usage
var result = await chargeViaUssd('customer@example.com', 500000, '737');
// Show result.ussdCode to the customer
// e.g., "Dial *737*000*5000# on your phone to complete payment"
Bank type codes vary. Common ones include 737 for GTBank, 966 for Zenith, 770 for Fidelity, and 919 for UBA. Check the Paystack documentation for the full list of supported bank types.
Timeout and Transaction Limits
USSD sessions have timeouts. If the customer does not complete the USSD flow within the bank's timeout window (typically 1-2 minutes after dialing), the session expires and the payment fails.
Each bank also sets per-transaction limits for USSD payments. These limits are typically lower than card or bank transfer limits. For example, a bank might allow USSD transactions up to 100,000 NGN. If your transaction exceeds the bank's USSD limit, the payment will fail even if the customer has sufficient funds.
To handle this:
- For high-value transactions, do not restrict channels to USSD only. Include card and bank_transfer as alternatives.
- If a USSD charge fails, show the customer the option to try a different payment method.
- Consider removing USSD from the channels list for transactions above a certain threshold (e.g., above 100,000 NGN).
Designing the Customer Experience
USSD payments involve the customer switching between your checkout (on their phone browser or computer) and their phone's dialer. Make this transition smooth:
- Display the code clearly: Large font, easy to read. If on mobile, add a "Dial" button that opens the phone dialer with the code pre-filled.
- Instructions: "Dial the code below on your phone, then follow the prompts to confirm payment."
- Waiting state: After displaying the code, show "Waiting for confirmation..." with a loading indicator.
- Timeout message: If no confirmation comes within 3 minutes, show "Payment not yet confirmed. Please try again or use a different payment method."
For mobile web checkouts, the customer is already on their phone. They can copy the code, switch to the dialer, dial it, and switch back. Some checkout implementations add a tap-to-dial link that opens the dialer directly.
When to Offer USSD
USSD is most valuable when your customer base includes people who:
- Use feature phones (no smartphone)
- Have limited or no data connectivity
- Prefer not to share card details online
- Are familiar with USSD banking from daily use
If your audience is primarily urban professionals with smartphones, card and bank transfer may be sufficient. If you serve a broader Nigerian population including rural areas and older demographics, USSD can significantly increase your payment completion rate.
For the full overview of all payment channels and how to choose between them, see payment channels overview.
Key Takeaways
- ✓USSD payments are available for NGN transactions in Nigeria. The customer dials a bank-specific code on their phone to pay.
- ✓No smartphone or data connection required. USSD works on any phone that can make calls, including basic feature phones.
- ✓Supported banks include GTBank (*737*), Zenith (*966*), UBA, First Bank, and others. Each bank has its own USSD format.
- ✓USSD is asynchronous. The customer dials on their phone and your checkout waits for confirmation, which can take 30 seconds to a few minutes.
- ✓USSD transactions have per-bank limits. High-value transactions may exceed these limits. Offer card or bank transfer as alternatives.
- ✓Paystack checkout generates the correct USSD code for the customer selected bank. Via the Charge API, you specify the bank type.
Frequently Asked Questions
- Does USSD work outside Nigeria?
- USSD payments on Paystack are currently available only for NGN transactions in Nigeria. For Ghana, mobile money is the equivalent non-card channel. For other markets, card payments are the primary option.
- Can the customer use USSD from a different phone number?
- The USSD code is not tied to a specific phone number. The customer can dial it from any phone that is linked to their bank account via USSD banking. The bank authenticates the customer based on the phone number registered with their account.
- Why did the USSD payment fail even though the customer has money?
- Common reasons: the transaction amount exceeds the bank USSD limit, the customer entered the wrong PIN, the USSD session timed out, or the customer phone number is not registered for USSD banking at that bank. Each bank has its own USSD registration process.
- Can USSD be used for recurring payments?
- No. USSD requires the customer to actively dial a code and confirm each payment. It cannot be used for automated recurring charges. For recurring billing, use saved card authorization codes or direct debit.
Ready to build real-world apps?
Join the McTaba Labs full-stack marathon (4 months full-time · 6 months part-time). Learn M-Pesa, USSD, and WhatsApp engineering while shipping 8 production apps.
Apply to the McTaba Marathon