Apple Pay - authorize.net retorna o erro 153 somente quando estiver ativo, o sandbox funciona

14

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:

  1. O certificado de processamento de pagamento foi alterado com um da conta do authorize.net em tempo real
  2. Alteradas as credenciais que estou usando para processar os pagamentos do authorize.net na mesma conta ativa, obtive o certificado do processo de pagamento
  3. Use o dispositivo da apple ao vivo com cartão de crédito real.
  4. 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"
                }
            ]
        }
    }
}

}

bksi
fonte
11
Tentou regenerar certificados?
Mully
11
Sim, regenerei os certificados de processamento de pagamento uma dúzia de vezes, até recriei a identidade do comerciante na conta da apple.
achou
11
transactionRequest -> customer -> email está vazio, pode ser necessário configurá-lo. É possível configurá-lo mediante solicitação?
Janes Botis
11
Você pode postar o código relacionado à configuração do campo "opaqueData"? Onde deveria estar o token codificado em base64 recebido da carteira ApplePay.
DinushaNT 12/12
2
@Roadowl qual é o problema. Eu editei a postagem. Observe que o mesmo código funciona no modo sandbox. Além disso, a solicitação é gerada e pode ser vista. Não tem muito a ver com a forma como é gerado, eu acho.
BKSI

Respostas:

3

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 .

Você precisará de um 'Certificado de processamento de pagamento' e uma chave privada da Apple (mencionadas como merch.cer e priv.p12 abaixo). Você pode gerá-los no Centro de Desenvolvimento da Apple. Você também precisará de um exemplo de token de pagamento gerado em um dispositivo de usuário final e o carimbo de data e hora em que foi gerado. Um token criptografado por RSA deve ter a seguinte aparência:

{
 "data": "<base64>",
 "header": {
     "applicationData": "<hex_optional>"
     "wrappedKey": "<base64>",
     "publicKeyHash": "<base64>",
     "transactionId": "<hex>"
 },
 "signature": "<base64>",
 "version": "RSA_v1"
}

Demo

$ # Copy in your payment processing cert and test token
$ cd examples
$ cp /secret/place/merch.cer .
$ cp /secret/place/token.json .
$
$ # Extract private key from cert
$ openssl pkcs12 -export -nocerts -inkey merch.key -out priv.p12 -password 'pass:'
$
$ # Get intermediate and root certs from Apple
$ wget -O int.cer 'https://www.apple.com/certificateauthority/AppleAAICAG3.cer'
$ wget -O root.cer 'https://www.apple.com/certificateauthority/AppleRootCA-G3.cer'
$
$ # Verify chain of trust
$ openssl x509 -inform DER -in merch.cer -pubkey > pub.pem
$ openssl x509 -inform DER -in root.cer > root.pem
$ openssl x509 -inform DER -in int.cer > int_merch.pem
$ openssl x509 -inform DER -in merch.cer >> int_merch.pem
$ openssl verify -verbose -CAfile root.pem int_merch.pem # should output OK
$
$ # Run demo
$ cd ..
$ php -denable_dl=on -dextension=`pwd`/modules/applepay.so examples/decrypt.php -p <privkey_pass> -c examples/token.json -t <time_of_transaction>
DinushaNT
fonte
Sim, esse é o meu próximo passo. Tenho que gerar meus certificados de processamento de pagamentos para poder fazer isso.
BKSI
@bksi você pode descriptografar os tokens?
DinushaNT
Infelizmente ainda não. Estou tentando usar o github.com/PayU-EMEA/apple-pay
bksi
-1

Como mencionado aqui

Algumas coisas a serem observadas:

  • O ID do comerciante da Apple inserido no site deve ser idêntico ao que você criou no site da Apple. Se for diferente, não poderemos descriptografar os dados de pagamento.
  • Deve ser uma transação de comércio eletrônico. Confirme se sua conta de gateway está configurada como uma conta que não está presente no cartão.
  • Os dados enviados devem ser codificados em base64. Até onde eu sei, você está fazendo o certo, mas verifique. Não sei se o BLOB
    você está retornando já está codificado em base64, mas talvez verifique duas vezes para garantir que não o esteja codificando duas vezes.
  • O campo opaqueData NÃO deve ser justo token.paymentData.data. Pelo contrário, deve ser umBase64-encoded string JSON representando o todo token.paymentData object.

Ocorreu um erro ao processar os dados de pagamento.

  • Ambos os parâmetros opacos devem ser especificados.
  • Você não pode incluir o número do cartão ou a data de validade.
  • Você não pode incluir dados da faixa.
  • Deve ser uma transação de comércio eletrônico. Confirme se a sua conta do gateway está configurada como uma conta Cartão ausente.
  • A transação deve ser uma autorização ou autorizar e capturar o tipo de transação.
  • Você não pode incluir dados 3DS.
  • Você deve enviar dados que possam ser descriptografados com sucesso.
  • Os dados descriptografados devem pertencer ao comerciante que envia a solicitação.
  • Os dados enviados devem ser codificados em base64.
Vignesh Kumar A
fonte
Obrigado pelas sugestões. Todos eles são aplicados. Não sei se você observou que todas as transações são passadas no modo sandbox. Criei um ID de comerciante totalmente novo e o usei para as transações com o mesmo resultado. Então eu tentei o mesmo id de volta na sandbox e as transações estão passando.
BKSI
@bksi Eu atualizei a resposta. Verifique se você concluiu todas as listas de verificação e ainda enfrenta o problema. Tente refazer todo o processo, criando um novo identificador de pacote, identificação de comerciante, registrando-o para identificação de pacote e no portal de autorização, gerando um novo CSR do portal de autorização e criação de novo certificado de processamento de pagamentos on desenvolvedor maçã & usando 3DS tipo de pagamento
Vignesh Kumar a