---
title: "แจ้งเตือนการชำระเงินล้มเหลวของ Stripe: ข้อโต้แย้ง การถูกปฏิเสธ และเว็บฮุกที่ตายไปแล้ว"
description: "Stripe แจ้งเรื่องข้อโต้แย้งและการชำระเงินที่ล้มเหลวทางอีเมล นี่คือวิธีเปลี่ยนเหตุการณ์เว็บฮุกของ Stripe ให้เป็นพุช การแจ้งเตือนเร่งด่วน หรือสายโทรเข้า"
date: 2026-09-11
author: Nooc
authorAvatarLink: /images/avatars/nooc.webp
authorLink: https://nooc.me
tags:
  - Stripe
  - การชำระเงิน
  - เว็บฮุก
  - ข้อโต้แย้ง
  - SaaS
  - การแจ้งเตือน
---

# แจ้งเตือนการชำระเงินล้มเหลวของ Stripe: ข้อโต้แย้ง การถูกปฏิเสธ และเว็บฮุกที่ตายไปแล้ว

Stripe รู้อยู่แล้วว่าเมื่อไรมีข้อโต้แย้งเปิดขึ้น เมื่อไรการเก็บเงินค่าสมาชิกล้มเหลว และเมื่อไรเงินโอนออกเด้งกลับ มันบอกคุณทางอีเมล ถ้าอยากได้เสียงที่ดังกว่านั้น ให้ลงทะเบียนปลายทางเว็บฮุกอีกอันใน Stripe ที่ชี้ไปยัง URL ของแชนเนล Echobell สมัครรับเหตุการณ์เพียงไม่กี่ชนิด แล้วเลือกชนิดการแจ้งเตือนตามกำหนดเวลาที่ติดมากับแต่ละเหตุการณ์ ข้อโต้แย้งและคำเตือนการฉ้อโกงล่วงหน้ามีนาฬิกาเดินอยู่ ส่วนการต่ออายุที่ล้มเหลวมักไม่มี

คู่มือนี้ครอบคลุมว่าเหตุการณ์ไหนของ Stripe คุ้มค่าจะขัดจังหวะคุณ วิธีชี้ Stripe มาที่ Echobell ในราวห้านาที ฟิลด์เทมเพลตที่มีอยู่จริงบนแต่ละอ็อบเจกต์ และสิ่งที่คุณยอมแลกเมื่อข้ามการตรวจสอบลายเซ็น

## เหตุการณ์ที่คุ้มค่าจะขัดจังหวะจริง ๆ

การแจ้งเตือนเรื่องการชำระเงินพังในแบบเดิมเสมอ: มีคนสมัครรับ `payment_intent.succeeded` เพราะมันรู้สึกดี โทรศัพท์สั่นวันละสี่สิบครั้ง แล้วอีกหกสัปดาห์ต่อมาการแจ้งเตือนข้อโต้แย้งก็เลื่อนผ่านไปโดยไม่มีใครอ่าน ให้เริ่มจากกำหนดเวลาแทน ถ้าพลาดเหตุการณ์ไปแปดชั่วโมงแล้วไม่เสียอะไรเลย มันก็ไม่จำเป็นต้องถึงคุณภายในแปดวินาที

