2.1 版本文件
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/**
|
||||
* 支付异步通知回调(支付宝 / 微信支付)
|
||||
*
|
||||
* 支付宝 POST 到此页面
|
||||
* 微信支付 POST 到此页面
|
||||
*
|
||||
* 路由方式:通过 ?gateway=alipay 或 ?gateway=wechat 区分
|
||||
*/
|
||||
require __DIR__ . '/includes/init.php';
|
||||
|
||||
// 关闭输出缓冲,确保原始响应
|
||||
ob_clean();
|
||||
|
||||
$gateway = trim($_GET['gateway'] ?? $_POST['gateway'] ?? '');
|
||||
|
||||
if (empty($gateway)) {
|
||||
http_response_code(400);
|
||||
exit('missing gateway param');
|
||||
}
|
||||
|
||||
Payment::initGateways();
|
||||
$gw = Payment::get($gateway);
|
||||
|
||||
if (!$gw) {
|
||||
http_response_code(404);
|
||||
exit('unknown gateway');
|
||||
}
|
||||
|
||||
Logger::info('收到支付通知', ['gateway' => $gateway, 'raw_input' => file_get_contents('php://input')]);
|
||||
|
||||
// 收集所有参数
|
||||
$params = array_merge($_GET, $_POST);
|
||||
unset($params['gateway']);
|
||||
|
||||
if (!$gw->verifyNotify($params)) {
|
||||
Logger::warn('支付通知验签失败', ['gateway' => $gateway]);
|
||||
http_response_code(403);
|
||||
exit('signature mismatch');
|
||||
}
|
||||
|
||||
$tradeNo = $gw->getTradeNo($params);
|
||||
$isPaid = $gw->isPaid($params);
|
||||
|
||||
// 查找对应的支付记录
|
||||
$outTradeNo = $params['out_trade_no'] ?? '';
|
||||
$stmt = db()->prepare('SELECT id,order_id,status FROM ' . tn('pay_logs') . ' WHERE order_id=? AND pay_method=? ORDER BY id DESC LIMIT 1');
|
||||
$stmt->execute([$outTradeNo, $gateway]);
|
||||
$payLog = $stmt->fetch();
|
||||
|
||||
if (!$payLog) {
|
||||
Logger::error('支付通知:未找到支付记录', ['out_trade_no' => $outTradeNo]);
|
||||
// 即使找不到记录也返回成功,避免重复通知
|
||||
$gw->respondSuccess();
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($payLog['status'] === 'paid') {
|
||||
// 已处理过,直接返回成功
|
||||
$gw->respondSuccess();
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($isPaid) {
|
||||
// 支付成功 → 更新订单状态
|
||||
db()->beginTransaction();
|
||||
try {
|
||||
Payment::updatePayStatus($payLog['id'], 'paid', $tradeNo);
|
||||
// 更新订单状态为已付款
|
||||
db()->prepare('UPDATE ' . tn('orders') . ' SET status=\'paid\', paid_at=NOW() WHERE id=?')
|
||||
->execute([$payLog['order_id']]);
|
||||
db()->commit();
|
||||
Logger::info('支付成功', ['order_id' => $payLog['order_id'], 'trade_no' => $tradeNo, 'gateway' => $gateway]);
|
||||
|
||||
// TODO: 发送支付成功通知邮件
|
||||
} catch (Exception $e) {
|
||||
db()->rollBack();
|
||||
Logger::error('支付成功后更新订单失败', ['error' => $e->getMessage()]);
|
||||
}
|
||||
} else {
|
||||
Logger::warn('支付未成功', ['trade_status' => $params['trade_status'] ?? '']);
|
||||
}
|
||||
|
||||
$gw->respondSuccess();
|
||||
exit;
|
||||
Reference in New Issue
Block a user