Authorize.net встроенный iFrame accept.js транзакция ответа

#javascript #node.js #angular #authorize.net #accept.js

#javascript #node.js #угловой #authorize.net #accept.js

Вопрос:

Я интегрировал authorize.net accept.js встроенный iFrame в моем приложении. Возникли проблемы с настройкой ответа транзакции в моей лямбда-функции для получения ответа. Я видел похожие вопросы о переполнении стека, но у меня пока ничего не получилось.

Использование Nodejs для моего бэкэнда и angular7 для интерфейса.

Я успешно получаю токен из своей лямбда-функции, поэтому мой iframe отображается в пользовательском интерфейсе. Я "showReceipt": false установил URL-адрес для cancel amp; continue, поскольку в документации говорится, что я должен установить параметр show receipt «false» для связи с IFrameCommunicator.html в пользовательском интерфейсе. Но когда я нажимаю «Оплатить», он застревает в «Обработке». долгое время.

Ниже приведены заголовки запроса и ответа соответственно на вкладке сеть:

 * Cookie: __cfruid=deb63d2f12d9690aeea838cf7f31ada6da92bc1c-1602260930
* Host: test.authorize.net
* Origin: https://test.authorize.net
* Referer: https://test.authorize.net/payment/payment
* Sec-Fetch-Dest: empty
* Sec-Fetch-Mode: cors
* 
Sec-Fetch-Site: same-origin
  
 {"resultCode":"Ok","messageCode":"Ok","transactionData":{"accountType":"Discover","accountNumber":"XXXX0012","transId":"40055282319","responseCode":"4","authorization":"TYIUU7","merchantName":"iMart Inc.","totalAmount":"1999.9","dateTime":"10/09/2020 4:20:27 PM"}}
  

Я уверен, что транзакция происходит, глядя на ответ, но не уверен, почему она не подключается к коммуникатору.

Я прочитал шаги в документации, а также следовал образцу кода GitHub -https://github.com/AuthorizeNet/accept-sample-app, что еще больше меня смутило, поскольку в некоторых местах они оба говорят разные вещи. Ниже приведены шаги, которые я выполнил до сих пор :

  1. Создал функцию оплаты, размещенную на лямбде, со всеми настройками (соблюдая правильную последовательность), чтобы вернуть токен.
  2. Создана размещенная форма оплаты для отображения iframe.
  3. Возможность произвести платеж -> получить страницу получения -> перенаправление на экран успеха.

Чего я пытаюсь достичь:

  1. После того, как я произвожу платеж, первоначальная идея заключалась в том, чтобы запустить другую лямбда-функцию на основе ответа от authorize.net без общения с IFrameCommunicator.html , но поскольку я не могу этого сделать, я хочу получить ответ, чтобы инициировать следующий процесс в серверной части.

  2. Кроме того, мы не храним никаких пользовательских данных на нашем сервере и не заинтересованы в создании профиля клиента, если это не является необходимым шагом для получения ответа транзакции. Пожалуйста, предложите интеграцию шага, если я могу сделать это в той же лямбда-функции, которую я создал для получения токена, или мне придется создать для этого другую, и когда этот шаг будет реализован?

  3. Я знаю о Webhooks, но не уверен, является ли это абсолютной необходимостью на данный момент, когда я просто пытаюсь реализовать простую транзакцию.

Я новичок, и я не смог найти много примеров, связанных с тем же, чтобы решить мои проблемы / путаницы. Был бы очень признателен, если бы я получил четкое объяснение шагов здесь и где я ошибаюсь.

Ниже приведен код —

