集成结账
集成我们无缝的结账解决方案,让您的用户在亚太地区畅享多种支付方式。
自动集成(AI 辅助)
将下面的提示词粘贴到项目目录中的 AI 编程工具(Claude Code、Cursor、Codex 等)。代理会获取我们的机器可读文档并完成完整的测试模式集成,包括结账、Webhook,以及在发生支付争议或拒付时作为交付证据的配送记录;您只需审核改动、填入 API 密钥即可上线。
更进一步 — 接入 Tokenz MCP。 如果你的 AI 工具支持 MCP,添加我们的 MCP 服务器后,代理即可直接搜索文档、创建测试结账会话并验证 Webhook 签名 —— 一套引导式、可自我验证的集成流程。下方的提示词在有无 MCP 的情况下都能运行。
claude mcp add --transport http tokenz https://mcp.tokenz.one/mcp --header "Authorization: Bearer secret_test_YOUR_KEY_HERE"
提示词:在测试模式下端到端集成 Tokenz Checkout
You are integrating Tokenz — a Merchant of Record (MoR) checkout — into this project, end to end, in TEST MODE.
If a Tokenz MCP server is connected to you (you will see tools like `search_docs`, `get_openapi`, `create_test_checkout_session`, and `verify_webhook_signature`), use it throughout the steps below: prefer `search_docs`/`get_doc` over fetching raw doc URLs, take test cards from `list_test_cards`, and use `create_test_checkout_session` + `get_order` to prove the integration works against the real API. Everything below still applies either way.
Before writing any code:
1. Detect my project's stack and find the code that grants purchased items to a customer (fulfillment). Then ask me the questions below immediately, and fetch https://docs.tokenz.one/llms-checkout.txt while you wait for my answers. It contains the v2 checkout guides and links to the raw OpenAPI contracts. Fetch the linked Checkout Session, Order, and Webhook JSON specs before implementing their requests and payloads; those raw specs are authoritative for fields, constraints, errors, and response formats. Use https://docs.tokenz.one/llms.txt to find any additional guides you need. Stay on v2 for this new integration. If you cannot fetch URLs, ask me to paste the relevant guides and raw contracts.
2. The questions:
- What product(s) should the checkout sell (name, amount, currency)?
- Which environment file should hold my Tokenz test secret key (secret_test_...) and webhook signing secret (e.g. .env.local)? I will fill in the values myself. Remind me that the key needs the `CreateCheckoutSession`, `GetOrder`, and `RegisterDeliveryRecord` permissions.
- Confirm the framework/stack and the fulfillment code you found before patching anything. If the project has no fulfillment code yet, ask me how a paid order should be delivered and which ID identifies the customer.
- If this project only runs locally: how should Tokenz reach the webhook endpoint? (Offer to set up a tunnel such as ngrok or cloudflared, or ask me for a deployed HTTPS URL.)
Constraints (non-negotiable):
- Never hardcode, log, or commit secrets — API keys and webhook signing secrets alike; read them from environment variables only.
- Create Checkout Sessions server-side only; never expose the secret key to the browser.
- Define products and prices server-side; never trust amounts sent by the browser. Amounts are in minor units, and every product item needs a taxCategory from the docs' enum.
- Verify webhook signatures (Tokenz-Signature header) over the raw, unparsed request body; do not skip this.
- Fulfill orders from verified webhook events (order.succeeded), never from the customer reaching the success page — redirects prove navigation, webhooks prove payment. Handle webhook retries idempotently, keyed on the event's top-level `id`; the same event can be delivered more than once.
- Register a delivery record with Tokenz for every order you fulfill (POST /v2/order/{orderId}/delivery). This is a required part of the integration, not an extra: the delivery record is the proof of delivery sent to the bank or card issuer when a customer disputes a payment or files a chargeback, and an order without one has no evidence to defend it. Do not skip it, stub it, or offer it to me as optional.
- Build redirect URLs from a configured base URL, not from request headers such as Origin.
- Stay in Tokenz test mode until I explicitly ask to go live.
- Keep changes minimal; do not refactor unrelated code.
- Communicate with me in the language I use with you.
Deliverables — verify each actually works before claiming it is done:
1. A server endpoint that creates a Tokenz Checkout Session and returns its URL.
2. A checkout button/flow that redirects the customer to the hosted checkout.
3. Success, processing, and canceled pages wired to the session's redirect URLs. (Some payment methods settle asynchronously — the processing page is not optional.)
4. A webhook endpoint that receives events, verifies the signature, and updates order state. As soon as the webhook URL is known, tell me so I can register it in the Tokenz Dashboard (remind me: register it in TEST mode; the Dashboard shows the signing secret once, and I will put it into the env file myself — never ask me to paste it in chat) — then keep building while I do that.
5. Delivery registration, for every order the webhook fulfills:
- Order of operations: in the webhook handler, mark the event as processed, grant the items, and store the delivery record (or a job for it) as one transaction or one durable write, and only then acknowledge with 2xx. A retried webhook must find either nothing done or everything done, never granted items with no delivery record; if the project's storage cannot make that atomic, have the handler re-check fulfilled orders that lack a record and create it. Call the Delivery Registration API from outside the webhook response path (a queued job or background task), so a slow or unreachable API never delays the acknowledgement.
- Payload: send the full payload the docs recommend — `status`, `progress`, `at`, `user`, `items` with `deliveredQuantity` (plus the in-app balance before and after, when the item is a currency), `cartContext`, `deliveryContext`, and `deliveryInfo` — built from the real fulfillment data, never from placeholders. `cartContext` and `deliveryContext` describe the customer's device: capture the IP address, user agent, and device ID from the customer's own requests (when the Checkout Session is created, and at delivery if the customer is present), and store them with the order. Never fill them from the webhook request, which comes from Tokenz's servers; leave out a field you do not have.
- One record per delivery: register a failed delivery too (`status: failed`), send one record per delivery when an order is delivered in parts, and never let a retried webhook create a second record for the same delivery.
- Response: treat every entry in `warnings` as a bug and fix it. A failed call must never repeat or undo the fulfillment.
- Retries: each call creates a new record and there is no idempotency key, so keep every record Tokenz has not accepted in the project's own storage, in one of three states. Retryable (Tokenz answered 5xx): re-send automatically, including after a restart. Blocked (Tokenz answered 4xx): fix the cause before re-sending — 403 Forbidden means the key lacks the `RegisterDeliveryRecord` permission (on by default for secret keys), so tell me to use a secret key that has it; 401 Unauthorized means the key is missing, invalid, or revoked, so tell me to fix the key; re-send either once the key changes. Any other 4xx means the request is wrong, so fix it first. Needs review (no answer: timeout or dropped connection): never resend automatically; flag it for me to check.
6. A completed end-to-end test purchase using the test cards from the docs, with the webhook received and verified, the items granted once, and the delivery record accepted (201 Created, no warnings). If you have browser-automation tools, perform the test purchase yourself; otherwise give me exact steps.
7. A short go-live checklist for me: everything that must change to leave test mode (a live secret key with the permissions this integration uses, including `RegisterDeliveryRecord`; live webhook registration with its new signing secret; a stable public webhook URL; real tax/fulfillment handling), plus anything you stubbed.
If any step is blocked (missing key, docs ambiguity, unsupported stack), stop and ask me instead of guessing.
先决条件
在进行集成之前,请确保您已从 Tokenz 获取 API 凭证(公钥和私钥)。您可以在控制台的开发页面找到这些凭证。
有关 Tokenz Checkout 的更多信息,请参见 Checkout。
集成期间请使用测试 API 密钥(包含 test_,例如 secret_test_...):使用测试密钥创建的结账会话运行在测试模式下,不会产生真实扣款。上线时再切换为正式密钥。
配置服务器
import os
from flask import Flask, request, redirect
from flask_cors import CORS
import requests
# Replace the keys with yours
SECRET_KEY = os.environ.get("SECRET_KEY", "secret_test_YOUR_KEY_HERE")
app = Flask(__name__, static_url_path="")
CORS(app)
root = "../client/build"
@app.route("/", methods=["GET"])
def index():
return redirect("http://localhost:3080")
创建结账会话
在您的服务器上添加一个端点来创建结账会话。结账会话控制您的客户在 Tokenz 托管的支付页面上看到的内容,例如商品、订单金额、货币和可用的支付方式。
定义商品
始终将与产品库存的敏感信息(如价格和库存)保存在您的服务器上,以防止客户在客户端篡改数据。在创建结账会话时,定义产品信息。
订单总额始终根据 itemDetails 中的价格计算。部分示例中出现的顶层 amount 字段为可选项,但如果提供该字段,其值必须与 itemDetails 的总额一致,否则请求将被拒绝。
税费。 本快速入门(及其示例载荷)基于 Merchant of Record(MoR)模式——即 Tokenz 账户的默认模式:Tokenz 会自动计算并代收税费,您只需为每个商品设置 taxCategory。如果您的账户被特别配置为 Payment Gateway 模式,则每个 Checkout Session 都必须额外包含顶层 tax 对象(以最小货币单位表示,例如 "tax": { "amount": 0, "currency": "USD" });缺少该字段的请求会被拒绝并返回 order.tax-required。如果不确定您的账户使用哪种模式,请与您的 Tokenz 联系人确认。
提供成功和取消的 URL
指定成功和取消页面的 URL,确保这些页面是公开可访问的,以便 Tokenz 可以将客户重定向到它们。您也可以使用同一个 URL 来处理成功和取消状态。
[可选] 定义可用的支付方式
指定为此结账向您的客户提供的支付方式列表。如果未提供支付方式或发送了空列表,则所有可用的支付方式都将显示给客户。
将客户重定向到 Tokenz 结账页面
创建会话后,将客户重定向到响应中返回的结账页面的 URL。
@app.route("/create-tokenz-checkout", methods=['POST'])
def create_tokenz_checkout():
CALLBACK_URL_PREFIX = request.headers['referer']
headers = {"Authorization": f'Bearer {SECRET_KEY}'}
print(headers)
payload = {
"amount": {
"currency": "JPY",
"amount": 5200
},
"itemDetails": [
{
"product": {
"label": "ひとにぎりのエメラルド",
"description": "80+8",
"images": [
"https://images.ctfassets.net/z82qbo7cv7ia/1dWPbk5Qx2M1Qikj6Knyuc/e37b2c26829c0d30793a348ae3adb3b0/fake-pass.webp"
],
"quantity": 3,
"price": {
"currency": "JPY",
"amount": 1200
},
"taxCategory": "DIGITAL_GOODS_AND_SERVICES"
}
},
{
"product": {
"label": "エメラルドの荷車",
"description": "100+10",
"images": [],
"quantity": 1,
"price": {
"currency": "JPY",
"amount": 1600
},
"taxCategory": "DIGITAL_GOODS_AND_SERVICES"
}
}
],
"customerInfo": {},
"successUrl": "http://localhost:9000/success",
"pendingUrl": "http://localhost:9000/pending",
"cancelUrl": "http://localhost:9000/cancel"
}
res = requests.post(
"https://api.tokenz.one/v2/checkoutsession", json=payload, headers=headers
)
session = res.json()
return redirect(session["url"], 303)
建立结账页面
添加成功页面
为结账会话 successUrl 创建一个成功页面,向您的客户显示订单确认信息或订单详细信息。客户成功完成结账后,Tokenz 将重定向到此页面。
<!DOCTYPE html>
<html>
<head>
<title>感谢您的订单!</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<section>
<p>
感谢您的惠顾!如果您有任何问题,请发送电子邮件至
<a href="mailto:orders@example.com">orders@example.com</a>。
</p>
</section>
</body>
</html>
添加待处理付款页面
对于异步支付方式(如便利店支付或银行转账),支付可能会处于待处理状态,时间从几分钟到几天不等。
为 pendingUrl 添加一个页面。当客户关闭异步支付的说明页面后,Tokenz 会重定向到此页面。
<!DOCTYPE html>
<html>
<head>
<title>感谢您的订单!</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<section>
<p>
您的支付正在处理中!我们会在完成后第一时间通知您。
如果您有任何问题,请发送电子邮件至
<a href="mailto:orders@example.com">orders@example.com</a>.
</p>
</section>
</body>
</html>
添加取消页面
为 cancelUrl 添加另一个页面。当客户在结账中点击返回按钮时,Tokenz 会重定向到此页面。
<!DOCTYPE html>
<html>
<head>
<title>结账已取消</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<section>
<p>忘记添加商品到购物车了?继续购物,然后回来支付!</p>
</section>
</body>
</html>
添加结账按钮
最后,添加一个页面来显示客户订单的预览。允许他们审核或修改订单—当他们被重定向到结账页面后,订单即为最终确定,除非创建新的结账会话,否则无法修改订单。
在您的订单预览页面中添加一个按钮。当您的客户点击此按钮时,他们会被重定向到 Tokenz 托管的支付页面。
<!DOCTYPE html>
<html>
<head>
<title>购买新产品</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<section>
<div class="product">
<img src="https://images.ctfassets.net/z82qbo7cv7ia/1dWPbk5Qx2M1Qikj6Knyuc/e37b2c26829c0d30793a348ae3adb3b0/fake-pass.webp" alt="Treasure chest" />
<div class="description">
<h3>宝箱</h3>
<h5>¥1,000</h5>
</div>
</div>
<form action="/create-tokenz-checkout" method="POST">
<button type="submit" id="checkout-button">结账</button>
</form>
</section>
</body>
</html>