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.
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.
.env), never in your HTML or JavaScript.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.
<script src="https://js.flowwithlit.com/v1/inline.js"></script>
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.
<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>
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"
data.status === "successful", the payment is confirmed. Now fulfil the order — ship the product, activate the subscription, etc.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 Number | Brand | Result |
|---|---|---|
4084 0841 1881 8818 | Visa | Success |
5531 8866 5214 2950 | Mastercard | Success |
5061 4600 0000 0000 | Verve | Success |