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

# Nouvelle tentative de paiement manuelle

> Relancez à la demande le paiement d’un renouvellement d’abonnement échoué depuis le tableau de bord ou l’API, sans attendre la prochaine tentative automatique.

<Info>
  Manual Retry retente immédiatement le paiement de **renouvellement** d’un abonnement échoué lorsque vous le demandez, depuis la page des détails du paiement ou via l’API. Le paiement est effectué avec le moyen de paiement enregistré sur l’abonnement, indépendamment du calendrier de [Payment Retries](/features/recovery/payment-retries) automatique.
</Info>

## Qu’est-ce que Manual Retry ?

Lorsqu’un paiement de renouvellement échoue, l’abonnement passe à `on_hold` et [Payment Retries](/features/recovery/payment-retries) retente le débit selon un calendrier de temporisation. Vous savez parfois que le paiement peut maintenant aboutir : le client vous a confirmé avoir approvisionné son compte, ou votre équipe d’assistance est en ligne avec lui. Manual Retry vous permet d’effectuer immédiatement une tentative au lieu d’attendre plusieurs heures ou jours la prochaine tentative planifiée.

* **Paiements de renouvellement uniquement** : Manual Retry s’applique aux factures de renouvellement d’abonnement lorsque l’abonnement est `on_hold`. Les premiers paiements, paiements ponctuels, frais liés à un changement de plan et frais à la demande ne sont pas éligibles.
* **Aucune action du client** : le débit est effectué sur le moyen de paiement déjà enregistré sur l’abonnement.
* **Indépendante des tentatives automatiques** : une nouvelle tentative manuelle ne consomme pas de tentative du calendrier automatique, ne décale pas la prochaine tentative planifiée et fonctionne même lorsque Payment Retries est désactivé.
* **Nouvelle tentative sur la facture, pas sur le paiement** : un paiement échoué n’est que le point de départ. Dodo Payments recherche la facture de renouvellement ouverte correspondante et recouvre cette dette ; le paiement échoué à partir duquel vous effectuez la nouvelle tentative n’a donc aucune importance.

## Effectuer une nouvelle tentative depuis le tableau de bord

