使用Faucetpay.io商户API处理回调数据时遇到的问题
Faucetpay商户API回调无POST数据,交易验证失败问题
问题背景
对接Faucetpay商户API时,交易流程显示成功(用户账户扣款、商户后台可见交易),但回调页面无法获取POST数据,导致交易验证失败,无法执行后续的用户积分添加逻辑。
表单代码(index.html)
<form action="https://faucetpay.io/merchant/webscr" method="post" autocomplete="off"> <input type="hidden" name="merchant_username" value="sanox"> <input type="hidden" name="item_description" value="RCP Webpage - buy 64 spesmilo points"> <input type="hidden" name="amount1" value="0.001"> <input type="hidden" name="currency1" value="USDT"> <input type="hidden" name="callback_url" value="https://example.com/callback.html"> <input type="hidden" name="success_url" value="https://example.com/callback.html"> <input type="hidden" name="cancel_url" value="https://example.com/index.html"> <input type="submit" class="w3-btn w3-purple" name="submit" value="Buy ₷64"> </form>
回调代码(callback.html)
<?php error_reporting(E_ALL ^ E_DEPRECATED ^ E_WARNING ^ E_NOTICE); header("Content-Type: text/html; charset=UTF-8"); require('res/config.php'); session_start(); if (isset($_SESSION['app'])) { $user = $_SESSION['app']; // Debugging var_dump($_POST); // Check the entire POST data $token = $_POST['token']; echo "Token: " . $token; $payment_info = json_decode(file_get_contents("https://faucetpay.io/merchant/get-payment/" . $token), true); $token_status = $payment_info['valid']; $merchant_username = $payment_info['merchant_username']; $my_username = "sanox"; if ($my_username == $merchant_username && $token_status) { // Processing logic when validation is successful mysql_query("UPDATE crypto_users SET points = points + 64 WHERE `email` = '$user'"); echo 'Thank you. Payment processed. ₷64 added to your account!'; } else { echo "Invalid payment attempt. TokenID: " . $token; echo " Merchant Username: " . $merchant_username; } } else { die('Please login first!'); } ?>
问题现象
- 用户支付后,sanox1账户成功扣除0.001 USDT,商户sanox后台可见该交易。
- callback.html页面输出
array(0) { },$token、$merchant_username等变量为空,最终显示Invalid payment attempt。
核心原因分析
混淆了
success_url和callback_url的作用success_url是用户支付成功后,Faucetpay前端跳转的页面,该请求为GET方式,不会携带POST数据。callback_url是Faucetpay后台异步通知商户的地址,才会以POST方式发送交易token等参数。- 你将两个URL设为同一个页面,导致用户跳转过来的GET请求被当作异步回调处理,自然获取不到POST数据。
接口关联说明
/merchant是商户管理后台及API文档入口,用于配置商户信息、查看交易记录。/merchant/get-payment/{token}是交易查询API,通过交易唯一标识token获取交易详情(有效性、商户信息、金额等),用于验证交易真实性,必须配合回调传递的token使用。
解决方案
1. 分离success_url和callback_url
修改表单代码,将两个URL分开:
<form action="https://faucetpay.io/merchant/webscr" method="post" autocomplete="off"> <!-- 其他隐藏字段不变 --> <input type="hidden" name="callback_url" value="https://example.com/callback.php"> <!-- 专门处理异步回调 --> <input type="hidden" name="success_url" value="https://example.com/success.html?token={token}"> <!-- 用户跳转页面,携带token参数 --> <!-- 其他字段不变 --> </form>
success_url中使用{token}占位符,Faucetpay会自动替换为实际交易token,用户跳转后可通过GET参数获取token。
2. 重构异步回调页面(callback.php)
专门处理Faucetpay的POST异步通知,逻辑如下:
<?php error_reporting(E_ALL); header("Content-Type: application/json"); require('res/config.php'); // 仅处理POST请求 if ($_SERVER['REQUEST_METHOD'] !== 'POST') { exit(json_encode(['status' => 'error', 'msg' => 'Invalid request method'])); } // 获取POST传递的token $token = $_POST['token'] ?? ''; if (empty($token)) { exit(json_encode(['status' => 'error', 'msg' => 'Missing token'])); } // 查询交易详情 $payment_info = json_decode(file_get_contents("https://faucetpay.io/merchant/get-payment/" . $token), true); if (!$payment_info || !$payment_info['valid']) { exit(json_encode(['status' => 'error', 'msg' => 'Invalid payment token'])); } // 验证商户用户名 $my_username = "sanox"; if ($payment_info['merchant_username'] !== $my_username) { exit(json_encode(['status' => 'error', 'msg' => 'Mismatched merchant'])); } // 执行积分更新(注意:使用mysqli/PDO替代已废弃的mysql_query) // 示例用mysqli: $conn = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME); // 建议表单中添加custom字段传递用户标识,避免依赖session(异步回调无用户session) $user_email = mysqli_real_escape_string($conn, $payment_info['custom'] ?? ''); if (!empty($user_email)) { mysqli_query($conn, "UPDATE crypto_users SET points = points + 64 WHERE `email` = '$user_email'"); } // 返回成功响应给Faucetpay exit(json_encode(['status' => 'success', 'msg' => 'Payment processed'])); ?>
- 建议在表单中添加
custom隐藏字段传递用户标识(如邮箱),异步回调是后台请求,无法获取用户session。 - 替换已废弃的
mysql_query为mysqli或PDO,避免安全风险和兼容性问题。
3. 用户成功页面(success.html)
用户跳转后,可通过GET参数获取token,展示成功信息:
<!DOCTYPE html> <html> <body> <?php $token = $_GET['token'] ?? ''; if ($token) { echo "<h1>Payment Successful!</h1>"; echo "<p>Your token: " . htmlspecialchars($token) . "</p>"; echo "<p>₷64 has been added to your account.</p>"; } else { echo "<h1>Invalid request</h1>"; } ?> </body> </html>
内容的提问来源于stack exchange,提问作者Thundermole
相关产品推荐
相关产品推荐

