<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Dynamically loading Accept.js: E_WC_03 Accept.js is not loaded correctly in Integration and Testing</title>
    <link>https://community.developer.cybersource.com/t5/Integration-and-Testing/Dynamically-loading-Accept-js-E-WC-03-Accept-js-is-not-loaded/m-p/63283#M37442</link>
    <description>&lt;P&gt;I am dynamically loading Accept.js only if it's needed during our checkout process. My initial approach was to just add the script to the &lt;FONT face="andale mono,monospace"&gt;&amp;lt;head&amp;gt;&lt;/FONT&gt; tag, listen for the script's &lt;FONT face="andale mono,monospace"&gt;load&lt;/FONT&gt; event, and then call &lt;FONT face="andale mono,monospace"&gt;Accept.dispatchData&lt;/FONT&gt;. Unfortunately, this results in E_WC_03: Accept.js is not loaded correctly.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Relevant code:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;async function loadScript(source, charset) {
  let script = document.createElement('script');
  script.setAttribute('src', source);
  if (charset) {
    script.setAttribute('charset', charset);
  }

  let onLoad = null;
  let onError = null;
  try {
    return await new Promise((resolve, reject) =&amp;gt; {
      onLoad = e =&amp;gt; resolve(e);
      onError = e =&amp;gt; reject(e);
      script.addEventListener('load', onLoad);
      script.addEventListener('error', onError);
      document.head.appendChild(script);
    });
  } finally {
    if (onLoad) {
      script.removeEventListener('load', onLoad);
    }
    if (onError) {
      script.removeEventListener('error', onError);
    }
  }
}
async loadAcceptApi() {
  if (typeof Accept != 'undefined') {
    return;
  }
  await loadScript('https://jstest.authorize.net/v1/Accept.js');
}
async getPaymentNonce(paymentDetails) {
  await loadAcceptApi();
  return await new Promise((resolve, reject) =&amp;gt; {
    Accept.dispatchData(paymentDetails, response =&amp;gt; {
      // ...
    });
  }
}&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Digging into the source for Accept.js, I think I see why this results in an error:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Our script loads the Accept.js script&lt;/LI&gt;&lt;LI&gt;Accept.js loads AcceptCore.js&lt;/LI&gt;&lt;LI&gt;Until AcceptCore.js is loaded, &lt;FONT face="andale mono,monospace"&gt;Accept.dispatchData&lt;/FONT&gt; is defined to just warn "Accept.js is not loaded correctly"&lt;/LI&gt;&lt;LI&gt;Loading Accept.js does not block or wait for AcceptCore.js to load&lt;/LI&gt;&lt;LI&gt;Since our script resumes execution immediately after loading the Accept.js script, there is a race condition where our call to &lt;FONT face="andale mono,monospace"&gt;Acccept.dispatchData&lt;/FONT&gt; can occur before AcceptCore.js is fully loaded, resulting in the warning&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;I dug into AcceptCore.js and found a workaround. AcceptCore.js appears to emit a &lt;FONT face="andale mono,monospace"&gt;handshake&lt;/FONT&gt; event on the &lt;FONT face="andale mono,monospace"&gt;body&lt;/FONT&gt; element when it is loaded. Knowing this, I updated our code to wait for Accept.js to load &lt;EM&gt;and&lt;/EM&gt; for the handshake event to fire before calling &lt;FONT face="andale mono,monospace"&gt;Accept.dispatchData&lt;/FONT&gt;.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Updated relevant code:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;async loadAcceptApi() {
  if (typeof Accept != 'undefined') {
    return;
  }

  let onHandshake = null;
  try {
    // Accept.js loads AcceptCore.js, so we have to wait for the
    // "handshake" event that AcceptCore.js emits after loading.
    let handshake = new Promise(resolve =&amp;gt; {
      onHandshake = () =&amp;gt; resolve();
      document.body.addEventListener('handshake', onHandshake);
    });

    // Wait for script load and handshake.
    await Promise.all([loadScript('https://jstest.authorize.net/v1/Accept.js', 'utf-8'), handshake]);
  } finally {
    if (onHandshake) {
      document.body.removeEventListener('handshake', onHandshake);
    }
  }
}&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;With the updated code, everything works as expected. We load Accept.js dynamically, wait for it to load, wait for AcceptCore.js to load via the &lt;FONT face="andale mono,monospace"&gt;handshake&lt;/FONT&gt; event and only then make our call through &lt;FONT face="andale mono,monospace"&gt;Accept.dispatchData&lt;/FONT&gt;.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Questions:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;I don't see AcceptCore.js's &lt;FONT face="andale mono,monospace"&gt;handshake&lt;/FONT&gt; event documented anywhere, so should we be relying on this internal implementation detail? The obvious answer is no, but then...&lt;/LI&gt;&lt;LI&gt;If not listening for &lt;FONT face="andale mono,monospace"&gt;handshake&lt;/FONT&gt;, how else are we supposed to know that &lt;FONT face="andale mono,monospace"&gt;Accept&lt;/FONT&gt; has fully loaded? Since Accept.js does a non-blocking load of AcceptCore.js, I'm not sure what alternative we have. Sleeping for a small amount of time also works, but that's an even worse workaround.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;Chris&lt;/P&gt;</description>
    <pubDate>Mon, 04 Jun 2018 02:12:33 GMT</pubDate>
    <dc:creator>schmich</dc:creator>
    <dc:date>2018-06-04T02:12:33Z</dc:date>
    <item>
      <title>Dynamically loading Accept.js: E_WC_03 Accept.js is not loaded correctly</title>
      <link>https://community.developer.cybersource.com/t5/Integration-and-Testing/Dynamically-loading-Accept-js-E-WC-03-Accept-js-is-not-loaded/m-p/63283#M37442</link>
      <description>&lt;P&gt;I am dynamically loading Accept.js only if it's needed during our checkout process. My initial approach was to just add the script to the &lt;FONT face="andale mono,monospace"&gt;&amp;lt;head&amp;gt;&lt;/FONT&gt; tag, listen for the script's &lt;FONT face="andale mono,monospace"&gt;load&lt;/FONT&gt; event, and then call &lt;FONT face="andale mono,monospace"&gt;Accept.dispatchData&lt;/FONT&gt;. Unfortunately, this results in E_WC_03: Accept.js is not loaded correctly.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Relevant code:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;async function loadScript(source, charset) {
  let script = document.createElement('script');
  script.setAttribute('src', source);
  if (charset) {
    script.setAttribute('charset', charset);
  }

  let onLoad = null;
  let onError = null;
  try {
    return await new Promise((resolve, reject) =&amp;gt; {
      onLoad = e =&amp;gt; resolve(e);
      onError = e =&amp;gt; reject(e);
      script.addEventListener('load', onLoad);
      script.addEventListener('error', onError);
      document.head.appendChild(script);
    });
  } finally {
    if (onLoad) {
      script.removeEventListener('load', onLoad);
    }
    if (onError) {
      script.removeEventListener('error', onError);
    }
  }
}
async loadAcceptApi() {
  if (typeof Accept != 'undefined') {
    return;
  }
  await loadScript('https://jstest.authorize.net/v1/Accept.js');
}
async getPaymentNonce(paymentDetails) {
  await loadAcceptApi();
  return await new Promise((resolve, reject) =&amp;gt; {
    Accept.dispatchData(paymentDetails, response =&amp;gt; {
      // ...
    });
  }
}&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Digging into the source for Accept.js, I think I see why this results in an error:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Our script loads the Accept.js script&lt;/LI&gt;&lt;LI&gt;Accept.js loads AcceptCore.js&lt;/LI&gt;&lt;LI&gt;Until AcceptCore.js is loaded, &lt;FONT face="andale mono,monospace"&gt;Accept.dispatchData&lt;/FONT&gt; is defined to just warn "Accept.js is not loaded correctly"&lt;/LI&gt;&lt;LI&gt;Loading Accept.js does not block or wait for AcceptCore.js to load&lt;/LI&gt;&lt;LI&gt;Since our script resumes execution immediately after loading the Accept.js script, there is a race condition where our call to &lt;FONT face="andale mono,monospace"&gt;Acccept.dispatchData&lt;/FONT&gt; can occur before AcceptCore.js is fully loaded, resulting in the warning&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;I dug into AcceptCore.js and found a workaround. AcceptCore.js appears to emit a &lt;FONT face="andale mono,monospace"&gt;handshake&lt;/FONT&gt; event on the &lt;FONT face="andale mono,monospace"&gt;body&lt;/FONT&gt; element when it is loaded. Knowing this, I updated our code to wait for Accept.js to load &lt;EM&gt;and&lt;/EM&gt; for the handshake event to fire before calling &lt;FONT face="andale mono,monospace"&gt;Accept.dispatchData&lt;/FONT&gt;.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Updated relevant code:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;async loadAcceptApi() {
  if (typeof Accept != 'undefined') {
    return;
  }

  let onHandshake = null;
  try {
    // Accept.js loads AcceptCore.js, so we have to wait for the
    // "handshake" event that AcceptCore.js emits after loading.
    let handshake = new Promise(resolve =&amp;gt; {
      onHandshake = () =&amp;gt; resolve();
      document.body.addEventListener('handshake', onHandshake);
    });

    // Wait for script load and handshake.
    await Promise.all([loadScript('https://jstest.authorize.net/v1/Accept.js', 'utf-8'), handshake]);
  } finally {
    if (onHandshake) {
      document.body.removeEventListener('handshake', onHandshake);
    }
  }
}&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;With the updated code, everything works as expected. We load Accept.js dynamically, wait for it to load, wait for AcceptCore.js to load via the &lt;FONT face="andale mono,monospace"&gt;handshake&lt;/FONT&gt; event and only then make our call through &lt;FONT face="andale mono,monospace"&gt;Accept.dispatchData&lt;/FONT&gt;.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Questions:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;I don't see AcceptCore.js's &lt;FONT face="andale mono,monospace"&gt;handshake&lt;/FONT&gt; event documented anywhere, so should we be relying on this internal implementation detail? The obvious answer is no, but then...&lt;/LI&gt;&lt;LI&gt;If not listening for &lt;FONT face="andale mono,monospace"&gt;handshake&lt;/FONT&gt;, how else are we supposed to know that &lt;FONT face="andale mono,monospace"&gt;Accept&lt;/FONT&gt; has fully loaded? Since Accept.js does a non-blocking load of AcceptCore.js, I'm not sure what alternative we have. Sleeping for a small amount of time also works, but that's an even worse workaround.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;Chris&lt;/P&gt;</description>
      <pubDate>Mon, 04 Jun 2018 02:12:33 GMT</pubDate>
      <guid>https://community.developer.cybersource.com/t5/Integration-and-Testing/Dynamically-loading-Accept-js-E-WC-03-Accept-js-is-not-loaded/m-p/63283#M37442</guid>
      <dc:creator>schmich</dc:creator>
      <dc:date>2018-06-04T02:12:33Z</dc:date>
    </item>
    <item>
      <title>Re: Dynamically loading Accept.js: E_WC_03 Accept.js is not loaded correctly</title>
      <link>https://community.developer.cybersource.com/t5/Integration-and-Testing/Dynamically-loading-Accept-js-E-WC-03-Accept-js-is-not-loaded/m-p/63388#M37525</link>
      <description>&lt;P&gt;Accept.js is designed to be loaded when page loads at the starting,&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Following should be the sequence:-&lt;/STRONG&gt;&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;Page load&lt;/LI&gt;&lt;LI&gt;AcceptJS loads&lt;/LI&gt;&lt;LI&gt;Merchant Page shows the Payment form to customer&lt;/LI&gt;&lt;LI&gt;Customer fills out the Payment form&lt;/LI&gt;&lt;LI&gt;Extract the needed payment info from the form&lt;/LI&gt;&lt;LI&gt;Call Accept.dispatchData with required parameters.&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;In this flow it takes around 1-2 mins for a customer to fill payment form.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Can you pls explain What is your flow, as I see you load accept.js and just after that you call dispatchData.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I feel you should change the load time of Accept script.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 14 Jun 2018 01:16:24 GMT</pubDate>
      <guid>https://community.developer.cybersource.com/t5/Integration-and-Testing/Dynamically-loading-Accept-js-E-WC-03-Accept-js-is-not-loaded/m-p/63388#M37525</guid>
      <dc:creator>Shoagraw</dc:creator>
      <dc:date>2018-06-14T01:16:24Z</dc:date>
    </item>
    <item>
      <title>Re: Dynamically loading Accept.js: E_WC_03 Accept.js is not loaded correctly</title>
      <link>https://community.developer.cybersource.com/t5/Integration-and-Testing/Dynamically-loading-Accept-js-E-WC-03-Accept-js-is-not-loaded/m-p/63438#M37564</link>
      <description>&lt;P&gt;Thanks for the reply. I understand and appreciate what you're saying, but the design feels flawed to me.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;We have a Vue-based single page app. It would be wasteful and would increase our vulnerability surface area to load Accept.js on the initial page since it would load for all of our pages, even though it is only used on a couple of them.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This isn't a problem, of course, since we can load Accept.js dynamically on just the routes that use it. Ultimately, to keep all of the Authorize.net front-end code together, I decided to only load the library right when we need it (when the user checks out). I could move it to when the route is loaded to reduce latency on checkout, but regardless,&amp;nbsp;there is no clean way of knowing for sure that Accept.js is loaded.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The current suggested&amp;nbsp;way to load Accept.js is basically:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;Load Accept.js on initial page load&lt;/LI&gt;&lt;LI&gt;(wait some arbitrary amount of time, hope that Accept.js has loaded)&lt;/LI&gt;&lt;LI&gt;Use the Accept.js API&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;I understand that this works fine in the majority of situations, I just don't care for the "hope that Accept.js has loaded" step (e.g. What about slow connections? What about prefilled forms that the user submits quickly? What about refreshing and submitting immediately? What about this scenario of loading at the last second?). There should be a simple, deterministic way of knowing that the library is ready.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The ways I can think of knowing when it's loaded off the top of my head:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;On Accept.js script load complete&lt;/LI&gt;&lt;LI&gt;Via a global callback or promise from Accept.js&lt;/LI&gt;&lt;LI&gt;Via a custom event raised from Accept.js&lt;/LI&gt;&lt;LI&gt;Via setInterval and checking to see if the Accept object is present&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;#1 doesn't work since Accept.js loads AcceptCore.js, which is the issue I ran into. #4 is hacky, inelegant, and wasteful. #2 and #3 seem fine to me.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;As an example, the &lt;A href="https://stackoverflow.com/a/32125607/332960" target="_self"&gt;Google Maps API accepts a callback parameter that is executed when the library is finished loading&lt;/A&gt;.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I understand that "load early, wait a while" is good enough for most scenarios, I just expect a bit more from a payment handling library.&lt;/P&gt;</description>
      <pubDate>Wed, 20 Jun 2018 03:04:36 GMT</pubDate>
      <guid>https://community.developer.cybersource.com/t5/Integration-and-Testing/Dynamically-loading-Accept-js-E-WC-03-Accept-js-is-not-loaded/m-p/63438#M37564</guid>
      <dc:creator>schmich</dc:creator>
      <dc:date>2018-06-20T03:04:36Z</dc:date>
    </item>
    <item>
      <title>Re: Dynamically loading Accept.js: E_WC_03 Accept.js is not loaded correctly</title>
      <link>https://community.developer.cybersource.com/t5/Integration-and-Testing/Dynamically-loading-Accept-js-E-WC-03-Accept-js-is-not-loaded/m-p/63468#M37589</link>
      <description>&lt;P&gt;Thanks&amp;nbsp;&amp;nbsp;for your suggestion!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I hope you are able to solve the issue now by following currently supported integration way&amp;nbsp;:-&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Load Accept.js on page load&amp;nbsp;&lt;/LI&gt;&lt;LI&gt;call dispatchData after user complete filling form&lt;/LI&gt;&lt;LI&gt;implement response handler.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;Till now we found it works fine. we want to keep&amp;nbsp;it&amp;nbsp;simple and easy&amp;nbsp;to integrate,&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;We are taking&amp;nbsp;your feedback and will think about implementing a new event(optional), Script at merchant page can listen to this if needed.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks!&lt;/P&gt;</description>
      <pubDate>Fri, 22 Jun 2018 23:01:09 GMT</pubDate>
      <guid>https://community.developer.cybersource.com/t5/Integration-and-Testing/Dynamically-loading-Accept-js-E-WC-03-Accept-js-is-not-loaded/m-p/63468#M37589</guid>
      <dc:creator>Shoagraw</dc:creator>
      <dc:date>2018-06-22T23:01:09Z</dc:date>
    </item>
  </channel>
</rss>