<Steps>
  <Step title="Open the failed payment">
    Accédez à **Transactions → Payments** et cliquez sur le paiement de renouvellement échoué pour ouvrir sa page **Transaction details**.
  </Step>

  <Step title="Click Retry Payment Manually">
    Cliquez sur **Retry Payment Manually** dans l’angle supérieur droit. Le bouton est disponible uniquement lorsque le paiement est [éligible](#eligibility).
  </Step>

  <Step title="Check the result">
    Un nouveau paiement est créé pour la tentative et apparaît dans l’**Activity Log**. Si le débit réussit, l’abonnement revient à `active` et la prochaine date de facturation est décalée comme prévu. Si le processeur de paiement n’a pas encore finalisé le débit, le paiement apparaît comme en cours jusqu’à ce que le webhook `payment.succeeded` ou `payment.failed` indique le résultat.
  </Step>
</Steps>

<Frame caption="Retry Payment Manually on the transaction details page of a failed renewal">
  <img src="https://mintcdn.com/dodopayments/0duTS18kYi2NwQ3m/images/recovery/manual-retry-transaction-details.png?fit=max&auto=format&n=0duTS18kYi2NwQ3m&q=85&s=5537fa5eff17cbe91a53599f887a26e7" alt="Page des détails d’une transaction pour un paiement échoué affichant le code et le message d’erreur, un Activity Log et un bouton Retry Payment Manually" style={{ maxHeight: '500px', width: 'auto' }} width="1285" height="698" data-path="images/recovery/manual-retry-transaction-details.png" />
</Frame>

## Éligibilité

Une nouvelle tentative manuelle est envoyée uniquement lorsque toutes les vérifications ci-dessous sont validées. La colonne **Reason code** correspond à la valeur renvoyée par l’API : dans `reason` sur `GET /payments/{payment_id}/retry`, et sous forme d’erreur `code` sur `POST /payments/{payment_id}/retry`.

| Vérification                 | Condition requise                                                                                                                                                                                                                                                                             | Reason code                                     |
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| Type de paiement             | Paiement de **renouvellement** d’un abonnement dont la facture est toujours ouverte. Les paiements sans facture, les premiers paiements, les paiements ponctuels, les frais liés à un changement de plan et les frais à la demande ne peuvent pas faire l’objet d’une nouvelle tentative.     | `PAYMENT_NOT_RETRYABLE`                         |
| Statut de l’abonnement       | `on_hold`                                                                                                                                                                                                                                                                                     | `SUBSCRIPTION_INACTIVE`                         |
| Annulation planifiée         | L’abonnement n’est pas planifié pour être annulé à la prochaine date de facturation.                                                                                                                                                                                                          | `CHARGE_NOT_ALLOWED_FOR_SCHEDULED_CANCELLATION` |
| Moyen de paiement enregistré | L’abonnement dispose d’un moyen de paiement enregistré à débiter.                                                                                                                                                                                                                             | `SUBSCRIPTION_HAS_NO_PAYMENT_METHOD`            |
| Dernier échec                | L’échec le plus récent est un **soft decline**. Un hard decline, ou un échec sans code d’erreur catégorisé, ne peut pas faire l’objet d’une nouvelle tentative.                                                                                                                               | `MANUAL_RETRY_HARD_DECLINE`                     |
| Aucune opération en cours    | Aucun paiement de la facture n’est `processing` ou ne présente encore de statut enregistré. Il s’agit d’une tentative, manuelle ou automatique, qui vient d’être envoyée et n’a pas encore renvoyé de résultat. Attendez d’abord son résultat.                                                | `MANUAL_RETRY_IN_FLIGHT`                        |
| Dernier paiement échoué      | Le paiement le plus récent de la facture possède le statut `failed`. Un dernier paiement dans tout autre état qui n’est pas `failed`, tel que `requires_customer_action`, `requires_payment_method` ou `cancelled`, bloque la nouvelle tentative même lorsqu’aucune opération n’est en cours. | `PREVIOUS_PAYMENT_PENDING`                      |
| Pas déjà payé                | Aucun paiement de la facture n’a réussi.                                                                                                                                                                                                                                                      | `MANUAL_RETRY_ALREADY_PAID`                     |
| Limite de tentatives         | Moins de 3 nouvelles tentatives manuelles ont été envoyées sur la facture et la période d’attente est écoulée. Consultez [Retry Limits](#retry-limits).                                                                                                                                       | `MANUAL_RETRY_LIMIT_REACHED`                    |
| Client                       | Le client ne figure pas sur votre [blocklist](/features/customer-blocklist).                                                                                                                                                                                                                  | `PAYMENT_NOT_RETRYABLE`                         |
| Connecteur de paiement       | Pour les abonnements [BYOP](/features/byop), le connecteur est activé.                                                                                                                                                                                                                        | `BYOP_CONNECTOR_DISABLED`                       |
| Mode live                    | En mode live, les paiements live sont activés pour votre entreprise.                                                                                                                                                                                                                          | `MERCHANT_NOT_LIVE`                             |

<Note>
  Manual Retry est plus restrictive que les tentatives automatiques sur un point : l’abonnement doit être `on_hold`. Les tentatives automatiques continuent de fonctionner pour les autres statuts non actifs ; consultez [Subscription Status Transitions](/features/recovery/payment-retries#subscription-status-transitions).
</Note>

<Warning>
  Retenter un hard decline avec la même carte ne peut pas réussir et les refus répétés nuisent à votre taux d’autorisation. Lorsque le motif est `MANUAL_RETRY_HARD_DECLINE`, demandez plutôt au client de mettre à jour son moyen de paiement. [Subscription Dunning](/features/recovery/subscription-dunning) le fait automatiquement.
</Warning>

## Limites des nouvelles tentatives

Chaque facture de renouvellement autorise **3** nouvelles tentatives manuelles, avec une période d’attente entre chacune :

| Nouvelle tentative manuelle | Disponible                       |
| --------------------------- | -------------------------------- |
| 1                           | Dès que le paiement est éligible |
| 2                           | 1 heure après la première        |
| 3                           | 3 heures après la deuxième       |

Les limites s’appliquent aussi bien en mode test qu’en mode live. Lorsqu’une nouvelle tentative est refusée pour cette raison, l’API renvoie `MANUAL_RETRY_LIMIT_REACHED` (HTTP `429`). Le corps de l’erreur contient uniquement `code` et `message`. Pour savoir quand la prochaine tentative sera disponible, [consultez l’état de la tentative](#check-whether-a-payment-can-be-retried) et lisez `retry_available_at`. Il est `null` une fois les trois tentatives utilisées.

Les tentatives automatiques ne comptent pas dans cette limite, et les tentatives manuelles ne comptent pas parmi les 8 tentatives du calendrier automatique.

## Tentatives manuelles et automatiques

|                                      | Manual Retry                                                                       | Payment Retries                                                          |
| ------------------------------------ | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| **Déclencheur**                      | Vous, depuis le tableau de bord ou l’API                                           | Dodo Payments, selon un calendrier de temporisation                      |
| **Moment**                           | Immédiatement                                                                      | 12 heures après l’échec, puis progressivement plus tard                  |
| **Tentatives**                       | 3 par facture, avec une période d’attente d’1 heure puis de 3 heures               | Jusqu’à 8 par facture, pendant votre fenêtre de récupération             |
| **Payment Retries doit être activé** | Non                                                                                | Oui                                                                      |
| **Effet sur l’autre mécanisme**      | Aucun. Un échec manuel ne planifie pas et ne décale pas une tentative automatique. | Aucun. La chaîne automatique continue indépendamment des envois manuels. |
| **Analytiques**                      | Comptabilisées dans les métriques **Payment retries** de l’onglet Recovery         | Comptabilisées dans les mêmes métriques                                  |

## Effectuer une nouvelle tentative via l’API

Vérifiez d’abord l’éligibilité, puis envoyez la nouvelle tentative. Les deux endpoints acceptent l’ID d’un paiement échoué.

### Vérifier si un paiement peut faire l’objet d’une nouvelle tentative

`GET /payments/{payment_id}/retry` n’échoue jamais pour un paiement non éligible. Il renvoie plutôt `can_retry: false` avec le code `reason`, afin que votre tableau de bord ou vos outils d’assistance puissent afficher le même état que le tableau de bord Dodo Payments. Il nécessite le rôle **Viewer**.

<CodeGroup>
  ```typescript Node.js theme={null}
  import DodoPayments from 'dodopayments';

  const client = new DodoPayments({
    bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  });

  const state = await client.payments.retrieveRetryState('pay_0NmDtkE0iRvmeTcT6t0ol');

  if (state.can_retry) {
    console.log(`Retry available. ${state.sends_used}/${state.sends_allowed} used.`);
  } else {
    console.log(`Cannot retry: ${state.reason}. Next window: ${state.retry_available_at}`);
  }
  ```

  ```python Python theme={null}
  import os
  from dodopayments import DodoPayments

  client = DodoPayments(bearer_token=os.environ["DODO_PAYMENTS_API_KEY"])

  state = client.payments.retrieve_retry_state("pay_0NmDtkE0iRvmeTcT6t0ol")

  if state.can_retry:
      print(f"Retry available. {state.sends_used}/{state.sends_allowed} used.")
  else:
      print(f"Cannot retry: {state.reason}. Next window: {state.retry_available_at}")
  ```

  ```bash cURL theme={null}
  curl https://live.dodopayments.com/payments/pay_0NmDtkE0iRvmeTcT6t0ol/retry \
    -H "Authorization: Bearer $DODO_PAYMENTS_API_KEY"
  ```
</CodeGroup>

```json Response theme={null}
{
  "can_retry": false,
  "reason": "MANUAL_RETRY_LIMIT_REACHED",
  "sends_used": 1,
  "sends_allowed": 3,
  "retry_available_at": "2026-08-26T16:51:00Z"
}
```

| Champ                | Description                                                                                                                                                              |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `can_retry`          | `true` lorsqu’une nouvelle tentative peut être envoyée immédiatement.                                                                                                    |
| `reason`             | Code de l’erreur qui serait renvoyée par la nouvelle tentative. `null` lorsque `can_retry` est `true`.                                                                   |
| `sends_used`         | Nouvelles tentatives manuelles déjà envoyées sur cette facture.                                                                                                          |
| `sends_allowed`      | Toujours `3`.                                                                                                                                                            |
| `retry_available_at` | Moment où la prochaine nouvelle tentative manuelle sera disponible. `null` lorsqu’il ne reste aucune tentative ou lorsque le refus n’est pas lié à la période d’attente. |

### Envoyer une nouvelle tentative manuelle

`POST /payments/{payment_id}/retry` crée un nouveau paiement et débite le moyen de paiement enregistré. Il nécessite le rôle **Editor**.

<CodeGroup>
  ```typescript Node.js theme={null}
  const retry = await client.payments.retry('pay_0NmDtkE0iRvmeTcT6t0ol');

  console.log(retry.payment_id, retry.status);
  ```

  ```python Python theme={null}
  retry = client.payments.retry("pay_0NmDtkE0iRvmeTcT6t0ol")

  print(retry.payment_id, retry.status)
  ```

  ```bash cURL theme={null}
  curl -X POST https://live.dodopayments.com/payments/pay_0NmDtkE0iRvmeTcT6t0ol/retry \
    -H "Authorization: Bearer $DODO_PAYMENTS_API_KEY"
  ```
</CodeGroup>

```json Response theme={null}
{
  "payment_id": "pay_2IjeQm4hqU6RA4Z4kwDee",
  "invoice_id": "inv_9Kp2mQ7vRt4LxYw3",
  "status": "processing",
  "retry_attempt": 1,
  "is_manual_retry": true,
  "sends_used": 1,
  "sends_allowed": 3,
  "retry_available_at": "2026-08-26T16:51:00Z"
}
```

| Champ                                               | Description                                                                                                                                                                                                                                         |
| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `payment_id`                                        | Nouveau paiement créé pour cette tentative.                                                                                                                                                                                                         |
| `invoice_id`                                        | Facture de renouvellement débitée.                                                                                                                                                                                                                  |
| `status`                                            | Résultat du débit. `processing` signifie que le processeur ne l’a pas encore finalisé. `null` signifie qu’aucun résultat n’a été enregistré avant le renvoi de la réponse. Dans les deux cas, les webhooks de paiement indiquent le résultat final. |
| `retry_attempt`                                     | Position de cette tentative parmi les nouvelles tentatives manuelles de la facture, à partir de `1`.                                                                                                                                                |
| `is_manual_retry`                                   | Toujours `true` sur cet endpoint.                                                                                                                                                                                                                   |
| `sends_used`, `sends_allowed`, `retry_available_at` | État de la limite de tentatives après cet envoi. `retry_available_at` correspond uniquement au délai d’attente. Il est défini même lorsque ce débit réussit ; dans ce cas, la facture est payée et aucune nouvelle tentative n’est disponible.      |

### Réponses d’erreur

| Statut HTTP | Codes                                                                                                                                                                                            | Action                                                                                                                                                                         |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `404`       | `NOT_FOUND`                                                                                                                                                                                      | Le paiement n’appartient pas à votre entreprise.                                                                                                                               |
| `409`       | `MANUAL_RETRY_IN_FLIGHT`, `PREVIOUS_PAYMENT_PENDING`, `CHARGE_NOT_ALLOWED_FOR_SCHEDULED_CANCELLATION`                                                                                            | Temporaire, ou un autre élément doit d’abord être modifié. Attendez que le paiement en cours ou en attente atteigne un état final, ou annulez l’annulation planifiée.          |
| `422`       | `PAYMENT_NOT_RETRYABLE`, `SUBSCRIPTION_INACTIVE`, `SUBSCRIPTION_HAS_NO_PAYMENT_METHOD`, `MANUAL_RETRY_HARD_DECLINE`, `MANUAL_RETRY_ALREADY_PAID`, `BYOP_CONNECTOR_DISABLED`, `MERCHANT_NOT_LIVE` | Ce paiement ne peut pas faire l’objet d’une nouvelle tentative. Ne répétez pas l’appel.                                                                                        |
| `429`       | `MANUAL_RETRY_LIMIT_REACHED`                                                                                                                                                                     | [Consultez l’état de la tentative](#check-whether-a-payment-can-be-retried) et attendez jusqu’à `retry_available_at`, ou arrêtez-vous une fois les trois tentatives utilisées. |

Chaque code est décrit dans la référence [Error Codes](/api-reference/error-codes).

## Webhooks

Une nouvelle tentative manuelle crée un paiement standard ; les mêmes webhooks sont donc déclenchés que pour toute tentative de renouvellement :

| Événement            | Déclenché lorsque                                                                                                                                      |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `payment.succeeded`  | La nouvelle tentative a été débitée. `subscription.active` suit lorsque l’abonnement est réactivé.                                                     |
| `payment.failed`     | La nouvelle tentative a été refusée. L’abonnement reste `on_hold` et aucune nouvelle tentative automatique n’est planifiée à partir d’un échec manuel. |
| `payment.processing` | Le processeur a accepté le débit, mais ne l’a pas encore finalisé.                                                                                     |

Sur l’objet de paiement de ces événements, `retry_attempt` est `1` ou supérieur et `subscription_id` est défini, exactement comme pour une nouvelle tentative automatique. Conservez `payment_id` de la réponse de nouvelle tentative si vous devez distinguer une tentative manuelle d’une tentative planifiée.

<Card title="Payment Webhook Payloads" icon="webhook" href="/developer-resources/webhooks/intents/payment">
  Schémas complets des payloads des événements de paiement.
</Card>

## Pages associées

<CardGroup cols={2}>
  <Card title="Subscription Payment Retries" icon="arrow-rotate-right" href="/features/recovery/payment-retries">
    Le calendrier automatique de temporisation qui fonctionne en parallèle des nouvelles tentatives manuelles.
  </Card>

  <Card title="Subscription Dunning" icon="repeat" href="/features/recovery/subscription-dunning">
    Envoyez un e-mail au client pour lui demander de mettre à jour son moyen de paiement après un hard decline.
  </Card>

  <Card title="Handle Payment Failures" icon="screwdriver-wrench" href="/developer-resources/handle-payment-failures">
    Lisez les codes de refus et déterminez quand une nouvelle tentative vaut la peine.
  </Card>

  <Card title="Error Codes" icon="triangle-exclamation" href="/api-reference/error-codes">
    Chaque code `MANUAL_RETRY_*`, son déclencheur et son message.
  </Card>
</CardGroup>
