Aller au contenu

Intentions de paiement

Une Intentions de paiement est un objet central dans le cycle de paiement Sangho. Il représente votre intention de collecter de l’argent auprès d’un client, et orchestre toutes les étapes du processus depuis l’attachement d’une méthode de paiement jusqu’à la confirmation finale et la création d’une Transaction.

À chaque paiement correspond exactement une Intention. Son cycle de vie est géré automatiquement par l’API Sangho en fonction des actions de votre client et des réponses des opérateurs.

Pourquoi une Intention et pas un paiement direct ?

Les Intentions de paiement permettent de gérer les scénarios complexes : authentification 3D Secure, redirection opérateur mobile, capture différée, et relance après échec sans jamais perdre l’état du paiement en cours. C’est l’approche recommandée pour toute intégration de paiement robuste.

Cycle de vie

requires_payment_methodrequires_confirmationrequires_actionpendingprocessingsucceeded / canceled
StatutSignificationAction requise
requires_payment_methodAucune méthode de paiement n'est encore attachée.Présenter le formulaire de paiement au client.
requires_confirmationUne méthode est attachée, en attente de confirmation.Appeler /confirm/ ou passer confirm: true à la création.
requires_actionL'opérateur demande une action supplémentaire (3DS, redirect).Rediriger le client vers next_action.redirect_url.
pendingEn attente de réponse de l'opérateur (mobile money).Attendre le webhook payment_intent.succeeded.
processingLe paiement est en cours de traitement chez l'opérateur.Ne rien faire — attendre le webhook.
requires_captureAutorisé — capture manuelle requise (capture différée).Appeler /capture/ avant expiration.
succeededPaiement réussi. Une Transaction a été créée.Livrer le service/produit.
canceledAnnulé définitivement. Non recouvrable.Créer une nouvelle Intention de Paiement si besoin.

Endpoints

MéthodeEndpointDescription
POST/payment-intents/Créer une Intention de Paiement
GET/payment-intents/Lister les Intentions de Paiement (paginé, filtrable)
GET/payment-intents/{id}/Récupérer une Intention de Paiement par son ID
PATCH/payment-intents/{id}/Mettre à jour une Intention de Paiement (avant confirmation)
POST/payment-intents/{id}/confirm/Confirmer le paiement et déclencher le traitement
POST/payment-intents/{id}/capture/Capturer un paiement autorisé (capture différée)
POST/payment-intents/{id}/cancel/Annuler définitivement

Schéma de l’objet

Response Objet PaymentIntent
Structure complète retournée par tous les endpoints GET et POST de cette ressource.
json
{
  "id": "pay_3Nx8mLKZ2eZvKYlo28m",
  "object": "payment_intent",
  "reference": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "amount": 15000,
  "amount_capturable": 0,
  "amount_received": 0,
  "currency": "XAF",
  "status": "requires_payment_method",
  "payment_method": null,
  "payment_method_types": ["mobile_money", "bank_card"],
  "customer": "cus_xxxxxxxx",
  "description": "Commande #CMD-2026-042",
  "receipt_email": "client@email.com",
  "category": "product",
  "confirm": false,
  "capture_method": "automatic",
  "next_action": null,
  "url": "https://checkout.sangho.com/pay/pay_xxx",
  "livemode": true,
  "metadata": {
    "order_id": "CMD-2026-042"
  },
  "created_at": "2026-03-01T10:00:00Z",
  "updated_at": "2026-03-01T10:00:00Z"
}

Créer une Intention de paiement

Instancie une nouvelle Intention de paiement dans le statut requires_payment_method. C’est la première étape de tout flux de paiement avec Sangho.

POST Corps de la requête
amount Requis
integer centimes ex : 15000

Montant à collecter, exprimé en centimes de la devise. Pour les devises sans décimales telles que XAF/XOF, 1 FCFA = 1 centime (pas de décimales). Pour USD/EUR, 1 unité = 100 centimes.

Le montant minimum accepté est de 100 centimes (1 XAF). Le montant maximum dépend de votre plafond de transaction configuré sur votre App. Utilisez toujours des entiers — les valeurs flottantes sont rejetées avec une erreur 400.

