Skip to content
StableAudienceDevMétierOwner@partners-teamDernière revue2026-05-24

Encaisser pour un marchand

Une fois qu'un marchand vous a autorisé, la séquence pour percevoir un paiement est : créer une commande → afficher le QR → attendre le webhook. Le client final n'a affaire qu'à Nex, pas à vous — il ne sait même pas que vous existez.

Vue d'ensemble

Procédure pas-à-pas

Étape 1 — Créer la commande

À l'instant où votre vendeur saisit un montant sur son terminal, vous appelez :

bash
curl -X POST "https://dev.paywithnex.com/api/partners-public/orders" \
  -H "Authorization: Bearer nex_sk_live_VOTRE_CLE" \
  -H "Content-Type: application/json" \
  -d '{
    "merchantId": "0d85d7a4-ead8-4d85-bce8-c3731d082e47",
    "amount": 2500,
    "currencyCode": "XAF",
    "ttlSeconds": 300,
    "description": "Baguettes × 3",
    "externalReference": "MAISHA-ORDER-42"
  }'
ChampTypeDescription
merchantIdUUIDRécupéré à l'étape "connexion active" — voir Connecter un marchand.
amountintMontant dans la plus petite unité : XAF/XOF = unités (2500 = 2500 XAF), USD/EUR = centimes.
currencyCodestringISO 4217. CEMAC : XAF (Cameroun, Congo, Gabon, Guinée éq., Tchad, RCA), XOF (UEMOA si futur).
ttlSecondsint (optionnel)Durée de validité du QR. Défaut 300s (5 min). Max 900s (15 min).
descriptionstring (optionnel, 0-280 chars)Affiché au client mobile lors du scan ("Vous allez payer 2500 XAF chez Boulangerie Papa Jean — Baguettes × 3").
externalReferencestring (optionnel, 0-128 chars)Votre référence interne (numéro de ticket, ordre POS…). Renvoyée telle quelle dans le webhook order.paid pour réconcilier de votre côté.

Réponse 201 :

json
{
  "orderId": "cdefc6f6-acd1-44f8-a725-fa1b62d79ba8",
  "qrToken": "T_bfB1miJXZISq2_21ixG2D",
  "status": "pending",
  "amount": 2500,
  "currencyCode": "XAF",
  "expiresAt": "2026-05-24T12:05:00.000Z",
  "merchantId": "0d85d7a4-ead8-4d85-bce8-c3731d082e47",
  "integrationId": "4dd5e991-d853-41ac-a35d-f578cf846a85"
}

Stocker la correspondance

Conservez le mapping (orderId, externalReference, montant, vendeur, contexte) côté votre BD avant d'afficher le QR. Vous en aurez besoin au moment du webhook pour matcher.

Étape 2 — Afficher le QR au client

Encodez la valeur du champ qrToken (ex: T_bfB1miJXZISq2_21ixG2D) dans un QR code visible. Le format est une chaîne ASCII opaque — n'essayez pas de la parser. Tous les générateurs QR standard (zxing, qrcode-svg, etc.) acceptent ces chaînes telles quelles.

Niveau de correction d'erreur recommandé : M (15%) — suffisant pour un écran terminal propre, robuste si la caméra du client tremble.

