Hi there,
wondering if you can help me understand why Accept.js is getting triggered two times, when I'm only (intentionally) calling it once.This is a screengrab of Firefox's "Network" debugger tab, where it shows both calls. It's the "OPTIONS" method one that seems to be the troublemaker:
https://www.dropbox.com/s/nqh1xcpcz9u13xk/Screenshot%202018-03-02%2014.46.46.png?dl=0
Here's the button that triggers the call:
<button name="sendRequest" type="button" id="processNowBtn" value="Record Payment" onClick="request_payment('666'); return false;">Record Payment</button>
And here's the function(s) that the above button triggers:
function request_payment(myThirdPartyID) { var myveryowntransactiontype = tmpCheckHistorical.Xttype.value; var active_form = document.BIGPAYMENTFORM; with (active_form) { wipeout_unused_form_data(); if (parseFloat(trxnAmt.value) <= 0.00) { $("#messageBoard").text('Please specify a valid amount, greater than 0.00.'); return; } if (Xttype.value == 'E' || Xttype.value == 'X') { if (orderPymtRecID.value == "" || orderPymtRecID.value == 0) { $("#messageBoard").text('Missing dependency value for this request.'); return; } } // The recording of cash or check payments is handled differently, so simply submit the form // right away and let the other process handle those if (thisPaymentTypeIs.value == 'cash' || thisPaymentTypeIs.value == 'check') { letsdo.value = "sendPayment"; submit(); } else { var allow_closed_order_payments = 'Y'; var tmpOrderDescription = 'Order: N' + orderID + ', Company: <?php echo $WOW['company']; ?>'; var form_data = $("#BIGPAYMENTFORM").serialize(); // "D" signifies that this is a request to "Capture" funds that have already // been "Authorized". This means we have a different set of data that needs // co be culled and passed. Note that the orderID and orderDescription parameters // are not needed for the Auth.net API call (it would perform the same with or // without them), but are still being passed, because they ARE needed in // down-stream subprocesses that create the payment record within PW if (myveryowntransactiontype == 'D') { // Prepare some data var tmpOrigTrxnID = document.getElementById("orgID").value; var tmpTrxnAmt = document.getElementById("trxnAmt").value; var tmp_sprID = document.getElementById("orgID2").value; capture_priorauth_funds_thru_gateway(tmpOrigTrxnID, tmpTrxnAmt, orderID, tmpOrderDescription, tmp_sprID, true, true); // If not a "Capture", then we are recording a NEW payment record in the // payment processor transaction system. The main differences between the two // are that this one will need a bit more data, but will NOT need a (prior) // transaction ID } else { var clientKey = '<?php echo trim($WOW['extraSpecialPublicKey']); ?>'; var tmpPmtStorageRecord = document.getElementById("pmtStorageRecord").value; var tmpTrxnAmount = document.getElementById("trxnAmt").value; var tmpTrxnTypes = document.getElementsByName('Xttype'); var tmpTrxnType; for(var i = 0; i < tmpTrxnTypes.length; i++){ if(tmpTrxnTypes[i].checked){ tmpTrxnType = tmpTrxnTypes[i].value; } } var tmpMpwRequest = true; // Here we are expecting either 1 element to the data, or 3 elements. Anything // else is an indication that something went south (for Auth.net anyway) // One element means new payment data, so gather from the HTML form var forker = tmpPmtStorageRecord.split("|"); if (forker.length == 1) { var tmp_sprID = ''; var tmpCcAcct = document.getElementById("cc__ACCT").value; var tmpCcExpM = document.getElementById("cc__expM").value; var tmpCcExpY = document.getElementById("cc__expY").value; var tmpCcCvv = document.getElementById("cc__CVV2").value; // Three elements means stored payment data, so don't bother gathering (but // still good to prep data for a normalized function call, so default it all // to empty strings) } else if (forker.length == 3) { var tmp_sprID = document.getElementById("orgID2").value; var tmpCcAcct = ''; var tmpCcExpM = ''; var tmpCcExpY = ''; var tmpCcCvv = ''; } else { $("#messageBoard").text('Payment data and/or configuration error. Please report this exact error to Customer Support.'); $("#messageBoard").delay(6400).slideUp(); return false; } record_payment_to_gateway(clientKey, myThirdPartyID, tmp_sprID, tmpPmtStorageRecord, orderID, tmpOrderDescription, tmpTrxnAmount, tmpTrxnType, tmpCcAcct, tmpCcExpM, tmpCcExpY, tmpCcCvv, tmpMpwRequest, true, true); } } } } function record_payment_to_gateway(authnetClientKey, myThirdPartyID, pymtStoragePointerRecID, pymtStorageRec, orderID, orderDescription, trxnAmount, trxnType, ccAcct, ccExpM, ccExpY, ccCvv, mpwRequest, reloadPage, reloadParent) { if (pymtStorageRec == 'hi') { var pymtRequestType = 'OneX'; } else if (pymtStorageRec == 'there') { var pymtRequestType = 'Stored'; } else { console.log('TRACKING THE ERROR: 34'); return false; } // Set some defaults if (!reloadPage) { reloadPage = false; } if (!reloadParent) { reloadParent = false; } var secureData = {}; authData = {}; cardData = {}; if (pymtRequestType == "OneX") { if (ccAcct == '' || ccExpM == '' || ccExpY == '' || ccCvv == '') { console.log('TRACKING THE ERROR: 35'); return false; } cardData.cardNumber = ccAcct; cardData.month = ccExpM; cardData.year = ccExpY; cardData.cardCode = ccCvv; secureData.cardData = cardData; authData.clientKey = authnetClientKey; authData.apiLoginID = myThirdPartyID; secureData.authData = authData; // Pass the card number, expiration date, and CVV to Accept.js for submission to Authorize.net. // Note: Attempting to avoide possible callback conflicts, I've added the acronym-ize name of // the parent function, for each of the "*_response)handler" calls Accept.dispatchData(secureData, rptg_response_handler); } else if (pymtRequestType == "Stored") { var cloudResponse; create_anet_transaction_for_order_from_saved_profile(pymtRequestType, orderID, orderDescription, trxnAmount, trxnType, pymtStoragePointerRecID, aCustProID, aCustPmtProID, mpwRequest, function (callbackData) { cloudResponse = callbackData; if (cloudResponse.success) { console.log('TRACKING THE SUCCESS: 01'); console.log('Transaction successfully and securely made.<br />Transaction ID: ' + cloudResponse.success.transactionResponse.transId); $("#messageBoard").text('Transaction successfully and securely made.<br />Transaction ID: ' + cloudResponse.success.transactionResponse.transId); if (reloadPage) { $("#messageBoard").delay(6400).slideUp(location.reload()); } else { $("#messageBoard").delay(6400).slideUp(); } if (reloadParent) { refreshParent(); } } else if (cloudResponse.error) { console.log('TRACKING THE ERROR: 01'); console.log(cloudResponse.error); } } ); } else { console.log('Error determining the nature of the charge. Please report this exact error to Customer Support.'); return false; } // Process the response from Authorize.Net to retrieve the two elements of the payment nonce. If // the data looks correct, record the OpaqueData to the console and call the data storage // function. function rptg_response_handler(response) { console.log(response.messages.resultCode); if (response.messages.resultCode === 'Error') { for (var i = 0; i < response.messages.message.length; i++) { console.log('TRACKING THE ERROR: 02'); console.log(response.messages.message[i].text); } } else { console.log('TRACKING THE SUCCESS: 02'); use_opaque_payment_data(pymtRequestType, orderID, orderDescription, trxnAmount, trxnType, response.opaqueData, aCustProID, aCustPmtProID, mpwRequest, reloadPage, reloadParent) } return false; } function use_opaque_payment_data(pymtRequestType, orderID, orderDescription, trxnAmount, trxnType, responseData, aCustProID, aCustPmtProID, mpwRequest, reloadPage, reloadParent) { var cloudResponse; create_anet_transaction_for_order(pymtRequestType, orderID, orderDescription, trxnAmount, trxnType, aCustProID, aCustPmtProID, mpwRequest, responseData.dataValue, function (callbackData) { cloudResponse = callbackData; } ); // These variables are for sub-string checks on the result (JS didn't like me using the // returned object, nor the literal string in the "indexOf" command, thus the variables) var tmpResult = String(cloudResponse.success); var tmpErrorCheck = 'ERROR'; // Successful transaction request the the API if (cloudResponse.success && tmpResult.indexOf(tmpErrorCheck) == -1) { console.log('TRACKING THE SUCCESS: 03'); if (reloadPage) { $("#messageBoard").delay(6400).slideUp(location.reload()); } else { $("#messageBoard").delay(6400).slideUp(); } if (reloadParent) { refreshParent().delay(6400); } // This indicates that thte API call was a suggess, but that the request was not granted } else if (tmpResult.indexOf(tmpErrorCheck) != -1) { $("#messageBoard").text(cloudResponse.success); console.log('TRACKING THE ERROR: 04'); // This suggests a problem with the actual API call } else if (cloudResponse.error) { $("#messageBoard").text(cloudResponse.error); console.log('TRACKING THE ERROR: 05'); } return false; } }
TIA for any insight!
โ03-02-2018 01:59 PM
Hi ,
OPTIONS call is due to the Cross Origin Resource Sharing(CORS). You are calling resource on authorize.net domain from the domain you have hosted your application on, which is different than authorize.net. This is where CORS comes into play.
"The Cross-Origin Resource Sharing standard works by adding new HTTP headers that allow servers to describe the set of origins that are permitted to read that information using a web browser. The specification mandates that browsers "preflight" the request, soliciting supported methods from the server with an HTTP OPTIONS request method, and then, upon "approval" from the server, sending the actual request with the actual HTTP request method."
As you can see, first an OPTIONS call is made and then the actual HTTP request is made. This is the reason you see two calls being made.
Hope this helps!
https://en.wikipedia.org/wiki/Cross-origin_resource_sharing#Preflight_example
Thanks,
Naman
โ03-04-2018 02:29 AM
Ok, but then why am I getting a fail response to it, but a success on the actual call? And why is the OPTION call getting returned last (and reported to the user) as an "Accept.js. encryption Failed" message?
โ03-05-2018 07:36 AM
Hi,
In the screenshot you shared both the calls have 200 OK response.
Can you please share details about the request in which you are getting error?
Thanks,
Naman
โ03-05-2018 10:50 AM
Absolutely! Here you go...
OPTIONS Request (This is the error "request"):
* Headers: https://www.dropbox.com/s/7l43rkcixgggpk5/Screenshot%202018-03-05%2013.39.54.png?dl=0
* Params: https://www.dropbox.com/s/1qh1ul5ogdxygn9/Screenshot%202018-03-05%2013.40.43.png?dl=0
* Response: https://www.dropbox.com/s/b0loyiiyhobi12s/Screenshot%202018-03-05%2013.36.21.png?dl=0
POST Request (This is the good request):
* Headers: https://www.dropbox.com/s/yv061t64g6xyb9v/Screenshot%202018-03-05%2013.41.50.png?dl=0
* Params: https://www.dropbox.com/s/jib3kk64yvig2gf/Screenshot%202018-03-05%2013.42.30.png?dl=0
* Response: https://www.dropbox.com/s/96eavb64ewfa84h/Screenshot%202018-03-05%2013.37.14.png?dl=0
โ03-05-2018 12:47 PM - edited โ03-05-2018 12:48 PM
So, no ideas here from anyone?
โ03-09-2018 08:05 AM
I had this problem and added this code to the top of the makePayment function
this.submitted=false; this.makePayment = function() { if ( this.submitted == 'true') { console.log('called twice'); } else { this.submitted='true'; ... ... normal processing code here ... }
โ03-09-2018 12:02 PM
I get the concept of what you are doing there, but my guess is that my call is different than yours. I'm not doing this as an onSubmit (form) action. I think that may change the way to implement.
Also, if this does work - and it looks like it may indeed - it is still a hack for something that shouldn't be happening in the first place. I just don't see why my call (to Accept.js) is happening twice! It has to be that either (a) somewhere there's a loose callback that I can't find, or (b) that Accept.js has an issue with it's response structure (or timing). If the former, then I'm stumped, cuz I can't find anything that would cause the 2nd call. If the latter, then that should be something addressed by the Accept.js development team.
What's frustrating is that this started happening out of the blue! No changes made, but now the response is *consistently* throwing hte "encryption" error response.
Any additional thoughts and/or advice would be greatly appreciated!
โ03-13-2018 02:44 PM
Hi @jima
Have you seen our Accept sample app on Github for a reference implementation of Accept.js
https://github.com/AuthorizeNet/accept-sample-app/blob/master/acceptJSCaller.js
Hope it helps !!!
โ03-13-2018 04:45 PM
โ03-13-2018 11:54 PM