cancel
Showing results for 
Search instead for 
Did you mean: 

Accept.dispatchData responseHandler called twice

Hello,

 

I'm trying to integrate Accept.js into my Django form but the responseHandler I'm passing to dispatchData gets called twice. The first time it's called, the response received has a resultCode of "Ok" but the second time, it has one of "Error". The error message contains code "E_WC_14" and text "Accept.js encryption failed.".

 

I'm wondering why it's getting called twice and why the second time it fails.

 

Here is my JS:

function sendPaymentDataToAuthNet(apiLoginID, clientKey) {
  event.preventDefault();
  var secureData = {},
      authData = {},
      cardData = {},
      expDate;

  cardData.cardNumber = document.getElementById('id_card_num').value;
  cardData.cardCode = document.getElementById('id_card_code').value;
  expDate = parseExpirationDate(document.getElementById('id_exp_date').value);
  cardData.month = expDate[0];
  cardData.year = expDate[1];
  secureData.cardData = cardData;

  authData.apiLoginID = apiLoginID;
  authData.clientKey = clientKey;
  secureData.authData = authData;
  Accept.dispatchData(secureData, 'responseHandler');
  return false;
}

function parseExpirationDate(expDate) {
  var expDateList;

  if (!expDate.includes('/')) {
    if (expDate.length == 3) {
      expDate = '0' + expDate;
    }
    expDate = expDate.substring(0,2) + '/' + expDate.substring(2);
  }
  expDateList = expDate.split('/');

  if (expDateList[1].length == 4) {
    expDateList[1] = expDateList[1].substring(2);
  }

  return expDateList;
}

function responseHandler(response) {
  if (response.messages.resultCode === 'Error') {
    for (var i = 0; i < response.messages.message.length; i++) {
      console.log(response.messages.message[i].code + ':' + response.messages.message[i].text);
    }
  } else {
    useOpaqueData(response.opaqueData);
  }
}

function useOpaqueData(responseData) {
  document.getElementById('id_opaque_data').value = responseData;
  jQuery('#payment').paymentForm.submit();
}

Here is the form tag that's calling the JS:

<form id="payment" name="payment" action="." onsubmit="sendPaymentDataToAuthNet('{{ api_login }}', '{{ client_key }}')" method="post" autocomplete="off">

And I am using the Sandbox Accept.js:

<script type="text/javascript" src="https://jstest.authorize.net/v1/Accept.js" charset="utf-8"></script>

Help appreciated,

Emily

echien
Member
2 REPLIES 2

Hi Emily,

 

In your last function, you're doing a submit action on the form again:

function useOpaqueData(responseData) {
  document.getElementById('id_opaque_data').value = responseData;
  jQuery('#payment').paymentForm.submit();
}

 

The form is set up to do a dispatchData call on submit, so that's why it's being called twice. The second time it fails because accept.js is designed to only return one nonce per script load.

 

One way to get around this double call would be to have your useOpaqueData function submit the form again. Instead, you'll have to code the function to get all the form elements and hand them off to something on your server that processes the transaction with a direct server to server connection to our API. For example, if you had a PHP script on your server to do the actual transaction submission (named paymentprocessor.php), your useOpaqueData function could use AJAX to call that script, then pass it the payment nonce and all of the other form information like this:

function useOpaqueData(responseData) {

    $.ajax({
           url: "paymentprocessor.php",
           data: {amount: document.getElementById('AMOUNT').value, dataDesc: responseData.dataDescriptor, dataValue: responseData.dataValue},
           method: 'POST',
           timeout: 5000
           
        }).done(function(data){
                   
                   console.log('Success');
                   
        }).fail(function(){
                           
                    console.log('Error');
                           
        }).always(function(textStatus){
                                     
                    console.log(textStatus);
                    messageFunc(textStatus);
                                     
        })
}

Then write another function to handle the response back from the script and display to the user.

Aaron
All Star

Hi Aaron,

 

Thanks for the reply! I moved the call to sendPaymentDataToAuthNet to an onclick on my submit button and am still using the jQuery submit function.

 

Emily