You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

API端点接收POST数据:$_POST与file_get_contents('php://input')的差异及Khipu网关适配问询

关于Khipu支付通知POST请求的特殊处理解析

我来帮你拆解Khipu这个特殊的POST处理逻辑——作为对接过不少支付网关的开发者,我太懂这种“非常规”操作的头疼了😅

1. Khipu与其他服务的核心区别

大多数现代支付网关(比如Stripe、PayPal的Webhook)会采用application/json格式发送通知数据:请求体是JSON字符串,请求头的Content-Type设为application/json。这种情况下PHP不会自动解析请求体到$_POST,必须手动读取php://input再用json_decode解析。

而Khipu遵循的是传统Web表单的提交标准:它发送的POST请求采用application/x-www-form-urlencoded格式(就是HTML表单用method="post"提交的格式,数据是key1=value1&key2=value2这样的键值对),这也是早期Web服务最常用的POST数据格式。

2. Khipu发送POST变量的具体方式

当Khipu触发支付完成通知时,它会向你的API端点发送一个POST请求:

  • 请求头的Content-Type会被设为application/x-www-form-urlencoded
  • 请求体是经过URL编码的键值对字符串,比如notification_token=abc123&transaction_id=456
  • PHP会自动识别这种格式,将请求体的键值对解析到$_POST超全局变量中,你直接通过$_POST['notification_token']就能获取对应值。

3. 为何必须通过$_POST接收?

这是由Khipu的数据发送格式直接决定的:

  • 因为它用的是application/x-www-form-urlencoded格式,PHP默认配置会自动处理这种请求,把数据填充到$_POST里,不需要你手动解析原始请求体,这是最简便且符合官方规范的方式。
  • 如果强行用json_decode(file_get_contents('php://input')),得到的会是null或者错误结果,因为原始请求体不是JSON格式,而是URL编码的字符串。

4. 你的兼容代码的合理性

你写的这段代码非常实用,能覆盖Khipu可能出现的边缘场景:

if (empty($_POST)) { 
    //For strange posts used by Khipu 
    $postVars = json_decode(file_get_contents('php://input')); 
} else { 
    $postVars = $_POST; 
}

虽然Khipu标准情况下会发送application/x-www-form-urlencoded格式,但偶尔可能因为网关重试、代理服务器修改请求头、或者PHP配置(比如enable_post_data_reading被禁用、post_max_size超限)导致$_POST无法被自动填充。这时候读取原始请求体并尝试JSON解析,能兜底处理这些异常情况,确保你不会漏掉通知。

内容的提问来源于stack exchange,提问作者Marcus Edensky

火山引擎 最新活动