Web上Apple Pay的Payfort返回签名不匹配

时间:2020-09-14 04:19:55

标签: laravel applepay payfort

我正在使用payfort在我们的网站上集成Apple Pay。

Payfort要求计算签名,如果输入值是字符串,则可以正常工作。但是问题是如果值是数组怎么办。

如该文档的下图所示。他们需要 apple_header apple_paymentMethod 字段为列表数据类型。现在,在这种情况下,我应该如何计算签名,因为它将键和值作为字符串。但在我们的例子中,值是数组。 (即 apple_paymentMethod apple_paymentMethod

我使用json_encode函数尝试了这两个字段。

如果我将这两个字段作为字符串发送,则payfort api返回无效的格式:apple_header 。 如果我将这两个字段作为数组发送,则payfort api返回签名不匹配

我不知道我想念什么。

这是我的代码:

控制器代码:

$parameters = [
            'digital_wallet'        => 'APPLE_PAY',
            'command'               => 'PURCHASE',
            'access_code'           => config('payfort.APPLE_ACCESS_CODE'),
            'merchant_identifier'   => config('payfort.APPLE_MERCHANT_IDENTIFIER'),
            'merchant_reference'    => date( 'Y' ).str_pad($request->iOrderId, 6, 0, STR_PAD_LEFT) . '_' . time(),
            'amount'                => 7000,
            'currency'              => 'SAR',
            'language'              => 'en',
            'customer_email'        => 'test@gmail.com',
            'apple_data'            => $request->token['paymentData']['data'],
            'apple_signature'       => $request->token['paymentData']['signature'],
            
            'apple_header'          => json_encode([
                'apple_transactionId'=> $request->token['paymentData']['header']['transactionId'],
                'apple_ephemeralPublicKey'=> $request->token['paymentData']['header']['ephemeralPublicKey'],
                'apple_publicKeyHash'=> $request->token['paymentData']['header']['publicKeyHash']
            ]),

            'apple_paymentMethod'   => json_encode([
                'apple_displayName'=> $request->token['paymentMethod']['displayName'],
                'apple_network'=> $request->token['paymentMethod']['network'],
                'apple_type'=> $request->token['paymentMethod']['type']
            ]),
         
            'customer_ip'           => $request->ip(),
            'customer_name'         => 'ABC',
            'merchant_extra'        => $request->iOrderId,
            'merchant_extra1'       => $request->order_number,
            'merchant_extra2'       => $request->locale_info,
        ];

        // canculate signature
        $parameters['signature'] = $this->payfortCoreHelpers->calculateSignature($parameters, 'request', true);

        // Add Array or List fields in back to parameters before send
        $parameters['apple_header'] = [
            'apple_transactionId'=> $request->token['paymentData']['header']['transactionId'],
            'apple_ephemeralPublicKey'=> $request->token['paymentData']['header']['ephemeralPublicKey'],
            'apple_publicKeyHash'=> $request->token['paymentData']['header']['publicKeyHash']
        ];
        $parameters['apple_paymentMethod'] = [
            'apple_displayName'=> $request->token['paymentMethod']['displayName'],
            'apple_network'=> $request->token['paymentMethod']['network'],
            'apple_type'=> $request->token['paymentMethod']['type']
        ];
        

calculateSignature函数

public function calculateSignature($arrData, $signType = 'request', $isAppleRequest = false)
{
    $shaString = '';
    ksort($arrData);

    foreach ($arrData as $k => $v) {
        $shaString .= "$k=$v";
    }

    $shaString = config('payfort.SHA_REQUEST_PHRASE') . $shaString . config('payfort.SHA_REQUEST_PHRASE');

    $signature = hash(config('payfort.SHA_TYPE'), $shaString);

    return $signature;
}

enter image description here

Payfort Response

{
  "amount": "7000",
  "response_code": "00008",
  "digital_wallet": "APPLE_PAY",
  "signature": "****",
  "merchant_identifier": "****",
  "access_code": "****",
  "customer_ip": "::1",
  "language": "en",
  "command": "PURCHASE",
  "merchant_extra": "****",
  "response_message": "Signature mismatch",
  "merchant_reference": "20201599817035025",
  "customer_email": "test@gmail.com",
  "merchant_extra1": "1599817035025",
  "merchant_extra2": "SAR",
  "currency": "SAR",
  "customer_name": "ABC",
  "status": "00"
}

2 个答案:

答案 0 :(得分:0)

您可能会发现此链接有帮助:https://github.com/devinweb/payment/blob/fa595fe60df4dff3c4f2189e37fd64fffdc8421b/src/Traits/Payfort/ApplePay.php#L51

这显示了为您的请求生成签名的calculateSignature方法。

尤其是第67行显示,您需要在逗号和后跟嵌套数组中各项之间加空格。

答案 1 :(得分:0)

ksort($arrData);
        foreach ($arrData as $key => $value) {
            if(is_array($value)){
                $shaSubString = '{';
                foreach ($value as $k => $v) {
                    $shaSubString .= "$k=$v, ";
                }
                $shaSubString = substr($shaSubString, 0, -2).'}';
                $shaString .= "$key=$shaSubString";
            }else{
                $shaString .= "$key=$value";
            }
        }