Payfort возвращает несоответствие подписи для Apple Pay в Интернете

#laravel #applepay #payfort

#laravel #applepay #payfort

Вопрос:

Я интегрирую Apple Pay на наш веб-сайт с помощью payfort.

Payfort запрашивает вычисление подписи, которая отлично работает, если входные значения являются строковыми. Но проблема в том, что, если значение равно массиву.

Как показано на следующем изображении из документации. Они требуют, чтобы поля apple_header и apple_paymentMethod имели тип данных списка. Теперь, как я должен вычислить подпись в этом случае, поскольку она принимает ключ и значение в виде строки. но в нашем случае значением является массив. (т.Е. apple_paymentMethod И apple_paymentMethod)

Я попробовал эти 2 поля, используя функцию json_encode.

Если я отправлю эти 2 поля в виде строки, то API payfort вернет недопустимый формат для поля: apple_header. Если я отправлю эти 2 поля в виде массива, то 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']
        ];
        
  

Функция вычисления подписи

 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;
}
  

введите описание изображения здесь

Ответ Payfort

 {
  "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"
}
  

Комментарии:

1. Работая над тем же, что и @Haris, вы нашли какое-либо решение? У меня такая же проблема.

Ответ №1:

Возможно, вам пригодится эта ссылка: https://github.com/devinweb/payment/blob/fa595fe60df4dff3c4f2189e37fd64fffdc8421b/src/Traits/Payfort/ApplePay.php#L51

Здесь показан метод calculateSignature, который генерирует подпись для вашего запроса.

В частности, строка 67 показывает, что между элементами во вложенном массиве должна быть запятая, за которой следует пробел.

Ответ №2:

 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";
            }
        }