PayPal API支付返回JSON无法插入MySQL数据库问题排查
PayPal支付结果无法入库、接口无返回故障排查
按下面顺序逐项排查即可定位问题,无需反复走完整支付流程验证。
1. 先解决「后端echo无输出」问题
你加的调试打印看不到,90%是前端fetch逻辑缺失响应处理:你只完成了POST请求发送,没有编写响应读取、打印的逻辑,后端返回的所有内容都被浏览器静默丢弃了。
先把onApprove回调里的fetch逻辑改成如下写法:
onApprove: function(data, actions) { // 必须等支付捕获完成、拿到完整交易数据再发请求 return actions.order.capture().then(function(detalles) { return fetch('GetDatosCompra.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ transactionId: detalles.id, amount: detalles.purchase_units[0].amount.value, status: detalles.status, updateTime: detalles.update_time, payerEmail: detalles.payer.email_address, payerId: detalles.payer.payer_id }) }) .then(response => response.text()) .then(resText => { alert('接口返回:' + resText); // 这里就能看到你加的echo内容 // 支付成功后的跳转、提示逻辑放在这 }) .catch(err => { console.error('请求后端失败:', err); }); }); }
注意:不要在
actions.order.capture()执行完成前发请求,否则会拿到残缺的交易数据,导致后端字段校验失败。
2. 补全后端接口基础校验逻辑
把以下代码加在GetDatosCompra.php文件最顶部,先解决请求根本没到插入逻辑的问题:
<?php // 调试阶段开启错误显示,解决报错被吞的问题 ini_set('display_errors', 1); error_reporting(E_ALL); // 跨域配置,解决fetch跨域被拦截的问题 header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: POST, OPTIONS'); header('Access-Control-Allow-Headers: Content-Type'); // 处理浏览器跨域预检OPTIONS请求,不处理的话POST请求会直接被拦截 if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit; } // 必须启动session,否则拿不到存储的用户ID、商品ID session_start();
紧接着加输入校验,定位数据接收阶段的问题:
// 读取原始POST数据 $rawInput = file_get_contents('php://input'); if (!$rawInput) { echo "未接收到JSON请求数据"; exit; } // 解析JSON $data = json_decode($rawInput, true); if (json_last_error() !== JSON_ERROR_NONE) { echo "JSON解析失败:" . json_last_error_msg(); exit; } // 校验必填支付字段 $requiredPayFields = ['transactionId', 'amount', 'status', 'updateTime', 'payerEmail', 'payerId']; foreach ($requiredPayFields as $field) { if (!isset($data[$field])) { echo "缺失支付字段:" . $field; exit; } } // 校验session必填字段 if (!isset($_SESSION['user_id'], $_SESSION['product_id'])) { echo "session失效或不存在,无法获取用户ID、商品ID"; exit; }
3. 修复数据库插入的常见问题
插入操作不执行,基本都是以下几个原因:
- 数据库连接未开启异常模式,报错被静默吞掉。连接PDO时务必加这行配置:
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- 时间格式不匹配:PayPal返回的
updateTime是ISO格式(例:2024-06-12T08:23:45Z),MySQL的datetime字段无法直接识别,需要先转格式:
$updateTime = date('Y-m-d H:i:s', strtotime($data['updateTime']));
- 预处理语句执行后没有捕获错误,改成try/catch写法即可看到具体报错:
try { $stmt = $pdo->prepare("INSERT INTO comprado (transaction_id, amount, status, update_time, payer_email, payer_id, user_id, product_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); $insertRes = $stmt->execute([ $data['transactionId'], $data['amount'], $data['status'], $updateTime, $data['payerEmail'], $data['payerId'], $_SESSION['user_id'], $_SESSION['product_id'] ]); echo $insertRes ? "插入成功,记录ID:".$pdo->lastInsertId() : "插入失败:".$stmt->errorInfo()[2]; } catch (PDOException $e) { echo "数据库错误:" . $e->getMessage(); }
调试效率技巧
不用每次都走完整PayPal支付流程调接口,直接用接口调试工具构造和前端格式一致的JSON POST请求,访问GetDatosCompra.php就能直接看到报错,排查效率能提升数倍。
内容的提问来源于stack exchange,提问作者CAMILA SALAZAR FIGUEROA
相关产品推荐
相关产品推荐

