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

# Créer une Checkout Session

> Créez une session de paiement pour rediriger vos clients vers la page de paiement hébergée Yabetoo

## Qu'est-ce qu'une Checkout Session ?

Une **Checkout Session** représente la session de paiement de votre client. Elle contrôle ce que le client voit sur la page de paiement : les produits, le montant, la devise, et les options disponibles.

<Info>
  **Format de l'identifiant** : `cs_` suivi de 24 caractères alphanumériques.

  Exemple : `cs_abc123def456ghi789jkl012`
</Info>

## Modes de la session

<CardGroup cols={3}>
  <Card title="payment" icon="credit-card">
    **Paiement unique**

    Pour les achats ponctuels de produits ou services.
  </Card>

  <Card title="subscription" icon="repeat">
    **Abonnement**

    Pour créer un abonnement récurrent avec facturation automatique.
  </Card>

  <Card title="setup" icon="gear">
    **Configuration**

    Pour enregistrer un moyen de paiement sans effectuer de paiement immédiat.
  </Card>
</CardGroup>

## Créer une Checkout Session

### Requête de base

```bash theme={null}
curl -X POST https://api.yabetoo.com/v1/checkout/sessions \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "success_url": "https://votre-site.com/success",
    "cancel_url": "https://votre-site.com/cancel",
    "line_items": [
      {
        "price_data": {
          "currency": "XOF",
          "unit_amount": 15000,
          "product_data": {
            "name": "T-shirt Premium"
          }
        },
        "quantity": 2
      }
    ]
  }'
```

### Paramètres requis

| Paramètre     | Type   | Description                              |
| ------------- | ------ | ---------------------------------------- |
| `success_url` | string | URL de redirection après paiement réussi |
| `line_items`  | array  | Liste des articles à acheter             |

### Paramètres optionnels

| Paramètre               | Type    | Description                                               |
| ----------------------- | ------- | --------------------------------------------------------- |
| `cancel_url`            | string  | URL de redirection si le client annule                    |
| `mode`                  | string  | `payment`, `subscription`, ou `setup` (défaut: `payment`) |
| `customer`              | string  | ID d'un client existant (`cus_xxx`)                       |
| `customer_email`        | string  | Email du client (pré-remplit le formulaire)               |
| `client_reference_id`   | string  | Votre référence interne (ex: ID commande)                 |
| `allow_promotion_codes` | boolean | Autoriser les codes promo                                 |
| `locale`                | string  | Langue de la page (`fr`, `en`, etc.)                      |
| `expires_at`            | number  | Timestamp Unix d'expiration                               |
| `metadata`              | object  | Données personnalisées                                    |

## Définir les articles (line\_items)

Vous avez deux options pour définir les articles :

<Tabs>
  <Tab title="Prix inline (price_data)">
    Définissez le prix directement dans la requête :

    ```json theme={null}
    {
      "line_items": [
        {
          "price_data": {
            "currency": "XOF",
            "unit_amount": 25000,
            "product_data": {
              "name": "Formation JavaScript",
              "description": "Accès complet à la formation",
              "images": ["https://example.com/image.jpg"]
            }
          },
          "quantity": 1
        }
      ]
    }
    ```
  </Tab>

  <Tab title="Prix existant (price)">
    Référencez un prix créé dans votre catalogue :

    ```json theme={null}
    {
      "line_items": [
        {
          "price": "price_abc123def456",
          "quantity": 1
        }
      ]
    }
    ```

    <Tip>
      Utilisez des prix pré-créés pour une gestion centralisée de votre catalogue.
    </Tip>
  </Tab>
</Tabs>

### Structure du line\_item

| Champ                 | Type   | Description                              |
| --------------------- | ------ | ---------------------------------------- |
| `price_data`          | object | Prix défini inline (voir ci-dessous)     |
| `price`               | string | ID d'un prix existant (`price_xxx`)      |
| `quantity`            | number | Quantité (minimum 1)                     |
| `adjustable_quantity` | object | Permet au client de modifier la quantité |

### Structure de price\_data

| Champ          | Type   | Description                       |
| -------------- | ------ | --------------------------------- |
| `currency`     | string | Code devise (`XOF`, `EUR`, `USD`) |
| `unit_amount`  | number | Prix unitaire                     |
| `product_data` | object | Informations sur le produit       |
| `recurring`    | object | Pour les abonnements uniquement   |

### Structure de product\_data

| Champ         | Type   | Description             |
| ------------- | ------ | ----------------------- |
| `name`        | string | Nom du produit (requis) |
| `description` | string | Description             |
| `images`      | array  | URLs des images         |
| `metadata`    | object | Données personnalisées  |

## Abonnements récurrents

Pour créer un abonnement, utilisez `mode: "subscription"` et ajoutez `recurring` dans `price_data` :

```json theme={null}
{
  "mode": "subscription",
  "success_url": "https://votre-site.com/success",
  "line_items": [
    {
      "price_data": {
        "currency": "XOF",
        "unit_amount": 9900,
        "product_data": {
          "name": "Abonnement Pro"
        },
        "recurring": {
          "interval": "month",
          "interval_count": 1
        }
      },
      "quantity": 1
    }
  ]
}
```

