@noryqa/node
v0.1.0
Published
Official NORYQA Node.js and TypeScript SDK
Maintainers
Readme
@noryqa/node
SDK officiel Node.js / TypeScript pour intégrer les paiements, payouts et webhooks NORYQA.
npm install @noryqa/nodeimport { Noryqa } from "@noryqa/node";
const noryqa = new Noryqa(process.env.NORYQA_API_KEY!);
const payment = await noryqa.pay({
amount: 1250,
currency: "XOF",
reference: "order_123",
description: "Commande 123",
returnUrl: "https://merchant.com/payment-return",
});
redirect(payment.checkoutUrl);Le SDK ajoute automatiquement l’Idempotency-Key, convertit les champs camelCase vers le contrat API NORYQA et transforme les réponses en objets TypeScript simples. Une clé personnalisée est possible avec noryqa.pay(payload, { idempotencyKey: "order_123_payment" }).
Les retries sont limités aux erreurs réseau, timeouts, 429 et 5xx, avec backoff borné. La même Idempotency-Key est conservée pendant tous les retries d’un appel afin que NORYQA rejoue ou tranche l’opération sans créer de doublon. Les erreurs sont exposées sous forme de NoryqaError (code, status, message, requestId) ; les codes connus sont typés par NoryqaErrorCode, tandis qu’un code serveur futur reste accepté comme valeur inconnue.
Pour un payout :
const payout = await noryqa.payout({
amount: 25000,
currency: "XOF",
reference: "withdrawal_123",
description: "Retrait vendeur",
recipient: { type: "mobile_money", country: "BJ", network: "mtn", phone: "22997000000" },
customer: { firstName: "John", lastName: "Doe", email: "[email protected]" },
});Pour vérifier un webhook NORYQA, transmettez le body brut :
const event = noryqa.webhook({
rawBody,
signature: request.headers["x-noryqa-signature"],
secret: process.env.NORYQA_WEBHOOK_SECRET!,
});Le SDK est serveur uniquement. NORYQA_API_KEY est une clé secrète : ne l’exposez jamais dans le navigateur, React, Vue ou du JavaScript client.
Node.js >=20 est supporté. Le SDK ne reçoit ni environment, ni provider : TEST/LIVE est déterminé exclusivement par le préfixe de la clé noryqa_test_... ou noryqa_live_.... baseUrl vaut https://api.noryqa.com par défaut. Une URL distante doit utiliser HTTPS ; HTTP est accepté uniquement pour localhost, 127.0.0.1 ou ::1. Les credentials intégrés dans l’URL sont refusés avant tout appel réseau. Un fetch injecté peut toutefois utiliser une URL HTTP valide pour les mocks et tests internes.
Pour réutiliser un recipient de payout, NORYQA le conserve comme Beneficiary de l’organisation :
const recipient = await noryqa.recipient({
type: "mobile_money",
country: "BJ",
network: "mtn",
phone: "22997000000",
});
await noryqa.payout({
amount: 25000,
currency: "XOF",
reference: "withdrawal_123",
description: "Retrait vendeur",
recipient: recipient.id,
customer: { firstName: "John", lastName: "Doe", email: "[email protected]" },
});La primitive webhook() vérifie toujours le raw body, la signature en comparaison constant-time et la fenêtre temporelle anti-rejeu. Elle retourne un événement complet avec id, type, createdAt et data. Aucun handler n’est appelé avant cette validation. Pour dispatcher simplement après vérification :
await noryqa.handleWebhook({
rawBody,
signature,
secret: process.env.NORYQA_WEBHOOK_SECRET!,
handlers: {
"payment.succeeded": async (event) => grantAccess(event.data.payment.reference),
"payment.failed": async (event) => markFailed(event.data.payment.reference),
},
});Idempotency
noryqa.pay(payload) et noryqa.payout(payload) génèrent une nouvelle clé sdk_<uuid> pour chaque invocation et conservent cette même clé pendant les retries réseau de cet appel. Une nouvelle invocation sans clé fournie reçoit donc une nouvelle clé.
Pour une opération qui doit rester idempotente après un crash, un redémarrage ou une nouvelle invocation, fournissez une clé métier stable :
await noryqa.pay(payload, {
idempotencyKey: `payment:${order.id}`,
});La clé n’est pas stockée automatiquement par le SDK. NORYQA reconnaît la clé côté API, rejoue la réponse existante si le payload canonique est identique et renvoie IDEMPOTENCY_CONFLICT si le payload diffère.
Webhook deduplication
Un webhook peut être redélivré. Le SDK vérifie chaque livraison mais ne les déduplique pas. Enregistrez event.id dans votre base si votre logique métier ne doit s’exécuter qu’une seule fois.
