> ## 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.

# मैन्युअल Payment Retry

> अगले automatic retry की प्रतीक्षा करने के बजाय dashboard या API से मांग पर विफल subscription renewal payment को फिर से आज़माएं।

<Info>
  Manual Retry, payment के detail page से या API के माध्यम से, आपके अनुरोध करते ही विफल subscription **renewal** payment को फिर से आज़माता है। यह subscription पर saved payment method से charge करता है और automatic [Payment Retries](/features/recovery/payment-retries) schedule से स्वतंत्र रूप से चलता है।
</Info>

## Manual Retry क्या है?

जब renewal payment विफल होता है, तो subscription `on_hold` में चला जाता है और [Payment Retries](/features/recovery/payment-retries) back-off schedule पर charge को फिर से आज़माता है। कभी-कभी आपको पता होता है कि payment अभी सफल होगा: customer ने पुष्टि की है कि उसने अपने account में funds add किए हैं, या आपकी support team उससे call पर है। Manual Retry आपको अगली scheduled attempt के लिए घंटों या दिनों तक प्रतीक्षा करने के बजाय तुरंत एक attempt भेजने देता है।

* **केवल Renewal payments**: Manual Retry subscription renewal invoices पर लागू होता है, जब subscription `on_hold` हो। First payments, one-time payments, plan-change charges और on-demand charges इसके लिए eligible नहीं हैं।
* **Customer action की आवश्यकता नहीं**: Charge subscription पर पहले से saved payment method पर भेजा जाता है।
* **Automatic retries से स्वतंत्र**: Manual retry automatic schedule की कोई attempt consume नहीं करता, अगली scheduled retry को आगे नहीं बढ़ाता और Payment Retries बंद होने पर भी काम करता है।
* **Payment नहीं, invoice को retry करता है**: विफल payment केवल entry point है। Dodo Payments उसके पीछे मौजूद open renewal invoice को ढूंढकर उस debt को charge करता है, इसलिए invoice पर मौजूद किसी भी विफल payment से retry करने पर कोई फर्क नहीं पड़ता।

## Dashboard से Retry करना

