소개
Dodo Payments 슬랙 통합을 통해 슬랙 작업 공간에서 직접 결제에 대한 실시간 알림을 받을 수 있습니다. 이 통합을 통해 결제 상태를 업데이트하고, 거래를 추적하며, 결제를 보다 효율적으로 관리할 수 있습니다.이 통합은 웹훅 관리 포털을 사용하여 Dodo Payments 웹훅 이벤트를 슬랙 호환 메시지로 자동 변환합니다. 추가 코딩이 필요하지 않으며, 커넥터를 구성하고 알림을 받기 시작하면 됩니다.
시작하기
변환 코드 사용자 정의
사용 사례에 맞게 슬랙 알림을 사용자 정의하기 위해 변환 코드를 추가하거나 수정합니다. 미리 만들어진 템플릿을 사용하거나 자신의 로직을 작성할 수 있습니다.

변환 코드 예제
기본 결제 알림
이 변환은 결제 이벤트에 대한 간단한 텍스트 메시지를 보냅니다:payment_notifs.js
복사
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;
}
풍부한 구독 알림
이 변환은 구독 이벤트에 대한 첨부 파일이 있는 풍부한 슬랙 메시지를 생성합니다:subscription_notifs.js
복사
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;
}
분쟁 관리 알림
이 변환은 적절한 색상과 긴급성을 가진 분쟁 이벤트를 처리합니다:dispute_notifs.js
복사
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;
}
포괄적인 모든 이벤트 핸들러
이 변환은 일관된 형식으로 모든 이벤트 유형을 처리합니다:all_events_notifs.js
복사
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;
}
모범 사례
슬랙 알림을 효과적으로 만들기 위해:- 명확성과 실행 가능성을 위해 색상, 필드 및 형식을 갖춘 풍부한 메시지 첨부 파일을 사용하세요.
- 빠른 식별을 위해 금액, 고객 이메일 및 ID와 같은 주요 데이터를 항상 포함하세요.
- 이벤트 유형에 맞는 색상을 선택하세요: 성공을 위한 초록색 (
good), 분쟁 또는 실패를 위한 빨간색 (danger), 취소를 위한 노란색 (warning), 정보 이벤트를 위한 파란색 (#36a64f)를 사용하세요. - 각 이벤트가 발생한 시간을 추적할 수 있도록 타임스탬프를 추가하세요.
민감한 데이터 처리: 슬랙 메시지에 전체 라이센스 키나 개인 데이터와 같은 민감한 정보를 포함하지 않도록 주의하세요. 민감한 값을 잘라내거나 마스킹하는 것을 고려하세요.
문제 해결
슬랙에 알림이 나타나지 않음
슬랙에 알림이 나타나지 않음
- 슬랙 웹훅 URL이 올바르고 활성 상태인지 확인하세요.
- 변환 코드가 유효한 JavaScript인지 확인하세요.
- 선택한 이벤트 유형이 트리거되고 있는지 확인하세요.
- 슬랙 앱에 필요한 권한이 있는지 확인하세요.
변환 오류
변환 오류
- 변환 오류 로그를 위해 웹훅 관리 포털을 확인하세요.
- 웹훅 페이로드 구조가 변환 코드와 일치하는지 확인하세요.
- 샘플 데이터로 변환 코드를 테스트하세요.
- 웹훅 페이로드에 모든 필수 필드가 포함되어 있는지 확인하세요.
누락된 이벤트 유형
누락된 이벤트 유형
- 수신하려는 이벤트가 Dodo Payments 웹훅 구성에서 활성화되어 있는지 확인하세요.
- 슬랙 커넥터 구성에서 이벤트 유형이 선택되어 있는지 확인하세요.
- 이벤트를 수신하도록 엔드포인트가 올바르게 구성되어 있는지 확인하세요.