currency Requis
string ISO 4217 ex : XAF

Code ISO 4217 de la devise du paiement. Sangho supporte plus de 132 devises dont XAF, USD, EUR

Consultez votre configuration App pour la liste des devises autorisées. Une fois créé, le champ currency d’une Intention de Paiement ne peut plus être modifié.

payment_method_types Optionnel
array[string] ex : [“mobile_money”, “bank_card”]

Liste des méthodes de paiement autorisées pour cette Intention. Si omis, toutes les méthodes actives de votre App sont disponibles.

En savoir plus

Valeurs possibles : mobile_money, bank_card, paypal. Restreindre les types améliore l’expérience utilisateur sur la page de paiement et réduit les erreurs liées à des méthodes non disponibles dans une région donnée.

customer Optionnel
string ID Customer ex : cus_xxxxxxxx

Identifiant ou email d’un objet Customer existant à associer à ce paiement. Permet de retrouver l’historique des paiements d’un client.

En savoir plus

Si vous passez un email non encore enregistré, Sangho crée automatiquement un Customer. Si vous passez un ID et que le Customer n’existe pas, l’API retourne une erreur 404. Associer un Customer vous permet aussi d’envoyer automatiquement un reçu si receipt_email n’est pas fourni.

description Optionnel
string

Description interne du paiement non visible par l’acheteur sur la page de paiement. Utile pour retrouver un paiement dans votre dashboard ou via l’API.

En savoir plus

Max 500 caractères. Cette description apparaît dans les logs et exports CSV du dashboard, mais pas sur les reçus ni sur la page checkout.

receipt_email Optionnel
string email ex : client@email.com

Adresse email à laquelle Sangho enverra le reçu de paiement automatiquement après un paiement réussi.

En savoir plus

Si non fourni et qu’un Customer est associé, l’email du Customer est utilisé par défaut. Pour désactiver l’envoi de reçu, passez explicitement null.

confirm Optionnel
boolean défaut : false

Si true, tente de confirmer le paiement immédiatement après la création. Requiert que payment_method soit fourni dans la même requête.

En savoir plus

Utile pour les paiements serveur-à-serveur où vous disposez déjà de la méthode de paiement. Si la confirmation échoue, le PaymentIntent passe en requires_payment_method — il n’est pas annulé.

payment_method Optionnel
string ID PaymentMethod ex : pm_xxxxxxxx

ID d’une méthode de paiement existante à attacher immédiatement au PaymentIntent.

En savoir plus

Nécessaire si confirm: true. La méthode doit appartenir à l’App ou au Customer associé.

category Optionnel
string défaut : product

Catégorie métier du paiement, utilisée pour les statistiques et la conformité réglementaire OHADA. Valeurs : product, service, donation, invoice.

capture_method Optionnel
string défaut : automatic

Détermine si le montant est capturé automatiquement après autorisation, ou si vous souhaitez capturer manuellement plus tard.

En savoir plus

automatic : capture immédiatement après confirmation (flux standard). manual : autorise uniquement — vous devez appeler /capture/ sous 7 jours, sinon l’autorisation est annulée automatiquement. La capture manuelle est utile pour les réservations, précommandes ou validations métier.

metadata Optionnel
object

Dictionnaire clé/valeur pour stocker vos propres données associées au PaymentIntent — référence commande, ID utilisateur interne, etc.

En savoir plus

Maximum 50 clés, chaque clé et valeur étant des strings de max 500 caractères. Les métadonnées sont retournées dans tous les webhooks liés à ce PaymentIntent. Elles ne sont pas visibles par le client final.

Créer une Intention de Paiement

bash
curl -X POST https://api.sangho.com/v1/payment-intents/ \
  -H "Authorization: Bearer sk_live_xxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: uuid-unique" \
  -d '{
    "amount": 15000,
    "currency": "XAF",
    "payment_method_types": ["mobile_money", "bank_card"],
    "customer": "cus_xxxxxxxx",
    "description": "Commande #CMD-2026-042",
    "metadata": { "order_id": "CMD-2026-042" }
  }'
