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

# Coba Lagi Pembayaran Manual

> Coba lagi pembayaran perpanjangan langganan yang gagal sesuai permintaan dari dashboard atau API, tanpa menunggu percobaan otomatis berikutnya.

<Info>
  Coba Lagi Manual mencoba kembali pembayaran **perpanjangan** langganan yang gagal segera setelah Anda memintanya, dari halaman detail pembayaran atau melalui API. Pembayaran dibebankan ke metode pembayaran yang tersimpan di langganan, dan berjalan secara independen dari jadwal [Payment Retries](/features/recovery/payment-retries) otomatis.
</Info>

## Apa Itu Coba Lagi Manual?

Saat pembayaran perpanjangan gagal, langganan berpindah ke `on_hold` dan [Payment Retries](/features/recovery/payment-retries) mencoba kembali membebankan biaya berdasarkan jadwal back-off. Terkadang Anda tahu bahwa pembayaran akan berhasil sekarang: pelanggan telah mengonfirmasi bahwa mereka mengisi saldo akunnya, atau tim dukungan Anda sedang berbicara dengan mereka. Coba Lagi Manual memungkinkan Anda mengirim satu percobaan segera, tanpa menunggu berjam-jam atau berhari-hari hingga percobaan terjadwal berikutnya.

* **Hanya pembayaran perpanjangan**: Coba Lagi Manual berlaku untuk invoice perpanjangan langganan saat langganan berada dalam status `on_hold`. Pembayaran pertama, pembayaran satu kali, biaya perubahan paket, dan biaya sesuai permintaan tidak memenuhi syarat.
* **Tanpa tindakan pelanggan**: Biaya dibebankan ke metode pembayaran yang sudah tersimpan di langganan.
* **Independen dari percobaan otomatis**: Percobaan manual tidak mengurangi jumlah percobaan dari jadwal otomatis, tidak memindahkan percobaan terjadwal berikutnya, dan tetap berfungsi meskipun Payment Retries dinonaktifkan.
* **Mencoba kembali invoice, bukan pembayaran**: Pembayaran yang gagal hanyalah titik awal. Dodo Payments mencari invoice perpanjangan terbuka yang mendasarinya dan menagihkan utang tersebut, sehingga tidak masalah pembayaran gagal mana pada invoice yang Anda gunakan untuk mencoba lagi.

## Mencoba Lagi dari Dashboard

