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

# Slack

> Tích hợp Dodo Payments với Slack để nhận thông báo thời gian thực về các khoản thanh toán của bạn.

## Giới thiệu

Tích hợp Dodo Payments với Slack cho phép bạn nhận thông báo thời gian thực về các khoản thanh toán của mình trực tiếp trong không gian làm việc Slack. Tích hợp này giúp bạn cập nhật tình trạng của các khoản thanh toán, theo dõi giao dịch và quản lý các khoản thanh toán của mình một cách hiệu quả hơn.

<Info>
  Tích hợp này sử dụng cổng quản lý webhook của chúng tôi để tự động chuyển đổi các sự kiện webhook của Dodo Payments thành các thông báo tương thích với Slack. Không cần lập trình bổ sung — chỉ cần cấu hình bộ kết nối và bắt đầu nhận thông báo.
</Info>

## Bắt đầu

<Steps>
  <Step title="Open the Webhook Section">
    Truy cập phần <b>Webhook</b> trong bảng điều khiển Dodo Payments của bạn. Nhấp vào nút <b>+ Add Endpoint</b>, sau đó mở trình đơn thả xuống webhook để hiển thị các tích hợp khác.

    <Frame>
      <img src="https://mintcdn.com/dodopayments/slbAEdrLLwKHfaRf/images/integrations/slack/1.png?fit=max&auto=format&n=slbAEdrLLwKHfaRf&q=85&s=46218103ebf0646011873758c76b9bb6" alt="Dodo Payments dashboard showing Add Endpoint button and integrations dropdown" width="1782" height="1016" data-path="images/integrations/slack/1.png" />
    </Frame>
  </Step>

  <Step title="Select Slack Integration">
    Chọn tích hợp <b>Slack</b> và nhấp vào <b>Connect your Slack workspace</b>.

    <Frame>
      <img src="https://mintcdn.com/dodopayments/slbAEdrLLwKHfaRf/images/integrations/slack/2.png?fit=max&auto=format&n=slbAEdrLLwKHfaRf&q=85&s=4bd696f82dbbab1bc099c6ccae5b9212" alt="Slack integration card and connect button" width="1670" height="226" data-path="images/integrations/slack/2.png" />
    </Frame>
  </Step>

  <Step title="Grant Slack Permissions">
    Cấp các quyền cần thiết cho Ứng dụng Slack Incoming Webhooks để nó có thể đăng tin nhắn vào kênh bạn chọn.

    <Frame>
      <img src="https://mintcdn.com/dodopayments/slbAEdrLLwKHfaRf/images/integrations/slack/3.png?fit=max&auto=format&n=slbAEdrLLwKHfaRf&q=85&s=00f04516a2720e377a29551ae42ad812" alt="Slack OAuth permissions screen for Incoming Webhooks app" width="1198" height="1536" data-path="images/integrations/slack/3.png" />
    </Frame>
  </Step>

  <Step title="Customize Transformation Code">
    Thêm hoặc chỉnh sửa mã biến đổi để tùy chỉnh thông báo Slack phù hợp với trường hợp sử dụng của bạn. Bạn có thể sử dụng các mẫu có sẵn hoặc tự viết logic riêng.

    <Frame>
      <img src="https://mintcdn.com/dodopayments/slbAEdrLLwKHfaRf/images/integrations/slack/4.png?fit=max&auto=format&n=slbAEdrLLwKHfaRf&q=85&s=f3c7f2b7a9bb6d6ba1d1d6922ad42bc4" alt="Transformation code editor for Slack integration" width="1686" height="1118" data-path="images/integrations/slack/4.png" />
    </Frame>
  </Step>

  <Step title="Test and Create">
    Kiểm tra mã biến đổi của bạn bằng các payload sự kiện tùy chỉnh hoặc có sẵn. Khi đã hài lòng, nhấp <b>Create</b> để kích hoạt tích hợp.

    <Frame>
      <img src="https://mintcdn.com/dodopayments/slbAEdrLLwKHfaRf/images/integrations/slack/5.png?fit=max&auto=format&n=slbAEdrLLwKHfaRf&q=85&s=7d22a91488a2038a177324fa627b7497" alt="Test transformation and create button" width="1852" height="490" data-path="images/integrations/slack/5.png" />
    </Frame>
  </Step>

  <Step title="Integration Complete!">
    🎉 Bạn đã tạo thành công tích hợp Slack! Các sự kiện Dodo Payments giờ sẽ được gửi đến kênh Slack bạn chọn theo thời gian thực.
  </Step>
