SDK JavaScript / TypeScript
Client officiel, sans aucune dépendance : fetch et WebCrypto suffisent. Node 18+, Deno, Bun, Cloudflare Workers, Vercel Edge.
Une dépendance dans un SDK de paiement est une surface d'attaque de plus dans la chaîne d'approvisionnement de chaque marchand qui l'installe. Il n'y en a aucune.
Installer
npm install https://docs.valsoriapay.avasoftware.net/valsoria-pay.tgz
Encaisser
import { ValsoriaPay, BASE_SANDBOX } from '@valsoria/pay';
const vp = new ValsoriaPay({ apiKey: process.env.VALSORIA_CLE, baseUrl: BASE_SANDBOX });
const paiement = await vp.creerPaiement(
{ amount: 10000, currency: 'XOF', operator: 'orange_ci',
counterparty: { msisdn: '0779149021' } },
{ idempotencyKey: 'cmd-2026-00412' },
);
idempotencyKey est facultative : sans elle, le SDK en génère une, parce que l'API refuse un appel qui n'en porte pas. Fournissez la vôtre dès que la tentative peut être relancée par autre chose que ce processus : un utilisateur qui recharge la page, une file de messages, un cron. Une clé générée en mémoire ne survit pas au processus, et deux exécutions créeraient deux paiements.
Les erreurs
import { ValsoriaPayError } from '@valsoria/pay';
try {
await vp.creerPaiement({ amount: -1 });
} catch (e) {
if (e instanceof ValsoriaPayError) {
e.code; // 'invalid_amount' — stable, testez ceci
e.status; // 422, ou null si la requête n'a jamais abouti
e.requestId; // à citer au support
}
}
Les erreurs réseau et les 5xx sont réessayés avec la même clé d'idempotence — c'est ce qui rend la reprise sûre. Les 4xx ne le sont pas : la requête est en cause, la rejouer donnerait le même refus. Sauf 429, où l'API demande explicitement d'attendre.
Les webhooks
app.post('/webhooks/valsoria', express.raw({ type: 'application/json' }), async (req, res) => {
let evenement;
try {
evenement = await ValsoriaPay.webhooks.construireEvenement({
corpsBrut: req.body.toString('utf8'),
signature: req.header('Valsoria-Signature'),
secret: process.env.VALSORIA_WEBHOOK_SECRET,
});
} catch {
return res.sendStatus(400);
}
await enregistrer(evenement);
res.sendStatus(200);
});
express.raw n'est pas un détail : avec express.json, req.body est un objet déjà re-sérialisé, il diffère des octets reçus, et la vérification échoue toujours.
Ce que le SDK ne fait pas
Il n'invente pas de routes. Décaissements, lots, bénéficiaires et règlements n'existent pas encore dans l'API, donc pas non plus ici.
Version d'API 2026-08-25 ·
changements ·
spécification OpenAPI