您无法在 Payora 的沙盒中测试加密支付网关,因为 Payora 没有沙盒:没有测试网络模式,没有测试模式 API 密钥,没有虚假发票。您可以做的是检查真实的托管结账页面,/demo,重放您自己签名的 webhook 到您自己的处理程序,然后向您在一个便宜网络上的发票发送一笔大约一美元的真实付款。最后一步的费用微不足道,并证明了沙盒永远无法证明的一件事。
为什么没有沙盒,以及为什么这不是您认为的问题
沙盒是一个模拟器。它让您在网关编写的虚构环境中排练您的代码。这对卡处理器来说确实很有用,因为收单方、风险引擎和结算通道都是不透明的,您没有其他方式进入。
加密是不同的。在生产中出错的部分几乎从来不是 API 调用。问题出在链上:付款落在错误的网络上、在买家复制地址时锁定的汇率过期、没有人阅读的确认政策、服务器从错误的密钥派生的地址。沙盒凭空生成了一张已付款的发票。它对这些都没有任何帮助。更糟的是,它告诉您一切都很好,这是测试能产生的最昂贵的谎言。
因此,测试加密支付网关的诚实方式是一个梯子:首先验证所有可以免费验证的内容,然后进行一次小额真实支付,以全面测试整个链条。以下是我建议的执行顺序。
1. 在编写代码之前查看真实的结账页面
打开 /demo。它在真实的托管结账页面上生成一个实时发票,买家将看到的页面。无需账户,无需代码。观察实际发生的事情:币种选择器的行为、汇率锁定窗口的样子、交易仍未确认时买家看到的内容、计时器到期时发生的事情。
在这里花五分钟可以节省以后的争论,因为大多数集成错误的起因是对流程的错误心理模型。阅读 /docs 并将每个屏幕与其背后的发票字段进行匹配。然后在 /register 创建您的账户并获取您的 API 密钥和 api_secret.
2. 在不花费任何费用的情况下测试您的 webhook 处理程序
这是最重要的一点。您的处理程序是将 "钱到账" 转换为 "客户收到了他们的东西" 的代码,它是您可以免费进行全面测试的部分,因为您持有签署 webhook 的密钥。Payora 能签署的任何内容,您都可以签署。
该方案是普通 HMAC。签名是hex(hmac_sha256(timestamp . '.' . rawBody, api_secret)),发送于X-Payora-Signature,具有相同的时间戳在X-Payora-Timestamp。时间戳必须在±120 秒之内,并且每次交付都携带一个Idempotency-Key头部,该头部在同一事件的重试中保持稳定。签署原始主体字节,而不是重新编码的数组 — 重新编码是正确签名失败的经典原因。
<?php
// Sign a webhook exactly the way Payora signs one, and POST it at your own endpoint.
$secret = 'YOUR_API_SECRET'; // the secret your handler verifies with
$url = 'https://yoursite.com/payora-webhook.php'; // your endpoint, on your dev host
$body = json_encode([
'event' => 'invoice.paid',
'invoice_id' => 'inv_local_1',
'order_id' => '1001',
'status' => 'paid',
'amount' => '1.00',
'currency' => 'USD',
'asset' => 'USDT',
'network' => 'tron',
], JSON_UNESCAPED_SLASHES);
$ts = (string) time();
$sig = hash_hmac('sha256', $ts . '.' . $body, $secret); // lowercase hex
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body, // send the RAW body you signed
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-Payora-Timestamp: ' . $ts,
'X-Payora-Signature: ' . $sig,
'Idempotency-Key: whk_local_1',
],
]);
$out = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo "$code\n$out\n";
将其指向您自己的开发端点,您就拥有一个无需费用且循环运行的 webhook 生成器。验证方面 — 常量时间比较、窗口检查、为什么必须读取原始输入流 — 在中详细介绍。使用 HMAC-SHA256 的 webhook 签名验证.
3. 实际捕捉错误的测试
对每个测试进行处理并检查数据库,而不仅仅是 HTTP 状态。预期结果不是脚注;它们就是测试。
- 有效签名 → 200,订单标记为已支付,仅一次。
- 相同的 webhook 被发送了两次(相同
Idempotency-Key)→ 仍然只有一个付费订单。没有双重信用,没有第二个许可证密钥,没有第二个运输标签。这是支付集成中最常见的真实错误,重试是正常的,而不是例外。 - 篡改的主体与旧签名 — 更改
amount从1.00到1000.00,保持签名 → 被拒绝,订单未支付。 - 错误或缺失的签名 → 被拒绝。一个空的
X-Payora-Signature必须像错误的那样失败。 - 过期的时间戳 — 将其设置为十分钟前 → 在窗口上被拒绝,尽管 HMAC 本身是有效的。
- 未知或外部发票 ID → 干净地被拒绝。没有致命错误,没有 500,没有半写的行。
- 您的端点返回 500 → 随后的重试必须不重复应用。如果您想确保,请在处理程序中途终止数据库连接。
- 恒定时间比较 — 使用
hash_equals(),绝不要==。并且永远不要记录api_secret,不是在调试级别,不是截断的,不是一次。
如果所有八个都通过,你的处理程序比大多数实时集成要好。现在注意他们没有证明的事情:钱实际上可以到达你那里。
4. 向自己支付一小笔真实款项
现在花一美元。通过 API 创建发票或从 /accept-payments打开结账,支付 从你自己的钱包,到你自己的发票,大约 $1。
选择一个便宜、快速的网络,这样费用就只需几美分而不是几美元:TON(Gram)、Tron 和 Solana 都在几秒钟内确认,费用仅为几美分。除非比特币是你特别要交付的内容,否则不要在比特币主网上运行此操作——你每次尝试都要等待十分钟,并为此付费。
这笔单一付款是唯一测试完整链的方式:利率锁定、链上检测、对该资产政策的确认(见 多少次确认是安全的),签名的 webhook,您的数据库。如果它有效,您的集成就有效。如果无效,失败是真实且具体的——这正是您希望在一个安静的星期二发现的,而不是在发布期间。
5. 证明您可以提取资金
每个人都跳过这一点。这是最痛苦的一步。
在您接受任何客户的付款之前,将那一美元提取回您控制的钱包。检查 /balance,进行一次提款或转账,观察它到账。如果您计划支付供应商或合作伙伴,请通过 /mass-payouts 推送一批包含两行和微不足道金额的交易,并确认离线签名步骤在您的实际机器上与您的实际密钥材料有效——而不是理论上,在机器上。
一个您可以接收但无法提取的网关不是一个网关。它是一个带有漂亮结账页面的陷阱。发现 $1 被卡住是一个后来的故事。发现 $40,000 被卡住是一个非常不同的下午。
6. 验证派生的地址确实是你的
这条是针对非托管设置的,且不可协商。Payora 仅从公钥材料中派生接收地址——你的 xPub 或主公钥。私钥从不接触服务器。这就是整个安全模型,它有一个严格的要求:你粘贴的 xPub 必须是你的钱包实际拥有的。
所以要独立验证。取一个服务器为发票派生的地址,从你的 xPub 自己派生相同的索引——在你的钱包软件中,或使用任何离线 HD 钱包库——并逐字符比较字符串。如果它们匹配,每笔付款都会落在你可以支出的地方。如果不匹配,每笔付款都会悄无声息地丢失,伴随着绿色结账和一张已支付的订单。该xPub 和 HD 钱包解释器会详细讲解派生过程。
在上线之前完成此操作。不要等到第一次投诉后。
诚实地说,权衡利弊
没有沙盒意味着你第一次真正的测试需要花费一点钱和一点心思。这是一个真实的成本,我不会假装不是。你所得到的回报是一个真实的测试。沙盒会给你一个 API 调用的绿色勾选,并不会告诉你关于利率锁定、确认政策、提款路径或地址是否属于你的任何信息——这四个因素实际上决定了你是否能收到付款。
一美元,一个下午和一个清单胜过一个与你意见一致的模拟器。
准备好运行它了吗?在 /register 创建一个免费账户,/accept-payments,从中生成你的第一张发票,然后逐项完成清单。整个过程大约需要一个小时和大约一美元。
Comments