Paystack Card Not Supported for Recurring
A card not supported for recurring charges on Paystack means the card issuer does not allow the card to be tokenized for future charges. Prepaid cards, most virtual cards, and certain bank-issued debit cards on restricted account tiers cannot be stored for automatic billing. The fix depends on your business: offer the Paystack checkout flow for each payment, suggest alternative payment channels like mobile money or bank transfer, or ask the customer to use a different card that supports recurring charges.
What the Error Looks Like
You see this error in two situations. First, when you try to create a Paystack subscription with a card that does not support recurring:
// Attempting to subscribe with a non-reusable card
POST /subscription
{
"customer": "CUS_abc123",
"plan": "PLN_xyz789"
}
// Response
{
"status": false,
"message": "Customer authorization is not reusable"
}
Second, when you try to charge an authorization that was flagged as non-reusable:
// Attempting to charge a non-reusable authorization
POST /transaction/charge_authorization
{
"authorization_code": "AUTH_def456",
"email": "customer@example.com",
"amount": 500000
}
// Response
{
"status": false,
"message": "Authorization is not reusable"
}
Both errors mean the same thing: the card behind this authorization cannot be charged without the cardholder actively entering their details through the checkout flow.
Card Types and Recurring Support
Not all cards are created equal when it comes to recurring charges. Here is a breakdown:
Credit cards almost always support recurring charges. They are designed for this. If your customer has a Visa or Mastercard credit card from a major bank, tokenization should work.
Standard debit cards from major banks usually support recurring charges. GTBank, First Bank, Access Bank, UBA, and Zenith Bank debit cards in Nigeria typically work. In Kenya, Equity Bank and KCB Visa debit cards generally work, though card-based recurring is less common than M-Pesa.
Prepaid cards almost never support recurring charges. This includes gift cards, prepaid Visa/Mastercards purchased at stores, and travel cards. These cards are designed for fixed-amount, one-time use.
Virtual cards from fintech apps are unpredictable. Some support recurring (like those from established banks with virtual card products), while many do not (especially disposable virtual cards designed for single-use online purchases).
Corporate/business cards depend on the company's bank and card program. Some support recurring, others are restricted by company policy.
| Card type | Recurring support | Notes |
|---|---|---|
| Credit card (major bank) | Almost always | Best option for subscriptions |
| Debit card (tier-1 bank) | Usually | GTBank, First Bank, Access, UBA |
| Debit card (digital bank) | Sometimes | Check reusable field |
| Prepaid card | Rarely | Not designed for recurring |
| Virtual card (fintech) | Rarely | Usually single-use |
| Student account card | Rarely | Bank restricts recurring on these tiers |
Bank-Level Restrictions
Even if a card type generally supports recurring charges, the issuing bank can block it at the account level. This is common in a few scenarios:
Student accounts. Banks often issue debit cards to student accounts with restrictions on automated debits. The card works for POS and online purchases but cannot be tokenized for recurring charges.
Basic savings accounts. Some banks restrict the lowest-tier savings account cards from recurring charges. The customer needs to upgrade their account tier to enable this feature.
Fraud prevention policies. After a fraud incident, a bank might temporarily disable recurring charge capabilities on certain BIN ranges or account types. This can affect your customers without warning.
New card issuance. Sometimes a freshly issued card needs a few days before the bank's systems fully enable tokenization. If a customer gets a new card and immediately tries to set up a subscription, it might fail but work a few days later.
You cannot query Paystack for why a specific bank blocked recurring charges. The reusable: false flag is all the information you get. If you see a pattern (many customers from the same bank with non-reusable cards), contact Paystack support for clarification.
Detecting the Problem at Signup
The worst time to discover a card does not support recurring charges is when the first renewal attempt fails, weeks after signup. Detect it during the initial payment:
// After the first successful payment, check card reusability
async function handleInitialPayment(transactionReference: string, customerId: string) {
const res = await fetch(
`https://api.paystack.co/transaction/verify/${transactionReference}`,
{
headers: {
Authorization: `Bearer ${process.env.PAYSTACK_SECRET_KEY}`,
},
}
);
const data = await res.json();
if (data.data.status !== 'success') {
return { success: false, reason: 'payment_failed' };
}
const auth = data.data.authorization;
const isReusable = auth.reusable === true;
// Store the authorization with reusable status
await db.query(
`INSERT INTO customer_payment_methods
(customer_id, authorization_code, last4, bank, card_type, reusable, created_at)
VALUES ($1, $2, $3, $4, $5, $6, NOW())`,
[customerId, auth.authorization_code, auth.last4, auth.bank, auth.card_type, isReusable]
);
if (!isReusable) {
// Alert the customer immediately, not weeks later
return {
success: true,
warning: 'card_not_reusable',
message: 'Your card ending in ' + auth.last4 + ' does not support automatic renewals. ' +
'You will receive a payment link before each renewal.',
};
}
return { success: true, warning: null };
}
Show the warning immediately after the first payment. The customer is still engaged and can switch to a different card or acknowledge the manual payment flow. Waiting until renewal time means the customer has forgotten about the payment method entirely.
Graceful Handling in Your Billing System
Your subscription billing logic should have two paths: one for reusable cards (automatic charge) and one for non-reusable cards (payment link). Both paths should be equally polished.
// Subscription renewal processor
async function processRenewal(subscriptionId: string) {
const sub = await getSubscription(subscriptionId);
const paymentMethod = await getPaymentMethod(sub.customerId);
if (!paymentMethod) {
// No payment method on file at all
await sendPaymentLinkEmail(sub);
await updateSubscriptionStatus(subscriptionId, 'awaiting_payment');
return;
}
if (paymentMethod.reusable) {
// Attempt automatic charge
try {
const charge = 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: paymentMethod.authorizationCode,
email: sub.customerEmail,
amount: sub.amount,
reference: `renewal_${subscriptionId}_${Date.now()}`,
}),
});
const result = await charge.json();
if (result.data?.status === 'success') {
await extendSubscription(subscriptionId);
await sendReceiptEmail(sub, result.data.reference);
return;
}
// Charge failed (insufficient funds, expired card, etc.)
// Fall through to payment link
} catch (err) {
console.error('Auto-charge failed:', err);
}
}
// Non-reusable card OR auto-charge failed: send payment link
const initRes = 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: sub.customerEmail,
amount: sub.amount,
reference: `renewal_link_${subscriptionId}_${Date.now()}`,
callback_url: `https://yoursite.com/subscription/${subscriptionId}/renewed`,
}),
});
const initData = await initRes.json();
await sendPaymentLinkEmail(sub, initData.data.authorization_url);
await updateSubscriptionStatus(subscriptionId, 'awaiting_payment');
}
This approach ensures no customer falls through the cracks. Whether their card is reusable or not, they get a path to pay.
Alternative Billing Approaches
If a significant portion of your customer base has non-reusable cards, consider these billing alternatives:
1. M-Pesa recurring (Kenya)
In Kenya, M-Pesa is far more reliable for recurring payments than cards. Use the Paystack charge API with the mobile_money channel to send an STK push for each renewal. The customer approves with their PIN. No tokenization needed.
2. Payment links via email or SMS
Send a payment link 3 days before the subscription renews. The customer clicks the link, lands on the Paystack checkout, and pays with whatever method they prefer. This works for all payment channels.
3. Invoice-based billing
For B2B or higher-value subscriptions, send an invoice with payment instructions. The customer pays via bank transfer to your dedicated virtual account on Paystack. Paystack notifies you via webhook when the payment arrives.
4. Pre-debit notifications
For customers with reusable cards, send a notification 24 to 48 hours before the automatic charge. This is good practice regardless because it reduces chargebacks and gives customers a chance to cancel before being charged.
// Pre-renewal notification schedule
async function scheduleRenewalNotifications(subscriptionId: string) {
const sub = await getSubscription(subscriptionId);
const renewalDate = new Date(sub.nextRenewalDate);
// 3 days before: send reminder
const reminderDate = new Date(renewalDate.getTime() - 3 * 24 * 60 * 60 * 1000);
await scheduleEmail({
to: sub.customerEmail,
template: 'renewal_reminder',
sendAt: reminderDate,
data: {
amount: sub.amount / 100,
renewalDate: renewalDate.toLocaleDateString('en-KE'),
manageUrl: `https://yoursite.com/subscription/${subscriptionId}/manage`,
},
});
}
Customer Communication Templates
Clear communication prevents confusion and reduces support tickets. Here are message templates for different scenarios:
At signup (card is not reusable):
// Show in the UI after first payment
const signupWarning = `
Your payment was successful. However, your card ending in ${last4}
does not support automatic renewals. We will send you a payment link
by email before each renewal. You can also update your payment method
in your account settings at any time.
`;
Before renewal (payment link):
// Email subject: "Your subscription renews in 3 days"
const renewalEmail = `
Hi ${name},
Your ${planName} subscription renews on ${renewalDate}.
Amount: KES ${amount}
Since your card does not support automatic payments,
please complete your renewal using this link:
${paymentLink}
This link expires on ${expiryDate}.
Want to set up automatic renewals? Update your payment
method here: ${billingUrl}
Thanks,
${companyName}
`;
After missed renewal:
// Email subject: "Your subscription payment is overdue"
const overdueEmail = `
Hi ${name},
We were unable to process your ${planName} subscription
renewal of KES ${amount} that was due on ${dueDate}.
To keep your subscription active, please pay here:
${paymentLink}
Your subscription will be suspended on ${suspensionDate}
if payment is not received.
Need help? Reply to this email.
${companyName}
`;
Track Your Non-Reusable Card Rate
Know what percentage of your customers have non-reusable cards. This number shapes your billing architecture decisions.
// Query to check your non-reusable card rate
async function getCardReusabilityMetrics() {
const result = await db.query(`
SELECT
COUNT(*) as total_customers,
COUNT(*) FILTER (WHERE reusable = true) as reusable_cards,
COUNT(*) FILTER (WHERE reusable = false) as non_reusable_cards,
ROUND(
COUNT(*) FILTER (WHERE reusable = false)::numeric /
NULLIF(COUNT(*), 0) * 100, 1
) as non_reusable_percentage
FROM customer_payment_methods
WHERE created_at > NOW() - INTERVAL '90 days'
`);
const metrics = result.rows[0];
console.log('Card reusability metrics (last 90 days):');
console.log(` Total customers with cards: ${metrics.total_customers}`);
console.log(` Reusable cards: ${metrics.reusable_cards}`);
console.log(` Non-reusable cards: ${metrics.non_reusable_cards}`);
console.log(` Non-reusable rate: ${metrics.non_reusable_percentage}%`);
return metrics;
}
If the non-reusable rate is above 20%, your payment link flow is not a fallback. It is a primary billing channel and should be designed accordingly, with proper retry sequences, overdue notifications, and grace periods.
Verification: Test Your Recurring Billing Flow
Before going live with recurring charges, test both paths:
- Test with a reusable card. In Paystack test mode, make a payment with the standard test card. Verify that the authorization returns
reusable: true. Charge the authorization again. Confirm the second charge succeeds. - Test with a non-reusable card. Since test mode cards are typically reusable, simulate a non-reusable card by setting
reusable = falsein your database for a test customer. Trigger the renewal process. Confirm that your system sends a payment link instead of attempting a charge. - Test the customer notification. Trigger the "card not reusable" notification. Read the email or in-app message. Confirm it is clear, non-technical, and includes a link to update the payment method.
- Test the payment link flow. Click the payment link sent during the non-reusable flow. Complete the payment. Confirm the subscription is extended and the customer receives a receipt.
- Test renewal failure. Let a payment link expire without paying. Confirm the system sends an overdue notification. Confirm the subscription status changes to "overdue" or "suspended" according to your grace period rules.
For detailed subscription troubleshooting, see Paystack Subscription Not Charging. For understanding how authorization codes work across different card types, see Paystack Authorization Code Not Reusable.
Key Takeaways
- ✓Paystack cannot override card issuer restrictions on recurring charges. If the bank or card network says no, the card will not work for subscriptions or future charges regardless of your Paystack configuration.
- ✓Prepaid cards (gift cards, prepaid Visa/Mastercard) almost never support recurring charges. Virtual cards from fintech apps are hit or miss depending on the issuer.
- ✓In the Nigerian market, standard debit cards from tier-1 banks (GTBank, First Bank, Access Bank, UBA) generally support recurring charges. Cards from newer digital banks and student accounts are less reliable.
- ✓In the Kenyan market, card-based recurring is less common. M-Pesa is the dominant recurring payment channel and does not have the same card tokenization restrictions.
- ✓Always check the authorization.reusable field after the first charge. If it is false, do not attempt recurring charges on that card. Build a fallback flow that sends a payment link instead.
- ✓Communicate the limitation in plain language. Customers do not understand tokenization. Tell them their card type does not support automatic payments and offer clear alternatives.
- ✓For subscription businesses, track your "non-reusable card" rate. If more than 20% of your customers have non-reusable cards, your billing architecture needs a payment-link fallback as a first-class feature, not an afterthought.
Frequently Asked Questions
- Why does my Paystack subscription fail on the second charge even though the first charge worked?
- The first charge goes through the full checkout flow where the customer enters their details. This always works regardless of card type. The second charge attempts to use the stored authorization code, which only works if the card is reusable. Check the authorization.reusable field from the first charge. If it is false, the card does not support recurring charges.
- Can I force a card to support recurring charges on Paystack?
- No. The reusable flag is set by the card issuer and card network. Neither Paystack nor your application can override this restriction. If a card does not support recurring charges, the only options are to use the checkout flow for each payment, use an alternative payment channel, or ask the customer to use a different card.
- Do M-Pesa payments support recurring charges through Paystack?
- M-Pesa does not use card tokenization. Each M-Pesa charge sends an STK push to the customer phone, and the customer approves with their PIN. You can initiate recurring M-Pesa charges through the Paystack charge API, but each one requires customer approval. There is no "silent" M-Pesa recurring charge without customer interaction.
- How do I know which of my customers have non-reusable cards?
- Query the authorization objects from your successful transactions. The reusable field tells you. If you have not been storing this field, you can check existing authorizations by listing a customer transactions via the Paystack API and reading the authorization object from each.
- What percentage of cards in Nigeria are not reusable?
- There is no published industry figure. In practice, for consumer-facing products, expect 10% to 30% of cards to be non-reusable depending on your customer demographic. Products targeting younger users or lower-income segments will see a higher non-reusable rate due to prepaid and student account cards. Track your own metrics to get an accurate number for your user base.
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