> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pulse-sell.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Checkout et paiement

> Générer un lien de paiement, avec code promo, variante, client prérempli et suivi marketing.

`POST /checkout` crée l'adresse de la **page de paiement hébergée** de votre boutique. Votre client y choisit son moyen de paiement (mobile money, carte…) : aucune donnée de paiement ne transite jamais par votre serveur ni par l'API.

> [!NOTE]
>
> Permission : `checkout.write`. Compteur de débit séparé (100 par minute). Référence : [Checkout](https://docs.pulse-sell.com/api-reference/checkout).

## Un lien simple

```bash theme={null}
curl -X POST https://api.pulse-sell.com/v1/checkout \
  -H "Authorization: Bearer $PULSESELL_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: cart-8841" \
  -d '{ "product_id": "cm1prod001", "quantity": 2 }'
```

```json theme={null}
{
  "data": {
    "checkout_url": "https://ma-boutique.pulse-sell.com/buy/guide-complet?quantity=2",
    "product_id": "cm1prod001",
    "quantity": 2
  }
}
```

Redirigez votre client vers `checkout_url`. Le produit doit être **publié** et appartenir à la boutique de la clé, sinon `404`.

## Avec un code promo

Passez `discount_code` : le code est vérifié **avant** de créer le lien, avec exactement les règles de la page de paiement.

```json theme={null}
{ "product_id": "cm1prod001", "discount_code": "LANCE20" }
```

Si le code est valide, la réponse détaille la remise et l'adresse contient `?promo=LANCE20` : la page de paiement l'applique automatiquement.

```json theme={null}
{
  "data": {
    "checkout_url": "https://ma-boutique.pulse-sell.com/buy/guide-complet?promo=LANCE20",
    "discount": { "code": "LANCE20", "type": "percentage", "value": 20, "discount_amount": { "value": 5000, "currency": "XOF" } }
  }
}
```

Si le code est inconnu, inactif, expiré ou épuisé : `422 invalid_discount_code` avec la raison. Vous ne fabriquez donc jamais un lien dont le code serait refusé. Pour un produit gratuit, aucun code ne s'applique.

> [!WARNING]
>
> Le prix ne voyage jamais dans l'adresse. Le serveur recalcule et revalide tout au moment de l'achat : modifier l'adresse ne change rien au montant payé.

## Champs optionnels

**variant\_id** `string`

Variante du produit (taille, édition…). `404` si elle n'appartient pas au produit.

**quantity** `integer` (default: 1)

De 1 à 100.

**customer** `object`

`email`, `first_name`, `last_name`, `phone` : préremplit le formulaire de paiement.

**ps\_ref** `string`

Référence libre (80 caractères) pour retrouver l'origine d'une vente, par exemple votre identifiant de panier.

**utm\_source / utm\_medium / utm\_campaign** `string`

Suivi marketing conservé avec la vente.

## Savoir si le client a payé

Ne vous fiez pas à la redirection de retour du client : il peut fermer son navigateur. La source de vérité est l'événement [`sale.completed`](https://docs.pulse-sell.com/pulses/events#sale-completed), envoyé par Pulse dès le paiement confirmé. Vous pouvez aussi lire la vente avec `GET /sales/{id}` et vérifier `payment_status`.

> [!TIP]
>
> Utilisez la même `Idempotency-Key` pour un même panier : si votre serveur réessaie, il récupère le même lien au lieu d'en créer un second.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.