Les SDK
Node et PHP, sans aucune dépendance. Les mêmes noms que l’API, l’idempotence posée d’office, et les reprises quand le réseau flanche.
Installer
npm install payiz
composer require payiz/payiz-php
La clé secrète vit dans vos serveurs — dans les variables d’environnement de votre hébergeur —, jamais dans une page web ni une application mobile.
Encaisser
import { Payiz } from 'payiz'
const payiz = new Payiz(process.env.PAYIZ_CLE)
const paiement = await payiz.payments.create({
amount: 10000, // entier, dans l'unité mineure de la devise
currency: 'XOF',
description: 'Commande 42',
reference: 'cmd-42',
})
// À envoyer au client, ou à ouvrir avec le widget.
console.log(paiement.payment_url)$payiz = new \Payiz\Payiz(getenv('PAYIZ_CLE'));
$paiement = $payiz->payments->create([
'amount' => 10000,
'currency' => 'XOF',
'description' => 'Commande 42',
'reference' => 'cmd-42',
]);
header('Location: ' . $paiement['payment_url']);Ce qu’ils savent faire
| Node | PHP | Ce qu’il fait |
|---|---|---|
| payiz.account() | $payiz->account() | qui parle, dans quel mode, et ce que la clé peut faire |
| payiz.payments | $payiz->payments | create, retrieve, list / all, cancel |
| payiz.payments.attempts | $payiz->payments->attempts | create (lancer, relancer), list / all |
| payiz.paymentMethods | $payiz->paymentMethods | list / all : les opérateurs ouverts, leurs bornes et frais |
| payiz.refunds | $payiz->refunds | create, retrieve, list / all, reasons |
| payiz.paymentLinks | $payiz->paymentLinks | create, retrieve, list / all, deactivate |
| payiz.balance | $payiz->balance | retrieve |
| payiz.recipients | $payiz->recipients | list / all, retrieve |
| payiz.payouts | $payiz->payouts | create, retrieve, list / all |
| payiz.disputes | $payiz->disputes | retrieve, list / all |
| payiz.conversions | $payiz->conversions | retrieve, list / all |
Le paiement direct
Avec payer, la demande part aussitôt sur le téléphone du payeur. La clé porte le geste Paiements · lancer, et l’appel une clé d’idempotence tirée de votre commande : sans elle, le SDK refuse avant d’appeler. Le guide : Le paiement direct.
const paiement = await payiz.payments.create(
{
amount: 10000,
currency: 'XOF',
reference: 'cmd-42',
payer: { phone: '+2290197000000', operator: 'mtn' },
},
{ idempotencyKey: 'cmd-42' }, // obligatoire : tirée de la commande
)
// paiement.latest_attempt.payer_message : la consigne à montrer au payeur.
// Après un échec, relancer sur le même paiement :
await payiz.payments.attempts.create(
paiement.id,
{ phone: '+2290196000000', operator: 'moov' },
{ idempotencyKey: 'cmd-42-relance-1' },
)$paiement = $payiz->payments->create([
'amount' => 10000,
'currency' => 'XOF',
'reference' => 'cmd-42',
'payer' => ['phone' => '+2290197000000', 'operator' => 'mtn'],
], 'cmd-42');
$payiz->payments->attempts->create(
$paiement['id'],
['phone' => '+2290196000000', 'operator' => 'moov'],
'cmd-42-relance-1'
);L’idempotence, d’office
Chaque POST part avec un en-tête Idempotency-Key : rejoué après une coupure, il rend la première réponse au lieu d’encaisser deux fois. Donnez la vôtre pour rejouer sciemment — et toujours quand l’appel touche un téléphone : une clé tirée au hasard à chaque clic n’empêcherait pas deux demandes.
await payiz.payments.create({ amount: 10000 }, { idempotencyKey: 'cmd-42' })$payiz->payments->create(['amount' => 10000], 'cmd-42');
Les erreurs
import { PayizError, PayizConnectionError } from 'payiz'
try {
await payiz.payments.create(corps, { idempotencyKey: 'cmd-42' })
} catch (erreur) {
if (erreur instanceof PayizError) {
// erreur.code : un code du registre, par exemple 'operator_required'
// erreur.details : ce qui aide à corriger, ici details.operators
// erreur.requestId : à citer au support
} else if (erreur instanceof PayizConnectionError) {
// le réseau n'a rien dit : rejouez avec la même clé d'idempotence
}
}try {
$payiz->payments->create($corps, 'cmd-42');
} catch (\Payiz\ApiException $e) {
// $e->errorCode, $e->details, $e->requestId, $e->statusCode
}Les codes sont ceux de Les erreurs : le SDK Node les exporte dans ERROR_CODES, le PHP dans ApiException::CODES, et les raisons d’échec d’une demande dans FAILURE_CODES. Une panne passagère (408, 429, 5xx) se reprend toute seule, deux fois par défaut. Une demande refusée, jamais.
Vérifier un webhook
Toujours sur le corps brut, avant de le lire en JSON. Voir Recevoir les webhooks.
import { verifyWebhook } from 'payiz'
const brut = await request.text()
if (!(await verifyWebhook(brut, request.headers.get('payiz-signature'), secret))) {
return new Response('Signature refusée', { status: 400 })
}
const evenement = JSON.parse(brut)$brut = file_get_contents('php://input');
$entete = $_SERVER['HTTP_PAYIZ_SIGNATURE'] ?? null;
if (!\Payiz\Webhook::verifier($brut, $entete, getenv('PAYIZ_WEBHOOK_SECRET'))) {
http_response_code(400);
exit;
}
$evenement = \Payiz\Webhook::lire($brut);Parcourir une liste
for await (const paiement of payiz.paginate((params) => payiz.payments.list(params))) {
console.log(paiement.id, paiement.status)
}En PHP, passez starting_after à all() tant que has_more est vrai.