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

# Inngest

> Trigger serverless functions and background jobs in Inngest based on Dodo Payments events.

## Pendahuluan

Eksekusi fungsi serverless dan pekerjaan latar belakang secara otomatis ketika peristiwa pembayaran terjadi. Proses pembayaran, kirim notifikasi, perbarui basis data, dan jalankan alur kerja yang kompleks dengan platform eksekusi fungsi Inngest yang andal.

<Info>
  Integrasi ini memerlukan URL webhook Inngest Anda dari konfigurasi fungsi Anda.
</Info>

## Memulai

<Steps>
  <Step title="Open the Webhook Section">
    Di dashboard Dodo Payments Anda, navigasikan ke <b>Webhooks → + Tambah Endpoint</b> dan perluas dropdown integrasi.

    <Frame>
      <img src="https://mintcdn.com/dodopayments/slbAEdrLLwKHfaRf/images/integrations/inngest.png?fit=max&auto=format&n=slbAEdrLLwKHfaRf&q=85&s=b160678c00ceed38439160b4b253c8f3" alt="Tambah Endpoint dan dropdown integrasi" style={{ maxHeight: '500px', width: 'auto' }} width="1646" height="944" data-path="images/integrations/inngest.png" />
    </Frame>
  </Step>

  <Step title="Select Inngest">
    Pilih kartu integrasi <b>Inngest</b>.
  </Step>

  <Step title="Create Inngest Function">
    Di Inngest, buat fungsi baru dan salin URL webhook dari konfigurasi fungsi.
  </Step>

  <Step title="Paste Webhook URL">
    Tempelkan URL webhook Inngest ke dalam konfigurasi endpoint.
  </Step>

  <Step title="Configure Transformation">
    Edit kode transformasi untuk memformat event sesuai fungsi Inngest Anda.
  </Step>

  <Step title="Test & Create">
    Uji dengan payload contoh dan klik <b>Create</b> untuk mengaktifkan integrasi.
  </Step>

  <Step title="Done!">
    🎉 Event pembayaran kini akan memicu fungsi Inngest Anda secara otomatis.
  </Step>
</Steps>

## Contoh Kode Transformasi

### Payload Peristiwa Dasar

```javascript basic_event.js icon="js" expandable theme={null}
function handler(webhook) {
  if (webhook.eventType === "payment.succeeded") {
    const p = webhook.payload.data;
    webhook.payload = {
      name: "payment.succeeded",
      data: {
        payment_id: p.payment_id,
        amount: (p.total_amount / 100).toFixed(2),
        currency: p.currency || "USD",
        customer_email: p.customer.email,
        customer_name: p.customer.name,
        payment_method: p.payment_method || "unknown"
      },
      user: {
        email: p.customer.email
      },
      ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
    };
  }
  return webhook;
}
```

### Penangan Acara Langganan

```javascript subscription_event.js icon="js" expandable theme={null}
function handler(webhook) {
  const s = webhook.payload.data;
  switch (webhook.eventType) {
    case "subscription.active":
      webhook.payload = {
        name: "subscription.started",
        data: {
          subscription_id: s.subscription_id,
          customer_email: s.customer.email,
          customer_name: s.customer.name,
          product_id: s.product_id,
          amount: (s.recurring_pre_tax_amount / 100).toFixed(2),
          frequency: s.payment_frequency_interval,
          next_billing: s.next_billing_date
        },
        user: {
          email: s.customer.email
        },
        ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
      };
      break;
    case "subscription.cancelled":
      webhook.payload = {
        name: "subscription.cancelled",
        data: {
          subscription_id: s.subscription_id,
          customer_email: s.customer.email,
          cancelled_at: s.cancelled_at,
          cancel_at_next_billing: s.cancel_at_next_billing_date
        },
        user: {
          email: s.customer.email
        },
        ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
      };
      break;
  }
  return webhook;
}
```

### Penangan Acara Sengketa

```javascript dispute_event.js icon="js" expandable theme={null}
function handler(webhook) {
  if (webhook.eventType.startsWith("dispute.")) {
    const d = webhook.payload.data;
    webhook.payload = {
      name: webhook.eventType,
      data: {
        dispute_id: d.dispute_id,
        payment_id: d.payment_id,
        amount: (d.amount / 100).toFixed(2),
        status: d.dispute_status,
        stage: d.dispute_stage,
        remarks: d.remarks || "",
        urgent: webhook.eventType === "dispute.opened"
      },
      user: {
        email: d.customer?.email || "unknown"
      },
      ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
    };
  }
  return webhook;
}
```

## Kasus Penggunaan Inngest yang Umum

<AccordionGroup>
  <Accordion title="Payment Processing">
    * Kirim email konfirmasi
    * Perbarui catatan pelanggan
    * Proses pengembalian dana
    * Buat faktur
    * Perbarui inventaris
  </Accordion>

  <Accordion title="Subscription Management">
    * Sambut pelanggan baru
    * Proses pembatalan
    * Kirim pengingat perpanjangan
    * Perbarui siklus penagihan
    * Tangani pembayaran gagal
  </Accordion>

  <Accordion title="Analytics & Reporting">
    * Perbarui metrik pendapatan
    * Lacak perilaku pelanggan
    * Buat laporan
    * Sinkronkan data ke platform analitik
    * Hitung tingkat churn
  </Accordion>
</AccordionGroup>

## Tips

* Gunakan nama peristiwa yang deskriptif untuk organisasi fungsi yang lebih baik
* Sertakan konteks pengguna untuk eksekusi fungsi
* Atur cap waktu yang tepat untuk urutan peristiwa
* Struktur data secara konsisten di seluruh peristiwa
* Gunakan fitur pengulangan dan penanganan kesalahan Inngest

## Pemecahan Masalah

<AccordionGroup>
  <Accordion title="Functions not triggering">
    * Verifikasi URL webhook sudah benar dan aktif
    * Periksa bahwa fungsi Inngest telah dideploy dan aktif
    * Pastikan nama event sesuai pemicu fungsi
    * Tinjau log fungsi Inngest untuk mencari kesalahan
  </Accordion>

  <Accordion title="Data not received correctly">
    * Periksa struktur payload sesuai harapan Inngest
    * Verifikasi nama event diformat dengan benar
    * Pastikan semua field wajib disertakan
    * Uji dengan alat pengujian webhook Inngest
  </Accordion>
</AccordionGroup>
