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.
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.
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 |
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
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.
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.
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.
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`,
},
});
}
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}
`;
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.
Before going live with recurring charges, test both paths:
reusable: true. Charge the authorization again. Confirm the second charge succeeds.reusable = false in your database for a test customer. Trigger the renewal process. Confirm that your system sends a payment link instead of attempting a charge.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.
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