Apple Pay - authorize.net возвращает ошибку 153 только при работе, песочница работает

14

После поиска многих статей я не смог найти решение своей проблемы.

Я встроил кнопку ApplePay на свой сайт и успешно провел транзакции в режиме песочницы . Я использую authorize.net php SDK для генерации запроса. Проблемы начались, когда я перешел к жизни. Сообщение от authorize.net: « Произошла ошибка при обработке данных платежа. В расшифрованных данных отсутствуют обязательные поля »

Вот что я сделал:

  1. Изменен сертификат обработки платежа с одним из живого аккаунта authorize.net
  2. Изменены учетные данные, которые я использую для обработки платежей authorize.net на тот же реальный счет, на который я получил сертификат процесса оплаты.
  3. Используйте живое устройство Apple с реальной кредитной картой.
  4. Я использую процессор First Data 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"
                }
            ]
        }
    }
}

}

bksi
источник
1
Пытались восстановить сертификаты?
Муллы
1
Да, я восстановил сертификаты обработки платежей десятки раз, даже воссоздал личность продавца в учетной записи Apple.
bksi
1
actionRequest -> customer -> электронная почта пуста, ее может потребоваться установить, возможно ли установить ее по запросу?
Яннес Ботис
1
Можете ли вы опубликовать код, связанный с настройкой поля "opaqueData"? Где это должен быть токен в кодировке base64, полученный от кошелька ApplePay.
DinushaNT
2
@Roadowl в чем дело. Я редактировал пост. Обратите внимание, что тот же код работает в режиме песочницы. Также запрос генерируется, и его можно увидеть. Я думаю, это не сильно зависит от того, как оно генерируется.
bksi

Ответы:

3

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

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

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


Вот как это делается с помощью библиотеки etsy applepay-php .

Вам понадобится «Сертификат обработки платежа» и закрытый ключ от Apple (именуемые ниже merch.cer и priv.p12). Вы можете создать их в Центре разработки Apple. Вам также понадобится пример токена оплаты, сгенерированного на устройстве конечного пользователя, и отметка времени, в которую он был сгенерирован. 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>
DinushaNT
источник
Да, это мой следующий шаг. Я должен создать свои сертификаты обработки платежей, чтобы иметь возможность сделать это.
bksi
@bksi не могли бы вы расшифровать токены?
DinushaNT
К сожалению до сих пор нет. Я пытаюсь использовать github.com/PayU-EMEA/apple-pay
bksi
-1

Как уже упоминалось здесь

Несколько вещей, на которые нужно посмотреть:

  • Идентификатор продавца Apple, который вы вводите на нашем сайте, должен совпадать с идентификатором, который вы создали на сайте Apple. В противном случае мы не сможем расшифровать данные платежа.
  • Должно быть транзакция электронной коммерции. Убедитесь, что ваша учетная запись шлюза настроена как учетная запись, отсутствующая на карте.
  • Представленные данные должны быть в кодировке base64. Насколько я могу сказать, вы делаете это правильно, но перепроверьте. Я не знаю, является
    ли возвращаемый BLOB уже закодированным в base64, но, возможно, перепроверьте, чтобы убедиться, что вы его не кодируете дважды.
  • Поле opaqueData НЕ должно быть просто token.paymentData.data. Скорее, это должна быть Base64-encodedстрока JSON, представляющая целое token.paymentData object.

При обработке данных платежа произошла ошибка.

  • Оба непрозрачных параметра должны быть указаны.
  • Вы не можете указать номер карты или срок действия.
  • Вы не можете включить данные трека.
  • Должна быть транзакция электронной коммерции. Убедитесь, что ваша учетная запись шлюза настроена как учетная запись отсутствия карты.
  • Транзакция должна быть авторизацией или авторизацией и фиксировать тип транзакции.
  • Вы не можете включить данные 3DS.
  • Вы должны предоставить данные, которые могут быть успешно расшифрованы.
  • Расшифрованные данные должны принадлежать продавцу, отправляющему запрос.
  • Представленные данные должны быть в кодировке base64.
Виньеш Кумар А
источник
Спасибо за предложения. Все они применяются. Я не уверен, что вы заметили, что все транзакции проходят в режиме песочницы. Я сделал новый идентификатор продавца и использовал его для транзакций с тем же результатом. Затем я попробовал тот же идентификатор обратно в песочнице, и транзакции проходят.
bksi
@bksi Я обновил ответ. Пожалуйста, убедитесь, что вы заполнили все контрольные списки, и все же вы столкнулись с проблемой, затем попробуйте повторить весь процесс от создания нового идентификатора пакета, идентификатора продавца, регистрации его для идентификатора пакета и на портале авторизации, создания нового CSR из портала авторизации и создание нового сертификата обработки платежей на Apple
Vignesh Kumar A