### Intervalles disponibles

| Interval | Description              |
| -------- | ------------------------ |
| `day`    | Facturation quotidienne  |
| `week`   | Facturation hebdomadaire |
| `month`  | Facturation mensuelle    |
| `year`   | Facturation annuelle     |

## Options avancées

### Collecter les adresses

```json theme={null}
{
  "billing_address_collection": "required",
  "shipping_address_collection": {
    "allowed_countries": ["CG", "CD", "CI", "SN"]
  }
}
```

### Collecter le numéro de téléphone

```json theme={null}
{
  "phone_number_collection": {
    "enabled": true
  }
}
```

### Autoriser les codes promo

```json theme={null}
{
  "allow_promotion_codes": true
}
```

### Appliquer un code promo automatiquement

```json theme={null}
{
  "discounts": [
    {
      "promotion_code": "promo_abc123"
    }
  ]
}
```

### Personnaliser le bouton de paiement

```json theme={null}
{
  "submit_type": "pay"
}
```

| Valeur   | Texte du bouton               |
| -------- | ----------------------------- |
| `auto`   | Automatique selon le contexte |
| `pay`    | "Payer"                       |
| `book`   | "Réserver"                    |
| `donate` | "Faire un don"                |

### Quantité ajustable

Permettez au client de modifier la quantité sur la page de paiement :

```json theme={null}
{
  "line_items": [
    {
      "price_data": {
        "currency": "XOF",
        "unit_amount": 5000,
        "product_data": { "name": "Article" }
      },
      "quantity": 1,
      "adjustable_quantity": {
        "enabled": true,
        "minimum": 1,
        "maximum": 10
      }
    }
  ]
}
```

## Exemple complet

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.yabetoo.com/v1/checkout/sessions \
    -H "Authorization: Bearer sk_live_..." \
    -H "Content-Type: application/json" \
    -d '{
      "mode": "payment",
      "success_url": "https://votre-site.com/success?session_id={CHECKOUT_SESSION_ID}",
      "cancel_url": "https://votre-site.com/cancel",
      "customer_email": "client@example.com",
      "client_reference_id": "order_12345",
      "allow_promotion_codes": true,
      "billing_address_collection": "required",
      "phone_number_collection": { "enabled": true },
      "locale": "fr",
      "metadata": {
        "order_id": "12345",
        "source": "website"
      },
      "line_items": [
        {
          "price_data": {
            "currency": "XOF",
            "unit_amount": 25000,
            "product_data": {
              "name": "Écran HD",
              "description": "Écran 24 pouces Full HD",
              "images": ["https://example.com/ecran.jpg"]
            }
          },
          "quantity": 1
        },
        {
          "price_data": {
            "currency": "XOF",
            "unit_amount": 5000,
            "product_data": {
              "name": "Câble HDMI"
            }
          },
          "quantity": 2
        }
      ]
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://api.yabetoo.com/v1/checkout/sessions", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: "Bearer sk_live_...",
    },
    body: JSON.stringify({
      mode: "payment",
      success_url: "https://votre-site.com/success?session_id={CHECKOUT_SESSION_ID}",
      cancel_url: "https://votre-site.com/cancel",
      customer_email: "client@example.com",
      allow_promotion_codes: true,
      line_items: [
        {
          price_data: {
            currency: "XOF",
            unit_amount: 25000,
            product_data: {
              name: "Écran HD",
            },
          },
          quantity: 1,
        },
      ],
    }),
  });

  const session = await response.json();
  // Rediriger vers session.url
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.yabetoo.com/v1/checkout/sessions",
      headers={
          "Authorization": "Bearer sk_live_...",
          "Content-Type": "application/json"
      },
      json={
          "mode": "payment",
          "success_url": "https://votre-site.com/success",
          "cancel_url": "https://votre-site.com/cancel",
          "line_items": [
              {
                  "price_data": {
                      "currency": "XOF",
                      "unit_amount": 25000,
                      "product_data": {
                          "name": "Écran HD"
                      }
                  },
                  "quantity": 1
              }
          ]
      }
  )

  session = response.json()
  ```

  ```php PHP theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
      CURLOPT_URL => "https://api.yabetoo.com/v1/checkout/sessions",
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_POST => true,
      CURLOPT_HTTPHEADER => [
          "Authorization: Bearer sk_live_...",
          "Content-Type: application/json"
      ],
      CURLOPT_POSTFIELDS => json_encode([
          "mode" => "payment",
          "success_url" => "https://votre-site.com/success",
          "cancel_url" => "https://votre-site.com/cancel",
          "line_items" => [
              [
                  "price_data" => [
                      "currency" => "XOF",
                      "unit_amount" => 25000,
                      "product_data" => [
                          "name" => "Écran HD"
                      ]
                  ],
                  "quantity" => 1
              ]
          ]
      ])
  ]);

  $response = curl_exec($curl);
  $session = json_decode($response, true);
  ```
</CodeGroup>

## Réponse

```json theme={null}
{
  "id": "cs_abc123def456ghi789",
  "object": "checkout.session",
  "mode": "payment",
  "status": "open",
  "payment_status": "unpaid",
  "url": "https://checkout.yabetoo.com/cs_abc123def456ghi789",
  "success_url": "https://votre-site.com/success?session_id={CHECKOUT_SESSION_ID}",
  "cancel_url": "https://votre-site.com/cancel",
  "customer_email": "client@example.com",
  "client_reference_id": "order_12345",
  "amount_subtotal": 35000,
  "amount_total": 35000,
  "amount_discount": 0,
  "currency": "XOF",
  "allow_promotion_codes": true,
  "line_items": [
    {
      "price_data": {
        "currency": "XOF",
        "unit_amount": 25000,
        "product_data": { "name": "Écran HD" }
      },
      "quantity": 1,
      "amount_subtotal": 25000,
      "amount_total": 25000
    },
    {
      "price_data": {
        "currency": "XOF",
        "unit_amount": 5000,
        "product_data": { "name": "Câble HDMI" }
      },
      "quantity": 2,
      "amount_subtotal": 10000,
      "amount_total": 10000
    }
  ],
  "metadata": {
    "order_id": "12345",
    "source": "website"
  },
  "expires_at": "2024-01-15T12:00:00.000Z",
  "created_at": "2024-01-15T11:00:00.000Z"
}
```

### Champs de la réponse

| Champ             | Description                                |
| ----------------- | ------------------------------------------ |
| `id`              | Identifiant unique de la session           |
| `url`             | URL de la page de paiement                 |
| `status`          | `open`, `complete`, ou `expired`           |
| `payment_status`  | `unpaid`, `paid`, ou `no_payment_required` |
| `amount_subtotal` | Sous-total avant réductions                |
| `amount_total`    | Montant total à payer                      |
| `amount_discount` | Montant des réductions appliquées          |

## Rediriger le client

Une fois la session créée, redirigez le client vers l'URL de paiement :

```javascript theme={null}
// Côté serveur : créer la session
const session = await createCheckoutSession(/* ... */);

