Công cụ13 tháng 9, 20265 phút đọc

URL tunnel đổi sau mỗi lần khởi động lại. URL webhook thì không cần phải thế.

ngrok đổi URL mỗi lần khởi động lại, và bạn phải dán lại vào Stripe hay Shopify. Đặt một URL cố định ở nhà cung cấp, trỏ nó tới tunnel đang chạy hôm nay.

TUNNEL · URL GẮN VỚI MỘT CHIẾC LAPTOPStripetunnelđổi liên tục, hết hạnlaptopđang ngủsự kiện mất luônRELAY · URL KHÔNG GẮN VỚI THỨ GÌ CẢStriperelaylưu + 200prodlaptopphát lại được sau
Nhà cung cấp nên nói chuyện với một địa chỉ sống lâu hơn terminal của bạn.

Bạn chạy ngrok http 3000. Bạn copy URL. Bạn dán nó vào dashboard của Stripe. Bạn debug một tiếng, gập laptop, và sáng hôm sau cả nghi thức lặp lại vì URL đã mất.

Đây không phải vấn đề khó. Nó là một vết xước nhỏ mở miệng lại mỗi ngày, và phần lớn câu trả lời cho nó là “trả tiền mua domain tĩnh” hoặc “dùng tunnel khác”. Có một lựa chọn thứ ba không tốn đồng nào và sửa nó ở một tầng khác.

Đăng ký một địa chỉ sống lâu hơn terminal

Nhà cung cấp không cần biết laptop của bạn ở đâu. Nó cần một URL lúc nào cũng có mặt.

Stripe / Shopify / GitHub
        │
        ▼
in.anyhook.net/you/dev      ← registered once, never changes
        │
        ▼
https://whatever-ngrok-gave-you-today.ngrok-free.app/webhook

Nhà cung cấp nói chuyện với nửa cố định. Bạn đổi nửa tạm thời mỗi khi tunnel khởi động lại, trong một trường duy nhất, không cần đụng tới dashboard của nhà cung cấp. Thay đổi tới mọi điểm edge (lớp máy chủ biên của Cloudflare) trong vòng khoảng một phút.

Ý tưởng chỉ có vậy. Phần còn lại của bài là vì sao nó đáng năm phút của bạn, và nó không giúp được ở đâu.

Với Shopify, chuyện này tệ hơn một vết xước

Với phần lớn nhà cung cấp, một URL cũ chỉ có nghĩa là các lượt gửi thất bại mà bạn có thể bỏ qua. Với Shopify, nó có thể khiến bạn mất webhook subscription.

Một webhook subscription được tạo qua Shopify Admin API sẽ giữ nguyên URL lúc tạo. Khởi động dev server, nhận một URL tunnel mới, và subscription đó vẫn trỏ về địa chỉ của hôm qua. Shopify gửi tới đó, thất bại, thử lại (retry) và sau đủ số lần thất bại liên tiếp thì xóa hẳn webhook subscription. Giờ không có gì tới nữa kể cả khi bạn đã sửa tunnel, và lỗi trông như “Shopify ngừng gửi” chứ không phải “tôi đã đổi URL”.

WooCommerce vô hiệu hóa webhook sau hơn năm lần thất bại liên tiếp. Stripe vô hiệu hóa endpoint sau khi lỗi kéo dài. Một URL đổi mỗi ngày là cỗ máy sản xuất các lần thất bại liên tiếp.

Điều cách này làm được mà domain tĩnh trả phí không làm được

Một domain tunnel tĩnh giải quyết chuyện dán lại. Nó không giải quyết chuyện laptop của bạn đang gập.

Khi có một dịch vụ trung chuyển webhook (webhook relay) đứng trước, sự kiện tới trong lúc tunnel ngừng hoạt động vẫn được nhận, xác minh và ghi vào nhật ký trước khi thử gửi. Lượt gửi tới máy của bạn thất bại, điều đó nằm trong dự tính và không sao cả. Sự kiện vẫn còn đó.

  • Quay lại, bật tunnel, bấm phát lại (replay). Các sự kiện thất bại trong lúc bạn vắng mặt được gửi tới handler (đoạn code xử lý webhook trên server của bạn) thêm lần nữa, cũ nhất trước
  • Phát lại không bị tính vào hạn mức hằng tháng của bạn, dù vẫn có giới hạn hằng ngày và dùng đến hạn mức compute (tài nguyên tính toán đi kèm gói)
  • Bạn thấy chính xác những gì nhà cung cấp đã gửi, cả header và body, thay vì phải suy đoán từ một handler chưa từng chạy

Gói Free gồm một App (một URL nhận cho một nguồn webhook, ví dụ “Stripe production”), 10.000 sự kiện mỗi tháng và 1.000 sự kiện mỗi ngày, nhiều hơn mức một vòng phát triển dùng tới. Trên gói này, sự kiện phát lại được trong ba ngày, và đó là giới hạn thật: đây là lưới an toàn cho dịp cuối tuần, không phải kho lưu trữ.

Chỗ cách này không giúp được

  • Nó không giữ cho handler của bạn chạy. Khi tunnel ngừng hoạt động, các lượt gửi tới đó thất bại. Thứ bạn có là nhật ký và nút phát lại, không phải lượt gửi tới một chiếc máy đang tắt
  • Nó không phải lý do để bỏ qua xác minh chữ ký. Header gốc của nhà cung cấp được chuyển tiếp nguyên vẹn, nên chữ ký bạn vẫn kiểm tra vẫn là chữ ký bạn kiểm tra
  • Trên production, tunnel nên biến mất hoàn toàn. Đó là một lập luận khác, và chúng tôi đã trình bày trong bài Vì sao ngrok là chưa đủ. ngrok vẫn là công cụ đúng cho vòng phát triển; bài này chỉ nói về chuyện URL liên tục thay đổi mà nó gây ra

Thiết lập

  1. Tạo một App. Bạn có ngay in.anyhook.net/{you}/{app}
  2. Dán URL đó vào dashboard của nhà cung cấp một lần
  3. Đặt đích là URL tunnel hiện tại của bạn
  4. Gửi một sự kiện thử từ trang App và xem nó tới nơi

Ngày mai, khi tunnel đưa bạn một địa chỉ mới, bạn đổi bước 3 và không đổi gì khác. Nếu sau này bạn đổi tên App hoặc tài khoản, URL cũ vẫn tiếp tục định tuyến thay vì trả về 404, vì một URL bạn đã đưa cho nhà cung cấp thì không bao giờ được ngừng hoạt động.

Điều cần nhớ

Dashboard của nhà cung cấp là chỗ sai để lưu một địa chỉ thay đổi mỗi ngày. Đặt thứ gì đó cố định ở đó, giữ phần tạm thời ở phía bạn, thế là nghi thức hằng ngày sẽ biến mất cùng với những bộ đếm lượt gửi thất bại mà nó vẫn lặng lẽ đẩy lên.

Nếu bạn muốn phiên bản sâu hơn, về chuyện xác minh chữ ký vẫn đứng vững qua các lần thử lại và phải làm gì khi một nhà cung cấp đã vô hiệu hóa bạn, hãy bắt đầu với bài Xác minh chữ ký webhook và Cách phát lại webhook.

Tất cả bài viết13 tháng 9, 2026 · 5 phút

Đừng để mất webhook nữa.

Đổi một URL. Có ngay cơ chế thử lại, nhật ký sự kiện và phát lại bằng một cú bấm. Hoặc xem tận mắt trước: đăng ký, chạy bài diễn tập sự cố 30 giây và xem một sự kiện vẫn còn nguyên khi server của bạn ngừng hoạt động. Không cần có server.