Factures et paiements

Un abonnement émet ses factures ; vous pouvez aussi en créer à la main. Les exemples utilisent une clé qb_test_sk_….

Cycle de vie

Statut Sens
draft Brouillon, pas encore envoyé.
open Émise, en attente de paiement.
paid Payée.
failed Le paiement a échoué.
void Annulée.
refunded Remboursée.

Facture manuelle

curl -X POST https://api.qbill.dev/v1/invoices \
  -H "x-api-key: qb_test_sk_…" \
  -H "content-type: application/json" \
  -d '{"customer":"<id du client>","amount":15000,"description":"Mise en place","due_date":"2026-11-01","status":"open"}'

amount est en XOF, avant taxes. status vaut draft ou open. Trois actions sur une facture existante :

  • POST /v1/invoices/:id/finalize : fait sortir un brouillon (draft uniquement) ;
  • POST /v1/invoices/:id/void : annule une facture draft, open ou failed ;
  • POST /v1/invoices/:id/resend : renvoie la facture au client.

Le lien de paiement

Une facture lue par l’API porte un payment_url, de la forme …/pay/<token>, null pour un brouillon. Ce lien est envoyé dans les e-mails de facture et dans l’événement invoice.created.

Encaisser avec Wave

curl -X POST https://api.qbill.dev/v1/payments/initiate \
  -H "x-api-key: qb_live_sk_…" \
  -H "content-type: application/json" \
  -d '{"invoice_id":"<id de la facture>","phone_number":"+2250700000000","provider":"wave"}'

Corps : invoice_id, phone_number, provider: "wave", et en option success_url et error_url. La réponse est { reference, status, redirectUrl } : redirigez le client vers redirectUrl. Avec une clé de test, cette page est simulée (voir Mode test). Avec le SDK Node (bientôt sur npm) : qbill.payments.initiate(...).

Votre compte Wave ou celui de QBill

  • Sur votre propre compte Wave : 0 % de frais QBill, l’argent arrive directement chez vous.
  • Sur le compte Wave de QBill : 1,5 % de chaque paiement encaissé, avec un minimum de 100 XOF (jamais plus que le paiement lui-même). Le montant est crédité sur votre portefeuille, que vous retirez vers un numéro Wave après vérification.

Rembourser

curl -X POST https://api.qbill.dev/v1/refunds \
  -H "x-api-key: qb_live_sk_…" \
  -H "content-type: application/json" \
  -d '{"invoice_id":"<id de la facture>","reason":"Demande du client"}'

Le remboursement est total et ne s’applique qu’à une facture payée ; sinon l’erreur est invoice_not_refundable. Rembourser deux fois la même facture est sans danger : la réponse porte already_refunded: true. Une clé publishable ne peut jamais rembourser (voir Authentification et clés).