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

# Panduan Integrasi Langganan

> Panduan ini akan membantu Anda mengintegrasikan Produk Langganan Dodo Payments ke dalam situs web Anda.

## Prasyarat

Untuk mengintegrasikan API Dodo Payments, Anda memerlukan:

* Akun pedagang Dodo Payments
* Kredensial API (kunci API dan kunci rahasia webhook) dari dasbor

Untuk panduan yang lebih rinci tentang prasyarat, periksa [bagian ini](/developer-resources/integration-guide#dashboard-setup).

## Integrasi API

### Sesi Checkout

Gunakan Checkout Sessions untuk menjual produk langganan dengan checkout yang aman dan dihosting. Sertakan produk langganan Anda di `product_cart` dan alihkan pelanggan ke `checkout_url`.

<Tip>
  **Mixed Checkout**: Anda dapat menggabungkan produk langganan dengan produk satu kali dalam sesi checkout yang sama. Ini memungkinkan kasus penggunaan seperti biaya penyiapan dengan langganan, paket perangkat keras dengan SaaS, dan lainnya. Lihat [Checkout Sessions guide](/developer-resources/checkout-session) untuk contoh.
</Tip>

<Tabs>
  <Tab title="Node.js SDK">
    ```javascript theme={null}
    import DodoPayments from 'dodopayments';

    const client = new DodoPayments({
      bearerToken: process.env.DODO_PAYMENTS_API_KEY,
      environment: 'test_mode', // defaults to 'live_mode'
    });

    async function main() {
      const session = await client.checkoutSessions.create({
        product_cart: [
          { product_id: 'prod_subscription_monthly', quantity: 1 }
        ],
        // Optional: configure trials for subscription products
        subscription_data: { trial_period_days: 14 },
        customer: {
          email: 'subscriber@example.com',
          name: 'Jane Doe',
        },
        return_url: 'https://example.com/success',
      });

      console.log(session.checkout_url);
    }

    main();
    ```
  </Tab>

  <Tab title="Python SDK">
    ```python theme={null}
    import os
    from dodopayments import DodoPayments

    client = DodoPayments(
        bearer_token=os.environ.get("DODO_PAYMENTS_API_KEY"),
        environment="test_mode",  # defaults to "live_mode"
    )

    session = client.checkout_sessions.create(
        product_cart=[
            {"product_id": "prod_subscription_monthly", "quantity": 1}
        ],
        subscription_data={"trial_period_days": 14},  # optional
        customer={
            "email": "subscriber@example.com",
            "name": "Jane Doe",
        },
        return_url="https://example.com/success",
    )

    print(session.checkout_url)
    ```
  </Tab>

  <Tab title="REST API">
    ```javascript theme={null}
    const response = await fetch('https://test.dodopayments.com/checkouts', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${process.env.DODO_PAYMENTS_API_KEY}`
      },
      body: JSON.stringify({
        product_cart: [
          { product_id: 'prod_subscription_monthly', quantity: 1 }
        ],
        subscription_data: { trial_period_days: 14 }, // optional
        customer: {
          email: 'subscriber@example.com',
          name: 'Jane Doe'
        },
        return_url: 'https://example.com/success'
      })
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const session = await response.json();
    console.log(session.checkout_url);
    ```
  </Tab>
</Tabs>

### Respons API

Berikut adalah contoh respons:

```json theme={null}
{
  "session_id": "cks_Gi6KGJ2zFJo9rq9Ukifwa",
  "checkout_url": "https://test.checkout.dodopayments.com/session/cks_Gi6KGJ2zFJo9rq9Ukifwa"
}
```

Alihkan pelanggan ke `checkout_url`.

### Webhook

Saat mengintegrasikan langganan, Anda akan menerima webhook untuk melacak siklus hidup langganan. Webhook ini membantu Anda mengelola status langganan dan skenario pembayaran dengan efektif.

Untuk mengatur endpoint webhook Anda, silakan ikuti [Panduan Integrasi Rinci](/developer-resources/integration-guide#implementing-webhooks).

#### Jenis Acara Langganan

Berikut adalah acara webhook yang melacak perubahan status langganan:

1. **`subscription.active`** - Langganan berhasil diaktifkan.
2. **`subscription.updated`** - Objek langganan diperbarui (dipicu pada setiap perubahan bidang).
3. **`subscription.on_hold`** - Langganan ditangguhkan karena pembaruan gagal.
4. **`subscription.failed`** - Pembuatan langganan gagal selama pembuatan mandat.
5. **`subscription.renewed`** - Langganan diperbarui untuk periode penagihan berikutnya.

Untuk manajemen siklus hidup langganan yang andal, kami merekomendasikan untuk melacak acara langganan ini.

<Tip>
  Gunakan `subscription.updated` untuk mendapatkan pemberitahuan waktu nyata tentang perubahan langganan apa pun, menjaga status aplikasi Anda tetap sinkron tanpa harus memanggil API secara berkala.
</Tip>

#### Skenario Pembayaran

**Alur Pembayaran Berhasil**

Ketika pembayaran berhasil, Anda akan menerima webhook berikut:

1. `subscription.active` - Menunjukkan aktivasi langganan
2. `payment.succeeded` - Mengonfirmasi pembayaran awal:
   * Untuk penagihan langsung (0 hari percobaan): Harapkan dalam 2-10 menit
   * Untuk masa percobaan: kapan pun itu berakhir
3. `subscription.renewed` - Menunjukkan pemotongan pembayaran dan pembaruan untuk siklus berikutnya. (Pada dasarnya, kapan pun pembayaran ditagihkan untuk produk langganan, Anda akan menerima webhook `subscription.renewed` bersamaan dengan `payment.succeeded`)

**Skenario Kegagalan Pembayaran**

1. Kegagalan Langganan

* `subscription.failed` - Pembuatan langganan gagal karena kegagalan membuat mandat.
* `payment.failed` - Menunjukkan pembayaran gagal.

2. Langganan Ditangguhkan

* `subscription.on_hold` - Langganan ditangguhkan karena pembayaran pembaruan gagal atau biaya perubahan paket gagal.
* Saat langganan ditangguhkan, langganan tidak akan diperbarui otomatis sampai metode pembayaran diperbarui.

<Info>**Praktik Terbaik**: Untuk menyederhanakan implementasi, kami menyarankan agar Anda terutama melacak event langganan untuk mengelola siklus hidup langganan.</Info>

### Menangani Langganan Ditangguhkan

Saat langganan memasuki status `on_hold`, Anda perlu memperbarui metode pembayaran untuk mengaktifkannya kembali. Bagian ini menjelaskan kapan langganan ditangguhkan dan cara menanganinya.

#### Ketika Langganan Ditangguhkan

Sebuah langganan ditangguhkan ketika:

* **Pembayaran pembaruan gagal**: Biaya pembaruan otomatis gagal karena dana tidak mencukupi, kartu kadaluarsa, atau penolakan bank
* **Biaya perubahan rencana gagal**: Biaya segera selama peningkatan/penurunan rencana gagal
* **Otorisasi metode pembayaran gagal**: Metode pembayaran tidak dapat diotorisasi untuk biaya berulang

<Warning>
  Langganan dalam status `on_hold` tidak akan diperbarui secara otomatis. Anda harus memperbarui metode pembayaran agar langganan aktif kembali.
</Warning>

#### Mengaktifkan Kembali Langganan dari Ditangguhkan

Untuk mengaktifkan kembali langganan dari status `on_hold`, gunakan Update Payment Method API. Ini secara otomatis:

1. Membuat biaya untuk tunggakan yang tersisa
2. Menghasilkan faktur untuk biaya tersebut
3. Memproses pembayaran menggunakan metode pembayaran baru
4. Mengaktifkan kembali langganan ke status `active` setelah pembayaran berhasil

<Steps>
  <Step title="Handle subscription.on_hold webhook">
    Saat Anda menerima webhook `subscription.on_hold`, perbarui status aplikasi Anda dan beri tahu pelanggan:

    ```javascript theme={null}
    // Webhook handler
    app.post('/webhooks/dodo', async (req, res) => {
      const event = req.body;
      
      if (event.type === 'subscription.on_hold') {
        const subscription = event.data;
        
        // Update subscription status in your database
        await updateSubscriptionStatus(subscription.subscription_id, 'on_hold');
        
        // Notify customer to update payment method
        await sendEmailToCustomer(subscription.customer_id, {
          subject: 'Payment Required - Subscription On Hold',
          message: 'Your subscription is on hold. Please update your payment method to continue service.'
        });
      }
      
      res.json({ received: true });
    });
    ```
  </Step>

  <Step title="Update payment method">
    Saat pelanggan siap memperbarui metode pembayarannya, panggil Update Payment Method API:

    <CodeGroup>
      ```javascript Node.js theme={null}
      // Update with new payment method
      const response = await client.subscriptions.updatePaymentMethod(subscriptionId, {
        type: 'new',
        return_url: 'https://example.com/return'
      });

      // For on_hold subscriptions, a charge is automatically created
      if (response.payment_id) {
        console.log('Charge created for remaining dues:', response.payment_id);
        // Redirect customer to response.payment_link to complete payment
      }
      ```

      ```python Python theme={null}
      # Update with new payment method
      response = client.subscriptions.update_payment_method(
          subscription_id=subscription_id,
          type="new",
          return_url="https://example.com/return"
      )

      # For on_hold subscriptions, a charge is automatically created
      if response.payment_id:
          print("Charge created for remaining dues:", response.payment_id)
          # Redirect customer to response.payment_link to complete payment
      ```
    </CodeGroup>

    <Info>
      Anda juga dapat menggunakan ID metode pembayaran yang sudah ada jika pelanggan telah menyimpan metode pembayaran:

      ```javascript theme={null}
      await client.subscriptions.updatePaymentMethod(subscriptionId, {
        type: 'existing',
        payment_method_id: 'pm_abc123'
      });
      ```
    </Info>
  </Step>

  <Step title="Monitor webhook events">
    Setelah memperbarui metode pembayaran, pantau event webhook berikut:

    1. **`payment.succeeded`** - Biaya untuk tunggakan berhasil

    2. **`subscription.active`** - Langganan telah diaktifkan kembali

    3. **`payment.succeeded`** - Tagihan untuk tunggakan yang tersisa berhasil

    4. **`subscription.active`** - Langganan telah diaktifkan kembali

    ```javascript theme={null}
    if (event.type === 'payment.succeeded') {
      const payment = event.data;
      
      // Check if this payment is for an on_hold subscription
      if (payment.subscription_id) {
        // Wait for subscription.active webhook to confirm reactivation
      }
    }

    if (event.type === 'subscription.active') {
      const subscription = event.data;
      
      // Update subscription status in your database
      await updateSubscriptionStatus(subscription.subscription_id, 'active');
      
      // Restore customer access
      await restoreCustomerAccess(subscription.customer_id);
      
      // Notify customer of successful reactivation
      await sendEmailToCustomer(subscription.customer_id, {
        subject: 'Subscription Reactivated',
        message: 'Your subscription has been reactivated successfully.'
      });
    }
    ```
  </Step>
</Steps>

### Contoh Payload Acara Langganan

***

| Properti      | Tipe   | Wajib | Deskripsi                                                              |
| ------------- | ------ | ----- | ---------------------------------------------------------------------- |
| `business_id` | string | Yes   | Pengidentifikasi unik untuk bisnis                                     |
| `timestamp`   | string | Yes   | Cap waktu saat event terjadi (tidak harus sama dengan saat dikirimkan) |
| `type`        | string | Yes   | Jenis event. Lihat [Event Types](#event-types)                         |
| `data`        | object | Yes   | Muatan data utama. Lihat [Data Object](#data-object)                   |

## Mengubah Rencana Langganan

Anda dapat meningkatkan atau menurunkan rencana langganan menggunakan endpoint API perubahan rencana. Ini memungkinkan Anda untuk memodifikasi produk langganan, kuantitas, dan menangani proration.

<Card title="Change Plan API Reference" icon="arrows-rotate" href="/api-reference/subscriptions/change-plan">
  Untuk informasi rinci tentang mengubah paket langganan, silakan merujuk ke dokumentasi Change Plan API kami.
</Card>

### Opsi Prorata

Saat mengubah rencana langganan, Anda memiliki dua opsi untuk menangani biaya segera:

#### 1. `prorated_immediately`

* Menghitung jumlah prorata berdasarkan waktu yang tersisa dalam siklus penagihan saat ini
* Menagih pelanggan hanya untuk selisih antara paket lama dan baru
* Selama masa percobaan, ini akan langsung memindahkan pengguna ke paket baru dan menagih pelanggan segera

#### 2. `full_immediately`

* Menagih pelanggan jumlah langganan penuh untuk paket baru
* Mengabaikan waktu tersisa atau kredit dari paket sebelumnya
* Berguna ketika Anda ingin mereset siklus penagihan atau menagih jumlah penuh tanpa memperhatikan prorata

#### 3. `difference_immediately`

* Saat upgrade, pelanggan langsung dikenakan selisih antara dua jumlah paket yang berbeda.
* Misalnya, jika paket saat ini 30 Dollars dan pelanggan upgrade ke 80 Dollars, mereka langsung dikenakan \$50.
* Saat downgrade, jumlah yang tidak terpakai dari paket saat ini ditambahkan sebagai kredit internal dan otomatis diterapkan ke pembaruan langganan berikutnya.
* Misalnya, jika paket saat ini 50 Dollars dan pelanggan beralih ke paket 20 Dollars, sisa \$30 dikreditkan dan digunakan untuk siklus penagihan berikutnya.

### Perilaku

* Saat Anda memanggil API ini, Dodo Payments segera memulai biaya berdasarkan opsi prorata yang Anda pilih
* Jika perubahan paket adalah downgrade dan Anda menggunakan `prorated_immediately`, kredit akan otomatis dihitung dan ditambahkan ke saldo kredit langganan. Kredit ini khusus untuk langganan tersebut dan hanya akan digunakan untuk mengimbangi pembayaran berulang di masa depan dari langganan yang sama
* Opsi `full_immediately` melewati perhitungan kredit dan menagih jumlah paket baru secara penuh

<Tip>
  **Pilih opsi prorata Anda dengan hati-hati**: Gunakan `prorated_immediately` untuk penagihan yang adil yang memperhitungkan waktu yang belum digunakan, atau `full_immediately` ketika Anda ingin menagih jumlah paket baru secara penuh tanpa memperhatikan siklus penagihan saat ini.
</Tip>

### Pemrosesan Biaya

* Biaya segera yang dimulai saat perubahan rencana biasanya selesai diproses dalam waktu kurang dari 2 menit
* Jika biaya segera ini gagal karena alasan apa pun, langganan secara otomatis ditangguhkan sampai masalah teratasi

## Langganan Sesuai Permintaan

<Info>
  Langganan on-demand memungkinkan Anda menagih pelanggan secara fleksibel, tidak hanya berdasarkan jadwal tetap. Fitur ini tersedia untuk semua akun.
</Info>

**Untuk membuat langganan sesuai permintaan:**

Untuk membuat langganan on-demand, gunakan endpoint API [POST /subscriptions](/api-reference/subscriptions/post-subscriptions) dan sertakan bidang `on_demand` dalam tubuh permintaan Anda. Ini memungkinkan Anda mengotorisasi metode pembayaran tanpa biaya langsung, atau menetapkan harga awal kustom.

**Untuk mengenakan biaya langganan sesuai permintaan:**

Untuk tagihan selanjutnya, gunakan endpoint [POST /subscriptions/{subscription_id}/charge](/api-reference/subscriptions/create-charge) dan tentukan jumlah yang akan ditagihkan kepada pelanggan untuk transaksi tersebut.

<Note>
  Untuk panduan lengkap langkah demi langkah—termasuk contoh permintaan/respons, kebijakan percobaan aman, dan penanganan webhook—lihat <a href="/developer-resources/ondemand-subscriptions">On-Demand Subscriptions Guide</a>.
</Note>

## Referensi API Terkait

API reference untuk membuat produk langganan dan mengelola siklus hidup langganan
API reference untuk meningkatkan, menurunkan, atau mengubah rencana langganan dengan opsi proration
API reference untuk memperbarui metode pembayaran dan mengaktifkan kembali langganan yang ditunda
API reference untuk memperbarui detail dan konfigurasi langganan

**Untuk mengisi langganan sesuai permintaan:**

Untuk biaya berikutnya, gunakan endpoint [POST /subscriptions/{subscription_id}/charge](/api-reference/subscriptions/create-charge) dan tentukan jumlah yang akan dibebankan kepada pelanggan untuk transaksi tersebut.

<Note>
  Untuk panduan lengkap langkah demi langkah—termasuk contoh permintaan/respons, kebijakan retry aman, dan penanganan webhook—lihat <a href="/developer-resources/ondemand-subscriptions">Panduan Langganan Sesuai Permintaan</a>.
</Note>

## Referensi API Terkait

<CardGroup cols={2}>
  <Card title="Create Subscription" icon="code" href="/api-reference/subscriptions/post-subscriptions">
    Referensi API untuk membuat produk langganan dan mengelola siklus hidup langganan
  </Card>

  <Card title="Change Subscription Plan" icon="arrows-rotate" href="/api-reference/subscriptions/change-plan">
    Referensi API untuk meningkatkan, menurunkan, atau mengubah paket langganan dengan opsi prorata
  </Card>

  <Card title="Update Payment Method" icon="credit-card" href="/api-reference/subscriptions/update-payment-method">
    Referensi API untuk memperbarui metode pembayaran dan mengaktifkan kembali langganan yang ditunda
  </Card>

  <Card title="Patch Subscription" icon="pen" href="/api-reference/subscriptions/patch-subscriptions">
    Referensi API untuk memperbarui detail dan konfigurasi langganan
  </Card>
</CardGroup>