<Steps>
  <Step title="Open the failed payment">
    **Transactions → Payments** पर जाएं और विफल renewal payment पर click करके उसका **Transaction details** page खोलें।
  </Step>

  <Step title="Click Retry Payment Manually">
    ऊपरी-दाएं कोने में **Retry Payment Manually** पर click करें। यह button केवल तभी उपलब्ध होता है जब payment [eligible](#eligibility) हो।
  </Step>

  <Step title="Check the result">
    इस attempt के लिए एक नया payment बनाया जाता है और वह **Activity Log** में दिखाई देता है। यदि charge सफल होता है, तो subscription `active` में लौट आता है और अगली billing date सामान्य रूप से आगे बढ़ती है। यदि payment processor ने अभी तक charge settle नहीं किया है, तो payment in progress के रूप में दिखाई देता है, जब तक कि `payment.succeeded` या `payment.failed` webhook परिणाम की सूचना नहीं देता।
  </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="विफल payment का Transaction details page, जिसमें error code और message, Activity Log और Retry Payment Manually button दिख रहे हैं" style={{ maxHeight: '500px', width: 'auto' }} width="1285" height="698" data-path="images/recovery/manual-retry-transaction-details.png" />
</Frame>

## Eligibility

Manual retry तभी भेजा जाता है जब नीचे दी गई हर जांच सफल हो। **Reason code** column वही है जो API लौटाता है: `GET /payments/{payment_id}/retry` पर `reason` में और `POST /payments/{payment_id}/retry` पर error `code` के रूप में।

| Check                  | Requirement                                                                                                                                                                                                                                       | Reason code                                     |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| Payment type           | Subscription का **renewal** payment, जिसका invoice अभी भी open है। बिना invoice वाले payments, first payments, one-time payments, plan-change charges और on-demand charges को retry नहीं किया जा सकता।                                            | `PAYMENT_NOT_RETRYABLE`                         |
| Subscription status    | `on_hold`                                                                                                                                                                                                                                         | `SUBSCRIPTION_INACTIVE`                         |
| Scheduled cancellation | Subscription अगली billing date पर cancel होने के लिए scheduled नहीं है।                                                                                                                                                                           | `CHARGE_NOT_ALLOWED_FOR_SCHEDULED_CANCELLATION` |
| Saved payment method   | Subscription पर charge करने के लिए saved payment method मौजूद है।                                                                                                                                                                                 | `SUBSCRIPTION_HAS_NO_PAYMENT_METHOD`            |
| Last failure           | सबसे हाल की failure **soft decline** है। Hard decline या classified error code के बिना failure को retry नहीं किया जा सकता।                                                                                                                        | `MANUAL_RETRY_HARD_DECLINE`                     |
| Nothing in flight      | Invoice का कोई payment `processing` नहीं है और उसका recorded status भी नहीं है। यह ऐसी attempt है, manual या automatic, जो अभी भेजी गई है और जिसका परिणाम वापस नहीं आया है। पहले उसके परिणाम की प्रतीक्षा करें।                                   | `MANUAL_RETRY_IN_FLIGHT`                        |
| Newest payment failed  | Invoice के सबसे हाल के payment का status `failed` है। किसी अन्य state में मौजूद newest payment, जो `failed` नहीं है, जैसे `requires_customer_action`, `requires_payment_method` या `cancelled`, तब भी retry को रोकता है जब कुछ भी in flight न हो। | `PREVIOUS_PAYMENT_PENDING`                      |
| Not already paid       | Invoice पर किसी payment को सफलता नहीं मिली है।                                                                                                                                                                                                    | `MANUAL_RETRY_ALREADY_PAID`                     |
| Retry limit            | Invoice पर 3 से कम manual retries भेजी गई हैं और cooldown पूरा हो चुका है। [Retry Limits](#retry-limits) देखें।                                                                                                                                   | `MANUAL_RETRY_LIMIT_REACHED`                    |
| Customer               | Customer आपकी [blocklist](/features/customer-blocklist) पर नहीं है।                                                                                                                                                                               | `PAYMENT_NOT_RETRYABLE`                         |
| Payment connector      | [BYOP](/features/byop) subscriptions के लिए connector enabled है।                                                                                                                                                                                 | `BYOP_CONNECTOR_DISABLED`                       |
| Live mode              | Live mode में आपके business के लिए live payments enabled हैं।                                                                                                                                                                                     | `MERCHANT_NOT_LIVE`                             |

<Note>
  एक मामले में Manual Retry, automatic retries से अधिक सीमित है: इसके लिए subscription का `on_hold` होना आवश्यक है। Automatic retries अन्य non-active statuses के लिए चलती रहती हैं; [Subscription Status Transitions](/features/recovery/payment-retries#subscription-status-transitions) देखें।
</Note>

<Warning>
  उसी card के विरुद्ध hard decline को retry करने से सफलता नहीं मिल सकती और बार-बार declines आपकी authorization rate को नुकसान पहुंचाते हैं। जब reason `MANUAL_RETRY_HARD_DECLINE` हो, तो customer से अपना payment method update करने के लिए कहें। [Subscription Dunning](/features/recovery/subscription-dunning) यह अपने-आप करता है।
</Warning>

## Retry Limits

हर renewal invoice में **3** manual retries की अनुमति होती है और इनके बीच cooldown होता है:

| Manual retry | Available                |
| ------------ | ------------------------ |
| 1            | Payment eligible होते ही |
| 2            | पहली के 1 घंटे बाद       |
| 3            | दूसरी के 3 घंटे बाद      |

ये limits test mode और live mode दोनों में लागू होती हैं। जब इस कारण से retry अस्वीकार किया जाता है, तो API `MANUAL_RETRY_LIMIT_REACHED` (HTTP `429`) लौटाता है। Error body में केवल `code` और `message` होते हैं। अगली retry कब उपलब्ध होगी, यह जानने के लिए [retry state जांचें](#check-whether-a-payment-can-be-retried) और `retry_available_at` पढ़ें। तीनों खर्च हो जाने पर यह `null` होता है।

Automatic retries इस limit में नहीं गिनी जातीं और manual retries automatic schedule की 8 attempts में नहीं गिनी जातीं।

## Manual बनाम Automatic Retries

|                                   | Manual Retry                                                                   | Payment Retries                                                |
| --------------------------------- | ------------------------------------------------------------------------------ | -------------------------------------------------------------- |
| **Trigger**                       | आप, dashboard या API से                                                        | Dodo Payments, back-off schedule पर                            |
| **Timing**                        | तुरंत                                                                          | Failure के 12 घंटे बाद, फिर धीरे-धीरे अधिक अंतराल पर           |
| **Attempts**                      | प्रति invoice 3, पहले 1 घंटे और फिर 3 घंटे का cooldown                         | Recovery window के भीतर प्रति invoice अधिकतम 8                 |
| **Needs Payment Retries enabled** | नहीं                                                                           | हां                                                            |
| **Effect on the other**           | कोई नहीं। Manual failure किसी automatic attempt को schedule या move नहीं करता। | कोई नहीं। Manual sends के बावजूद automatic chain जारी रहती है। |
| **Analytics**                     | Recovery tab में **Payment retries** metrics में गिनी जाती हैं                 | उन्हीं metrics में गिनी जाती हैं                               |

## API के माध्यम से Retry करना

पहले eligibility जांचें, फिर retry भेजें। दोनों endpoints विफल payment की ID लेते हैं।

### जांचें कि Payment को Retry किया जा सकता है या नहीं

`GET /payments/{payment_id}/retry` कभी भी ineligible payment पर fail नहीं होता। इसके बजाय यह `can_retry: false` को `reason` code के साथ लौटाता है, ताकि आपका dashboard या support tooling वही state दिखा सके जो Dodo Payments dashboard दिखाता है। इसके लिए **Viewer** role आवश्यक है।

<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"
}
```

| Field                | Description                                                                                                  |
| -------------------- | ------------------------------------------------------------------------------------------------------------ |
| `can_retry`          | जब retry तुरंत भेजी जा सकती हो, तब `true`।                                                                   |
| `reason`             | वह code जिसके साथ retry fail होगी। जब `can_retry` `true` हो, तब `null`।                                      |
| `sends_used`         | इस invoice पर पहले से भेजी गई manual retries।                                                                |
| `sends_allowed`      | हमेशा `3`।                                                                                                   |
| `retry_available_at` | अगली manual retry कब उपलब्ध होगी। जब कोई retry शेष न हो या refusal का cooldown से कोई संबंध न हो, तब `null`। |

### Manual Retry भेजें

`POST /payments/{payment_id}/retry` एक नया payment बनाता है और saved payment method से charge करता है। इसके लिए **Editor** role आवश्यक है।

<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"
}
```

| Field                                               | Description                                                                                                                                                                                                                                  |
| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `payment_id`                                        | इस attempt के लिए बनाया गया नया payment।                                                                                                                                                                                                     |
| `invoice_id`                                        | Charge किया गया renewal invoice।                                                                                                                                                                                                             |
| `status`                                            | Charge का outcome। `processing` का अर्थ है कि processor ने अभी इसे settle नहीं किया है। `null` का अर्थ है कि response लौटाए जाने से पहले कोई outcome record नहीं किया गया। दोनों मामलों में payment webhooks अंतिम परिणाम की सूचना देते हैं। |
| `retry_attempt`                                     | Invoice पर manual retries में इस attempt की position, `1` से शुरू।                                                                                                                                                                           |
| `is_manual_retry`                                   | इस endpoint पर हमेशा `true`।                                                                                                                                                                                                                 |
| `sends_used`, `sends_allowed`, `retry_available_at` | इस send के बाद retry limit state। `retry_available_at` केवल cooldown clock है। यह तब भी set होता है जब यह charge सफल हो जाए; उस स्थिति में invoice paid होता है और कोई अगली retry उपलब्ध नहीं होती।                                          |

### Error Responses

| HTTP status | Codes                                                                                                                                                                                            | What to do                                                                                                                                                  |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `404`       | `NOT_FOUND`                                                                                                                                                                                      | Payment आपके business का नहीं है।                                                                                                                           |
| `409`       | `MANUAL_RETRY_IN_FLIGHT`, `PREVIOUS_PAYMENT_PENDING`, `CHARGE_NOT_ALLOWED_FOR_SCHEDULED_CANCELLATION`                                                                                            | अस्थायी समस्या है या पहले कुछ और बदलना आवश्यक है। In-flight या pending payment के final state तक पहुंचने की प्रतीक्षा करें या scheduled cancellation हटाएं। |
| `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` | इस payment को retry नहीं किया जा सकता। Call को दोहराएं नहीं।                                                                                                |
| `429`       | `MANUAL_RETRY_LIMIT_REACHED`                                                                                                                                                                     | [Retry state जांचें](#check-whether-a-payment-can-be-retried) और `retry_available_at` तक प्रतीक्षा करें, या तीनों retries खर्च हो जाने पर रुक जाएं।         |

हर code का विवरण [Error Codes](/api-reference/error-codes) reference में दिया गया है।

## Webhooks

Manual retry एक सामान्य payment बनाता है, इसलिए वही webhooks fire होते हैं जो किसी भी renewal attempt के लिए होते हैं:

| Event                | Fires when                                                                                                             |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `payment.succeeded`  | Retry charge हो गई। Subscription के reactivated होने पर `subscription.active` इसके बाद आता है।                         |
| `payment.failed`     | Retry decline हो गई। Subscription `on_hold` पर रहती है और manual failure से कोई automatic retry schedule नहीं की जाती। |
| `payment.processing` | Processor ने charge स्वीकार कर लिया है, लेकिन अभी इसे settle नहीं किया है।                                             |

इन events में payment object पर `retry_attempt` `1` या उससे अधिक होता है और `subscription_id` set होता है, ठीक automatic retry की तरह। यदि आपको manual attempt को scheduled attempt से अलग पहचानना हो, तो retry response से `payment_id` सुरक्षित रखें।

<Card title="Payment Webhook Payloads" icon="webhook" href="/developer-resources/webhooks/intents/payment">
  Payment events के full payload schemas।
</Card>

## संबंधित

<CardGroup cols={2}>
  <Card title="Subscription Payment Retries" icon="arrow-rotate-right" href="/features/recovery/payment-retries">
    Manual retries के साथ चलने वाला automatic back-off schedule।
  </Card>

  <Card title="Subscription Dunning" icon="repeat" href="/features/recovery/subscription-dunning">
    Hard decline के बाद customer को अपना payment method update करने के लिए email करें।
  </Card>

  <Card title="Handle Payment Failures" icon="screwdriver-wrench" href="/developer-resources/handle-payment-failures">
    Decline codes पढ़ें और तय करें कि retry कब करना उपयोगी है।
  </Card>

  <Card title="Error Codes" icon="triangle-exclamation" href="/api-reference/error-codes">
    हर `MANUAL_RETRY_*` code, उसका trigger और उसका message।
  </Card>
</CardGroup>