Affichez aussi en clair sur l'écran :

  • Le montant + devise (2500 XAF)
  • Le nom du marchand (récupéré depuis votre BD ou affiché en dur si vous êtes mono-marchand)
  • Un compte à rebours visuel du expiresAt (utile UX, le client voit qu'il a 4 min restantes)

Étape 3 — Le client paie

Ce que vous n'avez pas à coder. Le client scanne le QR avec son app mobile Nex, voit le récap, confirme avec son PIN (ou biométrie). Nex :

  1. Débite son wallet
  2. Crédite le wallet du marchand
  3. Marque la transaction comme completed en BD
  4. Marque votre QR comme CONSUMED (idempotent — si le client retente, le QR refuse)

Tout ce flow prend typiquement 2-5 secondes.

Étape 4 — Recevoir le webhook order.paid

Dès que la transaction commit, Nex enqueue un webhook signé HMAC SHA256 vers votre URL configurée. Format du payload :

json
{
  "event": "order.paid",
  "id": "evt-uuid-xxxxxxxx",
  "createdAt": "2026-05-24T12:02:34.567Z",
  "data": {
    "orderId": "cdefc6f6-acd1-44f8-a725-fa1b62d79ba8",
    "transactionId": "tx-uuid-yyyyyyyy",
    "amount": 2500,
    "currencyCode": "XAF",
    "paidAt": "2026-05-24T12:02:34.000Z",
    "externalReference": "MAISHA-ORDER-42",
    "description": "Baguettes × 3"
  }
}

Headers envoyés :

http
Content-Type: application/json
User-Agent: Nex-Webhooks/1.0
Nex-Signature: t=1716553354,v1=5e7c1a3f4b8d2c9e6f1a2b3c4d5e6f7a8b9c0d1e...
Nex-Event: order.paid
Nex-Event-Id: evt-uuid-xxxxxxxx

Voir Recevoir les webhooks pour la vue d'ensemble, et le Guide implémentation receiver pour le code Express/Fastify complet (signature, anti-rejeu, idempotence).

Étape 5 — Action métier de votre côté

Une fois le webhook reçu, vérifié et idempotent, vous savez que l'argent est arrivé. Vous pouvez :

  • Imprimer le ticket caisse
  • Débloquer la marchandise / le service
  • Notifier votre vendeur ("✅ payé")
  • Marquer la commande paid côté votre BD
  • Etc.

Cas particuliers

Le client n'a pas scanné dans les 5 min

Le QR passe à EXPIRED côté Nex. Aucun webhook envoyé. Vous pouvez :

  1. Détecter l'expiration côté votre BD (expiresAt est dépassé + pas de webhook) → marquer la commande comme expired
  2. Re-créer un nouveau QR (POST /orders à nouveau) — c'est une nouvelle commande, nouvel orderId, nouveau QR

Il n'y a pas d'endpoint pour "renouveler" un QR existant : un QR = un paiement unique.

Le client paie deux fois (double-scan)

Impossible : le QR est marqué CONSUMED après le premier paiement (verrou ledger). Le 2e scan recevra une erreur QR_CONSUMED côté app mobile Nex.

Le client paie mais vous ne recevez pas le webhook

Nex retry 7 fois avec backoff exponentiel (30s, 1m, 2m, 4m, 8m, 16m, 32m — cumulé ~1h). Si après ça votre endpoint n'a toujours pas répondu 200, le job est en DLQ côté Nex. L'admin Nex peut le rejouer manuellement (endpoint admin dédié).

Diagnostic

Si vous suspectez ne pas recevoir un webhook : contactez partners@paywithnex.com avec le orderId ou le externalReference. Nex peut consulter la DLQ et vous dire l'erreur exacte (4xx receveur ? timeout ? hostname unreachable ?).

Vous avez changé d'URL webhook après création de la commande

Pas de souci : Nex relit l'URL configurée au moment du dispatch, pas au moment de la création de commande. Si vous changez via l'admin Nex (procédure manuelle V1), le prochain webhook ira sur la nouvelle URL.

Vous voulez annuler une commande pending

Pas d'endpoint V1. Soit vous laissez expirer (5 min), soit vous demandez à Nex (CMMS) de révoquer le QR.

Limites V1

  • Une commande = un QR statique. Pas de QR dynamique long-vivant pour un "POS qui accepte tout".
  • Pas de remboursement via l'API. À ce stade, refunds sont gérés manuellement par l'équipe Nex sur demande.
  • Pas de webhook order.expired ni order.cancelled. Vous polez côté votre BD via expiresAt.

Voir aussi

Nex — Plateforme fintech CEMAC