cancel
Showing results for 
Search instead for 
Did you mean: 

Errors E00003/E00117 with Accept JS

I am using the sandbox.

 

When I run Accept.dispatchData, I see two network requests take place, both of which return error responses.

 

> OPTIONS /xml/v1/request.api HTTP/1.1
> Host: apitest.authorize.net
> Connection: keep-alive
> Access-Control-Request-Method: POST
> Origin: https://localhost:8000
> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
> Access-Control-Request-Headers: content-type
> Accept: */*
> Referer: https://localhost:8000/donate/
> Accept-Encoding: gzip, deflate, br
> Accept-Language: en-US,en;q=0.8
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Type: application/json; charset=utf-8
< Server: Microsoft-IIS/7.5
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: PUT,OPTIONS,POST,GET
< Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method,SOAPAction
< X-Cnection: close
< X-Powered-By: ASP.NET
< Content-Length: 102
< Date: Tue, 08 Aug 2017 18:17:15 GMT
< Connection: keep-alive
{"messages":{"resultCode":"Error","message":[{"code":"E00003","text":"Root element is missing."}]}}

And:

 

> POST /xml/v1/request.api HTTP/1.1
> Host: apitest.authorize.net
> Connection: keep-alive
> Content-Length: 313
> Origin: https://localhost:8000
> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
> Content-Type: application/json; charset=UTF-8
> Accept: */*
> Referer: https://localhost:8000/donate/
> Accept-Encoding: gzip, deflate, br
> Accept-Language: en-US,en;q=0.8
{"securePaymentContainerRequest":{"merchantAuthentication":{"name":"...","clientKey":"..."},"data":{"type":"TOKEN","id":"...","token":{"cardNumber":"4007 0000 0002 7","expirationDate":"122033","cardCode":"123"}}}}
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Type: application/json; charset=utf-8
< Server: Microsoft-IIS/7.5
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: PUT,OPTIONS,POST,GET
< Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method,SOAPAction
< X-Powered-By: ASP.NET
< Content-Length: 121
< Date: Tue, 08 Aug 2017 18:17:16 GMT
< Connection: keep-alive
{"messages":{"resultCode":"Error","message":[{"code":"E00117","text":"OTS Service Error 'Field validation error.'"}]}}

That leaves me little to nothing to go on with as both error codes don't perform well in a google search.

 

The worst part of all of this is that the response handler passed to Accept.dispatchData is never even fired!

felixschl
Contributor
1 ACCEPTED SOLUTION

Accepted Solutions

Hi @felixschl,

 

For future reference, we have a response code lookup tool at http://developer.authorize.net/api/reference/responseCodes.html. That wouldn't help you much in this case, though, because neither code has much of a description in that tool (yet).

 

In a nutshell, a dispatchData call to Accept.js will end up calling AcceptCore.js, which well do a request to our API to get a token. If an error is returned by our API, AcceptCore.js will map that to an Accept.js specific error and return it so that your response handler can deal with it.

 

