cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to receive Transaction Response through iFrame

Hello! Beginner Web Dev here trying to integrate Authroize.net payment system.

 

I am trying to setup and test Accept Hosted on my site using an iframe/lightbox by following this page. I am able to get the payment form to show up in the iframe and transactions are going through just fine once I click the "Pay" button as I can see it when I log into the sandbox.authorize.net. The issue is I can't receieve the Transaction Response from my site. I need to basically be able to tell from my site if the user clicked on "Pay" and the transaction was Auth/Captured so that I can email my digital products to the user OR if they clicked "Cancel" in which case I don't send them the product.

 

I am getting these error messages from the console:

 

'The loading of “https://mysite/store/partials/iFrameCommunicator.html#actionresizeWindow&width427&height925.8” in a frame is denied by “X-Frame-Options“ directive set to “SAMEORIGIN“.'

'Failed to execute ‘postMessage’ on ‘DOMWindow’: The target origin provided (‘mysite’) does not match the recipient window’s origin (‘null’)'

 

It looked like the issue was with CSP headers being SAMEORIGIN? So I tried to add a CSP Header in my .htcaccess like this but it still didn't work:

 

 
<IfModule mod_headers.c>
Header set Content-Security-Policy "frame-ancestors 'self' *.mysite https://mysite/ https://test.authorize.net *.authorize.net;";
</IfModule>
 

I'm using craftCMS nitro and Docker on my local to test everything out.

 

My server side code for the payment token form:

$req = Craft::$app->getRequest();
    $cost = $req->getBodyParam('price');
    // define("AUTHORIZENET_LOG_FILE", "phplog");
    
    
    /* Create a merchantAuthenticationType object with authentication details
      retrieved from the constants file */
    $merchantAuthentication = new AnetAPI\MerchantAuthenticationType();
    $merchantAuthentication->setName(getenv("ANET_SANDBOX_ID"));
    $merchantAuthentication->setTransactionKey(getenv("ANET_SANDBOX_KEY"));
    
    // Set the transaction's refId
    $refId = 'ref' . time();

    //create a transaction
    $transactionRequestType = new AnetAPI\TransactionRequestType();
    $transactionRequestType->setTransactionType("authCaptureTransaction");
    $transactionRequestType->setAmount($cost);

    // Set Hosted Form options
    $setting1 = new AnetAPI\SettingType();
    $setting1->setSettingName("hostedPaymentButtonOptions");
    $setting1->setSettingValue("{\"text\": \"Pay\"}");

    $setting2 = new AnetAPI\SettingType();
    $setting2->setSettingName("hostedPaymentOrderOptions");
    $setting2->setSettingValue("{\"show\": false}");

    $setting3 = new AnetAPI\SettingType();
    $setting3->setSettingName("hostedPaymentReturnOptions");
    $setting3->setSettingValue("{\"showReceipt\": false, \"urlText\": \"Return\", \"cancelUrl\": \"https://qpr.nitro/store/partials/checkout-pay.twig\", \"cancelUrlText\": \"Cancel\"}");

    $setting4 = new AnetAPI\SettingType();
    $setting4->setSettingName("hostedPaymentIFrameCommunicatorUrl");
    $setting4->setSettingValue("{\"url\": \"https://qpr.nitro/store/partials/iFrameCommunicator.html\"}");

    $setting5 = new AnetAPI\SettingType();
    $setting5->setSettingName("hostedPaymentPaymentOptions");
    $setting5->setSettingValue("{\"cardCodeRequired\": true, \"showCreditCard\": true, \"showBankAccount\": false}");
    
    $setting6 = new AnetAPI\SettingType();
    $setting6->setSettingName("hostedPaymentSecurityOptions");
    $setting6->setSettingValue("{\"captcha\": true}");
    
    $setting7 = new AnetAPI\SettingType();
    $setting7->setSettingName("hostedPaymentShippingAddressOptions");
    $setting7->setSettingValue("{\"show\": true, \"required\": true}");

    $setting8 = new AnetAPI\SettingType();
    $setting8->setSettingName("hostedPaymentCustomerOptions");
    $setting8->setSettingValue("{\"showEmail\": true, \"requiredEmail\": true, \"addPaymentProfile\": false}");
    
    // Build transaction request
    $request = new AnetAPI\GetHostedPaymentPageRequest();
    $request->setMerchantAuthentication($merchantAuthentication);
    $request->setRefId($refId);
    $request->setTransactionRequest($transactionRequestType);

    $request->addToHostedPaymentSettings($setting1);
    $request->addToHostedPaymentSettings($setting2);
    $request->addToHostedPaymentSettings($setting3);
    $request->addToHostedPaymentSettings($setting4);
    $request->addToHostedPaymentSettings($setting5);
    $request->addToHostedPaymentSettings($setting6);
    $request->addToHostedPaymentSettings($setting7);
    $request->addToHostedPaymentSettings($setting8);
    
    //execute request
    $controller = new AnetController\GetHostedPaymentPageController($request);
    $response = $controller->executeWithApiResponse(\net\authorize\api\constants\ANetEnvironment::SANDBOX);
    

    return $this->asJSON($response->getToken());

