Apple Pay - authorize.net zwraca błąd 153 tylko wtedy, gdy na żywo działa piaskownica

14

Po przeszukaniu wielu artykułów nie mogłem znaleźć rozwiązania mojego problemu.

Zintegrowałem przycisk ApplePay na mojej stronie i pomyślnie przeprowadziłem transakcje w trybie piaskownicy . Korzystam z SDK autoryzacji php SDK do wygenerowania żądania. Problemy zaczęły się, kiedy przestawiłem się na życie. Komunikat z autoryzacji.net brzmi: „ Wystąpił błąd podczas przetwarzania danych płatności. Brakuje wymaganych pól w danych odszyfrowanych

Oto co zrobiłem:

  1. Zmieniono certyfikat przetwarzania płatności na jeden z konta Live Authorize.net
  2. Zmieniono dane uwierzytelniające, których używam do przetwarzania płatności Authorize.net na to samo konto rzeczywiste, które otrzymałem certyfikat procesu płatności
  3. Używaj żywego urządzenia Apple z prawdziwą kartą kredytową.
  4. Używam procesora First Data Nashville jako procesora CC, który obsługuje ApplePay

Pamiętaj, że jeśli przejdę ponownie do trybu piaskownicy, transakcja przebiegnie bez problemów.

Żądanie i nieudana odpowiedź są następujące:

Żądanie:

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

Odpowiedź:

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

Czego mi brakuje?

EDYTOWAĆ:

Oto kod dotyczący wysyłania nieprzejrzystych danych z 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) {
             ...
          }
       }
        ...
    }
    ...
}

EDYCJA 2:

Do żądania dodałem adres e-mail oraz numer telefonu i adres IP z takim samym rezultatem. Zmodyfikowane żądanie wygląda następująco:

{ 
"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
źródło
1
Próbowałeś zregenerować certyfikaty?
Mully,
1
Tak, kilkakrotnie zregenerowałem certyfikaty przetwarzania płatności, nawet odtworzyłem tożsamość handlowca na koncie Apple.
bksi
1
transakcja Żądanie -> klient -> adres e-mail jest pusty, może być wymagane ustawienie, czy można ustawić na żądanie?
Jannes Botis,
1
Czy możesz opublikować kod związany z ustawieniem pola „opaqueData”? Gdzie powinien być token zakodowany w standardzie base64, otrzymany z portfela ApplePay.
DinushaNT,
2
@Roadowl o co chodzi. Zredagowałem post. Pamiętaj, że ten sam kod działa w trybie piaskownicy. Również żądanie jest generowane i można je zobaczyć. Myślę, że to niewiele z tego, jak jest generowany.
bksi,

Odpowiedzi:

3

Jest to najprawdopodobniej spowodowane problemem z danymi w polu OpaqueData, który pochodzi ze strony ApplePay. Dlatego proponuję wydrukować ten token w pliku dziennika, a następnie odszyfrować go za pomocą jednej z następujących bibliotek, aby ręcznie sprawdzić, czy wszystkie dane tam są. Możesz zrobić to samo dla środowiska Sandbox i środowiska Live. Tak więc zobaczysz różnicę w danych tokena.

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

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


Tak to działa przy użyciu biblioteki etsy applepay-php .

Potrzebny będzie „Certyfikat przetwarzania płatności” oraz klucz prywatny od Apple (zwany poniżej merch.cer i priv.p12). Możesz je wygenerować w Apple Dev Center. Potrzebny będzie również przykładowy token płatności wygenerowany na urządzeniu użytkownika końcowego i sygnatura czasowa, w której został wygenerowany. Token zaszyfrowany RSA powinien wyglądać następująco:

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

Próbny

$ # 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
źródło
Tak, to mój następny krok. Aby to zrobić, muszę wygenerować certyfikaty przetwarzania płatności.
bksi
@bksi czy mógłbyś odszyfrować tokeny?
DinushaNT
Niestety nadal nie. Próbuję użyć github.com/PayU-EMEA/apple-pay
bksi
-1

Jak wspomniano tutaj

Kilka rzeczy do obejrzenia:

  • Identyfikator sprzedawcy Apple, który wpisujesz na naszej stronie, musi być identyczny z tym, który utworzyłeś na stronie Apple. Jeśli jest inaczej, nie będziemy w stanie odszyfrować danych płatności.
  • Musi to być transakcja e-commerce. Potwierdź, że twoje konto bramy jest skonfigurowane jako konto nieobecne na karcie.
  • Przesłane dane muszą być zakodowane w standardzie base64. O ile wiem, robisz to dobrze, ale sprawdź dokładnie. Nie wiem, czy BLOB,
    który odzyskujesz , jest już zakodowany w standardzie base64, ale może dokładnie sprawdź, czy go nie kodujesz.
  • pole opaqueData NIE powinno być po prostu token.paymentData.data. Raczej powinien to być Base64-encodedciąg JSON reprezentujący całość token.paymentData object.

Wystąpił błąd podczas przetwarzania danych płatności.

  • Należy podać oba nieprzezroczyste parametry.
  • Nie możesz podać numeru karty ani daty ważności.
  • Nie możesz dołączyć danych śledzenia.
  • Musi to być transakcja e-commerce. Potwierdź, że konto w bramie zostało skonfigurowane jako konto nieobecne w karcie.
  • Transakcja musi być autoryzacją lub autoryzacją i przechwycić typ transakcji.
  • Nie możesz dołączyć danych 3DS.
  • Musisz przesłać dane, które można pomyślnie odszyfrować.
  • Odszyfrowane dane muszą należeć do handlowca wysyłającego zapytanie.
  • Przesłane dane muszą być zakodowane w standardzie base64.
Vignesh Kumar A.
źródło
Dziękuję za sugestie. Wszystkie są stosowane. Nie jestem pewien, czy zauważyłeś, że wszystkie transakcje przebiegają w trybie piaskownicy. Zrobiłem całkowicie nowy identyfikator handlowca i wykorzystałem go do transakcji z tym samym wynikiem. Następnie wypróbowałem ten sam identyfikator z powrotem w piaskownicy i transakcje przebiegają.
bksi
@bksi Zaktualizowałem odpowiedź. Upewnij się, że ukończyłeś wszystkie listy kontrolne i nadal masz problem, a następnie spróbuj ponownie wykonać cały proces od utworzenia nowego identyfikatora pakietu, identyfikatora sprzedawcy, zarejestrowania go do identyfikatora pakietu i na portalu autoryzacji, wygenerowania nowego CSR z portalu autoryzacji i tworzenie nowego certyfikatu przetwarzania płatności dla programistów Apple i korzystanie z rodzaju płatności 3DS
Vignesh Kumar A