PHP 解析 JSON callback 中的 merchant_data
支付老李
结论
merchant_data 并不是已经解析好的嵌套数组,而是一段 JSON 字符串,需要再次调用 json_decode()。解析完成后,遍历其中的字段,通过 label 找到 first name 和 phone,再将它们写入文本文件。
回调数据中的名字标签是 fist_name,这很可能是 first_name 的拼写错误。代码仍应以支付平台实际返回的标签为准。
解析并保存字段
<?php
$json = file_get_contents('php://input');
$callback = json_decode($json, true);
if (!is_array($callback) || !isset($callback['merchant_data'])) {
exit('Invalid callback data');
}
$merchantData = json_decode($callback['merchant_data'], true);
if (!is_array($merchantData)) {
exit('Invalid merchant_data');
}
$values = [];
foreach ($merchantData as $field) {
if (isset($field['label'], $field['value'])) {
$values[$field['label']] = $field['value'];
}
}
// 回调示例中实际使用的是 fist_name
$firstName = $values['fist_name'] ?? '';
$phone = $values['phone'] ?? '';
file_put_contents(
'first_name.txt',
$firstName . PHP_EOL,
FILE_APPEND | LOCK_EX
);
file_put_contents(
'phone.txt',
$phone . PHP_EOL,
FILE_APPEND | LOCK_EX
);
执行后,两个文件会分别追加以下内容:
john_doe
以及:
07777777777
保存到同一个文件
如果要把两个值保存在同一个文本文件中,可以先将它们组合成一行:
$line = sprintf(
"first_name: %s, phone: %s%s",
$firstName,
$phone,
PHP_EOL
);
file_put_contents(
'merchant_data.txt',
$line,
FILE_APPEND | LOCK_EX
);
写入结果类似:
first_name: john_doe, phone: 07777777777
检查 JSON 解析错误
生产环境中不应直接忽略无效 JSON。对于较老的 PHP 版本,可以这样检查:
$callback = json_decode($json, true);
if (json_last_error() !== JSON_ERROR_NONE) {
exit('Callback JSON error: ' . json_last_error_msg());
}
if (!isset($callback['merchant_data']) ||
!is_string($callback['merchant_data'])) {
exit('merchant_data is missing');
}
$merchantData = json_decode($callback['merchant_data'], true);
if (json_last_error() !== JSON_ERROR_NONE) {
exit('merchant_data JSON error: ' . json_last_error_msg());
}
如果运行环境支持 JSON_THROW_ON_ERROR,也可以改用异常处理:
try {
$callback = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
$merchantData = json_decode(
$callback['merchant_data'] ?? '',
true,
512,
JSON_THROW_ON_ERROR
);
} catch (JsonException $e) {
exit('Invalid JSON: ' . $e->getMessage());
}
注意事项
- 示例数据使用的是
fist_name,不是first_name。如果可以控制支付页面的自定义字段,建议将其统一改为正确拼写。 - 手机号必须按字符串保存,否则开头的
0可能会丢失。 - 不建议将回调数据写入名为
robot.php的文件。如果该文件位于网站可访问目录,原始内容可能被公开,也可能带来安全问题。应改用.log或.txt文件,并尽量将文件放在 Web 根目录之外。 - 保存付款信息前,还需要验证支付平台提供的签名、订单号、金额和支付状态。仅检查 callback 中的
response_status或order_status,无法证明请求确实来自支付平台。 - 支付平台可能重复发送回调。如果收到数据后还会执行发货、充值等操作,应根据
payment_id或order_id做幂等处理,防止重复执行。
备注:内容仅供参考。