<Steps>
  <Step title="Open the failed payment">
    Buka **Transactions → Payments** dan klik pembayaran perpanjangan yang gagal untuk membuka halaman **Transaction details**.
  </Step>

  <Step title="Click Retry Payment Manually">
    Klik **Retry Payment Manually** di sudut kanan atas. Tombol ini hanya tersedia saat pembayaran [memenuhi syarat](#eligibility).
  </Step>

  <Step title="Check the result">
    Pembayaran baru dibuat untuk percobaan tersebut dan muncul di **Activity Log**. Jika biaya berhasil, langganan kembali ke `active` dan tanggal penagihan berikutnya maju seperti biasa. Jika pemroses pembayaran belum menyelesaikan biaya tersebut, pembayaran akan ditampilkan sebagai sedang diproses hingga webhook `payment.succeeded` atau `payment.failed` melaporkan hasilnya.
  </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="Transaction details page for a failed payment showing the error code and message, an Activity Log, and a Retry Payment Manually button" style={{ maxHeight: '500px', width: 'auto' }} width="1285" height="698" data-path="images/recovery/manual-retry-transaction-details.png" />
</Frame>

## Kelayakan

Percobaan manual hanya dikirim jika semua pemeriksaan di bawah ini berhasil. Kolom **Reason code** adalah yang dikembalikan API: dalam `reason` pada `GET /payments/{payment_id}/retry`, dan sebagai error `code` pada `POST /payments/{payment_id}/retry`.

| Pemeriksaan                               | Persyaratan                                                                                                                                                                                                                                                                             | Kode alasan                                     |
| ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| Jenis pembayaran                          | Pembayaran **perpanjangan** langganan dengan invoice yang masih terbuka. Pembayaran tanpa invoice, pembayaran pertama, pembayaran satu kali, biaya perubahan paket, dan biaya sesuai permintaan tidak dapat dicoba lagi.                                                                | `PAYMENT_NOT_RETRYABLE`                         |
| Status langganan                          | `on_hold`                                                                                                                                                                                                                                                                               | `SUBSCRIPTION_INACTIVE`                         |
| Pembatalan terjadwal                      | Langganan tidak dijadwalkan untuk dibatalkan pada tanggal penagihan berikutnya.                                                                                                                                                                                                         | `CHARGE_NOT_ALLOWED_FOR_SCHEDULED_CANCELLATION` |
| Metode pembayaran tersimpan               | Langganan memiliki metode pembayaran tersimpan untuk ditagihkan.                                                                                                                                                                                                                        | `SUBSCRIPTION_HAS_NO_PAYMENT_METHOD`            |
| Kegagalan terakhir                        | Kegagalan terbaru adalah **soft decline**. Hard decline, atau kegagalan tanpa kode error yang diklasifikasikan, tidak dapat dicoba lagi.                                                                                                                                                | `MANUAL_RETRY_HARD_DECLINE`                     |
| Tidak ada pembayaran yang sedang diproses | Tidak ada pembayaran pada invoice yang berstatus `processing` atau belum memiliki status tercatat. Ini adalah percobaan, manual atau otomatis, yang baru saja dikirim dan belum memberikan hasil. Tunggu hasilnya terlebih dahulu.                                                      | `MANUAL_RETRY_IN_FLIGHT`                        |
| Pembayaran terbaru gagal                  | Pembayaran terbaru pada invoice memiliki status `failed`. Pembayaran terbaru dalam status lain yang bukan `failed`, seperti `requires_customer_action`, `requires_payment_method`, atau `cancelled`, akan memblokir percobaan ulang meskipun tidak ada pembayaran yang sedang diproses. | `PREVIOUS_PAYMENT_PENDING`                      |
| Belum dibayar                             | Tidak ada pembayaran pada invoice yang berhasil.                                                                                                                                                                                                                                        | `MANUAL_RETRY_ALREADY_PAID`                     |
| Batas percobaan                           | Kurang dari 3 percobaan manual telah dikirim pada invoice, dan masa tunggu telah berlalu. Lihat [Batas Percobaan](#retry-limits).                                                                                                                                                       | `MANUAL_RETRY_LIMIT_REACHED`                    |
| Pelanggan                                 | Pelanggan tidak ada dalam [blocklist](/features/customer-blocklist) Anda.                                                                                                                                                                                                               | `PAYMENT_NOT_RETRYABLE`                         |
| Konektor pembayaran                       | Untuk langganan [BYOP](/features/byop), konektor diaktifkan.                                                                                                                                                                                                                            | `BYOP_CONNECTOR_DISABLED`                       |
| Mode live                                 | Dalam mode live, bisnis Anda telah mengaktifkan pembayaran live.                                                                                                                                                                                                                        | `MERCHANT_NOT_LIVE`                             |

<Note>
  Coba Lagi Manual lebih terbatas daripada percobaan otomatis dalam satu hal: status langganan harus `on_hold`. Percobaan otomatis tetap berjalan untuk status nonaktif lainnya; lihat [Transisi Status Langganan](/features/recovery/payment-retries#subscription-status-transitions).
</Note>

<Warning>
  Mencoba kembali hard decline pada kartu yang sama tidak akan berhasil, dan penolakan berulang dapat menurunkan tingkat otorisasi Anda. Jika alasannya adalah `MANUAL_RETRY_HARD_DECLINE`, minta pelanggan memperbarui metode pembayarannya. [Subscription Dunning](/features/recovery/subscription-dunning) melakukan hal ini secara otomatis.
</Warning>

## Batas Percobaan

Setiap invoice perpanjangan mengizinkan **3** percobaan manual, dengan masa tunggu di antaranya:

| Percobaan manual | Tersedia                                  |
| ---------------- | ----------------------------------------- |
| 1                | Segera setelah pembayaran memenuhi syarat |
| 2                | 1 jam setelah percobaan pertama           |
| 3                | 3 jam setelah percobaan kedua             |

Batas ini berlaku dalam mode test dan mode live. Saat percobaan ditolak karena alasan ini, API mengembalikan `MANUAL_RETRY_LIMIT_REACHED` (HTTP `429`). Isi error hanya memuat `code` dan `message`. Untuk mengetahui kapan percobaan berikutnya tersedia, [periksa status percobaan](#check-whether-a-payment-can-be-retried) dan baca `retry_available_at`. Nilainya adalah `null` setelah ketiganya digunakan.

Percobaan otomatis tidak dihitung dalam batas ini, dan percobaan manual tidak dihitung dalam 8 percobaan pada jadwal otomatis.

## Percobaan Manual vs. Otomatis

|                                      | Coba Lagi Manual                                                                    | Payment Retries                                                               |
| ------------------------------------ | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
| **Pemicu**                           | Anda, dari dashboard atau API                                                       | Dodo Payments, berdasarkan jadwal back-off                                    |
| **Waktu**                            | Segera                                                                              | 12 jam setelah kegagalan, lalu semakin lama                                   |
| **Percobaan**                        | 3 per invoice, dengan masa tunggu 1 jam lalu 3 jam                                  | Hingga 8 per invoice, dalam periode pemulihan                                 |
| **Memerlukan Payment Retries aktif** | Tidak                                                                               | Ya                                                                            |
| **Dampak terhadap yang lain**        | Tidak ada. Kegagalan manual tidak menjadwalkan atau memindahkan percobaan otomatis. | Tidak ada. Rangkaian otomatis terus berjalan terlepas dari pengiriman manual. |
| **Analitik**                         | Dihitung dalam metrik **Payment retries** pada tab Recovery                         | Dihitung dalam metrik yang sama                                               |

## Mencoba Lagi melalui API

Periksa kelayakan terlebih dahulu, lalu kirim percobaan ulang. Kedua endpoint menerima ID pembayaran yang gagal.

### Memeriksa Apakah Pembayaran Dapat Dicoba Lagi

`GET /payments/{payment_id}/retry` tidak pernah gagal untuk pembayaran yang tidak memenuhi syarat. Endpoint ini mengembalikan `can_retry: false` dengan kode `reason`, sehingga dashboard atau alat dukungan Anda dapat menampilkan status yang sama seperti dashboard Dodo Payments. Endpoint ini memerlukan peran **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"
}
```

| Kolom                | Deskripsi                                                                                                                                  |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `can_retry`          | `true` saat percobaan ulang dapat dikirim sekarang.                                                                                        |
| `reason`             | Kode yang akan menyebabkan percobaan ulang gagal. `null` saat `can_retry` bernilai `true`.                                                 |
| `sends_used`         | Jumlah percobaan manual yang telah dikirim pada invoice ini.                                                                               |
| `sends_allowed`      | Selalu `3`.                                                                                                                                |
| `retry_available_at` | Waktu percobaan manual berikutnya tersedia. `null` jika tidak ada percobaan tersisa, atau jika penolakan tidak terkait dengan masa tunggu. |

### Mengirim Coba Lagi Manual

`POST /payments/{payment_id}/retry` membuat pembayaran baru dan menagihkan metode pembayaran yang tersimpan. Endpoint ini memerlukan peran **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"
}
```

| Kolom                                               | Deskripsi                                                                                                                                                                                                                                      |
| --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `payment_id`                                        | Pembayaran baru yang dibuat untuk percobaan ini.                                                                                                                                                                                               |
| `invoice_id`                                        | Invoice perpanjangan yang ditagihkan.                                                                                                                                                                                                          |
| `status`                                            | Hasil penagihan. `processing` berarti pemroses belum menyelesaikannya. `null` berarti tidak ada hasil yang tercatat sebelum respons dikembalikan. Dalam kedua kasus, webhook pembayaran melaporkan hasil akhir.                                |
| `retry_attempt`                                     | Posisi percobaan ini di antara percobaan manual pada invoice, dimulai dari `1`.                                                                                                                                                                |
| `is_manual_retry`                                   | Selalu `true` pada endpoint ini.                                                                                                                                                                                                               |
| `sends_used`, `sends_allowed`, `retry_available_at` | Status batas percobaan setelah pengiriman ini. `retry_available_at` hanya merupakan penghitung masa tunggu. Nilai ini ditetapkan meskipun biaya berhasil, yang berarti invoice telah dibayar dan tidak ada percobaan berikutnya yang tersedia. |

### Respons Error

| Status HTTP | Kode                                                                                                                                                                                             | Tindakan                                                                                                                                                                                     |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `404`       | `NOT_FOUND`                                                                                                                                                                                      | Pembayaran bukan milik bisnis Anda.                                                                                                                                                          |
| `409`       | `MANUAL_RETRY_IN_FLIGHT`, `PREVIOUS_PAYMENT_PENDING`, `CHARGE_NOT_ALLOWED_FOR_SCHEDULED_CANCELLATION`                                                                                            | Bersifat sementara, atau ada hal lain yang harus diubah terlebih dahulu. Tunggu hingga pembayaran yang sedang diproses atau tertunda mencapai status final, atau hapus pembatalan terjadwal. |
| `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` | Pembayaran ini tidak dapat dicoba lagi. Jangan ulangi panggilan.                                                                                                                             |
| `429`       | `MANUAL_RETRY_LIMIT_REACHED`                                                                                                                                                                     | [Periksa status percobaan](#check-whether-a-payment-can-be-retried) dan tunggu hingga `retry_available_at`, atau berhenti setelah ketiga percobaan digunakan.                                |

Setiap kode dijelaskan dalam referensi [Error Codes](/api-reference/error-codes).

## Webhook

Coba lagi manual membuat pembayaran biasa, sehingga webhook yang sama dipicu seperti pada percobaan perpanjangan lainnya:

| Event                | Dipicu saat                                                                                                                    |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `payment.succeeded`  | Percobaan ulang berhasil ditagihkan. `subscription.active` menyusul saat langganan diaktifkan kembali.                         |
| `payment.failed`     | Percobaan ulang ditolak. Langganan tetap `on_hold`, dan tidak ada percobaan otomatis yang dijadwalkan akibat kegagalan manual. |
| `payment.processing` | Pemroses telah menerima biaya, tetapi belum menyelesaikannya.                                                                  |

Pada objek pembayaran dalam event ini, `retry_attempt` bernilai `1` atau lebih tinggi dan `subscription_id` ditetapkan, sama seperti pada percobaan otomatis. Simpan `payment_id` dari respons percobaan ulang jika Anda perlu membedakan percobaan manual dari percobaan terjadwal.

<Card title="Payment Webhook Payloads" icon="webhook" href="/developer-resources/webhooks/intents/payment">
  Skema payload lengkap untuk event pembayaran.
</Card>

## Terkait

<CardGroup cols={2}>
  <Card title="Subscription Payment Retries" icon="arrow-rotate-right" href="/features/recovery/payment-retries">
    Jadwal back-off otomatis yang berjalan bersamaan dengan percobaan manual.
  </Card>

  <Card title="Subscription Dunning" icon="repeat" href="/features/recovery/subscription-dunning">
    Kirim email kepada pelanggan untuk memperbarui metode pembayaran mereka setelah hard decline.
  </Card>

  <Card title="Handle Payment Failures" icon="screwdriver-wrench" href="/developer-resources/handle-payment-failures">
    Baca kode penolakan dan tentukan kapan percobaan ulang layak dilakukan.
  </Card>

  <Card title="Error Codes" icon="triangle-exclamation" href="/api-reference/error-codes">
    Setiap kode `MANUAL_RETRY_*`, pemicunya, dan pesannya.
  </Card>
</CardGroup>
