# Composer une facture

`POST https://api.payiz.app/v1/invoices`

Demande une clé secrète qui porte le geste « Factures · gérer ».

Elle naît en brouillon : pas de numéro, pas de lien, rien ne part.

Une ligne peut venir de votre catalogue (« product », « price ») : elle garde tout de même sa désignation et son prix, ce qui a été vendu ce jour-là.

## Les en-têtes

| Champ | Type | Requis | Ce que c'est |
| --- | --- | --- | --- |
| `Idempotency-Key` | texte | — | Conseillée : rejouée, la même clé rend la première réponse au lieu de refaire le geste. |

## Ce qu'on envoie

Un corps JSON.

| Champ | Type | Requis | Ce que c'est |
| --- | --- | --- | --- |
| `customer` | texte | oui | Le client facturé : un client de l’espace, pas archivé. |
| `currency` | texte | — | Sans précision : la monnaie de l’espace. |
| `lines` | liste de objet | oui | Ses lignes : de une à cinquante. |
| `due_date` | entier | — | L’échéance, en secondes depuis 1970. Sans elle, le délai réglé chez Payiz. |
| `note` | texte | — | Ce que la facture dit au client, sous les lignes. |
| `fees_paid_by` | « merchant » · « customer » | — | « customer » : les frais s’ajoutent au paiement, pas à la facture. |
| `template` | « classic » · « banner » · « detailed » · « ticket » | — | Le dessin voulu pour celle-ci. Sans rien, celui de la boutique. |

## Ce qu'on reçoit

`201` · un objet `invoice`

| Champ | Type | Requis | Ce que c'est |
| --- | --- | --- | --- |
| `object` | « invoice » | — | Le genre de l’objet rendu : il ne change jamais. |
| `id` | texte | — | Un identifiant préfixé « fac_ », par exemple fac_01j9xp6vb2n4rtw8kd3m. |
| `number` | texte ou null | — | Son numéro, donné à l’émission et jamais avant : un brouillon n’en a pas. |
| `customer` | texte | — | Le client facturé. |
| `customer_name` | texte | — | Son nom. |
| `customer_email` | texte ou null | — | L’adresse où la facture part. |
| `customer_phone` | texte ou null | — | Son numéro, masqué. |
| `status` | « draft » · « open » · « paid » · « canceled » | — | « draft » : se compose encore ; « open » : émise, elle attend d’être payée ; « paid » : son lien a encaissé ; « canceled » : son lien n’encaisse plus. |
| `overdue` | vrai ou faux | — | L’échéance est passée et rien n’est payé. Ce n’est pas un statut de plus. |
| `currency` | texte | — | Le code ISO 4217, en majuscules. |
| `subtotal` | entier | — | Hors taxe, remises déduites. |
| `total_discount` | entier | — | Les remises de toutes les lignes. |
| `total_tax` | entier | — | La taxe de toutes les lignes. |
| `total` | entier | — | Ce que le client paie : le lien encaisse celui-là. |
| `fees_paid_by` | « merchant » · « customer » | — | Qui porte la commission sur le paiement de la facture. |
| `template` | « classic » · « banner » · « detailed » · « ticket » ou null | — | Le dessin voulu pour celle-ci ; null : celui de la boutique, figé à l’émission. |
| `note` | texte ou null | — | Ce que la facture dit au client, sous les lignes. |
| `lines` | liste de objet | — | Ses lignes, dans l’ordre. |
| `payment_link` | texte ou null | — | Le lien de paiement né à l’émission : c’est lui qui la règle. |
| `payment_url` | texte ou null | — | L’adresse où le client paie, celle que l’e-mail et le PDF portent. |
| `payment` | texte ou null | — | Le paiement qui l’a réglée. |
| `due_date` | entier ou null | — | L’échéance. |
| `finalized_at` | entier ou null | — | Quand elle a été émise. |
| `sent_at` | entier ou null | — | Quand elle est partie chez le client par e-mail. Émise n’est pas envoyée : null tant qu’elle ne l’est pas. |
| `paid_at` | entier ou null | — | Des secondes depuis 1970, ou null. |
| `canceled_at` | entier ou null | — | Des secondes depuis 1970, ou null. |
| `cancellation_reason` | texte ou null | — | Le motif de l’annulation. |
| `created` | entier ou null | — | Des secondes depuis 1970, ou null. |
| `livemode` | vrai ou faux | — | Faux en mode test : aucun argent ne circule. |

## La demande

```bash
curl https://api.payiz.app/v1/invoices \
  -H "Authorization: Bearer sk_test_…" \
  -H "Idempotency-Key: factures-creer-01" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": "cli_01j9xn4rt6m8wqv2hc5d",
    "currency": "XOF",
    "lines": [
      {
        "description": "Pagne wax 6 yards",
        "detail": "bleu indigo",
        "product": "prd_01j9xm2hp7t4wzq6vc3k",
        "price": "prx_01j9xm3kq8v2tzr5wd7n",
        "quantity": 2,
        "unit_amount": 10000
      },
      {
        "description": "Retouches",
        "detail": "ourlet et cintrage",
        "quantity": 1,
        "unit_amount": 4000,
        "discount": 1000
      }
    ],
    "note": "Merci de votre confiance."
  }'
```

## La réponse

```json
{
  "object": "invoice",
  "id": "fac_01j9xp6vb2n4rtw8kd3m",
  "number": "FAC-2026-0045",
  "customer": "cli_01j9xn4rt6m8wqv2hc5d",
  "customer_name": "Awa Houénou",
  "customer_email": "awa.h@exemple.bj",
  "customer_phone": "+229 01 •• •• 21 07",
  "status": "open",
  "overdue": false,
  "currency": "XOF",
  "subtotal": 23000,
  "total_discount": 1000,
  "total_tax": 4140,
  "total": 27140,
  "fees_paid_by": "merchant",
  "template": null,
  "note": "Merci de votre confiance.",
  "lines": [
    {
      "object": "invoice_line",
      "id": "lgf_01j9xp8wd3k5tzm7qr2v",
      "description": "Pagne wax 6 yards",
      "detail": "bleu indigo",
      "product": "prd_01j9xm2hp7t4wzq6vc3k",
      "price": "prx_01j9xm3kq8v2tzr5wd7n",
      "quantity": 2,
      "unit_amount": 10000,
      "discount": 0,
      "tax_rate_bps": 1800,
      "amount": 20000,
      "tax": 3600
    },
    {
      "object": "invoice_line",
      "id": "lgf_01j9xp8wd3k5tzm7qr2w",
      "description": "Retouches",
      "detail": "ourlet et cintrage",
      "product": null,
      "price": null,
      "quantity": 1,
      "unit_amount": 4000,
      "discount": 1000,
      "tax_rate_bps": 1800,
      "amount": 3000,
      "tax": 540
    }
  ],
  "payment_link": "lnk_01j9xq2mt7c4vwd8hr5n",
  "payment_url": "https://pay.payiz.app/l/fac-2026-0045-k3f8",
  "payment": null,
  "due_date": 1792594892,
  "finalized_at": 1790002892,
  "sent_at": 1790002893,
  "paid_at": null,
  "canceled_at": null,
  "cancellation_reason": null,
  "created": 1790002092,
  "livemode": false
}
```
