1

由于我似乎无法解决的问题,我目前正在撞到一堵巨大的墙。

问题是,当您通过 Facebook 支付平台 (facebook javascript sdk) 发出付款时,它会将数据发送到您的回调页面,该页面应该在后台处理付款。

这一切都很好,但有一个问题:facebook 使用的订单 ID 是 64 位 ID,而我的服务器是 32 位服务器,因此当它保存到回调页面中的变量时,它会失去 ID 的精度。这最终导致最终无法获得正确的 order_ID,因为它无法保存 ID。

该问题已在此论坛的多个页面上进行了描述,例如:

facebook 信用回调,order_id 移动到新服务器后更改格式更改

PHP:将 64 位整数转换为字符串

然而,在这两个页面上都没有解决问题的方法,而且我自己似乎无法解决这个问题。我试图将 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)
4

1 回答 1

1

您正在运行哪个版本的 PHP?

如果您正在运行支持 JSON“JSON_BIGINT_AS_STRING”选项的 PHP 版本,那可能就是您的答案。您可能必须在使用 json_decode 添加该选项的地方修改他们的库。见http://php.net/manual/en/function.json-decode.php

如果您的 PHP 版本不支持 JSON_BIGINT_AS_STRING,那么您的选项仅限于:

hacky 选项:对从 FB API 返回的 JSON 字符串执行某种正则表达式操作,并将大整数用双引号括起来,以便它们解码为字符串而不是大整数。

理想的选择:硬着头皮迁移到 64 位环境。从长远来看,它将使您免于很多麻烦。

于 2013-01-17T19:12:07.133 回答