Flowwithlit Docs
GETTING STARTED

Quickstart Guide

Accept your first test payment in under 5 minutes. You'll add our checkout script to your page, trigger a payment modal, and verify the transaction on your server.

ℹ️
You'll need a Flowwithlit account and your test API keys from the Developer API dashboard.
1

Get your API keys

Log into your dashboard and go to Developer API. Copy your Public Key (Test) — it starts with flw_pub_test_. You'll also need your Secret Key (Test) for server-side verification.

⚠️
The secret key is only shown once. Store it in an environment variable (.env), never in your HTML or JavaScript.
2

Add the script tag to your page

Paste this tag just before the closing </body> of your HTML page. That's it — no npm, no bundler required.

HTML
<script src="https://js.flowwithlit.com/v1/inline.js"></script>
3

Trigger checkout

Add a button and call FlowPay.init(). By default checkout opens in a popup iframe on your page. For a Paystack-style redirect (leave your site → pay → return), pass mode: 'redirect' and a callback_url. See Checkout docs for both patterns.

HTML + JavaScript
<button onclick="payNow()">Pay ₦5,000</button>

<script src="https://js.flowwithlit.com/v1/inline.js"></script>
<script>
function payNow() {
  FlowPay.init({
    public_key: 'flw_pub_test_YOUR_KEY_HERE',
    amount:     5000 * 100,          // amount in kobo (₦5,000)
    currency:   'NGN',
    email:      'customer@email.com',
    name:       'John Doe',

    onSuccess: function(response) {
      // response.transaction_ref — verify this server-side!
      verifyPayment(response.transaction_ref);
    },
    onClose: function() {
      console.log('Customer closed the checkout');
    },
    onError: function(err) {
      console.error('Checkout error:', err);
    }
  });
}

function verifyPayment(ref) {
  fetch('/verify.php', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ ref: ref })
  })
  .then(r => r.json())
  .then(data => {
    if (data.verified) {
      alert('Payment confirmed! Ref: ' + ref);
      // unlock the product / fulfil the order
    }
  });
}
</script>
4

Verify the payment on your server

Always verify server-side. The onSuccess callback fires in the customer's browser and can be spoofed. Your server must call our verification endpoint using your secret key before you deliver any goods or services.

<?php
// verify.php — your server-side verification endpoint

define('FLW_SECRET_KEY', getenv('FLW_SECRET_KEY')); // from .env
define('API_BASE', 'https://api.flowwithlit.com');

header('Content-Type: application/json');

$body = json_decode(file_get_contents('php://input'), true);
$ref  = trim($body['ref'] ?? '');

if (!$ref) {
    http_response_code(400);
    echo json_encode(['verified' => false, 'message' => 'ref required']);
    exit;
}

$ch = curl_init(API_BASE . '/v1/transaction/verify/' . urlencode($ref));
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . FLW_SECRET_KEY],
    CURLOPT_TIMEOUT        => 10,
]);
$res  = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($code === 200 && ($res['data']['status'] ?? '') === 'successful') {
    // ✅ Safe to fulfil the order
    echo json_encode([
        'verified' => true,
        'ref'      => $res['data']['transaction_ref'],
        'amount'   => $res['data']['amount'],   // in kobo
        'currency' => $res['data']['currency'],
    ]);
} else {
    http_response_code(402);
    echo json_encode(['verified' => false, 'message' => 'Payment not confirmed']);
}
// verify.js — Express route example
const express = require('express');
const fetch   = require('node-fetch'); // npm i node-fetch@2
const router  = express.Router();

const API_BASE = 'https://api.flowwithlit.com';

router.post('/verify', async (req, res) => {
  const { ref } = req.body;
  if (!ref) return res.status(400).json({ verified: false });

  try {
    const resp = await fetch(`${API_BASE}/v1/transaction/verify/${encodeURIComponent(ref)}`, {
      headers: { Authorization: `Bearer ${process.env.FLW_SECRET_KEY}` }
    });
    const data = await resp.json();

    if (resp.ok && data.data?.status === 'successful') {
      // ✅ Safe to fulfil the order
      return res.json({
        verified: true,
        ref:      data.data.transaction_ref,
        amount:   data.data.amount,    // kobo
        currency: data.data.currency,
      });
    }
    res.status(402).json({ verified: false, message: 'Payment not confirmed' });
  } catch (err) {
    res.status(502).json({ verified: false, message: 'Gateway error' });
  }
});

module.exports = router;
# verify.py — Flask route example
import os, requests
from flask import Flask, request, jsonify

app     = Flask(__name__)
API_BASE = 'https://api.flowwithlit.com'
SECRET  = os.getenv('FLW_SECRET_KEY')

@app.route('/verify', methods=['POST'])
def verify():
    ref = request.json.get('ref', '').strip()
    if not ref:
        return jsonify(verified=False, message='ref required'), 400

    resp = requests.get(
        f'{API_BASE}/v1/transaction/verify/{ref}',
        headers={'Authorization': f'Bearer {SECRET}'},
        timeout=10
    )

    if resp.ok and resp.json().get('data', {}).get('status') == 'successful':
        d = resp.json()['data']
        # ✅ Safe to fulfil the order
        return jsonify(verified=True, ref=d['transaction_ref'],
                       amount=d['amount'], currency=d['currency'])

    return jsonify(verified=False, message='Payment not confirmed'), 402
curl -X GET \
  https://api.flowwithlit.com/v1/transaction/verify/FLW_TXN_ABCD1234 \
  -H "Authorization: Bearer flw_sec_test_YOUR_SECRET_KEY"
When data.status === "successful", the payment is confirmed. Now fulfil the order — ship the product, activate the subscription, etc.
5

Test it with a test card

Use one of these cards in test mode. Any future expiry date and any 3-digit CVV will work.

Card NumberBrandResult
4084 0841 1881 8818VisaSuccess
5531 8866 5214 2950MastercardSuccess
5061 4600 0000 0000VerveSuccess

What's Next?