Front End:

if (!window.AuthorizeNetPopup) window.AuthorizeNetPopup = {};
  if (!AuthorizeNetPopup.options) AuthorizeNetPopup.options = {
    onPopupClosed: null
    };
    
  AuthorizeNetPopup.openPopup = function () {
      var popup = document.getElementById("divAuthorizeNetPopup");
      var popupScreen = document.getElementById("divAuthorizeNetPopupScreen");
      var ifrm = document.getElementById("iframeAuthorizeNet");
      var form = document.forms["formAuthorizeNetPopup"];
      let paypalCont = document.getElementById("paypalContainer");
      let aNetUrl = "/actions/cls-lms/shop/shop-anet-token",
        total = "{{ totalPrice }}"
        csrfToken = "{{ csrfToken }}",
        csrfParam = "{{ csrfParam }}",
        shopApi = new craftApi();
  
      let payload = { price: total }
      paypalCont.style.display = "none";
      form.action = "https://test.authorize.net/payment/payment";
      ifrm.style.width = "442px";
      ifrm.style.height = "578px";
  
      shopApi.controllerAjaxRequest(aNetUrl, payload, csrfParam, csrfToken).
        then(function(response){ 
          $("#popupToken").val(response);
          setTimeout(form.submit(), 2);
        });
  
      popup.style.display = "";
      popupScreen.style.display = "";
      centerPopup();
    };
  
  
    AuthorizeNetPopup.closePopup = function () {
      document.getElementById("divAuthorizeNetPopupScreen").style.display = "none";
      document.getElementById("divAuthorizeNetPopup").style.display = "none";
      document.getElementById("iframeAuthorizeNet").src="empty.html";
      document.getElementById("btnOpenAuthorizeNetPopup").disabled = false;
      if (AuthorizeNetPopup.options.onPopupClosed) AuthorizeNetPopup.options.onPopupClosed();
      };
  
  
    AuthorizeNetPopup.openPopup = function () {
      var popup = document.getElementById("divAuthorizeNetPopup");
      var popupScreen = document.getElementById("divAuthorizeNetPopupScreen");
      var ifrm = document.getElementById("iframeAuthorizeNet");
      var form = document.forms["formAuthorizeNetPopup"];
      let paypalCont = document.getElementById("paypalContainer");
      let aNetUrl = "/actions/cls-lms/shop/shop-anet-token",
        total = "{{ totalPrice }}"
        csrfToken = "{{ csrfToken }}",
        csrfParam = "{{ csrfParam }}",
        shopApi = new craftApi();
  
      let payload = { price: total }
      paypalCont.style.display = "none";
      form.action = "https://test.authorize.net/payment/payment";
      ifrm.style.width = "442px";
      ifrm.style.height = "578px";
  
      shopApi.controllerAjaxRequest(aNetUrl, payload, csrfParam, csrfToken).
        then(function(response){ 
          $("#popupToken").val(response);
          setTimeout(form.submit(), 2);
        });
  
      popup.style.display = "";
      popupScreen.style.display = "";
      centerPopup();
    };
  
    AuthorizeNetPopup.onReceiveCommunication = function (querystr) {
        var params = parseQueryString(querystr);
        switch (params["action"]) {
          case "successfulSave":
            AuthorizeNetPopup.closePopup();
            break;
          case "cancel":
            AuthorizeNetPopup.closePopup();
            break;
          case "transactResponse":
            var response = params["response"];
            document.getElementById("token").value = response;
            AuthorizeNetPopup.closePopup();
            break;
          case "resizeWindow":
            var w = parseInt(params["width"]);
            var h = parseInt(params["height"]);
            var ifrm = document.getElementById("iframeAuthorizeNet");
            ifrm.style.width = w.toString() + "px";
            ifrm.style.height = h.toString() + "px";
            centerPopup();
            break;
          }
      };
  
  
    function centerPopup() {
      var d = document.getElementById("divAuthorizeNetPopup");
      d.style.left = "50%";
      d.style.top = "50%";
      var left = -Math.floor(d.clientWidth / 2);
      var top = -Math.floor(d.clientHeight / 2);
      d.style.marginLeft = left.toString() + "px";
      d.style.marginTop = top.toString() + "px";
      d.style.zIndex = "2";
      if (d.offsetLeft < 16) {
        d.style.left = "16px";
        d.style.marginLeft = "0px";
        }
      if (d.offsetTop < 16) {
        d.style.top = "16px";
        d.style.marginTop = "0px";
        }
      }
  
    function parseQueryString(str) {
        var vars = [];
        var arr = str.split('&');
        var pair;
        for (var i = 0; i < arr.length; i++) {
          pair = arr[i].split('=');
          vars.push(pair[0]);
          vars[pair[0]] = unescape(pair[1]);
        }
        return vars;
    }

 

mrfish55
Member
0 REPLIES 0