Response 201 Created
Statut requires_payment_method. Le champ url contient l'URL de checkout vers laquelle rediriger votre client.
json
{
  "id": "pay_3Nx8mLKZ2eZvKYlo28m",
  "object": "payment_intent",
  "amount": 15000,
  "currency": "XAF",
  "status": "requires_payment_method",
  "payment_method_types": ["mobile_money", "bank_card"],
  "customer": "cus_xxxxxxxx",
  "description": "Commande #CMD-2026-042",
  "url": "https://checkout.sangho.com/pay/pay_3Nx8mLKZ",
  "livemode": true,
  "metadata": { "order_id": "CMD-2026-042" },
  "created_at": "2026-03-01T10:00:00Z",
  "updated_at": "2026-03-01T10:00:00Z"
}
Response 400 Bad Request
Le corps contient des données invalides. Le champ errors détaille chaque champ en erreur.
Causes fréquentes : montant ≤ 0, devise non supportée, ou montant sous la limite minimale de l'App.
json
{
  "error": {
    "type": "validation_error",
    "code": "invalid_amount",
    "message": "Le montant doit être un entier positif supérieur à 100.",
    "param": "amount"
  }
}
Response 401 Unauthorized
La clé API est absente, expirée ou invalide.
Ne jamais exposer votre clé secrète en front-end ou dans un dépôt Git public.
json
{
  "error": {
    "type": "authentication_error",
    "code": "invalid_api_key",
    "message": "Aucune clé API valide fournie."
  }
}

Lister les Intentions de paiement

Retourne une liste paginée de toutes les Intentions de paiement de votre App, triés par date de création décroissante par défaut. Supporte le filtrage, la recherche et le tri.

GET Paramètres de requête (query)
status Optionnel
string query

Filtrer les Intentions par statut. Accepte les valeurs du cycle de vie.

En savoir plus

Vous pouvez passer plusieurs valeurs séparées par une virgule : status=succeeded,canceled.

currency Optionnel
string ISO 4217 query ex : XAF

Filtrer par code devise ISO 4217.

customer Optionnel
string query

Filtrer par ID ou email d’un Customer. Retourne tous les paiements associés à ce client.

En savoir plus

Vous pouvez passer soit l’ID (cus_xxx) soit l’adresse email exacte. La recherche par email est sensible à la casse.

created_after Optionnel
string ISO 8601 query ex : 2026-01-01T00:00:00Z

Retourne uniquement les Intentions de paiement créés après cette date/heure (inclusif).

created_before Optionnel
string ISO 8601 query ex : 2026-12-31T23:59:59Z

Retourne uniquement les Intentions de paiement créés avant cette date/heure (inclusif).

ordering Optionnel
string query défaut : -created_at

Champ de tri. Préfixez avec - pour un ordre décroissant.

En savoir plus

Champs triables : created_at, amount, status. Exemples : ordering=amount (croissant), ordering=-amount (décroissant).

page Optionnel
integer query défaut : 1

Numéro de la page à retourner. La pagination commence à 1.

En savoir plus

Si la page demandée dépasse le nombre total de pages, une liste vide est retournée (pas d’erreur 404).

page_size Optionnel
integer query défaut : 20

Nombre de résultats par page. Minimum : 1. Maximum : 100.

En savoir plus

Pour récupérer tous les Intentions de paiement d’une période, utilisez page_size=100 et itérez tant que pagination.next est non nul dans la réponse.

Pagination

Tous les endpoints de liste Sangho utilisent une pagination par offset. La réponse inclut les métadonnées dans un objet pagination.

Itérer sur toutes les pages

Continuez à incrémenter page tant que pagination.next est non nul. La propriété next contient l’URL complète de la page suivante, prête à être appelée directement.

Lister les Intentions de paiement

bash
# Paiements réussis en XAF, 50 par page
curl "https://api.sangho.com/v1/payment-intents/?status=succeeded&currency=XAF&page_size=50" \
  -H "Authorization: Bearer sk_live_xxxx"
