Hosted Checkout
Tạo một phiên checkout, chuyển hướng khách hàng và xác minh thanh toán từ máy chủ của bạn.
Chuyển khách hàng đến một trang thanh toán do Tapaya lưu trữ cho thẻ, Apple Pay và Google Pay, sau đó xác minh kết quả trên máy chủ của bạn. Trang của bạn không bao giờ xử lý thông tin thẻ, và bạn không cần thêm trường nhập thẻ nào vào cửa hàng.
- 1. Your backend to Tapaya: Create session.
- 2. Tapaya to Your backend: Session ID and URL.
- 3. Your backend to Your frontend: Redirect to Checkout.
- 4. Your frontend to Tapaya: Open Checkout and pay.
- 5. Tapaya to Your frontend: Return to your shop.
- 6. Your backend to Tapaya: Retrieve session.
- 7. Tapaya to Your backend: Payment status.
- 8. Your backend to Your frontend: Show verified result.
Trước khi bắt đầu
Chọn key phù hợp với bên vận hành backend của bạn. Dù dùng key nào, hãy giữ nó trên máy chủ; Bảo mật Checkout liệt kê các quy tắc phía máy chủ.
Một cửa hàng
Dùng checkout key của merchant. Key này tự xác định merchant của nó, và các ví dụ ở đây dùng key này.
Nhiều merchant
Dùng Secret key của tổ chức và gửi merchant token trong mọi yêu cầu.
Sau đó, trong Checkout của Tapaya Platform:
- Thêm merchant của bạn và kiểm tra rằng merchant hiển thị Ready. Xem Cài đặt Checkout.
- Đăng ký cửa hàng của bạn làm website được phép, kèm URL thành công và URL hủy mặc định, cho key bạn đã chọn. Các
ví dụ dùng
https://shop.example.
URL trả về đi theo key
Các phiên tạo bằng key của merchant dùng URL trả về của merchant. Các phiên tạo bằng Secret key của tổ chức thì dùng đích trả về của tổ chức. Hai cấu hình này không bao giờ được kết hợp.
Nhận một khoản thanh toán
Cả ba lựa chọn đều tạo cùng loại phiên Checkout với cùng thông tin xác thực. Hãy chọn một; mọi bước bên dưới đều theo lựa chọn của bạn.
Thiết lập máy chủ
Đặt TAPAYA_CHECKOUT_API_URL thành https://api.sandbox.tapaya.com và lưu key của bạn vào TAPAYA_CHECKOUT_API_KEY.
Gọi API bằng fetch của môi trường chạy trên máy chủ, không bao giờ gọi từ trình duyệt của khách hàng. Các ví dụ đọc những giá trị này
qua process.env; hãy điều chỉnh cách đọc nếu môi trường chạy của bạn dùng một giao diện quản lý secret khác.
Tạo một hàm hỗ trợ kiểm tra lỗi HTTP trước khi trả về phần thân phản hồi:
const apiUrl = process.env.TAPAYA_CHECKOUT_API_URL;
const apiKey = process.env.TAPAYA_CHECKOUT_API_KEY;
async function checkoutRequest(path, options = {}) {
const response = await fetch(new URL(path, apiUrl), {
...options,
headers: {
...options.headers,
Authorization: `Bearer ${apiKey}`,
},
redirect: 'error',
cache: 'no-store',
signal: AbortSignal.timeout(8000),
});
if (!response.ok) {
throw new Error(`Checkout request failed (${response.status})`);
}
return response.json();
}Tạo một phiên
Tính tổng tiền đơn hàng trên máy chủ của bạn, bao gồm thuế và phí giao hàng. Lưu đơn hàng và một
checkoutAttemptKey duy nhất trước khi gửi yêu cầu, và tải order từ bản lưu (snapshot) đó. merchantOrderId
là bắt buộc.
const session = await checkoutRequest('/merchant/checkout-sessions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Idempotency-Key': order.checkoutAttemptKey,
},
body: JSON.stringify({
merchantOrderId: order.id,
amount: order.totalInMinorUnits,
currency: order.currency,
successUrl: 'https://shop.example/checkout/return',
cancelUrl: 'https://shop.example/checkout/cancel',
}),
});Phản hồi chứa id của phiên và url của trang Hosted Checkout. Để biết về tóm tắt mặt hàng, chi tiết thuế, thông tin khách hàng
và mọi trường phản hồi, xem Tạo phiên Checkout.
Nếu yêu cầu thất bại hoặc hết thời gian chờ, hãy thử lại với cùng key và phần thân không thay đổi. Không bao giờ tạo key mới khi kết quả chưa chắc chắn: một phần thân đã thay đổi đi kèm cùng key sẽ trả về HTTP 409.
| Lựa chọn | Tự động thử lại |
|---|---|
| HTTP (fetch), cURL | Không. Bạn tự lặp lại yêu cầu. Xem Idempotency và lỗi. |
| Node.js SDK | Tối đa hai lần sau lỗi kết nối, hết thời gian chờ, hoặc HTTP 429, 502, 503 hay 504, với cùng key và phần thân. Xem Idempotency và thử lại. Giữa các lệnh gọi riêng biệt hoặc sau khi khởi động lại, hãy truyền key bạn đã lưu: nếu bỏ qua, mỗi lệnh gọi sẽ tạo một key mới. |
Chuyển hướng khách hàng
Lưu session.id cùng với đơn hàng làm checkoutSessionId của đơn hàng, sau đó chuyển trình duyệt đến session.url bằng HTTP
303. Dùng nguyên URL được trả về thay vì tự tạo URL.
// First persist session.id as the order's checkoutSessionId.
return Response.redirect(session.url, 303);Nếu framework của bạn dùng một API phản hồi khác, hãy gửi HTTP 303 với session.url trong header Location. Với
cURL, hãy mở url được trả về trong trình duyệt để kiểm thử thanh toán thủ công.
Xác minh thanh toán
Trong trình xử lý trang trả về, hãy xác định đơn hàng từ ngữ cảnh checkout của người dùng đã đăng nhập trong ứng dụng và truy xuất phiên đã lưu của đơn hàng đó từ máy chủ. Hãy làm như vậy cả trên URL hủy: việc truy cập bất kỳ URL nào trong hai URL này đều không chứng minh điều gì.
const current = await checkoutRequest(
`/merchant/checkout-sessions/${encodeURIComponent(order.checkoutSessionId)}`,
);
if (
current.id !== order.checkoutSessionId ||
current.merchantOrderId !== order.id ||
current.amount !== order.totalInMinorUnits ||
current.currency !== order.currency
) {
throw new Error('Checkout session does not match the order');
}
const paid = current.paymentStatus === 'successful';Hoàn tất đơn hàng một lần, và chỉ khi đã thanh toán
Chỉ ghi nhận khoản thanh toán và hoàn tất đơn hàng khi phiên khớp với đơn hàng đã lưu và paymentStatus là
successful, đồng thời ghi nhận một cách nguyên tử (atomic) để việc này chỉ xảy ra một lần. Nếu truy xuất thất bại hoặc khoản thanh toán chưa xác định kết quả, hãy giữ
ID phiên và kiểm tra lại. Xem Trạng thái thanh toán.
Xử lý kết quả thanh toán
Bảo mật Checkout trình bày những gì cần xác minh và cách thử lại khi kết quả chưa rõ mà không tạo phiên thứ hai.
| Kết quả | Phiên hiển thị gì | Cần làm gì |
|---|---|---|
| Bị từ chối | open, với paymentStatus: failed | Không cần làm gì. Khách hàng có thể thử thẻ hoặc ví khác trên cùng trang. |
| Chưa xác định | open và unpaid trong khi Tapaya xác nhận kết quả | Truy xuất lại phiên sau. |
| Phiên mới cho cùng đơn hàng | Phiên chưa thanh toán trước đó báo expired | Dùng phiên mới. Một đơn hàng đã thanh toán, hoặc đang có khoản thanh toán được xử lý, sẽ trả về HTTP 409. Xem Một khoản thanh toán cho mỗi đơn hàng. |
| Hết hạn | Ngừng nhận thanh toán mới sau 30 phút kể từ khi tạo | Tạo phiên mới nếu đơn hàng vẫn chưa được thanh toán. Một khoản thanh toán đã gửi trước khi hết hạn vẫn được hoàn tất. |
Chưa có webhook
Hiện chưa có webhook cho Checkout. Hãy chạy một tác vụ đối soát phía máy chủ để truy xuất phiên cho những đơn hàng mà khách hàng không bao giờ quay lại.
Kiểm tra tích hợp
Thẻ thử nghiệm
Chạy mọi kết quả thanh toán trên sandbox.
Danh sách kiểm tra QA
Kiểm tra việc thử lại, checkout bị gián đoạn và hết hạn trước khi vận hành chính thức.