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