Web上Apple Pay的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,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_publicKeyHash'=> $request->token['paymentData']['header']['publicKeyHash']
        ];
        $parameters['apple_paymentMethod'] = [
            'apple_displayName'=> $request->token['paymentMethod']['displayName'],'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"
}

解决方法

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

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

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

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

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...