Apple Pay - authorize.net renvoie l'erreur 153 uniquement en direct, sandbox fonctionne

14

Après avoir cherché beaucoup d'articles, je n'ai pas trouvé de solution à mon problème.

J'ai intégré le bouton ApplePay sur mon site et effectué avec succès des transactions en mode sandbox . J'utilise le SDK php authorize.net pour générer la demande. Les problèmes ont commencé quand je suis passé vivre. Le message de authorize.net est " Une erreur s'est produite lors du traitement des données de paiement. Les champs obligatoires sont manquants dans les données déchiffrées "

Voici ce que j'ai fait:

  1. Changement du certificat de traitement des paiements avec celui du compte live authorize.net
  2. Modification des informations d'identification que j'utilise pour traiter les paiements authorize.net sur le même compte réel que j'ai obtenu le certificat de processus de paiement
  3. Utilisez un appareil Apple en direct avec une vraie carte de crédit.
  4. J'utilise le processeur First data Nashville comme processeur CC qui prend en charge ApplePay

Notez que si je repasse en mode sandbox, la transaction passe sans problème.

La demande et la réponse échouée suivent:

Demande:

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

Réponse:

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

Qu'est-ce que je rate?

ÉDITER:

Voici le code concernant l'envoi d'opaqueData d'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:

J'ai ajouté un e-mail, un téléphone et une adresse IP dans la demande avec le même résultat. La demande modifiée suit:

{ 
"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
la source
1
Vous avez essayé de régénérer des certificats?
Mully
1
Oui, j'ai régénéré les certificats de traitement des paiements des dizaines de fois, même recréé l'identité du commerçant dans le compte Apple.
bksi
1
transactionRequest -> client -> l'e-mail est vide, il peut être nécessaire de le définir, est-il possible de le définir à la demande?
Jannes Botis
1
Pouvez-vous publier le code lié à la définition du champ "opaqueData"? Où il devrait être le jeton encodé en base64 reçu du portefeuille ApplePay.
DinushaNT
2
@Roadowl quelle est la question. J'ai édité le post. Notez que le même code fonctionne en mode sandbox. La demande est également générée et peut être vue. Il ne fait pas grand-chose avec la façon dont il est généré, je pense.
bksi

Réponses:

3

Cela est probablement dû à un problème de données dans le champ OpaqueData qui provient du côté ApplePay. Donc, ma suggestion est d'imprimer ce jeton dans le fichier journal, puis de le déchiffrer en utilisant l'une des bibliothèques suivantes pour vérifier manuellement si toutes les données y sont présentes. Vous pouvez faire de même pour l'environnement Sandbox et l'environnement Live. Vous verrez donc toute différence dans les données de jeton.

https://github.com/PayU-EMEA/apple-pay

https://github.com/etsy/applepay-php


C'est ainsi qu'il utilise la bibliothèque etsy applepay-php .

Vous aurez besoin d'un `` Certificat de traitement des paiements '' et d'une clé privée d'Apple (ci-dessous appelés merch.cer et priv.p12). Vous pouvez les générer sur le Dev Center d'Apple. Vous aurez également besoin d'un exemple de jeton de paiement généré sur un appareil d'utilisateur final et de l'horodatage auquel il a été généré. Un jeton chiffré par RSA devrait ressembler à ceci:

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

Démo

$ # 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
la source
Oui, c'est ma prochaine étape. Je dois générer mes certificats de traitement des paiements pour pouvoir le faire.
bksi
@bksi pourriez-vous décrypter les jetons?
DinushaNT
Malheureusement toujours pas. J'essaie d'utiliser github.com/PayU-EMEA/apple-pay
bksi
-1

Comme mentionné ici

Quelques points à considérer:

  • L'ID marchand Apple que vous saisissez sur notre site doit être identique à celui que vous avez créé sur le site Apple. S'il est différent, nous ne pourrons pas décrypter les données de paiement.
  • Doit être une transaction de commerce électronique. Confirmez que votre compte de passerelle est configuré en tant que compte sans carte.
  • Les données soumises doivent être codées en base64. Pour autant que je sache, vous faites cela correctement, mais vérifiez bien. Je ne sais pas si le BLOB
    que vous récupérez est déjà encodé en base64, mais peut-être revérifiez pour vous assurer que vous ne le doublez pas.
  • Le champ opaqueData ne doit PAS être juste token.paymentData.data. Il doit plutôt s'agir d'une Base64-encodedchaîne JSON représentant l'ensemble token.paymentData object.

Une erreur s'est produite lors du traitement des données de paiement.

  • Les deux paramètres opaques doivent être spécifiés.
  • Vous ne pouvez pas inclure le numéro de carte ou la date d'expiration.
  • Vous ne pouvez pas inclure de données de suivi.
  • Doit être une transaction de commerce électronique. Confirmez que votre compte de passerelle est configuré en tant que compte Card Not Present.
  • La transaction doit être une autorisation ou un type d'autorisation et de capture de transaction.
  • Vous ne pouvez pas inclure de données 3DS.
  • Vous devez soumettre des données pouvant être déchiffrées avec succès.
  • Les données déchiffrées doivent appartenir au commerçant soumettant la demande.
  • Les données soumises doivent être codées en base64.
Vignesh Kumar A
la source
Merci pour les suggestions. Tous sont appliqués. Je ne suis pas sûr que vous ayez noté que toutes les transactions passent en mode sandbox. J'ai créé un nouvel identifiant de commerçant et l'ai utilisé pour les transactions avec le même résultat. Ensuite, j'ai réessayé le même identifiant sur le bac à sable et les transactions sont en cours.
bksi
@bksi J'ai mis à jour la réponse. Veuillez vous assurer que vous avez rempli toutes les listes de contrôle et que vous êtes toujours confronté au problème, puis essayez de refaire tout le processus de création d'un nouvel identifiant de bundle, de l'ID du commerçant, de l'enregistrer dans le bundle id & sur le portail d'autorisation, de générer un nouveau CSR à partir du portail d'autorisation et création d'un nouveau certificat de traitement des paiements sur le développeur Apple et utilisation du type de paiement 3DS
Vignesh Kumar A