REST + webhooks signés HMAC. Générez votre clé API depuis le Dashboard et commencez tout de suite.
Sandbox · Onboarding guidé
Dans le Dashboard → API Keys, créez une clé sk_test_… (sandbox, isolée des fonds réels).
POST /api/public/v1/payment-intents avec votre clé Bearer. Vous recevez un pay_url court /p/{code}.
Ajoutez l'URL dans Dashboard → Webhooks. Chaque événement est signé HMAC SHA-256.
Téléchargez fathpay-webhook-test.sh et exécutez-le contre votre endpoint pour valider la vérification.
Après validation KYC, créez une clé sk_live_… La rotation est instantanée et révoque l'ancienne.
curl -X POST https://app.fathpay.app/api/public/v1/payment-intents \
-H "Authorization: Bearer sk_test_xxx" \
-H "Content-Type: application/json" \
-d '{
"amount": 25000,
"currency": "XOF",
"country": "SN",
"description": "Commande #ORD-8821",
"customer_email": "client@exemple.sn",
"customer_phone": "+221771234567",
"metadata": { "order_id": "ORD-8821" }
}'
# Réponse 201
{
"id": "uuid",
"short_code": "K7M2QP8R",
"reference": "FP_TXN_...",
"amount": 25000,
"currency": "XOF",
"status": "open",
"checkout_url": "https://provider/...",
"pay_url": "https://app.fathpay.app/p/K7M2QP8R"
}const res = await fetch("https://app.fathpay.app/api/public/v1/payment-intents", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.FATHPAY_SECRET_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
amount: 25000, currency: "XOF", country: "SN",
description: "Commande #ORD-8821",
}),
});
const intent = await res.json();
console.log(intent.pay_url); // partagez ce lien à votre client// Node — vérifier x-fathpay-signature (HMAC SHA-256 du body brut)
import crypto from "node:crypto";
app.post("/webhooks/fathpay", express.raw({ type: "*/*" }), (req, res) => {
const sig = req.header("x-fathpay-signature");
const expected = crypto
.createHmac("sha256", process.env.FATHPAY_WEBHOOK_SECRET)
.update(req.body)
.digest("hex");
if (sig !== expected) return res.status(401).send("invalid signature");
const event = JSON.parse(req.body.toString("utf8"));
// event.type: payment.succeeded | payment.failed | payment.expired
res.send("ok");
});