</Steps>

## Ví Dụ Mã Chuyển Đổi

### Thông Báo Thanh Toán Cơ Bản

Chuyển đổi này gửi các tin nhắn văn bản đơn giản cho các sự kiện thanh toán:

```javascript payment_notifs.js icon="js" expandable theme={null}
function handler(webhook) {
  switch (webhook.eventType) {
    case "payment.succeeded":
      webhook.payload = {
        text: `✅ Payment Successful\nAmount: $${(webhook.payload.data.total_amount / 100).toFixed(2)}\nCustomer: ${webhook.payload.data.customer.email}\nPayment ID: ${webhook.payload.data.payment_id}`
      };
      break;
      
    case "payment.failed":
      webhook.payload = {
        text: `❌ Payment Failed\nAmount: $${(webhook.payload.data.total_amount / 100).toFixed(2)}\nCustomer: ${webhook.payload.data.customer.email}\nReason: ${webhook.payload.data.error_message || 'Unknown'}`
      };
      break;
      
    case "payment.processing":
      webhook.payload = {
        text: `⏳ Payment Processing\nAmount: $${(webhook.payload.data.total_amount / 100).toFixed(2)}\nCustomer: ${webhook.payload.data.customer.email}`
      };
      break;
  }

  return webhook;
}
```

### Thông Báo Đăng Ký Đầy Đủ

Chuyển đổi này tạo ra các tin nhắn Slack phong phú với các tệp đính kèm cho các sự kiện đăng ký:

```javascript subscription_notifs.js icon="js" expandable theme={null}
function handler(webhook) {
  switch (webhook.eventType) {
    case "subscription.active":
      webhook.payload = {
        attachments: [{
          color: "good",
          title: "🎉 Subscription Activated",
          fields: [
            {
              title: "Customer",
              value: webhook.payload.data.customer.email,
              short: true
            },
            {
              title: "Product ID",
              value: webhook.payload.data.product_id,
              short: true
            },
            {
              title: "Amount",
              value: `$${(webhook.payload.data.recurring_pre_tax_amount / 100).toFixed(2)}/${webhook.payload.data.payment_frequency_interval}`,
              short: true
            },
            {
              title: "Next Billing",
              value: new Date(webhook.payload.data.next_billing_date).toLocaleDateString(),
              short: true
            }
          ],
          footer: "Dodo Payments",
          ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
        }]
      };
      break;
      
    case "subscription.cancelled":
      webhook.payload = {
        attachments: [{
          color: "warning",
          title: "⚠️ Subscription Cancelled",
          fields: [
            {
              title: "Customer",
              value: webhook.payload.data.customer.email,
              short: true
            },
            {
              title: "Product ID",
              value: webhook.payload.data.product_id,
              short: true
            },
            {
              title: "Cancellation Date",
              value: new Date(webhook.payload.data.cancelled_at).toLocaleDateString(),
              short: true
            },
            {
              title: "Cancel at Next Billing",
              value: webhook.payload.data.cancel_at_next_billing_date ? "Yes" : "No",
              short: true
            }
          ],
          footer: "Dodo Payments",
          ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
        }]
      };
      break;
      
    case "subscription.renewed":
      webhook.payload = {
        attachments: [{
          color: "good",
          title: "🔄 Subscription Renewed",
          fields: [
            {
              title: "Customer",
              value: webhook.payload.data.customer.email,
              short: true
            },
            {
              title: "Product ID",
              value: webhook.payload.data.product_id,
              short: true
            },
            {
              title: "Amount",
              value: `$${(webhook.payload.data.recurring_pre_tax_amount / 100).toFixed(2)}`,
              short: true
            },
            {
              title: "Next Billing",
              value: new Date(webhook.payload.data.next_billing_date).toLocaleDateString(),
              short: true
            }
          ],
          footer: "Dodo Payments",
          ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
        }]
      };
      break;
  }

  return webhook;
}
```

### Thông Báo Quản Lý Tranh Chấp

Chuyển đổi này xử lý các sự kiện tranh chấp với màu sắc và độ khẩn cấp phù hợp:

