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

# Kincir Angin

> Trigger alur kerja dan skrip Kincir Angin berdasarkan peristiwa Pembayaran Dodo untuk otomatisasi kustom.

## Pendahuluan

Eksekusi alur kerja dan skrip kustom di Kincir Angin saat peristiwa pembayaran terjadi. Jalankan operasi basis data, kirim notifikasi, proses data, dan otomatisasi logika bisnis yang kompleks dengan mesin alur kerja Kincir Angin yang kuat.

<Info>
  Integrasi ini memerlukan URL webhook Windmill Anda dari konfigurasi workflow.
</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/windmill.png?fit=max&auto=format&n=slbAEdrLLwKHfaRf&q=85&s=695fe639c086c3d899efae177d646591" alt="Tambah Endpoint dan dropdown integrasi" style={{ maxHeight: '500px', width: 'auto' }} width="1678" height="954" data-path="images/integrations/windmill.png" />
    </Frame>
  </Step>

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

  <Step title="Create Windmill Workflow">
    Di Windmill, buat workflow baru dan salin URL webhook dari konfigurasi pemicu.
  </Step>

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

  <Step title="Configure Transformation">
    Edit kode transformasi untuk memformat event bagi workflow Windmill Anda.
  </Step>

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

  <Step title="Done!">
    🎉 Event pembayaran sekarang akan memicu workflow Windmill Anda secara otomatis.
  </Step>
</Steps>

## Contoh Kode Transformasi

### Payload Alur Kerja Dasar

```javascript basic_workflow.js icon="js" expandable theme={null}
function handler(webhook) {
  if (webhook.eventType === "payment.succeeded") {
    const p = webhook.payload.data;
    webhook.payload = {
      event_type: webhook.eventType,
      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",
      timestamp: webhook.payload.timestamp,
      metadata: {
        business_id: p.business_id,
        product_id: p.product_id
      }
    };
  }
  return webhook;
}
```

### Penangan Alur Kerja Langganan

```javascript subscription_workflow.js icon="js" expandable theme={null}
function handler(webhook) {
  const s = webhook.payload.data;
  switch (webhook.eventType) {
    case "subscription.active":
      webhook.payload = {
        event_type: "subscription_started",
        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,
        customer_id: s.customer.customer_id,
        timestamp: webhook.payload.timestamp
      };
      break;
    case "subscription.cancelled":
      webhook.payload = {
        event_type: "subscription_cancelled",
        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,
        customer_id: s.customer.customer_id,
        timestamp: webhook.payload.timestamp
      };
      break;
  }
  return webhook;
}
```

### Penangan Alur Kerja Sengketa

```javascript dispute_workflow.js icon="js" expandable theme={null}
function handler(webhook) {
  if (webhook.eventType.startsWith("dispute.")) {
    const d = webhook.payload.data;
    webhook.payload = {
      event_type: webhook.eventType,
      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",
      business_id: d.business_id,
      timestamp: webhook.payload.timestamp
    };
  }
  return webhook;
}
```

## Kasus Penggunaan Kincir Angin yang Umum

<AccordionGroup>
  <Accordion title="Database Operations">
    * Perbarui catatan pelanggan di PostgreSQL/MySQL
    * Catat event pembayaran ke gudang data
    * Sinkronkan data ke sistem eksternal
    * Perbarui tingkat inventaris
    * Lacak metrik analitik
  </Accordion>

  <Accordion title="Business Logic">
    * Hitung metrik pendapatan
    * Proses pengembalian dana dan penyesuaian
    * Tangani siklus hidup langganan
    * Hasilkan laporan dan ekspor
    * Validasi data pembayaran
  </Accordion>

  <Accordion title="External Integrations">
    * Kirim data ke platform analitik
    * Perbarui sistem CRM
    * Picu kampanye email
    * Buat event kalender
    * Kirim notifikasi SMS
  </Accordion>
</AccordionGroup>

## Tips

* Struktur data payload untuk pemrosesan alur kerja yang mudah
* Sertakan semua metadata relevan untuk logika bisnis
* Gunakan penamaan field yang konsisten di seluruh peristiwa
* Sertakan cap waktu untuk penjadwalan alur kerja
* Manfaatkan penanganan kesalahan bawaan Kincir Angin

## Pemecahan Masalah

<AccordionGroup>
  <Accordion title="Workflows not triggering">
    * Verifikasi bahwa URL webhook benar dan aktif
    * Periksa bahwa workflow Windmill sudah diterbitkan dan aktif
    * Pastikan struktur payload sesuai dengan ekspektasi workflow
    * Tinjau log eksekusi Windmill untuk kesalahan
  </Accordion>

  <Accordion title="Data processing issues">
    * Periksa pemetaan parameter input workflow
    * Verifikasi tipe data sesuai format yang diharapkan
    * Uji workflow dengan data sampel
    * Tinjau log eksekusi skrip Windmill
  </Accordion>
</AccordionGroup>
