Card tokenization

Tokenization allows you to implement recurring payments by saving a token representing the customer's card and using that on subsequent charges.

You should never save a customer's card details; the details are represented by a token, which is what you save.

Unlike payment plans, you are responsible for managing the customer's subscription yourself—cancellation, reactivation, and charging them are all your responsibility.

To implement a recurring charge, first you'll need to charge the customer normally, for instance via direct charge or Flutterwave Inline. Make sure to allow payments only via card, as only cards can be tokenized.

When the payment is done, verify the payment as usual. In the verification response, you'll find a token field in the data.card object. This is the token representing the card.

  "status": "success",
  "message": "Transaction fetched successfully",
  "data": {
    "status": "successful",
    "payment_type": "card",
    "card": {
      "first_6digits": "455605",
      "last_4digits": "2643",
      "issuer": "MASTERCARD GUARANTY TRUST BANK Mastercard Naira Debit Card",
      "country": "NG",
      "type": "MASTERCARD",
+     "token": "flw-t1nf-93da56b24f8ee332304cd2eea40a1fc4-m03k",
      "expiry": "01/23"
    "customer": {
      "email": "",
      // ...

You'll need to store this token (along with the customer's email you provided). To charge the card again in the future, pass the token and the email to the charge with token endpoint.

Tokens are tied to email addresses

The token is tied to the email address you specified on the first charge. This means that if a customer changes their email address on your app, you'll need to update the token details for future charges to work.

// Install with: npm i flutterwave-node-v3

const Flutterwave = require('flutterwave-node-v3');
const flw = new Flutterwave(process.env.FLW_PUBLIC_KEY, process.env.FLW_SECRET_KEY);
const details = {
    token: user.card_token,
    currency: "NGN",
    country: "NG",
    amount: 24000,
    tx_ref: this.generateTransactionReference(),
    narration: "Payment for monthly magazine subscription",
await flw.Tokenized.charge(details);
// Install with: composer require flutterwavedev/flutterwave-v3

$flw = new \Flutterwave\Rave(getenv('FLW_SECRET_KEY')); // Set `PUBLIC_KEY` as an environment variable
$tokenizedChargeService = new \Flutterwave\TokenizedCharge();
$details = [
    "token" => $user->card_token,
    "currency" => "NGN",
    "country" => "NG",
    "amount" => 24000,
    "email" => $user->email,
    "tx_ref" => $this->generateTransactionReference(),
    "narration" => "Payment for monthly magazine subscription",
$response = $tokenizedChargeService->tokenCharge($details);
# Install with: gem install flutterwave_sdk

require 'flutterwave_sdk'

charge =
details = {
    token: user.card_token,
    currency: "NGN",
    country: "NG",
    amount: 24000,
    tx_ref: generate_transaction_reference,
    narration: "Payment for monthly magazine subscription",
response = charge.tokenized_charge details
print response
curl --request POST '' \
  --header 'Authorization: Bearer YOUR_SECRET_KEY' \
  --header 'Content-Type: application/json' \
  --data-raw '{
     "token": "flw-t1nf-93da56b24f8ee332304cd2eea40a1fc4-m03k",
     "currency": "NGN",
     "country": "NG",
     "amount": 24000,
     "email": "",
     "tx_ref": "8676oi9764823kefth",
     "narration": "Payment for monthly magazine subscription",

See the endpoint docs for details and more options.

You can store the information in the data.card object and use it to provide a better experience for your customers. For example, you could send a reminder when their card is about to expire, or display "MasterCard ending in 2643" in their billing settings, so they can confirm which card will be charged.

You can also charge multiple tokens in one go. See the reference docs for details.