```javascript dispute_notifs.js icon="js" expandable theme={null}
function handler(webhook) {
  switch (webhook.eventType) {
    case "dispute.opened":
      webhook.payload = {
        attachments: [{
          color: "danger",
          title: "🚨 New Dispute Opened",
          fields: [
            {
              title: "Payment ID",
              value: webhook.payload.data.payment_id,
              short: true
            },
            {
              title: "Amount",
              value: `$${(webhook.payload.data.amount / 100).toFixed(2)}`,
              short: true
            },
            {
              title: "Status",
              value: webhook.payload.data.dispute_status,
              short: true
            },
            {
              title: "Stage",
              value: webhook.payload.data.dispute_stage,
              short: true
            },
            {
              title: "Remarks",
              value: webhook.payload.data.remarks || "No remarks",
              short: false
            }
          ],
          footer: "Dodo Payments - Action Required",
          ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
        }]
      };
      break;
      
    case "dispute.won":
      webhook.payload = {
        attachments: [{
          color: "good",
          title: "✅ Dispute Won",
          fields: [
            {
              title: "Payment ID",
              value: webhook.payload.data.payment_id,
              short: true
            },
            {
              title: "Amount",
              value: `$${(webhook.payload.data.amount / 100).toFixed(2)}`,
              short: true
            },
            {
              title: "Status",
              value: webhook.payload.data.dispute_status,
              short: true
            },
            {
              title: "Resolution",
              value: "Dispute resolved in your favor",
              short: false
            }
          ],
          footer: "Dodo Payments",
          ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
        }]
      };
      break;
      
    case "dispute.lost":
      webhook.payload = {
        attachments: [{
          color: "danger",
          title: "❌ Dispute Lost",
          fields: [
            {
              title: "Payment ID",
              value: webhook.payload.data.payment_id,
              short: true
            },
            {
              title: "Amount",
              value: `$${(webhook.payload.data.amount / 100).toFixed(2)}`,
              short: true
            },
            {
              title: "Status",
              value: webhook.payload.data.dispute_status,
              short: true
            },
            {
              title: "Impact",
              value: "Funds will be debited from your account",
              short: false
            }
          ],
          footer: "Dodo Payments - Review Required",
          ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
        }]
      };
      break;
  }

  return webhook;
}
```

### Trình Xử Lý Tất Cả Các Sự Kiện Toàn Diện

Chuyển đổi này xử lý tất cả các loại sự kiện với định dạng nhất quán:

```javascript all_events_notifs.js icon="js" expandable  theme={null}
function handler(webhook) {
  const event = webhook.payload.data;
  const timestamp = new Date(webhook.payload.timestamp).toLocaleString();
  
  let color, emoji, title, fields = [];
  
  switch (webhook.eventType) {
    case "payment.succeeded":
      color = "good";
      emoji = "✅";
      title = "Payment Successful";
      fields = [
        { title: "Amount", value: `$${(event.total_amount / 100).toFixed(2)}`, short: true },
        { title: "Customer", value: event.customer.email, short: true },
        { title: "Payment ID", value: event.payment_id, short: true },
        { title: "Method", value: event.payment_method || "Unknown", short: true }
      ];
      break;
      
    case "payment.failed":
      color = "danger";
      emoji = "❌";
      title = "Payment Failed";
      fields = [
        { title: "Amount", value: `$${(event.total_amount / 100).toFixed(2)}`, short: true },
        { title: "Customer", value: event.customer.email, short: true },
        { title: "Reason", value: event.error_message || "Unknown", short: false }
      ];
      break;
      
    case "subscription.active":
      color = "good";
      emoji = "🎉";
      title = "Subscription Activated";
      fields = [
        { title: "Customer", value: event.customer.email, short: true },
        { title: "Product ID", value: event.product_id, short: true },
        { title: "Amount", value: `$${(event.recurring_pre_tax_amount / 100).toFixed(2)}/${event.payment_frequency_interval}`, short: true },
        { title: "Next Billing", value: new Date(event.next_billing_date).toLocaleDateString(), short: true }
      ];
      break;
      
    case "subscription.cancelled":
      color = "warning";
      emoji = "⚠️";
      title = "Subscription Cancelled";
      fields = [
        { title: "Customer", value: event.customer.email, short: true },
        { title: "Product ID", value: event.product_id, short: true },
        { title: "Cancellation Date", value: new Date(event.cancelled_at).toLocaleDateString(), short: true },
        { title: "Cancel at Next Billing", value: event.cancel_at_next_billing_date ? "Yes" : "No", short: true }
      ];
      break;
      
    case "refund.succeeded":
      color = "good";
      emoji = "💰";
      title = "Refund Processed";
      fields = [
        { title: "Amount", value: `$${(event.amount / 100).toFixed(2)}`, short: true },
        { title: "Refund ID", value: event.refund_id, short: true },
        { title: "Payment ID", value: event.payment_id, short: true },
        { title: "Reason", value: event.reason || "Not specified", short: true }
      ];
      break;
      
    case "dispute.opened":
      color = "danger";
      emoji = "🚨";
      title = "New Dispute Opened";
      fields = [
        { title: "Payment ID", value: event.payment_id, short: true },
        { title: "Amount", value: `$${(event.amount / 100).toFixed(2)}`, short: true },
        { title: "Status", value: event.dispute_status, short: true },
        { title: "Stage", value: event.dispute_stage, short: true },
        { title: "Remarks", value: event.remarks || "No remarks", short: false }
      ];
      break;
      
    case "license_key.created":
      color = "good";
      emoji = "🔑";
      title = "License Key Created";
      fields = [
        { title: "License ID", value: event.id, short: true },
        { title: "Product ID", value: event.product_id, short: true },
        { title: "License Key", value: event.key.substring(0, 8) + "...", short: true },
        { title: "Expires", value: event.expires_at ? new Date(event.expires_at).toLocaleDateString() : "Never", short: true }
      ];
      break;
      
    default:
      // Handle any other events with a generic format
      color = "warning";
      emoji = "ℹ️";
      title = webhook.eventType.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
      fields = [
        { title: "Event Type", value: webhook.eventType, short: true },
        { title: "Timestamp", value: timestamp, short: true }
      ];
  }
  
  webhook.payload = {
    attachments: [{
      color: color,
      title: `${emoji} ${title}`,
      fields: fields,
      footer: "Dodo Payments",
      ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
    }]
  };

  return webhook;
}
```

