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

# Keplars

> 当 Dodo Payments 的支付和订阅事件发生时，通过 Keplars 发送事务性电子邮件，无需 middleware server。

## 介绍

当支付和订阅事件发生时，自动发送事务性电子邮件。支付确认、订阅更新和失败通知将通过 Keplars 发送，无需 middleware server：Dodo Payments 直接调用 Keplars API，并使用 JavaScript transformation handler。

> [!NOTE]
>
> 此集成使用你的 Keplars API key 进行身份验证。你可以在 Keplars dashboard 的 **Settings → API Keys** 下找到它，并在 **Domains** 下验证 sender domain 或 address。

## 入门指南

**1. Open the Webhook Section**

在 Dodo Payments dashboard 中，前往 **Developer → Webhooks**，然后点击 **Add endpoint**。

**2. Select Keplars**

在 **Integration** 中选择 **Keplars**。模板会填入 Keplars API URL 和转换代码。

![已在 Integration 下拉菜单中选择 Keplars 的添加 endpoint 对话框](https://mintcdn.com/dodopayments/DL_ADtkdH7ph5YST/images/integrations/keplars/select.png?fit=max\&auto=format\&n=DL_ADtkdH7ph5YST\&q=85\&s=6dd9d05d29a67d43e74f5870c839725d)

**3. Enter API Key**

将 Keplars API key 粘贴到 **API key** 中。Dodo Payments 会在每个请求中将其作为 Bearer token 发送。在 **Subscribed events** 下，选择应发送电子邮件的事件。

![已填入 Keplars endpoint URL、API key 字段和 Subscribed events 列表](https://mintcdn.com/dodopayments/DL_ADtkdH7ph5YST/images/integrations/keplars/api-key.png?fit=max\&auto=format\&n=DL_ADtkdH7ph5YST\&q=85\&s=1639bfeb8a79835a274bb6ea07695489)

**4. Configure Transformation**

在 **Transformation code** 中编辑代码，以便为 Keplars 格式化电子邮件。将占位模板 ID 替换为你自己的 ID。

**5. Test & Create**

在 **Test this code** 下选择事件类型，然后点击 **Simulate**，针对示例 payload 运行 transformation。然后点击 **Create endpoint**，开始发送电子邮件。

**6. Done**

> [!TIP]
>
> Dodo Payments 事件现在会通过 Keplars 发送事务性电子邮件。

## 转换代码示例

每个 handler 都会将 `webhook.url` 设置为 Keplars 高优先级发送 endpoint，并将 `webhook.payload` 重写为 Keplars 请求。Dodo Payments 会将 API key 添加为 Bearer token。将 `your-keplars-*-template-id` 替换为你的模板 ID。Keplars send API 没有 `from` 字段，因此 Keplars 会使用你在 Keplars dashboard 中设置的发件人发送每封电子邮件。

> [!WARNING]
>
> `to` 必须是一个 **array**，即使只有一个收件人也是如此。使用 `template_id` 时，**不要**同时发送 `subject` 或 `body`，因为模板会提供这些内容。

### Payment Confirmation Email

```javascript payment_succeeded.js icon="js" expandable theme={null}
function handler(webhook) {
  if (webhook.eventType !== "payment.succeeded") return webhook;

  const data = webhook.payload.data || {};
  const paymentDate = new Date(webhook.payload.timestamp).toLocaleDateString("en-US", {
    year: "numeric", month: "long", day: "numeric",
  });

  webhook.url = "https://api.keplars.com/api/v1/send-email/high";
  webhook.payload = {
    to: [data.customer?.email],
    template_id: "your-keplars-payment-success-template-id",
    params: {
      customer_name: data.customer?.name,
      amount: ((data.total_amount || 0) / 100).toFixed(2),
      currency: data.currency || "USD",
      payment_id: data.payment_id,
      payment_method: data.payment_method,
      payment_date: paymentDate,
    },
  };
  return webhook;
}
```

### Payment Failure Notification

```javascript payment_failed.js icon="js" expandable theme={null}
function handler(webhook) {
  if (webhook.eventType !== "payment.failed") return webhook;

  const data = webhook.payload.data || {};
  const paymentDate = new Date(webhook.payload.timestamp).toLocaleDateString("en-US", {
    year: "numeric", month: "long", day: "numeric",
  });

  webhook.url = "https://api.keplars.com/api/v1/send-email/high";
  webhook.payload = {
    to: [data.customer?.email],
    template_id: "your-keplars-payment-failed-template-id",
    params: {
      customer_name: data.customer?.name,
      amount: ((data.total_amount || 0) / 100).toFixed(2),
      currency: data.currency || "USD",
      payment_id: data.payment_id,
      error_message: data.error_message || "Your payment could not be processed.",
      payment_date: paymentDate,
    },
  };
  return webhook;
}
```

### Subscription Welcome Email

```javascript subscription_active.js icon="js" expandable theme={null}
function handler(webhook) {
  if (webhook.eventType !== "subscription.active") return webhook;

  const data = webhook.payload.data || {};
  const nextBilling = data.next_billing_date
    ? new Date(data.next_billing_date).toLocaleDateString("en-US", {
        year: "numeric", month: "long", day: "numeric",
      })
    : "";

  webhook.url = "https://api.keplars.com/api/v1/send-email/high";
  webhook.payload = {
    to: [data.customer?.email],
    template_id: "your-keplars-subscription-active-template-id",
    params: {
      customer_name: data.customer?.name,
      subscription_id: data.subscription_id,
      product_id: data.product_id,
      amount: ((data.recurring_pre_tax_amount || 0) / 100).toFixed(2),
      currency: data.currency || "USD",
      billing_interval: data.payment_frequency_interval || "Month",
      next_billing_date: nextBilling,
    },
  };
  return webhook;
}
```

### Subscription Cancellation Email

```javascript subscription_cancelled.js icon="js" expandable theme={null}
function handler(webhook) {
  if (webhook.eventType !== "subscription.cancelled") return webhook;

  const data = webhook.payload.data || {};
  const cancellationDate = new Date(webhook.payload.timestamp).toLocaleDateString("en-US", {
    year: "numeric", month: "long", day: "numeric",
  });

  webhook.url = "https://api.keplars.com/api/v1/send-email/high";
  webhook.payload = {
    to: [data.customer?.email],
    template_id: "your-keplars-subscription-cancelled-template-id",
    params: {
      customer_name: data.customer?.name,
      subscription_id: data.subscription_id,
      cancellation_date: cancellationDate,
    },
  };
  return webhook;
}
```

## 提示

* 使用经过验证的域名或地址发送邮件，以提高送达率。
* 为每种事件类型创建一个 Keplars 模板，以确保每封电子邮件都符合你的品牌风格并传达一致的信息。
* 通过在 `params` 中传递客户数据（例如姓名、金额和 payment ID），为每封电子邮件进行个性化设置。
* 首先在 sandbox mode 中进行测试。Keplars 会将 sandbox 发送记录在其 Test Inbox 中，而不会实际投递。

## 故障排除

> **Emails not being sent**
>
> * 在 Keplars 的 **Settings → API Keys** 中检查你的 API key 是否正确且处于 active 状态。
> * 检查你的发件人域名或地址是否已验证。
> * 在 Dodo Payments dashboard 中，打开 **Developer → Webhooks** 的 **Logs** 标签页中的消息。每次投递尝试都会显示来自 Keplars 的原始错误响应。

> **Template not found**
>
> * handler 中的 `template_id` 必须与 Keplars 账户中的 active 模板匹配。在 Keplars dashboard 中检查 ID，并确认模板处于 active 状态。

> **Wrong event triggered**
>
> * 每个 handler 都会检查 `webhook.eventType`；如果事件不匹配，则原样返回 webhook。检查 endpoint 的 **Subscribed events** 是否仅包含你需要的事件。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.