cancel
Showing results for 
Search instead for 
Did you mean: 

Not getting transactResponse event when using IFrameCommunicator method in sandbox

 

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.

yapi
Member
9 REPLIES 9

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>



yapi
Member

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>

 

 

Powered by NexWebSites.com -
Certified Authorize.net developers
NexusSoftware
Trusted Contributor

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"}

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.

 

Yes, that is correct, because when showReceipt is false, the transactResponse is sent via your Icommunicator URL instead of showing a receipt and you are able to handle the response yourself.
Powered by NexWebSites.com -
Certified Authorize.net developers
NexusSoftware
Trusted Contributor

Thank you for your help. It was not clear from documentation. 

Hi @yapi,

 

The design basically provides for two scenarios:

  1. We display a receipt and that receipt has a link back to your site
  2. We don't display a receipt, and you get enough transaction information to generate a receipt and proceed from there.

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.

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;
                    
                }
            };


           

Can anyone help me out here?