## Thực Hành Tốt Nhất

Để làm cho thông báo Slack hiệu quả:

* Sử dụng phần đính kèm tin nhắn phong phú với màu sắc, trường dữ liệu và định dạng để rõ ràng và dễ thao tác.
* Luôn bao gồm dữ liệu chính như số tiền, email khách hàng và ID để dễ dàng xác định.
* Chọn màu phù hợp với loại sự kiện: xanh (`good`) cho thành công, đỏ (`danger`) cho tranh chấp hoặc thất bại, vàng (`warning`) cho hủy bỏ và xanh dương (`#36a64f`) cho các sự kiện mang tính thông tin.
* Thêm dấu thời gian để theo dõi khi mỗi sự kiện xảy ra.

<Warning>
  **Xử lý Dữ liệu Nhạy cảm**: Hãy cẩn thận không đưa thông tin nhạy cảm như khóa giấy phép đầy đủ hoặc dữ liệu cá nhân vào các tin nhắn Slack. Hãy cân nhắc việc cắt ngắn hoặc che mặt các giá trị nhạy cảm.
</Warning>

## Khắc Phục Sự Cố

<AccordionGroup>
  <Accordion title="Notifications not appearing in Slack">
    * Xác minh rằng URL webhook Slack là chính xác và đang hoạt động
    * Kiểm tra xem mã biến đổi có phải là JavaScript hợp lệ không
    * Đảm bảo các loại sự kiện đã chọn đang được kích hoạt
    * Xác nhận rằng ứng dụng Slack của bạn có các quyền cần thiết
  </Accordion>

  <Accordion title="Transformation errors">
    * Kiểm tra cổng quản lý webhook để xem nhật ký lỗi biến đổi
    * Xác minh rằng cấu trúc payload webhook phù hợp với mã biến đổi của bạn
    * Thử nghiệm mã biến đổi với dữ liệu mẫu
    * Đảm bảo tất cả các trường bắt buộc đều có trong payload webhook
  </Accordion>

  <Accordion title="Missing event types">
    * Xác nhận rằng các sự kiện bạn muốn nhận đã được bật trong cấu hình webhook Dodo Payments
    * Kiểm tra rằng các loại sự kiện đã được chọn trong cấu hình bộ kết nối Slack
    * Xác minh rằng endpoint của bạn được cấu hình đúng để nhận các sự kiện
  </Accordion>
</AccordionGroup>
