
payfast支付成功后无法正确跳转,表面是url被转义(如`/`变为`\/`),实则根本原因在于`notify_url`未返回http 200响应——payfast强制要求通知接口必须成功响应,否则拒绝执行`return_url`跳转。
在PayFast Onsite(即“内嵌表单”)集成中,return_url、cancel_url和notify_url看似配置无误,但实际跳转失败,往往并非URL格式或转义问题——PayFast官方明确说明:其前端表单提交后,会先向你的notify_url发起服务器端回调验证;仅当该请求收到HTTP 200状态码且响应体为空(或仅含OK)时,才会触发后续的客户端重定向(即跳转至return_url)。若notify_url响应超时、返回5xx/4xx、输出额外空格、BOM头或任何非200内容,PayFast将静默终止流程,用户停留在支付结果页,且前端看到的URL参数中斜杠被JSON转义(如https:\/\/example.com\/success),这只是调试信息的显示副作用,并非根本原因。
✅ 正确的notify.php实现应极简、健壮、无副作用:
$value) {
if (substr($key, 0, 3) === 'pf_') {
$pfData[$key] = $value;
}
}
ksort($pfData);
$signature = md5(implode('|', $pfData));
return hash_equals($data['signature'] ?? '', $signature);
}
function processPaymentNotification($data) {
// 示例:记录日志、更新订单状态、触发发货等
error_log("PayFast notify received: " . json_encode($data));
// ⚠️ 注意:此处避免耗时操作;如需复杂处理,建议写入队列异步执行
}⚠️ 常见陷阱与检查清单:
- 输出污染:文件开头/结尾存在空格、UTF-8 BOM、echo/print、错误警告(开启display_errors=Off并检查error_log);
- HTTP状态码错误:未显式调用http_response_code(200),或被框架/中间件覆盖;
- 超时:notify_url响应时间超过PayFast默认30秒限制(建议控制在2秒内);
- HTTPS证书问题:确保服务器SSL证书有效,PayFast不接受自签名或过期证书;
- 防火墙/CDN拦截:确认服务器允许PayFast IP段(如197.251.192.0/18, 41.74.0.0/16)访问notify_url;
- 路径权限:notify.php需可被公网直接访问(禁止.htaccess重写拦截、IP白名单等)。
? 验证技巧:
使用curl手动模拟PayFast回调,观察真实响应:
curl -X POST https://www.example.co.za/signup/notify.php \ -H "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "pf_payment_id=12345" \ --data-urlencode "payment_status=completed" \ --data-urlencode "signature=abc123" \ -I # 仅查看响应头
确认返回 HTTP/2 200 且无Content-Length > 0。
总结:PayFast的跳转逻辑是强依赖notify_url可靠性的服务端契约。修复的核心不是修改前端URL编码,而是确保通知接口零容错、极速响应、严格遵循200协议。完成上述检查后,return_url将自动按原始配置精准跳转,JSON中的\/转义也将不再影响实际行为。










