angularjs2checkout

2Checkout + Angular > Inline Checkout > redirects to the full checkout page


Problem

I'm following the 2Checkout docs for setting up the Inline Checkout. I have not been able to get the iframe popup to appear. No matter what I try it redirects to the full checkout experience.

Failed Troubleshooting

I was unable to find anything that directly addressed my issue via Google or on Stackoverflow. The only mention of it seems to be from the docs themselves. At the bottom of the docs it suggests trying the following if you have this issue:

Clear your browser’s cache and cookies, close all open instances of your browser, then recommence testing.

Review your page to ensure that the mandatory JavaScript code has been properly implemented.

I can see via Chrome's dev tools Network tab that the JS from the docs (shown below) is loaded on the page without issue. Also, when I navigate to it directly I do see the minified JS.

<script src="https://www.2checkout.com/static/checkout/javascript/direct.min.js"></script>

Ensure that you are using the Hosted Checkout parameter set to pass in sale details.

(pointing at the sandbox per the docs)

<form action="https://sandbox.2checkout.com/checkout/purchase" method="post">
  <input name="sid" value="901341903" />
  <input name="mode" value="2CO" />
  <input name="li_0_tangible" value="N" />
  <input name="li_0_type" value="product" />
  <input name="li_0_name" value="Website" />
  <input name="li_0_price" value="5" />
  <input name="li_0_recurrence" value="1 Month" />
  <input name="card_holder_name" value="Joe Flagster" />
  <input name="street_address" value="123 Main Street" />
  <input name="street_address2" value="" />
  <input name="city" value="Townsville" />
  <input name="state" value="OH" />
  <input name="zip" value="43206" />
  <input name="country" value="USA" />
  <input name="email" value="example@2co.com" />
  <input name="phone" value="614-921-2450" />
  <input name="submit" type="submit" value="Checkout" />
</form>

Potentially Relevant Info

Any assistance, experience, insight, etc. with this will be greatly appreciated!


UPDATE 3/14/2017

Screenshot of my code (I added li_0_duration): Form

Screenshots of the standard cart after the undesired redirect: Review CartBilling InformationPayment Method

The only empty required fields are in the Payment Methods section, but that's data the user is supposed to submit in the iframe popup, right?


Solution

  • Problem Summary

    I downloaded the unminified version of the JS... https://www.2checkout.com/static/checkout/javascript/direct.js

    ...and hosted it locally so that I could troubleshoot. I discovered that onready was getting triggered before the DOM is fully ready. This caused the error.

    It seems the 2Checkout script was tricked by how the Angular framework loads and manages views. The 2Checkout script did not find and analyze the form element correctly because the form element wasn't in the DOM when the 2Checkout script was loaded. Among other things the 2Checkout script ought to inject a hidden input named tco_use_inline into the form (determined by the value of the form's action attribute), but it wasn't doing that for me.

    Angular Solution

    I created a temporary patch. Add this to the controller of the template the form is in...

    $scope.$watch("ready", function() {
      var s = document.createElement("script");
      s.src = 'https://www.2checkout.com/static/checkout/javascript/direct.min.js';
      document.body.append(s);
    });
    

    ...and then add ng-init="ready" to the form.

    <form ng-init="ready" action="..." method="...">
      ...
    </form>
    

    Once the form is loaded in the DOM it will declare ready, which triggers the $watch in the controller, which will dynamically inject the 2Checkout script. Thus, everything gets loaded in the correct order.