Compléter un paiement (/complete)

Référence détaillée de POST /checkout/pay/:sessionId/complete — corps, réponses, méthodes et payment intent.

Endpoint

Endpoint public (pas de Bearer). Appelé depuis la page checkout ou votre intégration embarquée.

text
POST /api/v1/checkout/pay/:sessionId/complete

Corps commun

paymentMethod : WALLET | MOBILE_MONEY | CARD | BANK_TRANSFER | QR

json
{
  "paymentMethod": "MOBILE_MONEY",
  "paymentDetails": { },
  "customerInfo": { }
}

MOBILE_MONEY

Réponse typique : status SUCCEEDED, paymentIntentId et chargeId renseignés, nextAction POLL.

json
{
  "paymentMethod": "MOBILE_MONEY",
  "paymentDetails": {
    "phone": "+243900000000",
    "operator": "ORANGE",
    "countryCode": "CD"
  }
}

CARD

Peut retourner nextAction REDIRECT avec actionUrl (3DS ou page provider).

json
{
  "paymentMethod": "CARD",
  "paymentDetails": {
    "cardNumber": "4242424242424242",
    "cardExpiry": "12/28",
    "cardCvc": "123"
  }
}

WALLET

Débit direct du portefeuille du payeur.

json
{
  "paymentMethod": "WALLET",
  "paymentDetails": {
    "walletId": "6015fa0e-0e44-461e-9ec8-b598ca19c14b"
  }
}

QR

Réponse avec nextAction DISPLAY_QR et qrPayload à afficher.

json
{
  "paymentMethod": "QR",
  "paymentDetails": {}
}

BANK_TRANSFER

Instructions de virement dans le champ instructions.

json
{
  "paymentMethod": "BANK_TRANSFER",
  "paymentDetails": {}
}

Réponse succès (SUCCEEDED)

paymentIntentId : identifiant financial-core — à conserver pour réconciliation.

redirectUrl : successUrl enrichie avec session_id, charge_id, amount, currency et status.

Si nextAction = POLL, appelez GET /checkout/pay/:sessionId/status jusqu'à SUCCEEDED.

json
{
  "success": true,
  "data": {
    "sessionId": "cs_38b62a204d2da0bcdd312c59",
    "status": "SUCCEEDED",
    "paymentIntentId": "b04cb5ed-3e0b-446a-b3cd-8ef2e2836b8d",
    "chargeId": "a76c830e-b7f1-4fd4-b5b6-618ffdb76b62",
    "providerCode": "INTERNAL",
    "nextAction": "POLL",
    "pollAfterMs": 2000,
    "redirectUrl": "https://merchant.example/success?session_id=cs_38b62a204d2da0bcdd312c59&amount=2500&currency=USD&status=SUCCEEDED&charge_id=a76c830e-b7f1-4fd4-b5b6-618ffdb76b62"
  }
}

Réponse asynchrone (PROCESSING)

PROCESSING : paymentIntentId et chargeId sont null tant que le provider n'a pas confirmé.

Puis GET /status ou POST /confirm selon la méthode.

json
{
  "success": true,
  "data": {
    "sessionId": "cs_38b62a204d2da0bcdd312c59",
    "status": "PROCESSING",
    "paymentIntentId": null,
    "chargeId": null,
    "providerCode": "INTERNAL",
    "nextAction": "POLL",
    "pollAfterMs": 4200,
    "instructions": "Confirmez la demande ORANGE sur votre téléphone."
  }
}

Confirmation QR (/confirm)

POST /checkout/pay/:sessionId/confirm est réservé aux paiements QR en statut PROCESSING.

La réponse reste status PROCESSING — la finalisation passe par le polling GET /status.

Les autres méthodes (MOBILE_MONEY, CARD, etc.) utilisent /complete et /status, pas /confirm.

json
{
  "success": true,
  "data": {
    "sessionId": "cs_38b62a204d2da0bcdd312c59",
    "status": "PROCESSING"
  }
}

Erreurs courantes

  • CHECKOUT_SESSION_EXPIRED (409) — session expirée
  • CHECKOUT_SESSION_NOT_OPEN (409) — déjà payée ou annulée
  • RISK_BLOCKED (409) — blocage conformité
  • PAYMENT_FAILED (409) — échec intent ou provider
  • INVALID_PAYMENT_DETAILS (400) — paymentDetails invalides