// Côté client : rediriger
window.location.href = session.url;
```

## Après le paiement

### Redirection

Après le paiement, le client est redirigé vers `success_url` avec l'ID de session :

```
https://votre-site.com/success?session_id=cs_abc123def456
```

### Vérifier le statut

<Warning>
  Ne faites jamais confiance uniquement à la redirection. Vérifiez toujours le statut de la session côté serveur.
</Warning>

```javascript theme={null}
// Récupérer l'ID de session depuis l'URL
const sessionId = new URLSearchParams(window.location.search).get("session_id");

// Vérifier le statut côté serveur
const response = await fetch(
  "https://api.yabetoo.com/v1/checkout/sessions/" + sessionId,
  {
    headers: {
      Authorization: "Bearer sk_live_...",
    },
  }
);

const session = await response.json();

if (session.status === "complete" && session.payment_status === "paid") {
  // Paiement confirmé - traiter la commande
}
```

### Webhooks

Pour une intégration robuste, utilisez les webhooks pour recevoir les notifications de paiement :

```json theme={null}
{
  "type": "checkout.session.completed",
  "data": {
    "object": {
      "id": "cs_abc123def456",
      "status": "complete",
      "payment_status": "paid",
      "amount_total": 35000,
      "currency": "XOF"
    }
  }
}
```

Voir [Documentation Webhooks](/fr/developer-tools/webhook/overview) pour plus de détails.

## Statuts de la session

| Statut     | Description                               |
| ---------- | ----------------------------------------- |
| `open`     | Session active, en attente de paiement    |
| `complete` | Paiement réussi                           |
| `expired`  | Session expirée (non payée dans le délai) |

## Bonnes pratiques

<AccordionGroup>
  <Accordion title="Sécurité">
    * Créez toujours les sessions côté serveur
    * Ne stockez jamais les clés API côté client
    * Vérifiez le statut via l'API ou les webhooks
  </Accordion>

  <Accordion title="Expérience utilisateur">
    * Pré-remplissez l'email si vous le connaissez
    * Utilisez `client_reference_id` pour lier à votre commande
    * Personnalisez le `submit_type` selon le contexte
  </Accordion>

  <Accordion title="Gestion des erreurs">
    * Gérez le cas où le client annule
    * Prévoyez l'expiration de la session
    * Utilisez les webhooks pour les cas edge
  </Accordion>
</AccordionGroup>

## Prochaines étapes

<CardGroup cols={2}>
  <Card title="Webhooks" icon="bell" href="/fr/developer-tools/webhook/overview">
    Recevez des notifications en temps réel
  </Card>

  <Card title="Codes promo" icon="percent" href="/fr/products/coupons">
    Appliquez des réductions à vos sessions
  </Card>
</CardGroup>