Response 200 OK — Liste paginée
L'objet retourné contient data (liste) et pagination (métadonnées de navigation).
json
{
  "object": "list",
  "data": [
    {
      "id": "pay_3Nx8mLKZ2eZvKYlo28m",
      "object": "payment_intent",
      "amount": 15000,
      "currency": "XAF",
      "status": "succeeded",
      "customer": "cus_xxxxxxxx",
      "created_at": "2026-03-01T10:00:00Z"
    }
  ],
  "pagination": {
    "count": 142,
    "total_pages": 3,
    "page": 1,
    "page_size": 50,
    "previous": null,
    "next": "https://api.sangho.com/v1/payment-intents/?page=2&page_size=50&status=succeeded"
  }
}

Confirmer une Intention de paiement

Déclenche le traitement du paiement. Passe le PaymentIntent en processing (ou requires_action si une étape supplémentaire est nécessaire).

POST Corps de la confirmation (POST)
payment_method Optionnel
string ID PaymentMethod

ID d’une méthode de paiement à attacher avant la confirmation. Requis si le PaymentIntent est en requires_payment_method.

Toujours utiliser une Idempotency-Key

Appelez /confirm/ avec un en-tête Idempotency-Key unique pour éviter les doubles confirmations en cas de timeout réseau. La clé doit être unique par PaymentIntent.

Capturer (capture différée)

Capture un montant autorisé. Disponible uniquement si capture_method: “manual” et statut requires_capture. Vous pouvez capturer un montant inférieur au montant autorisé.

POST Corps de la capture (POST)
amount_to_capture Optionnel
integer centimes

Montant à capturer. Doit être ≤ amount_capturable. Si omis, capture le montant total autorisé.

En savoir plus

Capturer un montant partiel annule automatiquement le reliquat. Exemple : autorisation de 20 000 XAF, capture de 15 000 → 5 000 annulés automatiquement.

Annuler

Annule définitivement le PaymentIntent. Irréversible. Si le PaymentIntent était en requires_capture, l’autorisation est libérée chez l’opérateur.

Annulation irréversible

Une Intention de Paiement annulée ne peut pas être réactivée. Si vous souhaitez relancer le paiement, vous devez créer une nouvelle Intention de paiement.

Confirmer

bash
curl -X POST https://api.sangho.com/v1/payment-intents/pay_xxx/confirm/ \
  -H "Authorization: Bearer sk_live_xxxx" \
  -H "Idempotency-Key: confirm-pay_xxx-1234" \
  -H "Content-Type: application/json" \
  -d '{ "payment_method": "pm_xxxxxxxx" }'
Response 200 OK — Confirmé
Le statut passe à processing ou requires_action si une redirection opérateur est requise (next_action non nul).
json
{
  "id": "pay_3Nx8mLKZ2eZvKYlo28m",
  "status": "processing",
  "next_action": null,
  "updated_at": "2026-03-01T10:01:00Z"
}
Response 422 — État invalide
Le PaymentIntent n'est pas dans un état confirmable (déjà succeeded, canceled, ou en processing).
Vérifiez le statut actuel avant d'appeler /confirm/. Un GET préalable est recommandé.
json
{
  "error": {
    "type": "invalid_request_error",
    "code": "payment_intent_unexpected_state",
    "message": "Ce PaymentIntent est déjà en statut succeeded."
  }
}

Capture partielle

bash
curl -X POST https://api.sangho.com/v1/payment-intents/pay_xxx/capture/ \
  -H "Authorization: Bearer sk_live_xxxx" \
  -H "Content-Type: application/json" \
  -d '{ "amount_to_capture": 12000 }'
Response 200 OK — Capturé
Le paiement est capturé. amount_received reflète le montant effectivement collecté. Le reliquat éventuel est annulé.
json
{
  "id": "pay_3Nx8mLKZ2eZvKYlo28m",
  "status": "succeeded",
  "amount": 20000,
  "amount_received": 12000,
  "amount_capturable": 0,
  "updated_at": "2026-03-01T10:05:00Z"
}