In your case, you have a log of the requests that AcceptCore.js is making. I don't think the first request means anything because it's just an OPTIONS request. But, the second request is AcceptCore actually calling the securePaymentContainerRequest call in our API to get a token. It gets a E00117 error back, which is not something that its error handling has set up to map to a specific Accept.js message, so it just passes it back (in my testing, the response handler still gets fired, though, so that part's a mystery).

 

The text passed back with the error is the real key: 

"OTS Service Error 'Field validation error.'"

 

The token service had trouble validating a field. In this case, it's the card number, because we don't allow spaces in the card number. Of course, it would be helpful if we returned an error that said something like "spaces aren't allowed in the card number", but error handling in Accept.js is an area for future improvement. Heck, advancing our js to strip out spaces before sending the number would be a good area for future improvement.

 

So, if you send the card number without spaces, does everything work correctly? If so, problem solved. You may just want to put something in to strip spaces out of your card number like:

 

cardData.cardNumber = document.getElementById("CARDNUMBER").value.split(" ").join("");

View solution in original post

Aaron
All Star
13 REPLIES 13

Hi @felixschl,

 

For future reference, we have a response code lookup tool at http://developer.authorize.net/api/reference/responseCodes.html. That wouldn't help you much in this case, though, because neither code has much of a description in that tool (yet).

 

In a nutshell, a dispatchData call to Accept.js will end up calling AcceptCore.js, which well do a request to our API to get a token. If an error is returned by our API, AcceptCore.js will map that to an Accept.js specific error and return it so that your response handler can deal with it.

 

In your case, you have a log of the requests that AcceptCore.js is making. I don't think the first request means anything because it's just an OPTIONS request. But, the second request is AcceptCore actually calling the securePaymentContainerRequest call in our API to get a token. It gets a E00117 error back, which is not something that its error handling has set up to map to a specific Accept.js message, so it just passes it back (in my testing, the response handler still gets fired, though, so that part's a mystery).

 

The text passed back with the error is the real key: 

"OTS Service Error 'Field validation error.'"

 

The token service had trouble validating a field. In this case, it's the card number, because we don't allow spaces in the card number. Of course, it would be helpful if we returned an error that said something like "spaces aren't allowed in the card number", but error handling in Accept.js is an area for future improvement. Heck, advancing our js to strip out spaces before sending the number would be a good area for future improvement.

 

So, if you send the card number without spaces, does everything work correctly? If so, problem solved. You may just want to put something in to strip spaces out of your card number like:

 

cardData.cardNumber = document.getElementById("CARDNUMBER").value.split(" ").join("");
Aaron
All Star

Thank you for that detailed and honest response. The suggested fix does indeed work! I had not noticed the spaces because I was using a JS library to render the card details entry form (card.js). In this context the error message was actually quite revealing, but what threw me off was that the error code had a different shape from the other error codes (I had a look at the minifed Accept JS / Core sources), so I figured something else must've thrown it off, perhaps my self signed cert or something. Anyway, maybe the catch all error message should be clear about what it is and what it means in the context of Accept JS.

Actually, the callback still does not seem to fire, or only does so sporadically, both on error or success.

 

EDIT: Here's the successful request / response, but callback not fired:

 

> HTTP/1.1 200 OK
> Cache-Control: private
> Content-Type: application/json; charset=utf-8
> Server: Microsoft-IIS/7.5
> Access-Control-Allow-Origin: *
> Access-Control-Allow-Methods: PUT,OPTIONS,POST,GET
> Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method,SOAPAction
> X-Powered-By: ASP.NET
> Content-Length: 379
> Date: Wed, 09 Aug 2017 10:12:59 GMT
> Connection: keep-alive
{"securePaymentContainerRequest":{"merchantAuthentication":{"name":"...","clientKey":"..."},"data":{"type":"TOKEN","id":"...","token":{"cardNumber":"4007000000027","expirationDate":"122033","cardCode":"123"}}}}
< POST /xml/v1/request.api HTTP/1.1
< Host: apitest.authorize.net
< Connection: keep-alive
< Content-Length: 310
< Origin: https://localhost:8000
< User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
< Content-Type: application/json; charset=UTF-8
< Accept: */*
< Referer: https://localhost:8000/donate/
< Accept-Encoding: gzip, deflate, br
< Accept-Language: en-US,en;q=0.8
{"opaqueData":{"dataDescriptor":"COMMON.ACCEPT.INAPP.PAYMENT","dataValue":"..."},"messages":{"resultCode":"Ok","message":[{"code":"I00001","text":"Successful."}]}}

The callback does seem to fire every now and then, but I have not found a pattern to it yet.

 

This is how I call `Accept.dispatchData`:

 

Accept.dispatchData({...}, function responseHandler(response) {
  console.log('response', response);
});

 

EDIT 2: I wonder, is there a non minified version of the Accept library to take a look at? It would be great to follow your code to see what's going on here

Hi @felixschl,

 

Can you move the responseHandler function out of the dispatchData call and see if that improves things at all? It shouldn't, but since I don't know what else is going on with your script, I'm sort of grasping at straws here.

I've put the debugger on the job to see what's happening. I think you will find this interesting:

 

    c = "undefined" != typeof XDomainRequest ? new XDomainRequest : new XMLHttpRequest,
1)  c.open("post", d, !0),
    "undefined" == typeof XDomainRequest && c.setRequestHeader("Content-Type", "application/json; charset=utf-8"),
    c.onload = function() {
2)      setTimeout(function() {
3)          n(c, b /* "b" is my responseHandler */),
            2e3
        })
    }
    ;

Breakpoint (1) always triggers, but (2) never, and subsequently (3) never. But in the network tab I can see the request coming through fine.

 

But beyond all that, the far bigger question on my mind, what is up with the artificial 2 second timeout?

 

EDIT: Another observation. The readyState on "c" changes properly from "1" (OPENED) to "4" (DONE) via the "onreadystatechanged" handler. The question now is why does "onload" not fire...

 

EDIT: And another observation. If I reload the page without a cache (cmd+shift+r in chrome), the first submission does work. or at least the callback gets fired but I am getting the dreaded "E_WC_14"

By the way, is there anything stopping you guys from open sourcing the Accept.JS codebase?

 

EDIT: So, I think changing the Accept.JS code to simply using ".onreadystatechange" would fix this

Hi @felixschl,

 

Can you either post your code or give me any URL I see your code and try to duplicate in my browser?

I won't be able to provide a complete runnable solution, but here's the gist of it:

 

        $submit.on('click', function(event) {
          event.preventDefault();
          var request = {
            cardData: {
              cardNumber: $cardNumberInput.val().split(' ').join(''),
              month: $cardExpiryInput.val().split('/')[0].trim(),
              year: '20'+$cardExpiryInput.val().split('/')[1].trim(),
              cardCode: $cardCvcInput.val()
            },
            authData: {
              clientKey: "{{ authnet_client_key }}",
              apiLoginID: "{{ authnet_api_login_id }}"
            }
          };

          Accept.dispatchData(
            request,
            responseHandler
          );

          function responseHandler(response) {
            console.log('response', response);
          }
        });

I can see that the request completes fine (sometimes erroneous, but most of the time fine). But the callback is not fired because XMLHttpRequest does not fire it's onload handler. It's onreadystatechange handler fires fine and reports "4" (DONE).

Well, I have no clue why onload does not fire.

 

I found these references, but the search reults on google are very scarce. You know it's bad when you have to go to page 2 of the search results.

 

 

I hope it's just related to testing locally. I have followed the steps here: https://certsimple.com/blog/localhost-ssl-fix and configured my server to use the produced certificate and key. But still no luck.

 

Anyway, here is a super hacky work around that does work!

 

Object.defineProperty(
  XMLHttpRequest.prototype, 
  'onload', { set: function(v) {
    this.onreadystatechange = function(x) {
      if (this.readyState == 4) {
        v();
      }
    }
  }}
);

I hope this will be addressed in a future version of Accept.JS