Paiements

Création, lecture, annulation et statuts via l’API v1 (clé secrète).

Créer un paiement

POST/v1/payments

Scope requis : payments:write. Header Idempotency-Key obligatoire.

Request body
{
  "amount": 25000,
  "merchantReference": "order_001",
  "customer": { "name": "Client Demo" },
  "metadata": { "source": "docs" },
  "sandboxScenario": "SUCCESS"
}

L’environnement et la boutique sont déduits de la clé API. Ne pas envoyer un organizationId / storeId différent du contexte de la clé.

Réponse 201 (forme)
{
  "payment": {
    "id": "…",
    "storeId": "…",
    "environment": "SANDBOX",
    "amount": "25000",
    "currency": "MGA",
    "status": "SUCCEEDED",
    "provider": "SANDBOX_SIMULATOR",
    "operatorReference": null,
    "merchantReference": "order_001",
    "createdAt": "…"
  }
}

Récupérer un paiement

GET/v1/payments/:id

Scope : payments:read. Le paiement doit appartenir à la boutique / environnement de la clé.

cURL
curl http://localhost:4000/v1/payments/PAYMENT_ID \
  -H "Authorization: Bearer sk_test_…"

Référence opérateur (reçu du client)

Quand le paiement est réussi, operatorReference contient le numéro que le client voit sur le reçu de son opérateur : le « Ref » du SMS MVola, ou l’« ID de transaction » Orange Money. Il vaut null tant que l’opérateur ne l’a pas communiqué, et toujours null avec le simulateur Sandbox.

Il figure dans la réponse de GET /v1/payments/:id et dans la notification (webhook) payment.succeeded. Enregistrez-le avec la commande : quand un client vous donne son numéro de reçu, vous retrouvez la commande. Dans le tableau de bord, la recherche des transactions accepte aussi ce numéro.

Exemple
{
  "payment": {
    "id": "cmv…",
    "status": "SUCCEEDED",
    "provider": "MVOLA",
    "providerReference": "c0ffee00-…",
    "operatorReference": "9185680971",
    "merchantReference": "order_001"
  }
}

Statuts

Statuts de paiement utilisés par la plateforme :

CREATED
PENDING
PROCESSING
SUCCEEDED
FAILED
CANCELLED
EXPIRED
REFUNDED
PARTIALLY_REFUNDED
DISPUTED

Annuler un paiement

POST/v1/payments/:id/cancel
Body optionnel
{ "reason": "client_abandoned" }

Alternative session marchand

Le dashboard peut aussi créer via POST /api/merchant/payments (cookie + CSRF + Idempotency-Key ou idempotencyKey dans le body, avec storeId).