Just started with Authorize.net SDK.
I am using hosted payment page in sandbox using IFrameCommunicato method. I implemented IFrameCommunicator mechanism to receive messages.
My main page gets resize events and cancel event. I am not getting transactResponse event on completed transaction.
Wondering whether transactResponse event is available in the sandbox environment? Am I missing something?
Appreciate your help.
โ09-03-2017 10:15 AM
Here is my code.
I see notification comming. But only resize and cancel; on successful payment my window gets resize but no transactResponse event
Main page. For simplicity, the page gets new token and embedd it into the form. Button click invokes the form
<?php
$token="";
$APILOGINID= 'XXXXXX';
$TRANSACTIONKEY= 'YYYYYYYY';
$AMT='20.00';
$EMAIL='testtesttest@gmail.com';
$CUSTOMERID=1;
$REFID=111;
$DESCRIPTION='This is order description';
$req=array(
'getHostedPaymentPageRequest' => array (
'merchantAuthentication' => array ( 'name' => $APILOGINID , 'transactionKey' => $TRANSACTIONKEY),
'refId' => $REFID,
'transactionRequest' => array (
'transactionType' => 'authCaptureTransaction',
'amount' => $AMT,
'order' => array( 'description' => $DESCRIPTION ),
'customer' => array( 'email' => $EMAIL),
),
'hostedPaymentSettings' => array (
'setting' => array (
array (
'settingName' => 'hostedPaymentPaymentOptions',
'settingValue' => '{"cardCodeRequired" : true}'
),
array (
'settingName' => 'hostedPaymentBillingAddressOptions',
'settingValue' => '{"show": true, "required":true}'
),
array (
'settingName' => 'hostedPaymentStyleOptions',
'settingValue' => '{"bgColor": "EE00EE"}'
),
array (
'settingName' => 'hostedPaymentButtonOptions',
'settingValue' => '{"text": "Pay Now"}'
),
array (
'settingName' => 'hostedPaymentSecurityOptions',
'settingValue' => '{"captcha": false}'
),
array (
'settingName' => 'hostedPaymentOrderOptions',
'settingValue' => '{"show": true, "merchantName" : "Smiling Dentist"}'
),
array (
'settingName' => 'hostedPaymentIFrameCommunicatorUrl',
'settingValue' => '{"url": "https://yapiapp.io/ph/ancallback.php"}'
),
array (
'settingName' => 'hostedPaymentReturnOptions',
'settingValue' => '{"url":"https://yapiapp.io/ph/ancontinue.php","urlText":"Continue","cancelUrl":"https://yapiapp.io/ph/ancanc..."}'
)
)
)
)
);
$request=json_encode($req);
try
{
$ch = curl_init('https://apitest.authorize.net/xml/v1/request.api');
curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0 YAPI/2');
curl_setopt($ch, CURLOPT_REFERER, 'https://yapiapp.io/ph/index.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Accept: application/json',
'Content-Type: application/json'));
curl_setopt($ch, CURLOPT_ENCODING, '');
curl_setopt($ch, CURLINFO_HEADER_OUT, true); // enable tracking
$response = curl_exec($ch);
$response=substr($response,3); //to get rid of funny characters
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$headerSent = curl_getinfo($ch, CURLINFO_HEADER_OUT );
$headerIn = curl_getinfo($ch, CURLINFO_HEADER_IN );
curl_close($ch);
$r=(array)json_decode($response,true);
$token=$r['token'];
$resultCode=$r['messages']['resultCode'];
$r["httpcode"]=$httpcode;
}
catch(Exception $e) {
echo "error " . print_r($e,1);
}
$stop='<!--';
$stop2='-->';
if($httpcode == 200 && $resultCode == 'Ok')
{
$stop='';
$stop2='';
}
?>
<html>
<header>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<style>
html, iframe{
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
</style>
<script type="text/javascript">
window.CommunicationHandler = {};
function parseQueryString(str) {
var vars = [];
var arr = str.split('&');
var pair;
for (var i = 0; i < arr.length; i++) {
pair = arr[i].split('=');
console.log(pair);
vars[pair[0]] = unescape(pair[1]);
}
console.log(vars);
return vars;
}
window.CommunicationHandler.onReceiveCommunication = function (argument) {
console.log(JSON.stringify(argument));
params = parseQueryString(argument.qstr)
parentFrame = argument.parent.split('/')[4];
console.log(params);
console.log(parentFrame);
console.log("action=" + params['action']);
switch(params['action']){
case "resizeWindow" :
if(parseInt(params['height'])<1000) params['height']=1000;
console.log("resize h=" + parseInt(params['height']));
$( "#iframe_holder" ).dialog({ height:parseInt(params['height'])});
break;
case "cancel" :
break;
case "transactResponse" :
var transResponse = JSON.parse(params['response']);
}
}
</script>
</header>
<body>
<div id="iframe_holder" class="center-block" style="width:90%;max-width: 1000px" >
<iframe id="load_payment" class="embed-responsive-item" name="load_payment" width="90%" height="1000px" frameborder="0" scrolling="yes" >
</iframe>
<form id="send_hptoken" name="send_hptoken" action="https://test.authorize.net/payment/payment" method="post" target="load_payment" >
<input type="hidden" name="token" value="<?php echo $token ?>" />
</form>
</div>
<script>
$("#iframe_holder iframe").hide();
function go(){
$('#load_payment').hidden=false;
var wWidth = $(window).width();
var dWidth = wWidth * 0.8;
var wHeight = $(window).height();
var dHeight = wHeight * 0.8;
$("#iframe_holder iframe").show();
$( "#iframe_holder" ).dialog({autoOpen : false, modal : true, show : "blind", hide : "blind", width:dWidth, height:dHeight, position: {my: 'bottom' }});
$( "#iframe_holder" ).dialog({title: "Pay now "});
document.send_hptoken.submit();
$( "#iframe_holder" ).dialog("open");
} ;
</script>
<?php echo $stop;?><button onclick="go();" style="height:50px;width:200px">Go</button><?php echo $stop2;?>
</body>
</html>
communication page is from github example
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>IFrame Communicator</title>
<!--
To securely communicate between our Accept Hosted form and your web page,
we need a communicator page which will be hosted on your site alongside
your checkout/payment page. You can provide the URL of the communicator
page in your token request, which will allow Authorize.Net to embed the
communicator page in the payment form, and send JavaScript messaging through
your communicator page to a listener script on your main page.
This page contains a JavaScript that listens for events from the payment
form and passes them to an event listener in the main page.
-->
<script type="text/javascript">
function callParentFunction(str) {
if (str && str.length > 0 && window.parent && window.parent.parent
&& window.parent.parent.CommunicationHandler && window.parent.parent.CommunicationHandler.onReceiveCommunication)
{
var referrer = document.referrer;
window.parent.parent.CommunicationHandler.onReceiveCommunication({qstr : str , parent : referrer});
}
}
function receiveMessage(event) {
if (event && event.data) {
callParentFunction(event.data);
}
}
if (window.addEventListener) {
window.addEventListener("message", receiveMessage, false);
} else if (window.attachEvent) {
window.attachEvent("onmessage", receiveMessage);
}
if (window.location.hash && window.location.hash.length > 1) {
callParentFunction(window.location.hash.substring(1));
}
</script>
</head>
<body>
</body>
</html>
โ09-03-2017 12:19 PM
You're checking for case "transactResponse" and assigning var transResponse = JSON.parse(params['response']); but not doing anything with the results.
<script> window.CommunicationHandler = {}; function parseQueryString(str) { var vars = []; var arr = str.split('&'); var pair; for (var i = 0; i < arr.length; i++) { pair = arr[i].split('='); vars[pair[0]] = unescape(pair[1]); } return vars; } window.CommunicationHandler.onReceiveCommunication = function (argument) { params = parseQueryString(argument.qstr) parentFrame = argument.parent.split('/')[4]; switch (params['action']) { case "transactResponse": var transResponse = JSON.parse(params['response']); console.log(transResponse); if (transResponse.transId > 0) { // Do something like $('#load_payment').hide(); $('#demo').html("Thank you. Your Transaction Id is: "+transResponse.transId); } } } </script>
โ09-03-2017 01:21 PM
I have console.log that shows all actions coming. No transactResponse though. Only resize and cancel
window.CommunicationHandler.onReceiveCommunication = function (argument) {
console.log(JSON.stringify(argument));
params = parseQueryString(argument.qstr)
parentFrame = argument.parent.split('/')[4];
console.log(params);
console.log(parentFrame);
console.log("action=" + params['action']);
console shows on form creation
{"qstr":"action=resizeWindow&width=729&height=1103","parent":"https://test.authorize.net/payment/payment"}
on transaction completed
{"qstr":"action=resizeWindow&width=729&height=971","parent":"https://test.authorize.net/payment/payment"}
when iclick continue button it loads url into the form and I am getting
{"qstr":"action=cancel","parent":"https://test.authorize.net/payment/payment"}
โ09-03-2017 04:47 PM
I discover that if I set showReceipt to false in "hostedPaymentReturnOptions'" the transactResponse notication finaly comes.
'settingName' => 'hostedPaymentReturnOptions',
'settingValue' => '{"showReceipt" : false, "url":"https://yapiapp.io/ph/ancontinue.php","urlText":"Continue","cancelUrl":"https://yapiapp.io/ph/ancanc..."}'
So i my code i can extract tranaction data and close the frame
case "transactResponse" :
var transResponse = JSON.parse(params['response']);
//extract data
var at=transResponse.accountType;
var an=transResponse.accountNumber;
var tid=transResponse.transId;
var auth=transResponse.authorization;
console.log("at=" + at + " an=" +an + " tid=" + tid + " auth=" +auth);
//close modal dialog
$( "#iframe_holder" ).dialog('close');
Though the url specified in transactResponse is not loaded in the frame.
According to the documentation
When the showReceipt parameter is true, our system will display a receipt page after the transaction, with a "Continue" button that points back to the URL provided in the urlparameter.
When showReceipt is false, a return URL must be provided in the url parameter. Otherwise the receipt page will be shown.
So what I found is that my page gets transactResponse action only if showReceipt if false and no url is loaded. Is this what I should expect or I am missing something still?
Appreciate your help.
โ09-03-2017 05:36 PM
โ09-03-2017 07:05 PM
Thank you for your help. It was not clear from documentation.
โ09-04-2017 10:56 PM
Hi @yapi,
The design basically provides for two scenarios:
There's nothing in the design of the system that would allow for any sort of hybrid between the two, like using our receipt page but then getting the transaction information directly.
Your concerns about documentation are well noted. I'll talk to the documentation team about ways to make that more clear in the documentation.
โ09-05-2017 09:44 AM
I am setting "showReceipt": false in hostedPaymentReturnOptions but I am not getting back transactResponse. The response I am getting back is just "resizeWindow"
Here is my code to generate the token. I am using the nugetpackages in MVC to acess authorize.net
public ActionResult GetAnAcceptPaymentPage(decimal amount) { string customerprofileid = "1927297243"; ApiOperationBase<ANetApiRequest, ANetApiResponse>.RunEnvironment = AuthorizeNet.Environment.SANDBOX; ApiOperationBase<ANetApiRequest, ANetApiResponse>.MerchantAuthentication = new merchantAuthenticationType() { name = ApiLoginID, ItemElementName = ItemChoiceType.transactionKey, Item = ApiTransactionKey, }; settingType[] settings = new settingType[10]; settings[0] = new settingType(); settings[0].settingName = settingNameEnum.hostedPaymentButtonOptions.ToString(); settings[0].settingValue = "{\"text\": \"Pay\"}"; settings[1] = new settingType(); settings[1].settingName = settingNameEnum.hostedPaymentOrderOptions.ToString(); settings[1].settingValue = "{\"show\": false}"; settings[2] = new settingType(); settings[2].settingName = settingNameEnum.hostedPaymentReturnOptions.ToString(); settings[2].settingValue = "{\"showReceipt\": false, \"url\": \"https://localhost:44398//AgentProfile/AgentProfile?tab_MyWallet\", \"cancelUrl\": \"https://localhost:44398//AgentProfile/AgentProfile?tab_MyWallet\", \"cancelUrlText\": \"Cancel\"}"; settings[3] = new settingType(); settings[3].settingName = settingNameEnum.hostedPaymentStyleOptions.ToString(); settings[3].settingValue = "{\"bgColor\": \"blue\"}"; settings[4] = new settingType(); settings[4].settingName = settingNameEnum.hostedPaymentPaymentOptions.ToString(); settings[4].settingValue = "{\"cardCodeRequired\": false, \"showCreditCard\": true, \"showBankAccount\": false}"; settings[5] = new settingType(); settings[5].settingName = settingNameEnum.hostedPaymentSecurityOptions.ToString(); settings[5].settingValue = "{\"captcha\": true}"; settings[6] = new settingType(); settings[6].settingName = settingNameEnum.hostedPaymentShippingAddressOptions.ToString(); settings[6].settingValue = "{\"show\": false, \"required\": false}"; settings[7] = new settingType(); settings[7].settingName = settingNameEnum.hostedPaymentBillingAddressOptions.ToString(); settings[7].settingValue = "{\"show\": false, \"required\": false}"; settings[8] = new settingType(); settings[8].settingName = settingNameEnum.hostedPaymentCustomerOptions.ToString(); settings[8].settingValue = "{\"showEmail\": false, \"requiredEmail\": false, \"addPaymentProfile\": true}"; settings[8] = new settingType(); settings[8].settingName = settingNameEnum.hostedPaymentIFrameCommunicatorUrl.ToString(); settings[8].settingValue = "{\"url\": \"https://localhost:44398//AgentProfile/IframeCommunicator\"}"; var transactionRequest = new transactionRequestType { transactionType = transactionTypeEnum.authCaptureTransaction.ToString(), // authorize capture only amount = amount, order = new orderType { invoiceNumber = "INV-123456", description = "TEST INVOICE" } }; var request = new getHostedPaymentPageRequest(); request.clientId = customerprofileid; request.transactionRequest = transactionRequest; request.hostedPaymentSettings = settings; var controller = new getHostedPaymentPageController(request); controller.Execute(); var response = controller.GetApiResponse(); if (response != null && response.messages.resultCode == messageTypeEnum.Ok) { } else if (response != null) { } return Json(response, "application/json", Encoding.UTF8, JsonRequestBehavior.AllowGet); }
JS Code:
$.ajax({ type: "POST", url: '/AgentProfile/GetAnAcceptPaymentPage?amount='+money+'', dataType: "json", success: function (response) { debugger; alert(JSON.stringify(response)); if (response.messages.resultCode == "Error") { alert(response.messages.message[0].text); } else { $("#inputtoken").val(response.token); console.log(response.token); alert(response.messages.message[0].text); AuthorizeNetPopup.openPopup(); } }, error: function (error) { alert(JSON.stringify(error)); alert("There is some technical issue in processing this transaction. Please try again later."); } }); AuthorizeNetPopup.openPopup = function () { var popup = document.getElementById("divAuthorizeNetPopup"); var popupScreen = document.getElementById("divAuthorizeNetPopupScreen"); var ifrm = document.getElementById("iframeAuthorizeNet"); var form = document.forms["formAuthorizeNetPopup"]; $("#popupToken").val($("#inputtoken").val()); form.action = "https://test.authorize.net/payment/payment"; ifrm.style.width = "700px"; ifrm.style.height = "578px"; var contentSecurityPolicy="https://localhost:44398.authorize.net"; ifrm.setAttribute("Content-Security-Policy:","frame-ancestors 'self' localhost" + contentSecurityPolicy); form.submit(); popup.style.display = ""; popupScreen.style.display = ""; centerPopup(); }; AuthorizeNetPopup.onReceiveCommunication = function (querystr) { console.log("onReceiveCommunication is called") var params = parseQueryString(querystr); switch (params["action"]) { case "successfulSave": AuthorizeNetPopup.closePopup(); break; case "cancel": AuthorizeNetPopup.closePopup(); break; case "transactResponse": var response = params["response"]; //document.getElementById("token").value = response; console.log(response); alert(response); AuthorizeNetPopup.closePopup(); break; case "resizeWindow": var w = parseInt(params["width"]); var h = parseInt(params["height"]); var ifrm = document.getElementById("iframeAuthorizeNet"); ifrm.style.width = w.toString() + "px"; ifrm.style.height = h.toString() + "px"; centerPopup(); break; } };
โ08-05-2020 09:14 AM
Can anyone help me out here?
โ08-06-2020 06:52 PM