Để thử nghiệm các webhook của Lemon Squeezy trên localhost, hãy khởi động ứng dụng của bạn, mở đường dẫn webhook của nó với một tunneling HTTPS công khai, tạo một webhook chế độ Test trong Cài đặt → Webhooks, và xác minh phần thân yêu cầu thô với X-Signature tiêu đề. Sử dụng thanh toán thử nghiệm cho dữ liệu đơn hàng thực và các điều khiển mô phỏng đăng ký của Lemon Squeezy cho các sự kiện vòng đời mà khó có thể chờ đợi.
Một cấu hình cục bộ đúng trông như thế nào
Lemon Squeezy gửi một HTTP POST từ cơ sở hạ tầng của nó, nên nó không thể tiếp cận localhost trên máy tính của bạn. Đường hầm kết thúc TLS công khai và chuyển tiếp phương thức, nội dung và tiêu đề không thay đổi đến một tuyến nội bộ như http://localhost:3000/api/webhooks/lemonsqueezy.
Một bài kiểm tra hoàn chỉnh có bốn phần: Chế độ kiểm tra Lemon Squeezy, một URL callback công khai, cùng một bí mật ký trong bảng điều khiển và môi trường cục bộ, và một trình xử lý xác minh trước khi thay đổi trạng thái đăng ký hoặc giấy phép. Điều này hữu ích hơn so với việc đăng tải JSON đã sao chép với curl, vì một lần giao hàng thực sự kiểm tra cả việc định tuyến và chữ ký do nhà cung cấp tạo ra.
Tạo webhook và gửi một sự kiện thử nghiệm
- Chạy ứng dụng của bạn trên cổng 3000 và xác minh rằng tuyến đường được chấp nhận
POST. - Bắt đầu đường hầm với
npx portpreview 3000. - Chuyển bảng điều khiển Lemon Squeezy sang chế độ Test.
- Mở Cài đặt → Webhooks và thêm
https://your-subdomain.portpreview.dev/api/webhooks/lemonsqueezy. - Tạo một bí mật ký ngẫu nhiên mạnh, lưu nó dưới dạng
LEMONSQUEEZY_WEBHOOK_SECRET, và chỉ chọn những sự kiện mà ứng dụng của bạn sử dụng. - Tạo một giao dịch mua thử hoặc sử dụng hành động mô phỏng đăng ký chế độ Kiểm tra có sẵn, sau đó kiểm tra nhật ký giao hàng và phản hồi cục bộ của bạn.
Chính thức Tài liệu webhook của Lemon Squeezy cho phép bạn kiểm tra các payload gần đây và gửi lại các webhook đã ghi lại từ trang cài đặt. Việc gửi lại rất hữu ích cho kiểm tra hồi quy, nhưng ứng dụng của bạn phải coi đây là bản sao chứ không phải là một sự kiện kinh doanh thứ hai.
Xác minh X-Signature trước khi phân tích JSON
Lemon Squeezy tính toán một bản tóm tắt HMAC-SHA256 trên dữ liệu payload của yêu cầu bằng cách sử dụng khóa ký và gửi bản tóm tắt ở dạng thập lục phân trong X-Signature. Tính toán tổng kiểm tra trên các byte chính xác của phần thân thô và so sánh các bộ đệm cùng độ dài bằng một hàm thời gian hằng số. Chính tài liệu yêu cầu ký bao gồm các ví dụ cho Node, PHP, Python và Ruby.
// app/api/webhooks/lemonsqueezy/route.ts
import crypto from 'node:crypto';
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
const secret = process.env.LEMONSQUEEZY_WEBHOOK_SECRET;
if (!secret) return new NextResponse('server misconfigured', { status: 500 });
const rawBody = await request.text();
const suppliedHex = request.headers.get('x-signature') ?? '';
if (!/^[0-9a-f]{64}$/i.test(suppliedHex)) {
return new NextResponse('invalid signature', { status: 401 });
}
const expected = crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest();
const supplied = Buffer.from(suppliedHex, 'hex');
if (supplied.length !== expected.length ||
!crypto.timingSafeEqual(supplied, expected)) {
return new NextResponse('invalid signature', { status: 401 });
}
const event = JSON.parse(rawBody);
await acceptEvent(event);
return NextResponse.json({ received: true });
}
Đừng gọi request.json() đầu tiên. Việc tái tuần tự hóa đối tượng kết quả có thể thay đổi các byte trông không quan trọng và làm hỏng HMAC. Kiểm tra độ dài cũng rất quan trọng vì Node timingSafeEqual ném ra khi độ dài bộ đệm khác nhau. Chính thức của Lemon Squeezy Hướng dẫn webhook Next.js tuân theo cùng một trình tự cơ thể thô.
Hiểu payload trước khi cập nhật cơ sở dữ liệu của bạn
Phần thân là một đối tượng tài nguyên JSON:API. meta.event_name xác định sự kiện, meta.custom_data chuyển dữ liệu được truyền qua quá trình thanh toán, và data chứa tài nguyên đơn hàng, đăng ký, hoặc khóa giấy phép. Lemon Squeezy cũng gửi X-Event-Name; coi phần nội dung đã ký là dữ liệu đầu vào có thẩm quyền và sử dụng tiêu đề để chẩn đoán định tuyến.
Đơn hàng và danh tính khách hàng
Cho order_created, ánh xạ việc mua hàng với một người dùng nội bộ bằng cách sử dụng định danh do máy chủ tạo trong dữ liệu tùy chỉnh của thanh toán. Không tin tưởng vào ID người dùng do khách hàng cung cấp mà không kiểm tra quyền sở hữu. Lưu giữ ID tài nguyên và ID biến thể của Lemon Squeezy để các sự kiện đăng ký hoặc hoàn tiền sau này có thể được đối chiếu.
Các đăng ký là một máy trạng thái
Tay cầm subscription_created, subscription_updated, subscription_cancelled, subscription_resumed, và subscription_expired như những chuyển đổi riêng biệt. Hủy bỏ có thể có nghĩa là quyền truy cập vẫn còn hiệu lực cho đến khi kết thúc kỳ thanh toán; hết hạn là tín hiệu mạnh hơn rằng đăng ký đã kết thúc. Mô hình hóa ngày tháng và trạng thái thay vì chỉ thay đổi một giá trị boolean.
Lỗi thanh toán và khôi phục
Kiểm tra các luồng gia hạn đã thất bại và phục hồi nơi chế độ Kiểm tra hỗ trợ chúng. Một khoản thanh toán thất bại không nhất thiết phải thu hồi quyền truy cập ngay lập tức; áp dụng thời gian ân hạn được định nghĩa bởi chính sách sản phẩm của bạn và để các khoản thanh toán hoặc sự kiện đăng ký sau đó đồng bộ tài khoản với trạng thái nhà cung cấp mới nhất.
Các lần thử lại yêu cầu xử lý không thay đổi kết quả khi thực hiện nhiều lần
Theo Lemon Squeezy tham chiếu yêu cầu webhook, một 200 Các dấu hiệu phản hồi được ghi nhận là thành công. Các trạng thái khác sẽ được thử lại tối đa ba lần với các khoảng thời gian trễ theo hàm mũ, lần lượt khoảng 5, 25 và 125 giây. Khi bảng điều khiển gửi lại, sẽ tạo ra một lý do khác khiến cùng một sự kiện logic có thể được gửi đến nhiều hơn một lần.
Xây dựng một khóa idempotency từ các trường payload được ký ổn định. Một cách tiếp cận thực tiễn là tạo một hàng cơ sở dữ liệu duy nhất cho ID tài nguyên của webhook, tên sự kiện và timestamp của sự kiện, hoặc một giá trị băm của thân ký gốc khi không có ID sự kiện riêng. Chèn biên nhận đó và cập nhật trạng thái ứng dụng trong một giao dịch. Trả về 200 cho một bản sao đã hoàn thành trước đó.
BEGIN;
INSERT INTO webhook_receipts (fingerprint, received_at)
VALUES ($1, now())
ON CONFLICT DO NOTHING;
-- Continue only if one row was inserted.
UPDATE subscriptions SET provider_status = $2 WHERE provider_id = $3;
COMMIT;
Đừng để việc gửi email hoặc gọi API của bên thứ ba chậm trở thành một phần của đường dẫn xác nhận. Lưu một công việc trong cùng một giao dịch, phản hồi, và để một công nhân xử lý các tác động phụ. Phạm vi rộng hơn hướng dẫn thử lại webhook và tính bất biến bao phủ mẫu này.
Khắc phục sự cố kiểm tra webhook Lemon Squeezy trên localhost
Không có yêu cầu nào đến ứng dụng
Kiểm tra xem đường hầm vẫn đang chạy, callback chứa hậu tố đường dẫn, và framework của bạn có một trình xử lý POST tại chính đường dẫn đó. Gọi endpoint công khai bằng chính bạn. Một lỗi 502 của đường hầm chỉ vào cổng địa phương; một lỗi 404 của framework chỉ vào vị trí đặt đường dẫn.
Mỗi chữ ký đều không hợp lệ
Xác nhận Chế độ Kiểm tra và chế độ trực tiếp không sử dụng các bản ghi hoặc bí mật webhook khác nhau. Đọc nội dung một lần dưới dạng văn bản hoặc byte, không cắt bớt nội dung hay bí mật, và đảm bảo middleware JSON toàn cục không chạy trước. Kiểm tra xem X-Signature đã đến, nhưng không bao giờ in ra bí mật ký.
Việc giao hàng liên tục thử lại
Lemon Squeezy mong đợi 200, không phải là chuyển hướng đến trang đăng nhập. Loại trừ đường dẫn webhook khỏi các middleware CSRF và phiên người dùng trong khi vẫn giữ xác minh chữ ký. Bắt lỗi cơ sở dữ liệu, giữ công việc ngắn gọn, và đảm bảo rằng phản hồi thành công thực sự được trả về trên mọi nhánh sự kiện được xử lý.
Mô phỏng đăng ký không khả dụng
Các điều khiển mô phỏng yêu cầu dữ liệu đăng ký Chế độ thử nghiệm phù hợp. Một số mô phỏng thanh toán cần lịch sử gia hạn. Trước tiên, tạo đăng ký thử nghiệm hoặc mua thử nghiệm cần thiết, sau đó sử dụng menu hành động đăng ký được mô tả trong Lemon Squeezy's hướng dẫn phát triển webhook.
Danh sách kiểm tra bảo mật và triển khai
- Tạo một bí mật ký ngẫu nhiên, lưu nó trong cấu hình môi trường và thay đổi nó nếu bị lộ.
- Xác minh HMAC trên phần thân thô trước khi phân tích JSON, ghi vào cơ sở dữ liệu, tạo giấy phép hoặc thay đổi quyền truy cập.
- Sử dụng so sánh an toàn về thời gian và từ chối các chữ ký bị thiếu hoặc không đúng định dạng.
- Giữ riêng chế độ Kiểm tra và các bí mật cũng như hồ sơ của webhook trực tiếp.
- Chỉ cho phép POST, áp đặt giới hạn kích thước thân bài hợp lý, giới hạn tần suất các yêu cầu không hợp lệ, và che dữ liệu khách hàng khỏi các bản ghi.
- Kiểm tra các bản sao, các sự kiện vòng đời không theo thứ tự, thời gian ngừng hoạt động của cơ sở dữ liệu và phục hồi sau khi hết thời gian chờ trước khi thay thế đường hầm bằng URL sản xuất của bạn.
Một quá trình thanh toán thành công chỉ chứng tỏ rằng một sự kiện đã đến. Một tích hợp sẵn sàng cho sản xuất chứng minh việc từ chối chữ ký, an toàn trùng lặp, hội tụ vòng đời và khả năng phục hồi từ phản hồi không phải 200. Đối với những cạm bẫy mật mã cơ bản, xem hướng dẫn xác minh chữ ký.
