【发布时间】:2013-01-17 19:06:52
【问题描述】:
由于一个我似乎无法解决的问题,我目前正撞上一堵巨大的墙。
问题是,当您通过 Facebook 支付平台(facebook javascript sdk)进行支付时,它会将数据发送到您的回调页面,该页面应该在后台处理支付。
这一切都很好,但有一个问题:facebook 使用的订单 ID 是 64 位 ID,而我的服务器是 32 位服务器,因此当它被保存到回调中的变量时,它会失去 ID 的精度页。这最终导致最终无法获得正确的order_ID,因为它无法保存ID。
该问题已在此论坛的多个页面上进行了描述,例如:
facebook credit callback, order_id changes format changes after moving to a new server
和
PHP: Converting a 64bit integer to string
然而,在这两个页面上都没有解决问题的方法,而且我自己似乎无法解决这个问题。 我试图将 facebook 发送到我的回调页面的 json 数据转换为字符串数据,而不是带有整数的数组(这发生在 facebook 提供的基本代码中),但我无法让它工作。
看到其他人已经克服了这个问题(无需将所有内容迁移到 64 位服务器),我想知道如何。
有没有人能阐明这个主题?
编辑: 我已尝试转换为字符串,即被调用以解码 json 数据的标准 facebook 代码(由 facebook 提供的代码):
$request = parse_signed_request($_POST['signed_request'], $app_secret);
这会调用函数 parse_signed_request,它会:
function parse_signed_request($signed_request, $secret) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$sig = base64_url_decode($encoded_sig);
$data = json_decode(base64_url_decode($payload), true);
if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
error_log('Unknown algorithm. Expected HMAC-SHA256');
return null;
}
// check sig
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {
error_log('Bad Signed JSON signature!');
return null;
}
return $data;
}
此函数解码来自 facebook 的加密 json 数据(使用应用程序密钥),并应将 json 数据解码为 PHP 数组。
该函数使用以下函数(确切:
function base64_url_decode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
现在,上面的代码导致订单ID没有被正确保存,它失去了它的精度,导致一个id像:4.8567130814993E+14
我尝试使用以下函数以某种方式将 json 数据解码为字符串(因此 64 位整数 ID 不会丢失其精度),但无济于事:
function largeint($rawjson) {
$rawjson = substr($rawjson, 1, -1);
$rawjson = explode(',' , $rawjson);
array_walk($rawjson, 'strfun');
$rawjson = implode(',', $rawjson);
$rawjson = '{' . $rawjson . '}';
$json = json_decode($rawjson);
return $json;
}
function strfun(&$entry, $key) {
$data = explode(':', $entry);
if (FALSE === strpos($data[1], '"')) {
$data[1] = '"' . $data[1] . '"';
$entry = implode(':', $data);
}
}
编辑(尤金斯回答):
如果我在使用 json_decode 使其成为 php 变量之前尝试修改 JSON 数据,我应该使用 preg_replace 函数吗? 下面是发送到回调页面以启动支付流程的初始 JSON 数据的示例。 这里已经可以看出问题出在哪里了(这是在使用json_decode之后,id等数据失去了精度)。 ID 被修改为不反映任何真实数据。 如果您比较顶部的买家 ID 和底部的用户 ID,您会发现精度有所下降。
Array
(
[algorithm] => HMAC-SHA256
[credits] => Array
(
[buyer] => 1.0055555551318E+14
[receiver] => 1.0055555551318E+14
[order_id] => 5.2555555501665E+14
[order_info] => {"item_id":"77"}
[test_mode] => 1
)
[expires] => 1358456400
[issued_at] => 1358452270
[oauth_token] => AAAH4s2ZCCEMkBAPiGSNsmj98HNdTandalotmoredata
[user] => Array
(
[country] => nl
[locale] => nl_NL
[age] => Array
(
[min] => 21
)
)
[user_id] => 100555555513181
)
编辑#3:
我已尝试以下方法将 JSON 数据中的所有整数视为字符串,但这会导致 facebook 平台出错。然而,它确实将整数更改为字符串,所以我不会失去精度(太糟糕了,现在 xD 没有其他工作了)
preg_replace('/([^\\\])":([0-9]{10,})(,|})/', '$1":"$2"$3', $a)
【问题讨论】:
-
是的,您需要使用字符串。向我们展示您尝试过但没有奏效的方法 - 发布一些代码。
-
我已经发布了很多信息来回应你的评论和尤金的评论。我尝试了几件事,但又一次没有成功。我还向我的托管服务提供商邮寄了有关将系统升级到 64 位(或 php 5.4)的可能性。
-
因此,因为您正在更改 JSON 对象,您的 HMAC 哈希签名将不匹配。作为策略的额外牺牲,您可能不得不绕过该安全功能。 EG:你必须修改库并绕过哈希签名检查。
标签: php facebook callback 32bit-64bit payment