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

# Solde & facturation

> Vérifiez votre solde de crédits et achetez des recharges de manière programmatique.

Utilisez les points de terminaison de facturation utilisateur pour lire le solde de crédits de votre équipe et acheter des recharges avec un moyen de paiement enregistré. Les deux points de terminaison nécessitent une authentification avec votre [clé API](/get-started/authentication). Les clés invalides renvoient **402**.

## Vérifier le solde de crédits

`GET /user/credits/info` renvoie le solde de crédits de l'équipe authentifiée, une répartition par lot, les détails de l'abonnement actif, et si l'utilisation est autorisée.

Utilisez ce point de terminaison pour alimenter les widgets de facturation, les tableaux de bord d'utilisation, ou les vérifications préalables avant d'exécuter de gros travaux.

Pour les détails de l'API, voir [Obtenir des informations sur les crédits](/api-reference/billing/credits-info).

<CodeGroup>
  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://api.olostep.com/user/credits/info",
      headers={"Authorization": "Bearer <API-TOKEN>"},
  )
  print(response.json())
  ```

  ```js Node theme={null}
  const res = await fetch("https://api.olostep.com/user/credits/info", {
    headers: { Authorization: "Bearer <API-TOKEN>" },
  })
  console.log(await res.json())
  ```

  ```bash cURL theme={null}
  curl -s "https://api.olostep.com/user/credits/info" \
    -H "Authorization: Bearer <API-TOKEN>"
  ```
</CodeGroup>

### Réponse

```json theme={null}
{
  "credits": 12500,
  "breakdown": [
    {
      "purchase_kind": "Subscription",
      "allocated_units": 10000,
      "remaining_units": 8500,
      "expiry_date": 1735689600
    },
    {
      "purchase_kind": "Top-up",
      "allocated_units": 5000,
      "remaining_units": 4000,
      "expiry_date": 1743465600
    }
  ],
  "active_subscription": {
    "id": "SUB_PRO",
    "display_name": "Pro",
    "credits": 10000,
    "created_at": 1704067200
  },
  "allow_usage": true
}
```

| Champ                 | Description                                                     |
| --------------------- | --------------------------------------------------------------- |
| `credits`             | Total des crédits restants sur tous les lots non expirés        |
| `breakdown`           | Détail par lot : type, unités allouées et restantes, expiration |
| `active_subscription` | Plan actuel (repli sur `SUB_BASE` si aucun n'est actif)         |
| `allow_usage`         | Si l'équipe peut encore consommer des crédits                   |

Chaque lot dans `breakdown` a un `purchase_kind` de `Subscription`, `Top-up`, `Manual`, `Setup`, ou `Pending`.

## Acheter une recharge

`POST /user/purchase-topup` débite une carte enregistrée sur Stripe et achète des crédits en une seule étape. Il n'y a pas de redirection Checkout ou d'interface de paiement intégrée.

Passez le montant des crédits dans le corps de la requête :

```json theme={null}
{ "credits": 10000 }
```

| Champ     | Description                 |
| --------- | --------------------------- |
| `credits` | Nombre de crédits à acheter |

Valeurs prises en charge : **10,000**, **20,000**, **80,000**, et **100,000**.

Pour les détails de l'API, voir [Acheter une recharge](/api-reference/billing/purchase-topup).

<CodeGroup>
  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.olostep.com/user/purchase-topup",
      headers={
          "Authorization": "Bearer <API-TOKEN>",
          "Content-Type": "application/json",
      },
      json={"credits": 10000},
  )
  print(response.status_code)
  print(response.json())
  ```

  ```js Node theme={null}
  const res = await fetch("https://api.olostep.com/user/purchase-topup", {
    method: "POST",
    headers: {
      Authorization: "Bearer <API-TOKEN>",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ credits: 10000 }),
  })
  console.log(res.status)
  console.log(await res.json())
  ```

  ```bash cURL theme={null}
  curl -s -X POST "https://api.olostep.com/user/purchase-topup" \
    -H "Authorization: Bearer <API-TOKEN>" \
    -H "Content-Type: application/json" \
    -d '{"credits": 10000}'
  ```
</CodeGroup>

### Exigences

* L'équipe doit avoir un client Stripe avec au moins une carte enregistrée.
* Une seule tentative d'achat est autorisée toutes les **60 secondes** par équipe. Si vous atteignez le délai de refroidissement, la réponse est **429** avec un en-tête `Retry-After`.

### Réponses

**200** — paiement réussi :

```json theme={null}
{
  "success": true,
  "payment_intent_id": "pi_xxx",
  "credits": 10000
}
```

**202** — le paiement est encore en cours de traitement. Les crédits sont ajoutés une fois que Stripe confirme le paiement :

```json theme={null}
{
  "success": true,
  "status": "processing",
  "payment_intent_id": "pi_xxx",
  "message": "Le paiement est en cours de traitement. Les crédits seront ajoutés une fois le paiement confirmé.",
  "credits": 10000
}
```

<Note>
  Les crédits sont émis par le webhook Stripe après confirmation du paiement, et non directement à partir de la réponse HTTP. Considérez **200** comme un succès de paiement ; interrogez `GET /user/credits/info` si vous devez confirmer le solde mis à jour.
</Note>

### Erreurs courantes

| Statut | Erreur                    | Quand                                                    |
| ------ | ------------------------- | -------------------------------------------------------- |
| 400    | `missing_topup_selector`  | `credits` n'a pas été envoyé                             |
| 400    | `invalid_credits`         | Le montant des crédits n'est pas dans la liste autorisée |
| 400    | `no_stripe_customer`      | L'équipe n'a pas de client Stripe                        |
| 400    | `no_payment_method`       | Aucune carte enregistrée                                 |
| 402    | `payment_failed`          | Aucune carte enregistrée n'a complété le débit           |
| 429    | `purchase_topup_cooldown` | Un autre achat a été tenté dans les 60 secondes          |
| 503    | `payment_status_unknown`  | Erreur Stripe ambiguë ; attendez avant de réessayer      |
