Depois de pesquisar muitos artigos, não consegui encontrar uma solução para o meu problema.
Integrei o botão ApplePay no meu site e fiz transações com êxito no modo sandbox . Estou usando o SDK do authorize.net php para gerar a solicitação. Os problemas começaram quando mudei para a vida. A mensagem do authorize.net é " Ocorreu um erro ao processar os dados do pagamento. Os campos obrigatórios estão ausentes nos dados descriptografados "
Aqui o que eu fiz:
- O certificado de processamento de pagamento foi alterado com um da conta do authorize.net em tempo real
- Alteradas as credenciais que estou usando para processar os pagamentos do authorize.net na mesma conta ativa, obtive o certificado do processo de pagamento
- Use o dispositivo da apple ao vivo com cartão de crédito real.
- Estou usando o processador First Data Nashville como processador CC compatível com ApplePay
Observe que, se eu voltar ao modo sandbox, a transação será transmitida sem problemas.
A solicitação e a resposta com falha são as seguintes:
Solicitação:
{
"createTransactionRequest":{
"merchantAuthentication":{
"name":"xxxxxxxxx",
"transactionKey":"xxxxxxxxxxx"
},
"clientId":"sdk-php-2.0.0",
"refId":"ref1575669789",
"transactionRequest":{
"transactionType":"authOnlyTransaction",
"amount":"14.08",
"payment":{
"opaqueData":{
"dataDescriptor":"COMMON.APPLE.INAPP.PAYMENT",
"dataValue":"eyJ2ZXJzaW9u...Q1OSJ9fQ=="
}
},
"order":{
"invoiceNumber":"63059-191206",
"description":"xxxxxxxxx, xxxxxxxxxxxx v9.0.12 (Order# 63059-191206)"
},
"customer":{
"type":"individual",
"email":""
},
"billTo":{
"firstName":"xxxxxxx",
"lastName":"xxxxxxx",
"address":"xxxx San Remo Cir ",
"city":"Vista",
"state":"CA",
"zip":"92084",
"country":"US"
},
"retail":{
"marketType":0,
"deviceType":8
},
"transactionSettings":{
"setting":[
{
"settingName":"duplicateWindow",
"settingValue":"60"
}
]
}
}
}
}
Resposta:
{
"transactionResponse":{
"responseCode":"3",
"authCode":"",
"avsResultCode":"P",
"cvvResultCode":"",
"cavvResultCode":"",
"transId":"0",
"refTransID":"",
"transHash":"",
"testRequest":"0",
"accountNumber":"",
"accountType":"",
"errors":[
{
"errorCode":"153",
"errorText":"There was an error processing the payment data. Required fields are missing from decrypted data."
}
],
"transHashSha2":"",
"SupplementalDataQualificationIndicator":0
},
"refId":"ref1575669789",
"messages":{
"resultCode":"Error",
"message":[
{
"code":"E00027",
"text":"The transaction was unsuccessful."
}
]
}
}
O que estou perdendo?
EDITAR:
Aqui está o código referente ao envio de opaqueData do ApplePay
$transactionMode = $cc_authorize_mode == $this->MODE_TEST ? \net\authorize\api\constants\ANetEnvironment::SANDBOX : \net\authorize\api\constants\ANetEnvironment::PRODUCTION;
$merchantAuthentication = new AnetAPI\MerchantAuthenticationType();
$merchantAuthentication->setName($cc_authorize_loginid);
$merchantAuthentication->setTransactionKey($cc_authorize_txnkey);
// Set the transaction's refId
$refId = 'ref' . time();
$phoneNumber = ! empty($co_b_phone) ? $co_b_phone : $co_phone;
$customerEmail = ! empty($co_b_email) ? $co_b_email : $co_email;
$ip = lloader()->getUtilByName('ip')->getClientIp();
// Create order information
$order = new AnetAPI\OrderType();
$order->setInvoiceNumber($order_number);
$order->setDescription($this->getOrderPostedByMessage($id_order, $order_number));
// Set the customer's Bill To address
$customerAddress = new AnetAPI\CustomerAddressType();
$customerAddress->setFirstName($co_ccholder_firstname);
$customerAddress->setLastName($co_ccholder_lastname);
if (! empty($co_b_company)) { $customerAddress->setCompany($co_b_company); }
$customerAddress->setAddress($co_b_address." ".$co_b_address2);
$customerAddress->setCity($co_b_city);
$bState = f_isUSState($co_b_state) ? $STATES_XX[$co_b_state] : $STATES[$co_b_state];
$customerAddress->setState($bState);
$customerAddress->setZip($co_b_zip);
$customerAddress->setCountry($countriesISO2[$co_country]);
$customerAddress->setPhoneNumber($phoneNumber);
$customerAddress->setEmail($customerEmail);
// Set the customer's identifying information
$customerData = new AnetAPI\CustomerDataType();
$customerData->setType("individual");
if ( ! empty($member_row['id'])) { $customerData->setId($member_row['id']); }
$customerData->setEmail($customerEmail);
// Add values for transaction settings
$duplicateWindowSetting = new AnetAPI\SettingType();
$duplicateWindowSetting->setSettingName("duplicateWindow");
$duplicateWindowSetting->setSettingValue("60");
// Create a TransactionRequestType object and add the previous objects to it
$transactionRequestType = new AnetAPI\TransactionRequestType();
$transactionRequestType->setCustomerIP($ip);
$transactionRequestType->setTransactionType($this->api_trtype_map[$transactionType]);
if (empty($this->applePayPaymentData)) {
// Normal CC request
// Create the payment data for a credit card
...
} else {
$retail = new AnetAPI\TransRetailInfoType();
$retail->setMarketType('0');
$retail->setDeviceType('8');
$transactionRequestType->setRetail($retail);
// Apple Pay Token Request
$op = new AnetAPI\OpaqueDataType();
$op->setDataDescriptor("COMMON.APPLE.INAPP.PAYMENT");
$paymentToken = base64_encode($this->applePayPaymentData);
$op->setDataValue($paymentToken);
$payment = new AnetAPI\PaymentType();
$payment->setOpaqueData($op);
}
$transactionRequestType->setAmount($grandTotal);
$transactionRequestType->setOrder($order);
$transactionRequestType->setPayment($payment);
$transactionRequestType->setBillTo($customerAddress);
$transactionRequestType->setCustomer($customerData);
$transactionRequestType->addToTransactionSettings($duplicateWindowSetting);
// Assemble the complete transaction request
$request = new AnetAPI\CreateTransactionRequest();
$request->setMerchantAuthentication($merchantAuthentication);
$request->setRefId($refId);
$request->setTransactionRequest($transactionRequestType);
// Create the controller and get the response
$controller = new AnetController\CreateTransactionController($request);
$response = $controller->executeWithApiResponse($transactionMode);
if ($response != null) {
if ($response->getMessages()->getResultCode() == "Ok") {
...
if ($tresponse != null && $tresponse->getMessages() != null) {
...
return true;
} else {
if ($tresponse->getErrors() != null) {
...
}
}
...
}
...
}
EDIT2:
Adicionei email, telefone e endereço IP na solicitação com o mesmo resultado. A solicitação modificada é a seguinte:
{
"createTransactionRequest":{
"merchantAuthentication":{
"name":"**********",
"transactionKey":"***************"
},
"clientId":"sdk-php-2.0.0",
"refId":"ref1576180306",
"transactionRequest":{
"transactionType":"authOnlyTransaction",
"amount":"14.08",
"payment":{
"opaqueData":{
"dataDescriptor":"COMMON.APPLE.INAPP.PAYMENT",
"dataValue":"eyJ2ZXJzaW9uIj...DFiZiJ9fQ=="
}
},
"order":{
"invoiceNumber":"63117-191212",
"description":"******************* v9.0.12 (Order# 63117-191212)"
},
"customer":{
"type":"individual",
"email":"*********@gmail.com"
},
"billTo":{
"firstName":"Gabe",
"lastName":"Garcia",
"address":"********* Cir ",
"city":"Vista",
"state":"CA",
"zip":"92084",
"country":"US",
"phoneNumber":"**************",
"email":"**********@gmail.com"
},
"customerIP":"************",
"retail":{
"marketType":"0",
"deviceType":"8"
},
"transactionSettings":{
"setting":[
{
"settingName":"duplicateWindow",
"settingValue":"60"
}
]
}
}
}
}
Respostas:
Provavelmente, isso ocorre devido a um problema de dados no campo OpaqueData, proveniente do lado ApplePay. Portanto, minha sugestão é imprimir esse token no arquivo de log e descriptografar o mesmo usando uma das seguintes bibliotecas para verificar manualmente se todos os dados estão lá. Você pode fazer o mesmo nos ambientes Sandbox e Live. Então você verá qualquer diferença nos dados do token.
https://github.com/PayU-EMEA/apple-pay
https://github.com/etsy/applepay-php
É assim que funciona usando a biblioteca etsy applepay-php .
Demo
fonte
Como mencionado aqui
token.paymentData.data
. Pelo contrário, deve ser umBase64-encoded
string JSON representando o todotoken.paymentData object
.Ocorreu um erro ao processar os dados de pagamento.
fonte