Paystack in South Africa supports card payments (Visa, Mastercard) with 3D Secure authentication and bank transfers via EFT. South Africa has the highest card penetration in Africa, making cards the primary payment channel. EFT serves B2B and higher-value transactions.
South Africa's payment channel mix is different from every other Paystack market. Cards dominate. Mobile money is not a factor. EFT handles the bank transfer segment.
// Card-first checkout for South Africa
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.co.za',
amount: 49900, // 499 ZAR in cents
currency: 'ZAR',
channels: ['card'],
reference: 'za_' + Date.now(),
}),
});
Card payments are the backbone of online commerce in South Africa. The five major banks (Standard Bank, FNB, ABSA, Nedbank, Capitec) have issued millions of Visa and Mastercard debit cards, and most South Africans are comfortable paying with cards online.
3D Secure (3DS) authentication:
Every South African card transaction goes through 3D Secure verification. After the customer enters their card details, they are redirected to their bank's 3DS page to verify the transaction. The verification method depends on the bank:
You cannot control which 3DS method the bank uses. Your job is to handle the redirect flow correctly and provide clear messaging to the customer:
// After initializing the transaction, redirect to the authorization URL
// The customer completes 3DS and is redirected back to your callback URL
app.get('/payment/callback', async function(req, res) {
var reference = req.query.reference;
// Verify the transaction server-side
var verifyResponse = await fetch(
'https://api.paystack.co/transaction/verify/' + reference,
{
headers: {
Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY,
},
}
);
var data = await verifyResponse.json();
if (data.data.status === 'success') {
// Payment verified. Show success page.
res.redirect('/order/success?ref=' + reference);
} else {
// Payment failed or pending. Show appropriate message.
res.redirect('/order/failed?ref=' + reference);
}
});
3DS drop-off mitigation:
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
EFT is South Africa's bank transfer system. It allows customers to transfer money directly from their bank account. EFT is deeply embedded in South African business culture and is the standard for B2B payments, rent, and large purchases.
How EFT works on Paystack:
EFT considerations:
South Africa is the one Paystack market where cards should always be your primary channel. Here is how to think about channel selection:
E-commerce (B2C): Cards first, EFT as a secondary option. Most South African consumers will pay with their Visa or Mastercard debit card.
SaaS subscriptions: Cards only. Authorization reuse makes recurring billing smooth. South Africa's high card penetration means you are not excluding a large segment.
B2B invoicing: EFT first, cards second. Businesses prefer EFT for accounting purposes and larger transaction amounts.
Mixed-market product (SA + Nigeria): Offer all channels in both markets but adjust defaults. In SA, cards first. In Nigeria, bank transfer (DVA) and cards.
// South Africa channel selection
function getSAChannels(useCase) {
if (useCase === 'subscription') {
return ['card'];
}
if (useCase === 'b2b_invoice') {
return ['bank_transfer', 'card'];
}
// Default: consumer purchase
return ['card', 'bank_transfer'];
}
South Africa is one of the best Paystack markets for recurring billing because card penetration is high and authorization reuse works reliably.
After the first successful card payment, store the authorization code and reuse it for future charges:
// First payment: customer enters card details and completes 3DS
// Store the authorization from the successful transaction
// Subsequent charges: use the stored authorization
var response = await fetch('https://api.paystack.co/transaction/charge_authorization', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
authorization_code: customer.paystackAuthCode,
email: customer.email,
amount: 29900, // 299 ZAR monthly subscription
currency: 'ZAR',
reference: 'sub_' + customer.id + '_' + Date.now(),
}),
});
var data = await response.json();
if (data.data.status === 'success') {
// Subscription renewed
} else {
// Card declined. Notify customer to update payment method.
}
Handling card expiry and decline:
Test both card and EFT flows before going live:
Card testing:
EFT testing:
After launch, monitor these metrics:
KES 2,999
The definitive guide to building payment systems with Paystack — from your first transaction to production-grade payment infrastructure across Africa. 9 modules, 47 lessons. Free preview available.
Start Paystack Course