Apple Pay - autorize.net повертає помилку 153 лише тоді, коли працює жива пісочниця


14

Після пошуку багатьох статей я не зміг знайти рішення для своєї проблеми.

Я інтегрував кнопку ApplePay на своєму сайті і успішно здійснював транзакції в режимі пісочниці . Я використовую autorize.net php SDK для створення запиту. Проблеми почалися, коли я перейшов жити. Повідомлення від autorize.net: " Під час обробки даних про оплату сталася помилка. У розшифрованих даних відсутні обов'язкові поля "

Ось що я зробив:

  1. Змінено сертифікат на обробку платежів на один з облікового запису live autize.net
  2. Змінено облікові дані, якими я користуюсь для обробки авторизованих платежів.net на той самий живий рахунок, я отримав сертифікат процесу платежу
  3. Використовуйте живий яблучний пристрій з реальною кредитною карткою.
  4. Я використовую перший процесор Nashville як процесор CC, який підтримує ApplePay

Зауважте, що якщо я повернусь до пісочного режиму, транзакція проходить без проблем.

Наступний запит і невдала відповідь:

Запит:

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

Відповідь:

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

Що я пропускаю?

Редагувати:

Ось код щодо надсилання opaqueData з 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:

Я додав електронну пошту, телефон та ip адресу у запиті з тим же результатом. Змінений запит наступний:

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

}


1
Намагалися відновити сертифікати?
Маллі

1
Так, я десятки разів регенерував сертифікати на обробку платежів, навіть відтворював посвідчення продавця в яблучному рахунку.
bksi

1
actionRequest -> клієнт -> електронний лист порожній, його може знадобитися встановити, чи можливо його встановити за запитом?
Jannes

1
Чи можете ви опублікувати код, пов’язаний із встановленням поля "opaqueData"? Де має бути закодований маркер base64, отриманий з гаманця ApplePay.
DinushaNT

2
@Roadowl в чому справа. Я редагував публікацію. Зауважте, що той самий код працює в режимі пісочниці. Також запит генерується і його можна побачити. Це не так сильно з тим, як це генерується, я думаю.
bksi

Відповіді:


3

Це, швидше за все, пов’язано з проблемою даних у полі OpaqueData, яка надходить з боку ApplePay. Тож моя пропозиція - надрукувати цей маркер у логфайлі, а потім розшифрувати той самий за допомогою однієї з наведених нижче бібліотек, щоб вручну перевірити, чи всі там дані. Ви можете зробити те ж саме для середовища Sandbox та Live Live. Так ви побачите будь-яку різницю в даних жетонів.

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

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


Ось як це відбувається за допомогою бібліотеки etsy applepay-php .

Вам знадобиться "Сертифікат на обробку платежів" та приватний ключ від Apple (згадані нижче merch.cer та priv.p12). Ви можете генерувати їх у Apple Dev Center. Вам також знадобиться приклад маркера платежу, згенерованого на пристрої кінцевого користувача, і часової позначки, в яку він був створений. Зашифрований RSA маркер повинен виглядати так:

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

Демо

$ # 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>

Так, це мій наступний крок. Я маю згенерувати свої сертифікати на обробку платежів, щоб це зробити.
bksi

@bksi Ви могли б розшифрувати жетони?
DinushaNT

На жаль, досі немає. Я намагаюся використовувати github.com/PayU-EMEA/apple-pay
bksi

-1

Як згадувалося тут

Декілька речей, які варто подивитися:

  • Ідентифікатор продавця Apple, який ви вводите на наш сайт, повинен бути ідентичним тому, який ви створили на сайті Apple. Якщо це інакше, ми не зможемо розшифрувати дані платежів.
  • Повинно бути транзакцією електронної комерції. Переконайтеся, що ваш обліковий запис шлюзу налаштовано як обліковий запис без картки.
  • Надіслані дані повинні бути закодовані base64. Наскільки я можу сказати, ви робите це правильно, але двічі перевіряйте. Я не знаю, чи BLOB,
    який ви повертаєте, вже закодований base64, але, можливо, двічі перевірте, щоб переконатися, що ви не подвійно кодуєте його.
  • Поле непрозорого Дані НЕ повинно бути просто token.paymentData.data. Швидше, це повинен бути Base64-encodedрядок JSON, що представляє всю token.paymentData object.

Під час обробки даних про оплату сталася помилка.

  • Обов'язні параметри повинні бути вказані.
  • Ви не можете вказати номер картки або термін придатності.
  • Ви не можете включати дані доріжок.
  • Повинно бути транзакцією електронної комерції. Переконайтесь, що ваш обліковий запис шлюзу налаштовано як картка Немає рахунку
  • Угода повинна бути авторизацією або авторизацією та захопленням типу транзакції.
  • Ви не можете включати дані 3DS.
  • Ви повинні подати дані, які можна успішно розшифрувати.
  • Розшифровані дані повинні належати продавцю, який подав запит.
  • Надіслані дані повинні бути закодовані base64.

Дякуємо за пропозиції. Усі вони застосовуються. Я не впевнений, що ви зазначили, що всі транзакції проходять у режимі пісочниці. Я зробив абсолютно новий ідентифікатор продавця і використав його для транзакцій з тим же результатом. Тоді я спробував той же id назад на пісочниці і транзакції проходять.
bksi

@bksi У мене оновлена ​​відповідь. Будь ласка, переконайтеся, що ви заповнили всі контрольні списки, і все-таки ви стикаєтеся з проблемою, то спробуйте повторно виконати весь процес, створивши новий ідентифікатор пакета, ідентифікатор продавця, зареєструвавши його для ідентифікації пакета та на авторизованому порталі, генеруючи новий CSR на порталі авторизації та створення нового сертифікату на обробку платежів для розробника яблук та використання способу оплати 3DS
Vignesh Kumar A
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.