Recurring Charges
Recurring charges let you debit a customer's saved card without requiring them to re-enter their card details. After a customer completes an initial payment, the provider returns an authorization code that you can use for all future charges against that card.
Provider support
Recurring charges are supported by Paystack and Flutterwave. Authorization codes are provider-specific — a code issued by Paystack cannot be used with Flutterwave and vice versa. You must pass the correct provider_id to match the provider that issued the authorization code.
How Authorization Codes Work
When a customer successfully completes a card payment for the first time, the provider returns an authorization_code in the payment webhook payload and in the GET /v1/payments/:id response under metadata.authorization_code. Store this code against the customer record in your database — it is the token you will pass to this endpoint for all subsequent charges.
Charge an Authorization
Use a stored authorization code to debit a customer's card without a checkout redirect. The charge is processed synchronously and returns a payment object.
/v1/charges/authorizeCharges a customer's card using a previously obtained authorization code.
Request headers
| Parameter | Type | Required | Description |
|---|---|---|---|
Authorization | string | Required | Bearer YOUR_API_KEY |
Content-Type | string | Required | Must be application/json |
Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
authorization_code | string | Required | The authorization code returned by the provider after the customer's first successful card payment. |
customer_email | string | Required | Email address of the customer being charged. Must match the email used in the original authorization. |
amount | integer | Required | Amount to charge in the smallest currency unit (kobo for NGN). |
currency | string | Optional | ISO 4217 currency code. Defaults to NGN. |
reference | string | Required | Your unique reference for this charge. Alphanumeric, hyphens, and underscores only. Max 255 characters. |
reason | string | Optional | Description or narration for this charge. Shown on the customer's statement where supported. |
metadata | object | Optional | Up to 20 key-value pairs of string:string. Returned in all charge responses. |
provider_id | string | Optional | The provider that issued the authorization code: paystack, flutterwave. Must match the original payment provider. |
curl -X POST https://api.popfab.io/v1/charges/authorize \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"authorization_code": "AUTH_abc123xyz",
"customer_email": "ada@example.com",
"amount": 500000,
"currency": "NGN",
"reference": "SUB-2026-03-001",
"reason": "March subscription",
"provider_id": "paystack"
}'{
"id": "ppfb_pay_01HXA3KBZQM4Z3YWN5E6R7VP8S",
"reference": "SUB-2026-03-001",
"amount": 500000,
"currency": "NGN",
"status": "success",
"provider": "paystack",
"provider_reference": "ps_abc123",
"customer": {
"email": "ada@example.com"
},
"reason": "March subscription",
"metadata": {},
"created_at": "2026-03-23T08:00:00.000Z",
"updated_at": "2026-03-23T08:00:00.000Z"
}payment.success and payment.failed events.provider_id alongside the authorization_code in your database and pass it in every recurring charge request. Mismatching the provider will result in a 422 INVALID_AUTHORIZATION error.