accept-hosted.js Лямбда — функция:

     merchantAuthenticationType.setName('*****');
    merchantAuthenticationType.setTransactionKey('******');

    var transactionRequestType = new ApiContracts.TransactionRequestType();
    transactionRequestType.setTransactionType(ApiContracts.TransactionTypeEnum.AUTHCAPTURETRANSACTION);
    transactionRequestType.setAmount(Total);

    var setting1 = new ApiContracts.SettingType();
    var setting2 = new ApiContracts.SettingType();
    var setting4 = new ApiContracts.SettingType();
    var setting5 = new ApiContracts.SettingType();
    var setting6 = new ApiContracts.SettingType();
    var setting7 = new ApiContracts.SettingType();
    var setting8 = new ApiContracts.SettingType();
    var setting9 = new ApiContracts.SettingType();
    var setting10 = new ApiContracts.SettingType();
    var setting11 = new ApiContracts.SettingType();

    setting2.setSettingName("hostedPaymentButtonOptions");
    setting2.setSettingValue("{"text": "Pay"}");

    setting1.setSettingName("hostedPaymentReturnOptions");
    setting1.setSettingValue(
        "{"showReceipt": false, "url": "https://iMart.com/success.html", "urlText": "Continue", "cancelUrl": "https://iMart.com/error.html", "cancelUrlText": "Cancel"}");


    setting10.setSettingName("hostedPaymentOrderOptions");
    setting10.setSettingValue("{"show": false, "merchantName": "iMart Inc."}");

    setting5.setSettingName("hostedPaymentPaymentOptions");
    setting5.setSettingValue("{"cardCodeRequired": true, "showCreditCard": true, "showBankAccount": false}");

    setting7.setSettingName("hostedPaymentShippingAddressOptions");
    setting7.setSettingValue("{"show": false, "required": false}");

    setting8.setSettingName("hostedPaymentBillingAddressOptions");
    setting8.setSettingValue("{"show": false, "required": false}");

    setting6.setSettingName("hostedPaymentSecurityOptions");
    setting6.setSettingValue("{"captcha": true}");

    setting4.setSettingName("hostedPaymentStyleOptions");
    setting4.setSettingValue("{"bgColor": "blue"}");

    setting9.setSettingName("hostedPaymentCustomerOptions");
    setting9.setSettingValue("{"showEmail": false, "requiredEmail": false, "addPaymentProfile": true }");

    setting11.setSettingName("hostedPaymentIFrameCommunicatorUrl");
    setting11.setSettingValue("{"url": "https://iMart.com/IFrameCommunicator.html"}");
    
    var settingList = [];

    settingList.push(setting2);
    settingList.push(setting10);
    settingList.push(setting5);
    settingList.push(setting7);
    settingList.push(setting8);
    settingList.push(setting6);
    settingList.push(setting4);
    settingList.push(setting9);
    settingList.push(setting11);
    settingList.push(setting1);


    var alist = new ApiContracts.ArrayOfSetting();
    alist.setSetting(settingList);
    var firstname = new ApiContracts.UserField();
    firstname.setName('First Name');
    firstname.setValue(firstName);

    var lastname = new ApiContracts.UserField();
    lastname.setName('Last Name');
    lastname.setValue(lastName);

    var userFieldList = [];
    userFieldList.push(firstname);
    userFieldList.push(lastname);

    var userFields = new ApiContracts.TransactionRequestType.UserFields();
    userFields.setUserField(userFieldList);

    var transactionSetting1 = new ApiContracts.SettingType();
    transactionSetting1.setSettingName('duplicateWindow');
    transactionSetting1.setSettingValue('120');

    var transactionSetting2 = new ApiContracts.SettingType();
    transactionSetting2.setSettingName('recurringBilling');
    transactionSetting2.setSettingValue('false');

    var transactionSetting3 = new ApiContracts.SettingType();
    transactionSetting3.setSettingName('emailCustomer');
    transactionSetting3.setSettingValue('true');

    var transactionSetting4 = new ApiContracts.SettingType();
    transactionSetting4.setSettingName('headerEmailReceipt');
    transactionSetting3.setSettingValue('You are all set!');

    var transactionSetting5 = new ApiContracts.SettingType();
    transactionSetting5.setSettingName('footerEmailReceipt');
    transactionSetting5.setSettingValue('This is the footer');

    var getRequest = new ApiContracts.GetHostedPaymentPageRequest();
    getRequest.setMerchantAuthentication(merchantAuthenticationType);
    getRequest.setTransactionRequest(transactionRequestType);
    getRequest.setHostedPaymentSettings(alist);
    
    var ctrl = new ApiControllers.GetHostedPaymentPageController(getRequest.getJSON());

    const basicAuth = encode.encode("*****", 'base64');
    await axios({
      method: 'post',
      url: 'https://apitest.authorize.net/xml/v1/request.api',
      headers: {
        'Authorization': 'Basic ' basicAuth,
        'Content-Type': 'application/json'
        
      },
      data:JSON.stringify(ctrl._request)
        }).then(async (data : any)=>{
          if(data.data.token) {
            callback(null, data.data) ; 
          } else callErr(data);   
        });
      async function callErr(data: any){
        callback(null, res) ;
      }
    
}
  

IFrameCommunicator.html:

 <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Iframe Communicator</title>
        <script type="text/javascript">
            //<![CDATA[
                function callParentFunction(str) {
                    if (str amp;amp; str.length > 0 
                        amp;amp; window.parent 
                        amp;amp; window.parent.parent
                        amp;amp; window.parent.parent.AuthorizeNetPopup 
                        amp;amp; window.parent.parent.AuthorizeNetPopup.onReceiveCommunication)
                        {
// Errors indicate a mismatch in domain between the page containing the iframe and this page.
                            window.parent.parent.AuthorizeNetPopup.onReceiveCommunication(str);
                        }
                    }

                function receiveMessage(event) {
                    if (event amp;amp; event.data) {
                        callParentFunction(event.data);
                        }
                    }

                if (window.addEventListener) {
                        console.log('addEventListener');
                        console.log(receiveMessage);
                    window.addEventListener("message", receiveMessage, false);
                    } else if (window.attachEvent) {
                        window.attachEvent("onmessage", receiveMessage);
                    }

                if (window.location.hash amp;amp; window.location.hash.length > 1) {                  callParentFunction(window.location.hash.substring(1));
                    }
            //]]/>
        </script>
    </head>
    <body>
    </body>
</html>
  

Угловой код для отображения iFrame:

    <iframe id="add_payment" class="embed-responsive-item panel" name="add_payment" width="100%" frameborder="0" scrolling="yes">
   </iframe>
 </div>
 <form id="send_token" action="" method="post" target="add_payment" >
   <input id="token" type="hidden" name="token" />
 </form>
  

Я много дней боролся с нехваткой времени. Было бы очень полезно, если бы кто-нибудь дал мне здесь хорошее представление. Пожалуйста, дайте мне знать, если требуется дополнительная информация. Заранее благодарю вас!!!

Ответ №1:

Вот ответ на все ваши вопросы, я надеюсь, что это сработает :

1) если вы используете iFrame, то iFrameCommunicator является обязательным

