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

# Loops

> Kirim email transaksional dan kelola komunikasi pelanggan melalui Loops berdasarkan peristiwa Dodo Payments.

## Pendahuluan

Kirim email transaksional dan kelola komunikasi pelanggan secara otomatis saat peristiwa pembayaran terjadi. Kirim konfirmasi pembayaran, pembaruan langganan, dan pemberitahuan penting dengan infrastruktur email Loops.

<Info>
  Integrasi ini memerlukan Kunci API Loops Anda untuk otentikasi.
</Info>

## Memulai

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

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

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

  <Step title="Enter API Key">
    Masukkan Kunci API Loops Anda dalam konfigurasi.
  </Step>

  <Step title="Configure Transformation">
    Sunting kode transformasi untuk memformat email bagi API Loops.
  </Step>

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

  <Step title="Done!">
    🎉 Event pembayaran kini akan secara otomatis memicu email transaksional melalui Loops.
  </Step>
</Steps>

## Contoh Kode Transformasi

### Email Konfirmasi Pembayaran

```javascript payment_confirmation.js icon="js" expandable theme={null}
function handler(webhook) {
  if (webhook.eventType === "payment.succeeded") {
    const p = webhook.payload.data;
    webhook.url = "https://api.loops.so/v1/events/send";
    webhook.payload = {
      eventName: "payment_confirmation",
      email: p.customer.email,
      properties: {
        customer_name: p.customer.name,
        payment_id: p.payment_id,
        amount: (p.total_amount / 100).toFixed(2),
        currency: p.currency || "USD",
        payment_method: p.payment_method || "unknown",
        payment_date: new Date(webhook.payload.timestamp).toLocaleDateString()
      }
    };
  }
  return webhook;
}
```

### Email Selamat Datang Langganan

```javascript subscription_welcome.js icon="js" expandable theme={null}
function handler(webhook) {
  if (webhook.eventType === "subscription.active") {
    const s = webhook.payload.data;
    webhook.url = "https://api.loops.so/v1/events/send";
    webhook.payload = {
      eventName: "subscription_welcome",
      email: s.customer.email,
      properties: {
        customer_name: s.customer.name,
        subscription_id: s.subscription_id,
        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
      }
    };
  }
  return webhook;
}
```

### Pemberitahuan Kegagalan Pembayaran

```javascript payment_failure.js icon="js" expandable theme={null}
function handler(webhook) {
  if (webhook.eventType === "payment.failed") {
    const p = webhook.payload.data;
    webhook.url = "https://api.loops.so/v1/events/send";
    webhook.payload = {
      eventName: "payment_failed",
      email: p.customer.email,
      properties: {
        customer_name: p.customer.name,
        payment_id: p.payment_id,
        amount: (p.total_amount / 100).toFixed(2),
        error_message: p.error_message || "Payment processing failed",
        retry_link: `https://yourdomain.com/retry-payment/${p.payment_id}`
      }
    };
  }
  return webhook;
}
```

## Tips

* Gunakan nama peristiwa yang deskriptif untuk organisasi template email yang lebih baik
* Sertakan properti pelanggan yang relevan untuk personalisasi
* Siapkan template email di dasbor Loops untuk setiap peristiwa
* Gunakan penamaan properti yang konsisten di seluruh peristiwa
* Uji pengiriman email sebelum diluncurkan

## Pemecahan Masalah

<AccordionGroup>
  <Accordion title="Emails not being sent">
    * Verifikasi bahwa Kunci API benar dan aktif
    * Periksa bahwa nama event sesuai template Loops Anda
    * Pastikan alamat email penerima valid
    * Tinjau batasan dan kuota pengiriman Loops
  </Accordion>

  <Accordion title="Transformation errors">
    * Validasi struktur JSON sesuai format API Loops
    * Periksa bahwa semua field wajib ada
    * Pastikan nama event diformat dengan benar
    * Verifikasi izin kunci API
  </Accordion>
</AccordionGroup>
