如何从PayFast获取数据并插入数据库?支付成功后存用户数据求助
PayFast 支付成功后插入用户数据到数据库指南
嘿,作为新手遇到这个问题太正常了,我来一步步帮你搞定从PayFast获取数据并插入数据库的事儿,重点是实现支付成功后自动把用户数据存到你的数据库里。
核心原理:PayFast的IPN(即时通知)机制
PayFast不会直接在用户跳转回你的网站时把所有支付数据都给你,而是通过IPN回调的方式,在支付完成后主动把数据发送到你指定的服务器脚本上——这才是你获取支付数据并插入数据库的关键。
第一步:配置PayFast商家账户的IPN地址
首先你得登录你的PayFast商家后台,找到「IPN设置」(一般在账户设置板块里),填写一个你服务器上的脚本URL,比如 https://你的域名.com/payfast_ipn.php。这个脚本就是后面要写的处理回调的核心文件。
第二步:调整你的支付表单
你现有的表单已经有基础支付参数了,但还需要补充几个关键字段,让PayFast知道该把回调数据发去哪,以及如何关联到对应的用户:
<form name="payment" class="form-inline w3-padding w3-light-grey" method="post" action="https://www.payfast.co.za/eng/process" onsubmit="return validateAmount()"> <?php while($row = mysqli_fetch_array($user_rec)){ ?> <input type="hidden" name="merchant_id" value="你的商家ID"> <!-- 新增以下隐藏字段 --> <input type="hidden" name="notify_url" value="https://你的域名.com/payfast_ipn.php"> <!-- 和后台配置的IPN地址一致,双重保障 --> <input type="hidden" name="return_url" value="https://你的域名.com/payment_success.php"> <!-- 用户支付成功后跳转的页面 --> <input type="hidden" name="cancel_url" value="https://你的域名.com/payment_cancel.php"> <!-- 用户取消支付后跳转的页面 --> <input type="hidden" name="custom_str1" value="<?php echo $row['user_id']; ?>"> <!-- 存用户ID,方便回调时关联到对应用户 --> <!-- 其他原有字段继续保留 --> <?php } ?> <!-- 表单提交按钮 --> <button type="submit">完成支付</button> </form>
这里的custom_str1是PayFast允许的自定义字段,用来传递你的用户ID,这样回调时就能精准知道是哪个用户完成了支付。
第三步:编写IPN回调脚本(payfast_ipn.php)
这个脚本是核心,它会接收PayFast发送的支付数据,验证数据的真实性,然后把数据插入你的数据库:
<?php // 1. 接收PayFast发送的POST数据 $postData = $_POST; // 2. 验证数据的真实性(防止伪造请求,PayFast官方推荐方式) $pfHost = 'www.payfast.co.za'; $pfParamString = ''; // 拼接参数字符串(排除signature字段) foreach ($postData as $key => $value) { if ($key !== 'signature') { $pfParamString .= $key . '=' . urlencode($value) . '&'; } } $pfParamString = rtrim($pfParamString, '&'); // 生成签名并对比验证 $signature = md5($pfParamString); if ($signature !== $postData['signature']) { error_log('PayFast IPN: 签名验证失败'); die('Invalid request'); } // 3. 发送验证请求回PayFast,确认支付合法性 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://' . $pfHost . '/eng/query/validate'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $pfParamString); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); $response = curl_exec($ch); curl_close($ch); if ($response !== 'VALID') { error_log('PayFast IPN: 支付验证不通过'); die('Invalid payment'); } // 4. 检查支付状态是否为完成 if ($postData['payment_status'] !== 'COMPLETE') { error_log('PayFast IPN: 支付未完成,状态:' . $postData['payment_status']); die('Payment not completed'); } // 5. 提取需要的数据(根据你的业务需求调整) $userId = $postData['custom_str1']; // 之前传递的用户ID $transactionId = $postData['m_payment_id']; // PayFast交易号 $amount = $postData['amount_gross']; // 支付金额 $paymentDate = $postData['payment_date']; // 支付时间 // 6. 连接数据库(替换成你的数据库信息) $conn = mysqli_connect('localhost', '你的数据库用户名', '你的数据库密码', '你的数据库名'); if (!$conn) { error_log('PayFast IPN: 数据库连接失败:' . mysqli_connect_error()); die('Database error'); } // 7. 插入数据到数据库(这里假设你有一个payments表,根据实际表结构调整) // 注意:生产环境必须用预处理语句防止SQL注入! $stmt = mysqli_prepare($conn, "INSERT INTO payments (user_id, transaction_id, amount, payment_date, status) VALUES (?, ?, ?, ?, ?)"); mysqli_stmt_bind_param($stmt, "ssdss", $userId, $transactionId, $amount, $paymentDate, 'completed'); if (mysqli_stmt_execute($stmt)) { error_log('PayFast IPN: 用户ID ' . $userId . ' 的支付记录已插入'); echo 'Success'; } else { error_log('PayFast IPN: 插入记录失败:' . mysqli_error($conn)); echo 'Database error'; } // 关闭连接 mysqli_stmt_close($stmt); mysqli_close($conn); ?>
关键注意事项
- SQL注入防护:上面的脚本用了预处理语句(
mysqli_prepare),这是必须的,绝对不要直接把用户数据拼到SQL语句里! - 测试环境:先用PayFast的沙箱环境测试,避免真实支付。沙箱的IPN验证地址是
https://sandbox.payfast.co.za/eng/query/validate,记得调整脚本里的对应地址。 - 日志记录:脚本里加了
error_log,方便你调试时查看错误信息,服务器日志一般在/var/log/apache2/error.log或类似路径。 - 服务器要求:确保你的服务器支持curl扩展,否则无法完成PayFast的验证步骤。
内容的提问来源于stack exchange,提问作者Siya Dlamini
相关产品推荐
相关产品推荐

