Recurring Charges
In a nutshell
Charge the first transaction
You can initialize this first charge from web or your mobile app. Check out the different integration methods for web and mobile.
Why do I need to charge the user to add their cards?
- Local regulations require that users authenticate the card through
2FA
in an initial transaction before we can charge the card subsequently. - It allows us to ensure that the card is valid and can be charged for subsequent transactions.
Minimum charge amount
The minimum amount we recommend for the first charge is NGN 50.00, GHS 0.10, ZAR 1.00, or USD 0.20. Lower amounts are not guaranteed to work on all card brands or banks.
It is standard practice to credit the user back with value (in your app) worth the tokenization amount, or simply refund the money back.
Get the Card authorization
If the first transaction is successful, you can listen to events on your webhook endpoint. Alternatively, you can use the Verify TransactionAPI endpoint to confirm the status of the transaction. In either case, the response looks like the sample below:
- JSON
1{2 ...3 "data": {4 ...5 "authorization": {6 "authorization_code":"AUTH_8dfhjjdt",7 "card_type":"visa",8 "last4":"1381",9 "exp_month":"08",10 "exp_year":"2018",11 "bin":"412345",12 "bank":"TEST BANK",13 "channel":"card",14 "signature": "SIG_idyuhgd87dUYSHO92D",15 "reusable":true,16 "country_code":"NG",17 "account_name": "BoJack Horseman"18 },19 ...20 }21}
You'll notice that the data
object in the response contains an authorization
object within it, which contains the details of the payment instrument (card in this case) that the user paid with.
Property | Description |
---|---|
authorization_code | This is the code that is used to charge the card subsequently |
card_type | This tells you the card brand - Visa, Mastercard, etc |
last4 | The last 4 digits of the card. This is one of the details you can use to help the user identify the card |
exp_month | The expiry month of the card in digits. Eg. "01" means January |
exp_year | The expiry year of the card |
bin | The first 6 digits of the card. This and the last 4 digits constitute the masked pan |
bank | The customer's bank, the bank that issued the card |
channel | What payment channel this is. In this case, it is a card payment |
signature | An identifier that enables you identify this card on your system (no matter the customer that used it. Since we generate a new authorization code every time a payment is made with a card (all former ones remain valid), authorization code cannot be an identifier, but every card has just one signature. |
reusable | A boolean flag that tells you if an authorization can be used for a recurring debit. This is always `true` for all cards, false for other payment channel since they can't be reused |
country_code | The country of the bank where the card was issued |
Store the authorization
Next, you need to store the authorization
and the email
used for the transaction. These details can be used to charge the card subsequently. Every payment instrument that is used on your site/app has a unique signature
. The signature
can be used to ensure that you do not save an authorization multiple times.
Note
It is important to store the entire authorization
object in order not to lose any context regarding the card.
It is also important to store the email used to create an authorization because only the email used to create an authorization can be used to charge it. If you rely on the user's email stored on your system and the user changes it, the authorization can no longer be charged.
When you have the whole authorization object saved, you can display customer payment details at the point of payment to charge recurrently. For example, when the user wants to pay again, you can display the card for the user as Access Bank Visa card ending with 1234.
Charge the authorization
When the user selects the card for a new transaction or when you want to charge them subsequently, you send the authorization_code
, user's email
and the amount
you want to charge to the charge authorizationAPI endpoint.
1curl https://api.paystack.co/transaction/charge_authorization2-H "Authorization: Bearer YOUR_SECRET_KEY"3-H "Content-Type: application/json"4-d '{ "authorization_code" : "AUTH_pmx3mgawyd", email: "mail@mail.com", amount: "300000" }'5-X POST
1{2 "status": true,3 "message": "Charge attempted",4 "data": {5 "amount": 300000,6 "currency": "NGN",7 "transaction_date": "2020-05-27T11:45:03.000Z",8 "status": "success",9 "reference": "cn65lf4ixmkzvda",10 "domain": "test",11 "metadata": "",12 "gateway_response": "Approved",13 "message": null,14 "channel": "card",15 "ip_address": null,16 "log": null,17 "fees": 14500,18 "authorization": {19 "authorization_code": "AUTH_pmx3mgawyd",20 "bin": "408408",21 "last4": "4081",22 "exp_month": "12",23 "exp_year": "2020",24 "channel": "card",25 "card_type": "visa DEBIT",26 "bank": "Test Bank",27 "country_code": "NG",28 "brand": "visa",29 "reusable": true,30 "signature": "SIG_2Gvc6pNuzJmj4TCchXfp",31 "account_name": null32 },33 "customer": {34 "id": 23215815,35 "first_name": null,36 "last_name": null,37 "email": "mail@mail.com",38 "customer_code": "CUS_wt0zmhzb0xqd4nr",39 "phone": null,40 "metadata": null,41 "risk_action": "default"42 },43 "plan": null,44 "id": 69610592845 }46}