cancel
Showing results forย 
Search instead forย 
Did you mean:ย 

Accept.js is getting triggered twice (2x)

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!

jima
Regular Contributor
16 REPLIES 16

@sudwebdesign77would you be willing to provide a little more context to your code patch there? If this is how I have to tackle it, I will (semi-unwillingly), but could use a little broader view of your implementation as a guide.

jima
Regular Contributor
Sure, what do you need?
Do you want me to share the whole class with you? It's evening here do I don't have the code with me at the moment.

Hi

 

I've pasted the PHP class into my snippet bin (link below) which generates the JS function class for each vendor.

 

You will see PHP variable substition in places like $this->funcName() which ensures that each vendor JS function class has a unique name (eg: AUTHJS_ABC123)

 

You will see the similar PHP vars with connection parameters.

 

Anything that refers to cartman.function-name is one of my app's libaray routines outside of Authorize functionality.

 

Let me know if you need any more details.

Chris

 

https://yii2.percipero.com/snippet/223

Thank you very much! I definitely appreciate it. Hopefully it helps with this issue. :)

jima
Regular Contributor

This is STILL an issue, even with the hack-patch that another contributor suggested. Can someone from the Authorize.net development team please address this? I don't think it's reasonable for each of us to try to suss out a hack-patch that only semi-works, for an issue that looks like it needs to be addressed on the Accept.js side. Please advise ASAP as this is a VERY active issue, with at least 13 independant reports of it in the forums alone.

jima
Regular Contributor

Experiencing a double trigger issue with Accept.js can be quite frustrating. Just like dealing with complicated paperwork for UAE embassy attestation, it requires a careful review and debugging process to identify the root cause and ensure that the problem is efficiently resolved.