2) URL-адрес успеха может использоваться только тогда, когда вы устанавливаете «showReceipt» как true, здесь вы не можете автоматически перейти на страницу успеха, это ссылка для кнопки «Продолжить», которая появляется, когда «showReceipt» разрешен

3) Если вы хотите запустить какую-либо функцию или хотите перейти после ответа, добавьте следующий код в свой HTML-файл

   <script type="text/javascript">

    $(document).ready(function () {

        window.CommunicationHandler = {};

        function parseQueryString(str) {
            var vars = [];
            var arr = str.split('amp;');
            var pair;
            for (var i = 0; i < arr.length; i  ) {
                pair = arr[i].split('=');
                vars[pair[0]] = unescape(pair[1]);
            }
            return vars;
        }

        window.CommunicationHandler.onReceiveCommunication = function (argument) {

            console.log('communication handler enter', argument);

            var params = parseQueryString(argument.qstr)

            switch (params['action']) {
                case "resizeWindow":

                    console.log('resize'); break;

                case "successfulSave":

                    console.log('save'); break;

                case "cancel":

                    console.log('cancel'); break;

                case "transactResponse":

                    sessionStorage.removeItem("HPTokenTime");

                    console.log('transaction complete');

                    var transResponse = JSON.parse(params['response']);

                    console.log('transaction complete1', transResponse);
                // window.location.href = '/checkout/complete';

            }
        }

        //send the token
        $('#send_hptoken').submit();


    });
</script>