You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP接收Interswitch支付回调JSON参数并更新数据库的问题

解决Interswitch支付网关JSON推送接收问题

你之前的代码思路完全搞反啦!你写的是主动请求拉取数据的CURL逻辑,但Interswitch支付网关是主动把支付结果推送到你预先提供的URL——根本不需要你去请求它的地址,你要做的是把自己的PHP页面改成一个能接收POST请求的接口,下面一步步帮你搞定:

核心逻辑梳理

支付网关的交互流程是这样的:

  • 用户完成支付后,网关会自动向你配置好的URL发送POST请求
  • 请求的Body里就是你提到的那些JSON格式支付参数
  • 你的PHP接口需要接收、解析这些参数,更新数据库后给网关返回成功响应

编写接收推送的PHP接口代码

这里给你一个完整的可落地示例,包含参数验证、数据库操作和响应返回:

<?php
// 1. 接收POST过来的原始JSON数据
$rawInput = file_get_contents('php://input');
if (empty($rawInput)) {
    http_response_code(400);
    echo json_encode(['status' => 'error', 'message' => 'Empty request body']);
    exit;
}

// 2. 解析JSON为对象(要数组的话可以加第二个参数true)
$paymentData = json_decode($rawInput);
if (json_last_error() !== JSON_ERROR_NONE) {
    http_response_code(400);
    echo json_encode(['status' => 'error', 'message' => 'Invalid JSON format']);
    exit;
}

// 3. 验证必填参数(根据网关要求的字段做校验,比如PaymentLogId、Amount这些是核心字段)
$requiredFields = ['PaymentLogId', 'CustReference', 'Amount', 'PaymentReference', 'PaymentDate'];
foreach ($requiredFields as $field) {
    if (!isset($paymentData->$field) || empty($paymentData->$field)) {
        http_response_code(400);
        echo json_encode(['status' => 'error', 'message' => "Missing required field: $field"]);
        exit;
    }
}

// 4. 连接数据库并处理记录(用PDO更安全,替换成你的数据库信息)
try {
    $db = new PDO('mysql:host=localhost;dbname=your_db;charset=utf8mb4', 'db_user', 'db_password');
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // 先检查是否已存在该支付记录(防止网关重复推送)
    $checkStmt = $db->prepare("SELECT COUNT(*) FROM payment_logs WHERE PaymentLogId = :logId");
    $checkStmt->bindParam(':logId', $paymentData->PaymentLogId);
    $checkStmt->execute();
    $recordExists = $checkStmt->fetchColumn();

    if ($recordExists) {
        // 已存在则更新记录
        $updateStmt = $db->prepare("
            UPDATE payment_logs 
            SET CustReference = :custRef, Amount = :amount, PaymentReference = :payRef, 
                IsReversal = :isReversal, PaymentDate = :payDate, BankName = :bankName, 
                CustomerName = :custName, ItemName = :itemName, CustomerAddress = :custAddr
            WHERE PaymentLogId = :logId
        ");
        $updateStmt->bindParam(':custRef', $paymentData->CustReference);
        $updateStmt->bindParam(':amount', $paymentData->Amount);
        $updateStmt->bindParam(':payRef', $paymentData->PaymentReference);
        $updateStmt->bindParam(':isReversal', $paymentData->IsReversal, PDO::PARAM_BOOL);
        $updateStmt->bindParam(':payDate', $paymentData->PaymentDate); // 注意DateTime字段可能需要转格式
        $updateStmt->bindParam(':bankName', $paymentData->BankName);
        $updateStmt->bindParam(':custName', $paymentData->CustomerName);
        $updateStmt->bindParam(':itemName', $paymentData->ItemName);
        $updateStmt->bindParam(':custAddr', $paymentData->CustomerAddress);
        $updateStmt->bindParam(':logId', $paymentData->PaymentLogId);
        $updateStmt->execute();
    } else {
        // 不存在则插入新记录
        $insertStmt = $db->prepare("
            INSERT INTO payment_logs (PaymentLogId, CustReference, Amount, PaymentReference, IsReversal, 
                                      PaymentDate, BankName, CustomerName, ItemName, CustomerAddress)
            VALUES (:logId, :custRef, :amount, :payRef, :isReversal, 
                    :payDate, :bankName, :custName, :itemName, :custAddr)
        ");
        $insertStmt->bindParam(':logId', $paymentData->PaymentLogId);
        $insertStmt->bindParam(':custRef', $paymentData->CustReference);
        $insertStmt->bindParam(':amount', $paymentData->Amount);
        $insertStmt->bindParam(':payRef', $paymentData->PaymentReference);
        $insertStmt->bindParam(':isReversal', $paymentData->IsReversal, PDO::PARAM_BOOL);
        $insertStmt->bindParam(':payDate', $paymentData->PaymentDate);
        $insertStmt->bindParam(':bankName', $paymentData->BankName);
        $insertStmt->bindParam(':custName', $paymentData->CustomerName);
        $insertStmt->bindParam(':itemName', $paymentData->ItemName);
        $insertStmt->bindParam(':custAddr', $paymentData->CustomerAddress);
        $insertStmt->execute();
    }

    // 5. 返回成功响应给网关(必须返回,否则网关可能重试推送)
    http_response_code(200);
    echo json_encode(['status' => 'success', 'message' => 'Payment log processed']);

} catch (PDOException $e) {
    // 错误日志记录到服务器(不要直接返回给网关,避免泄露敏感信息)
    error_log("Payment webhook error: " . $e->getMessage());
    http_response_code(500);
    echo json_encode(['status' => 'error', 'message' => 'Internal server error']);
}
?>

重要注意事项

  • 公网可访问:把这个PHP页面部署到公网服务器上,给网关提供的URL必须是网关能访问到的(比如https://your-domain.com/payment-webhook.php)
  • 强制HTTPS:支付相关请求必须用HTTPS,否则网关可能拒绝推送,同时保障数据传输安全
  • 日志记录:建议把每次接收的请求和处理结果写入日志文件,方便后续排查问题
  • 重复推送处理:网关可能因网络问题重复推送,一定要用唯一标识(比如PaymentLogId)检查记录是否已存在,避免重复操作
  • 字段类型匹配:数据库字段要和网关参数类型对应(比如IsReversal用布尔型,Amount用数值型,PaymentDate用DateTime型)

内容的提问来源于stack exchange,提问作者Sunusi Mohd Inuwa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:57:43