| เหตุการณ์ | ทำไมจึงสำคัญ | ชนิดที่แนะนำ |
| --- | --- | --- |
| `charge.dispute.created` | คุณมีเวลาตอบจำกัด — [ปกติ 7 ถึง 21 วัน ขึ้นกับเครือข่ายบัตร](https://docs.stripe.com/disputes/responding) พลาดแล้วคือแพ้โดยอัตโนมัติ | สายโทรเข้า |
| `radar.early_fraud_warning.created` | ผู้ออกบัตรแจ้ง Stripe แล้วว่ารายการหนึ่งอาจเป็นการฉ้อโกง การคืนเงินก่อนที่มันจะกลายเป็นข้อโต้แย้งอย่างเป็นทางการคือสิ่งที่คุณยังทำได้ และช่วงเวลานั้นสั้นมาก | สายโทรเข้า |
| `payout.failed` | เงินที่ Stripe เก็บมาไปไม่ถึงบัญชีธนาคารของคุณ ทุกอย่างที่ตามมา — เงินเดือน การคำนวณกระแสเงินสด — ตอนนี้ผิดหมด | สายโทรเข้า |
| `invoice.payment_failed` | การเลิกใช้แบบไม่ตั้งใจ มันหายไปเองบ่อยพอที่การโทรจะเกินจำเป็น แต่บัญชีใหญ่ ๆ ควรดูภายในวันเดียวกัน | เร่งด่วน |
| `customer.subscription.deleted` | การเลิกใช้โดยสมัครใจ ควรรู้วันนี้ แต่ไม่ควรถึงกับปลุกคุณ | ปกติ |
| `payment_intent.succeeded` | ไม่มีอะไรพัง นี่แหละคือเหตุการณ์ที่ฝึกให้คุณเพิกเฉยต่ออีกห้าอย่างข้างบน | ไม่ต้องแจ้ง |

ระดับเหล่านี้ตรงกับ[ชนิดการแจ้งเตือน](/th/docs/notification)สามแบบของ Echobell: **ปกติ** คือพุชธรรมดา **เร่งด่วน** ทะลุโหมดโฟกัสส่วนใหญ่ และ **สายโทรเข้า** ปรากฏเป็นสายเรียกเข้า จึงดังผ่านโหมดห้ามรบกวน ผู้ติดตามแต่ละคนเลือกระดับของตัวเองต่อแชนเนล ผู้ร่วมก่อตั้งจึงรับข้อโต้แย้งเป็นสายโทรเข้าได้ ขณะที่เพื่อนร่วมทีมซัพพอร์ตรับเป็นพุช

## สิ่งที่ต้องมี

- บัญชี Stripe ที่เข้าถึง[แท็บ Webhooks ใน Workbench](https://dashboard.stripe.com/webhooks) ได้
- ติดตั้ง Echobell แล้ว ([App Store](https://apps.apple.com/app/apple-store/id6743597198?pt=128151925&ct=blog-stripe-payment-failure-alerts-th&mt=8) / [Google Play](https://play.google.com/store/apps/details?id=one.echobell.echobellandroid))
- ห้านาที ไม่ต้องมีเซิร์ฟเวอร์ ไม่ต้องดีพลอย ไม่ต้องเขียนโค้ด — ยกเว้นถ้าคุณอยากได้การตรวจสอบลายเซ็น ซึ่งอยู่ในหัวข้อสุดท้าย

## ขั้นที่ 1 — หนึ่งแชนเนลต่อหนึ่งชนิดเหตุการณ์

มันน่าดึงดูดที่จะสร้างแชนเนลเดียวชื่อ "Stripe" แล้วส่งทุกอย่างเข้าไปที่นั่น อย่าทำ เทมเพลตเนื้อหาและลิงก์แดชบอร์ดต่างกันระหว่างข้อโต้แย้ง ใบแจ้งหนี้ และเงินโอนออก เพราะแต่ละอย่างพาอ็อบเจกต์คนละแบบมา — และหัวใจทั้งหมดของการตั้งค่านี้คือให้การแจ้งเตือนบอกคุณเองว่าเกิดอะไรขึ้น โดยไม่ต้องเปิดอะไรเลย

สร้างแชนเนลตั้งชื่อตามเหตุการณ์: `Stripe Disputes` เขียนเทมเพลตหัวข้อและเนื้อหาให้อ่านจบได้บนหน้าจอล็อก:

```
Title: 🔴 Dispute opened — {{data.object.reason}}
Body: Amount: {{data.object.amount}} {{data.object.currency}}
Charge: {{data.object.charge}}
Status: {{data.object.status}}
```

ตั้งเทมเพลตลิงก์ในการตั้งค่าขั้นสูง เพื่อให้บันทึกการแจ้งเตือนเปิดหน้าที่ถูกต้อง:

```
https://dashboard.stripe.com/disputes/{{data.object.id}}
```

จากนั้นสมัครรับด้วยชนิด **สายโทรเข้า** แล้วคัดลอก URL ของเว็บฮุกจากหน้ารายละเอียดแชนเนล หน้าตาประมาณ `https://hook.echobell.one/t/<channel-token>`

<Callout type="info">เปิด **POST Only** ในการตั้งค่าขั้นสูงของแชนเนล Stripe ส่งด้วย POST เสมอ และสวิตช์นี้ทำให้การวาง URL ลงในหน้าต่างแชตหรือแท็บเบราว์เซอร์ไม่สามารถจุดชนวนการแจ้งเตือนข้อโต้แย้งปลอมได้อีก</Callout>

## ขั้นที่ 2 — ชี้ Stripe มาที่แชนเนล

ในแดชบอร์ด Stripe เปิด[แท็บ Webhooks](https://dashboard.stripe.com/webhooks) แล้วสร้างปลายทางเหตุการณ์:

<Steps>

<Step>

คลิก **Create an event destination** เลือก **Your account** และคงเวอร์ชัน API ไว้ตามค่าเริ่มต้นของบัญชีคุณ

</Step>

<Step>

เลือกชนิดเหตุการณ์เพียงหนึ่งเดียว — `charge.dispute.created` สำหรับแชนเนลนี้ Stripe เองก็แนะนำให้[สมัครรับเฉพาะเหตุการณ์ที่การเชื่อมต่อของคุณต้องใช้](https://docs.stripe.com/webhooks) ซึ่งที่นี่ยังช่วยให้เทมเพลตซื่อตรงด้วย เพราะเพย์โหลดทุกชิ้นที่เข้ามามีรูปร่างเดียวกัน

</Step>

<Step>

เลือก **Webhook endpoint** เป็นชนิดปลายทาง แล้ววาง URL แชนเนล Echobell

</Step>

<Step>

บันทึก แล้วใช้ **Send test event** — หรือ `stripe trigger charge.dispute.created` จาก CLI — เพื่อยืนยันว่าโทรศัพท์ดังจริง

</Step>

</Steps>

ทำซ้ำกับทุกแชนเนลที่คุณสร้าง Stripe อนุญาตปลายทางเว็บฮุกได้ถึง 16 อันต่อบัญชี ซึ่งเหลือเฟือสำหรับหนึ่งอันต่อหนึ่งระดับการแจ้งเตือน

## ขั้นที่ 3 — สิ่งที่มาถึงจริง ๆ

Stripe ส่ง[อ็อบเจกต์ Event](https://docs.stripe.com/api/events/object) มาเป็น JSON Echobell อ่านเนื้อหาตามที่ได้มา ทุกฟิลด์จึงเข้าถึงได้ในเทมเพลตและเงื่อนไขด้วยการใช้จุด:

```json
{
  "id": "evt_1P...",
  "type": "charge.dispute.created",
  "livemode": true,
  "created": 1757548800,
  "data": {
    "object": {
      "id": "dp_1P...",
      "amount": 4900,
      "currency": "usd",
      "reason": "fraudulent",
      "status": "needs_response",
      "charge": "ch_3P...",
      "evidence_details": { "due_by": 1759449600 }
    }
  }
}
```

มีสามเรื่องในเพย์โหลดนี้ที่ทำให้คนแปลกใจ:

**จำนวนเงินเป็นจำนวนเต็มในหน่วยย่อยที่สุดของสกุลเงิน** `amount` เท่ากับ `4900` คือ 49.00 ดอลลาร์ เทมเพลตของ Echobell แทรกและเปรียบเทียบค่าได้ แต่ไม่คำนวณเลขคณิต ดังนั้น `{{data.object.amount}}` จะแสดงเป็น `4900` ให้ติดป้ายอย่างซื่อตรง (`Amount: 4900 (cents)`) หรือใช้ตัวส่งต่อในหัวข้อสุดท้ายเพื่อหารด้วย 100 ก่อนส่ง

**เวลาประทับเป็นวินาทีแบบ Unix** `{{data.object.evidence_details.due_by}}` จะแสดงเป็น `1759449600` ไม่ใช่วันที่ ถ้าการมีกำหนดเวลาสำคัญกว่าชั่วโมงที่แน่นอน ให้ตัดออกจากเทมเพลต — หน้าข้อโต้แย้งแสดงอยู่แล้ว — และปล่อยให้เทมเพลตลิงก์ทำงานแทน

**ชื่อฟิลด์ต่างกันไปตามอ็อบเจกต์** ข้อโต้แย้งมี `amount` ใบแจ้งหนี้มี `amount_due`, `customer_email`, `attempt_count` และ `hosted_invoice_url` เงินโอนออกมี `failure_message` กับ `arrival_date` ส่วนคำเตือนการฉ้อโกงล่วงหน้ามี `fraud_type`, `actionable` และ `charge` ที่เป็นสตริงไอดีล้วน ๆ ตัวแปรที่ไม่มีจะถูกเรนเดอร์เป็นสตริงว่างแทนที่จะเป็นข้อผิดพลาด เทมเพลตที่ก๊อปมาผิดแชนเนลจึงพังอย่างเงียบ ๆ นี่คือเหตุผลเชิงปฏิบัติของการมีหนึ่งแชนเนลต่อหนึ่งชนิดเหตุการณ์

## ขั้นที่ 4 — กรองด้วยเงื่อนไข ไม่ใช่ด้วยกำลังใจ

[เงื่อนไข](/th/docs/conditions)ของแชนเนลใช้ไวยากรณ์นิพจน์เดียวกับเทมเพลต เพียงแต่ไม่มีวงเล็บปีกกา และทำงานก่อนการส่งใด ๆ

อันที่ควรใส่ในทุกแชนเนลของ Stripe:

```
livemode == true
```

ทราฟฟิกโหมดทดสอบ — `stripe trigger` ที่คุณรันเอง เพื่อนร่วมทีมที่กำลังเล่นในแซนด์บ็อกซ์ — จะไม่มาถึงโทรศัพท์คุณอีก ใส่หลังจากยืนยันแล้วว่าสายเชื่อมต่อทำงาน ไม่ใช่ก่อนหน้านั้น

สำหรับแชนเนลใบแจ้งหนี้ที่ล้มเหลว เกณฑ์ขั้นต่ำจะกันบัญชีเล็ก ๆ ออกจากช่วงเย็นของคุณ:

```
livemode == true && data.object.amount_due > 20000
```

อ่านว่า "เกิน 200 ดอลลาร์" ในหน่วยเซนต์ และถ้าคุณอยากเห็นการลองใหม่ที่ติดขัดจริง ๆ แทนที่จะเห็นทุกความล้มเหลวครั้งแรก:

```
livemode == true && data.object.attempt_count > 1
```

ถ้าคุณชี้ปลายทางเดียวที่มีหลายชนิดเหตุการณ์มายังแชนเนลเดียวไปแล้ว เงื่อนไขจะช่วยแยกกลับได้:

```
type == "charge.dispute.created" || type == "payout.failed"
```

## ขั้นที่ 5 — วางเส้นทางแจ้งเตือนไว้นอกสิ่งที่จะพัง

ส่วนนี้มีค่ามากกว่าเทมเพลต

ปลายทางเว็บฮุกบนโปรดักชันของคุณคือที่ที่การส่งมอบเกิดขึ้น: มันให้สิทธิ์เข้าใช้ เขียนลงฐานข้อมูล ส่งใบเสร็จ ดังนั้นมันจึงเป็นปลายทางเดียวกันที่ล้มไปพร้อมกับแอปของคุณ เมื่อเป็นเช่นนั้น Stripe [จะลองใหม่นานถึงสามวันด้วยการถอยแบบเอ็กซ์โพเนนเชียล](https://docs.stripe.com/webhooks) และส่งอีเมลหาคุณ — ส่วนอีเมลเรื่องเว็บฮุกที่ส่งไม่สำเร็จนั้นหน้าตาเหมือนอีเมล Stripe ฉบับอื่นทุกประการ จึงมักถูกพบเอาวันจันทร์

สาเหตุที่เว็บฮุกตายเงียบ ๆ นั้นน่าเบื่อทั้งนั้น Stripe ถือว่าการเปลี่ยนเส้นทาง `3xx` เป็นความล้มเหลว ปลายทางที่เริ่มเปลี่ยน `http` เป็น `https` หรือเติมสแลชท้าย URL จึงหยุดรับเหตุการณ์ มันต้องใช้ TLS 1.2 ขึ้นไป ใบรับรองที่หมดอายุหรือตั้งค่าผิดจึงเพียงพอแล้ว `403` จากกฎ WAF ที่ใครบางคนเพิ่มเมื่อสัปดาห์ก่อนก็เช่นกัน

ปลายทางที่สองซึ่งชี้ตรงไปยัง Echobell ไม่ได้ใช้อะไรร่วมกับสิ่งเหล่านั้นเลย มันเป็น URL คนละตัวบนโฮสต์คนละเครื่องพร้อมใบรับรองคนละใบ และยังดังต่อไปขณะที่แอปของคุณล้มอยู่ กฎนี้ขยายความได้ว่า *เส้นทางที่บอกคุณว่ามีอะไรพัง ไม่ควรวิ่งผ่านสิ่งที่กำลังพังอยู่*

คุณยังอยากให้ความล้มเหลวของปลายทางตัวเองมองเห็นได้อยู่ดี เมื่อรู้สึกว่ามีอะไรผิดปกติ ให้ดูแท็บ **Event deliveries** ใน Workbench — มันแสดง `Delivered`, `Pending` และ `Failed` รายเหตุการณ์ พร้อมสถานะ HTTP ของแต่ละครั้งที่พยายามส่ง Stripe ให้ส่งเหตุการณ์ซ้ำได้ภายใน 15 วันจากแดชบอร์ด หรือ 30 วันด้วย `stripe events resend` จาก CLI ช่องว่างที่จับได้ภายในสองสัปดาห์จึงยังกู้คืนได้

<Callout type="warn">URL แชนเนลของ Echobell เป็นข้อมูลรับรองแบบ bearer ใครถือไว้ก็จุดชนวนแชนเนลได้ การชี้ Stripe ไปที่นั่นตรง ๆ หมายความว่าไม่มีอะไรตรวจสอบเฮดเดอร์ `Stripe-Signature` ดังนั้น URL ที่หลุดคือเครื่องผลิตการแจ้งเตือนปลอม ไม่ใช่การรั่วไหลของข้อมูล เก็บมันให้พ้นจากรีโพและภาพหน้าจอ ใช้ **Reset Token** หากมันหลุดออกไป และอ่านหัวข้อถัดไปถ้าการแลกเปลี่ยนนี้ทำให้คุณไม่สบายใจ</Callout>

## ทางเลือก — ตรวจสอบลายเซ็นก่อน

ถ้าคุณอยากให้ลายเซ็นของ Stripe ถูกตรวจสอบจริง ๆ และจำนวนเงินถูกจัดรูปแบบเหมือนเงิน ให้วางตัวส่งต่อเล็ก ๆ ไว้ด้านหน้า Cloudflare Worker ตัวนี้ตรวจสอบเหตุการณ์ ตอบ `200` ทันทีตามที่ Stripe ต้องการ แล้วส่งเพย์โหลดแบบแบนไปให้ Echobell:

```js
import Stripe from "stripe";

export default {
  async fetch(request, env, ctx) {
    const stripe = new Stripe(env.STRIPE_SECRET_KEY);
    const body = await request.text();

    let event;
    try {
      event = await stripe.webhooks.constructEventAsync(
        body,
        request.headers.get("stripe-signature"),
        env.STRIPE_WEBHOOK_SECRET,
      );
    } catch {
      return new Response("invalid signature", { status: 400 });
    }

    const invoice = event.data.object;
    ctx.waitUntil(
      fetch(env.ECHOBELL_HOOK_URL, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          customer: invoice.customer_email || invoice.customer,
          amount: (invoice.amount_due / 100).toFixed(2),
          currency: invoice.currency.toUpperCase(),
          attempt: invoice.attempt_count,
          externalLink: invoice.hosted_invoice_url,
        }),
      }),
    );

    return new Response("ok", { status: 200 });
  },
};
```

เทมเพลตอีกฝั่งจะสวยขึ้นมาก เพราะการจัดรูปแบบเกิดขึ้นในโค้ดไปแล้ว:

```
Title: 💳 Payment failed — {{currency}} {{amount}}
Body: Customer: {{customer}}
Attempt #{{attempt}}
```

`externalLink` เป็นตัวแปรพิเศษ: หากไม่ได้ตั้งเทมเพลตลิงก์ Echobell จะใช้มันเป็นลิงก์ของบันทึกการแจ้งเตือน หน้าใบแจ้งหนี้แบบโฮสต์จึงอยู่ห่างแค่แตะเดียว

สังเกตรูปร่างของการแลกเปลี่ยน: ตอนนี้มันคือโครงสร้างพื้นฐานอีกชิ้นที่ล้มได้เอง ซึ่งก็คือสิ่งที่ขั้นที่ 5 เตือนไว้พอดี ทางสายกลางที่สมเหตุสมผลคือตรวจสอบลายเซ็นบนแชนเนลที่มีปริมาณมาก ซึ่งการแจ้งเตือนปลอมจะน่ารำคาญ และปล่อยให้แชนเนลข้อโต้แย้งต่อตรงไว้ ที่นั่นต้นทุนของเสียงดังผิด ๆ คือการมองอย่างงุนงงหนึ่งครั้ง ส่วนต้นทุนของการพลาดคือยอดเงินที่ถูกโต้แย้ง

## สิ่งที่การตั้งค่านี้ไม่ได้ให้

- **ไม่มีการเวียนเวรหรือการยกระดับ** ทุกคนที่สมัครรับแชนเนลแบบสายโทรเข้าจะดังพร้อมกัน สี่คนคือข้อดี สี่สิบคนคือปัญหา ถ้าสี่สิบคนคุณต้องการแพลตฟอร์มจัดการเหตุการณ์
- **ไม่มีการตัดซ้ำ** Stripe [ไม่รับประกันลำดับเหตุการณ์](https://docs.stripe.com/webhooks) และอาจส่งเหตุการณ์เดียวกันมากกว่าหนึ่งครั้ง สองเสียงสำหรับข้อโต้แย้งเดียวจึงเป็นไปได้
- **ไม่มีการตอบรับ** ไม่มีอะไรบันทึกว่ามีมนุษย์เห็นแล้ว และไม่มีอะไรยกระดับไปยังคนที่สองถ้าไม่มีใครตอบสนอง
- **ไม่มีการแจ้งเตือนว่า "การชำระเงินหยุดไปแล้ว"** Stripe ปล่อยเหตุการณ์เมื่อมีอะไรเกิดขึ้น ไม่เคยปล่อยเมื่อสิ่งต่าง ๆ หยุดลง ถ้าหน้าชำระเงินของคุณพัง จะไม่มีเหตุการณ์ใดถูกจุดชนวนเลย เรื่องนี้ต้องใช้งานตามกำหนดเวลาฝั่งคุณที่ยิงไปยังแชนเนลเมื่อจำนวนรายการในหนึ่งชั่วโมงที่ผ่านมาเป็นศูนย์ — [สวิตช์คนตายที่อิงกับ cron](/th/blog/cron-job-failure-alerts)

## การแก้ปัญหา

**เหตุการณ์ทดสอบขึ้น `200` ใน Stripe แต่ไม่มีการแจ้งเตือนมาถึง** Echobell ตอบ `200` พร้อมเนื้อหา JSON แม้ตอนที่ไม่ได้ส่งอะไร — ให้ดูเนื้อหาการตอบกลับในแท็บ Event deliveries ถ้าเป็น `success: false` โดยที่โทเคนความยาวถูกต้อง แปลว่าโทเคนแชนเนลผิด ถ้า `success` เป็น `true` สาเหตุที่น่าจะเป็นคือเงื่อนไข: `livemode == true` บล็อกเหตุการณ์ทดสอบทุกอันตามที่ออกแบบไว้

**Stripe รายงาน `405 Method Not Allowed`** แชนเนลเปิด POST Only ไว้ แล้วมีอะไรบางอย่างส่ง GET มา ตัว Stripe เองส่ง POST เสมอ ดังนั้นนี่คือตัวอย่างลิงก์หรือแท็บเบราว์เซอร์ ไม่ใช่ Stripe

**การแจ้งเตือนมาถึงแต่ฟิลด์ว่าง** เทมเพลตอ้างอิงอ็อบเจกต์ผิด — ใช้ `{{data.object.amount}}` ในแชนเนลใบแจ้งหนี้ ซึ่งฟิลด์ชื่อ `amount_due` ลองส่งเหตุการณ์จริงหนึ่งครั้ง เปิดดูในแดชบอร์ด แล้วอ่าน JSON

**การส่งเริ่มล้มเหลวหลังใช้งานมาหลายสัปดาห์** ตรวจใบรับรองและการเปลี่ยนเส้นทางใด ๆ ที่อยู่หน้า URL สำหรับ URL แชนเนลที่ใช้ตรง ๆ เรื่องนี้เกิดยาก แต่สำหรับตัวส่งต่อที่คุณดีพลอยเอง นี่คือผู้ต้องสงสัยอันดับหนึ่ง

## คำถามที่พบบ่อย

### Stripe โทรหาฉันได้ไหมเมื่อมีข้อโต้แย้งเปิดขึ้น

ลำพังตัวมันเองไม่ได้ Stripe แจ้งทางอีเมล ในแดชบอร์ด ผ่านเหตุการณ์ `charge.dispute.created` และผ่านพุชถ้าคุณใช้แอป Stripe Dashboard หากอยากให้ดังจริง ให้ส่งเหตุการณ์นั้นไปยังแชนเนลที่ชนิดการสมัครรับเป็น **สายโทรเข้า**

### ต้องเขียนโค้ดไหมเพื่อเชื่อม Stripe กับ Echobell

ไม่ต้อง Stripe ส่ง JSON ไปยัง URL แบบ HTTPS สาธารณะใดก็ได้ และ URL แชนเนลของ Echobell ก็เป็นเช่นนั้น โค้ดจำเป็นเฉพาะเมื่อคุณต้องการตรวจสอบเฮดเดอร์ `Stripe-Signature` หรือจัดรูปแบบจำนวนเงินใหม่

### ปลอดภัยไหมที่จะให้ URL เว็บฮุกของบุคคลที่สามแก่ Stripe

เป็นการแลกเปลี่ยนที่ตั้งใจ เพย์โหลดที่ Stripe ส่งมามีข้อมูลกำกับของลูกค้าและการชำระเงิน และ Echobell ไม่เก็บเพย์โหลดดิบของเว็บฮุกไว้ถาวร — การแจ้งเตือนที่เรนเดอร์แล้วอยู่บนอุปกรณ์ของคุณ สิ่งที่คุณยอมสละคือการตรวจสอบลายเซ็น ใครก็ตามที่รู้ URL สามารถส่งของปลอมที่ดูน่าเชื่อมาให้คุณได้ ให้ถือมันเหมือนคีย์ API และใช้รูปแบบตัวส่งต่อสำหรับสิ่งที่คุณอยากให้ตรวจสอบ

### ทำไมการแจ้งเตือนของฉันขึ้น 4900 แทนที่จะเป็น 49.00 ดอลลาร์

Stripe ส่งจำนวนเงินเป็นจำนวนเต็มในหน่วยย่อยที่สุดของสกุลเงิน และเทมเพลตของ Echobell ไม่คำนวณเลขคณิต ให้ระบุหน่วยไว้ในเทมเพลต หรือหารด้วย 100 ในตัวส่งต่อก่อนส่ง

### จะกันไม่ให้เหตุการณ์โหมดทดสอบปลุกฉันได้อย่างไร

เพิ่มเงื่อนไข `livemode == true` ให้แชนเนล Stripe ทำเครื่องหมายทุกเหตุการณ์จากแซนด์บ็อกซ์และจาก `stripe trigger` เป็น `livemode: false`

### ผู้ร่วมก่อตั้งรับการแจ้งเตือนเดียวกันได้ไหมโดยไม่ต้องจ่ายค่าที่นั่ง

ได้ แชร์ลิงก์แชนเนลไป ผู้ติดตามแต่ละคนเลือกชนิดการแจ้งเตือนของตัวเอง คนหนึ่งรับข้อโต้แย้งเป็นสายโทรเข้าขณะที่อีกคนรับเป็นพุชธรรมดา และไม่มีการคิดเงินรายที่นั่งกับผู้ติดตาม

### ควรตั้งแจ้งเตือนสำหรับการชำระเงินที่สำเร็จไหม

ทำได้ในช่วงสั้น ๆ และเฉพาะตอนที่ธุรกิจยังเล็กพอที่แต่ละรายการยังนับเป็นเหตุการณ์ พอการแจ้งเตือนเรื่องจ่ายสำเร็จกลายเป็นเรื่องปกติ มันจะเริ่มกัดกร่อนการตอบสนองของคุณต่อสิ่งที่สำคัญจริง — กลไกหลักเบื้องหลัง[อาการล้าจากการแจ้งเตือน](/th/blog/fix-alert-fatigue-developer-guide)

## สรุป

ทั้งหมดของการตั้งค่านี้คือปลายทางเหตุการณ์ Stripe หนึ่งอันต่อหนึ่งแชนเนล Echobell เงื่อนไข `livemode == true` หนึ่งบรรทัด และวินัยในการเก็บระดับสายโทรเข้าไว้ให้เหตุการณ์ที่มีนาฬิกาเดินอยู่ ข้อโต้แย้งและคำเตือนการฉ้อโกงล่วงหน้ามีนาฬิกา การต่ออายุที่ล้มเหลวของแพ็กเกจ 9 ดอลลาร์ไม่มี และการแกล้งทำเป็นว่ามี ก็คือวิธีที่คุณจะหลับผ่านอันที่มีนาฬิกาจริง ๆ ไป

[ดาวน์โหลด Echobell สำหรับ iPhone](https://apps.apple.com/app/apple-store/id6743597198?pt=128151925&ct=blog-stripe-payment-failure-alerts-th&mt=8) หรือ[รับบน Google Play](https://play.google.com/store/apps/details?id=one.echobell.echobellandroid) สร้างแชนเนลข้อโต้แย้งก่อน แล้วยิง `stripe trigger charge.dispute.created` สักครั้งก่อนจะฝากอะไรที่สำคัญจริงไว้กับเส้นทางนี้

---

## บทความที่เกี่ยวข้อง

- [เอกสารการเชื่อมต่อเว็บฮุก](/th/docs/webhook)
- [คู่มืออ้างอิงเงื่อนไขของแชนเนล](/th/docs/conditions)
- [คู่มือนักพัฒนาสำหรับแก้อาการล้าจากการแจ้งเตือน](/th/blog/fix-alert-fatigue-developer-guide)
- [แจ้งเตือนเมื่อ cron job ล้มเหลว](/th/blog/cron-job-failure-alerts)
- [ส่งการแจ้งเตือนเว็บฮุกจาก Zapier เข้าโทรศัพท์](/th/blog/zapier-webhook-notifications-to-phone)
