Hello! Beginner Web Dev here trying to integrate Authroize.net payment system.
I am trying to setup and test Accept Hosted on my site using an iframe/lightbox by following this page. I am able to get the payment form to show up in the iframe and transactions are going through just fine once I click the "Pay" button as I can see it when I log into the sandbox.authorize.net. The issue is I can't receieve the Transaction Response from my site. I need to basically be able to tell from my site if the user clicked on "Pay" and the transaction was Auth/Captured so that I can email my digital products to the user OR if they clicked "Cancel" in which case I don't send them the product.
I am getting these error messages from the console:
'The loading of “https://mysite/store/partials/iFrameCommunicator.html#actionresizeWindow&width427&height925.8” in a frame is denied by “X-Frame-Options“ directive set to “SAMEORIGIN“.'
'Failed to execute ‘postMessage’ on ‘DOMWindow’: The target origin provided (‘mysite’) does not match the recipient window’s origin (‘null’)'
It looked like the issue was with CSP headers being SAMEORIGIN? So I tried to add a CSP Header in my .htcaccess like this but it still didn't work:
<IfModule mod_headers.c> Header set Content-Security-Policy "frame-ancestors 'self' *.mysite https://mysite/ https://test.authorize.net *.authorize.net;"; </IfModule>
I'm using craftCMS nitro and Docker on my local to test everything out.
My server side code for the payment token form:
$req = Craft::$app->getRequest();
$cost = $req->getBodyParam('price');
// define("AUTHORIZENET_LOG_FILE", "phplog");
/* Create a merchantAuthenticationType object with authentication details
retrieved from the constants file */
$merchantAuthentication = new AnetAPI\MerchantAuthenticationType();
$merchantAuthentication->setName(getenv("ANET_SANDBOX_ID"));
$merchantAuthentication->setTransactionKey(getenv("ANET_SANDBOX_KEY"));
// Set the transaction's refId
$refId = 'ref' . time();
//create a transaction
$transactionRequestType = new AnetAPI\TransactionRequestType();
$transactionRequestType->setTransactionType("authCaptureTransaction");
$transactionRequestType->setAmount($cost);
// Set Hosted Form options
$setting1 = new AnetAPI\SettingType();
$setting1->setSettingName("hostedPaymentButtonOptions");
$setting1->setSettingValue("{\"text\": \"Pay\"}");
$setting2 = new AnetAPI\SettingType();
$setting2->setSettingName("hostedPaymentOrderOptions");
$setting2->setSettingValue("{\"show\": false}");
$setting3 = new AnetAPI\SettingType();
$setting3->setSettingName("hostedPaymentReturnOptions");
$setting3->setSettingValue("{\"showReceipt\": false, \"urlText\": \"Return\", \"cancelUrl\": \"https://qpr.nitro/store/partials/checkout-pay.twig\", \"cancelUrlText\": \"Cancel\"}");
$setting4 = new AnetAPI\SettingType();
$setting4->setSettingName("hostedPaymentIFrameCommunicatorUrl");
$setting4->setSettingValue("{\"url\": \"https://qpr.nitro/store/partials/iFrameCommunicator.html\"}");
$setting5 = new AnetAPI\SettingType();
$setting5->setSettingName("hostedPaymentPaymentOptions");
$setting5->setSettingValue("{\"cardCodeRequired\": true, \"showCreditCard\": true, \"showBankAccount\": false}");
$setting6 = new AnetAPI\SettingType();
$setting6->setSettingName("hostedPaymentSecurityOptions");
$setting6->setSettingValue("{\"captcha\": true}");
$setting7 = new AnetAPI\SettingType();
$setting7->setSettingName("hostedPaymentShippingAddressOptions");
$setting7->setSettingValue("{\"show\": true, \"required\": true}");
$setting8 = new AnetAPI\SettingType();
$setting8->setSettingName("hostedPaymentCustomerOptions");
$setting8->setSettingValue("{\"showEmail\": true, \"requiredEmail\": true, \"addPaymentProfile\": false}");
// Build transaction request
$request = new AnetAPI\GetHostedPaymentPageRequest();
$request->setMerchantAuthentication($merchantAuthentication);
$request->setRefId($refId);
$request->setTransactionRequest($transactionRequestType);
$request->addToHostedPaymentSettings($setting1);
$request->addToHostedPaymentSettings($setting2);
$request->addToHostedPaymentSettings($setting3);
$request->addToHostedPaymentSettings($setting4);
$request->addToHostedPaymentSettings($setting5);
$request->addToHostedPaymentSettings($setting6);
$request->addToHostedPaymentSettings($setting7);
$request->addToHostedPaymentSettings($setting8);
//execute request
$controller = new AnetController\GetHostedPaymentPageController($request);
$response = $controller->executeWithApiResponse(\net\authorize\api\constants\ANetEnvironment::SANDBOX);
return $this->asJSON($response->getToken());Front End:
if (!window.AuthorizeNetPopup) window.AuthorizeNetPopup = {};
if (!AuthorizeNetPopup.options) AuthorizeNetPopup.options = {
onPopupClosed: null
};
AuthorizeNetPopup.openPopup = function () {
var popup = document.getElementById("divAuthorizeNetPopup");
var popupScreen = document.getElementById("divAuthorizeNetPopupScreen");
var ifrm = document.getElementById("iframeAuthorizeNet");
var form = document.forms["formAuthorizeNetPopup"];
let paypalCont = document.getElementById("paypalContainer");
let aNetUrl = "/actions/cls-lms/shop/shop-anet-token",
total = "{{ totalPrice }}"
csrfToken = "{{ csrfToken }}",
csrfParam = "{{ csrfParam }}",
shopApi = new craftApi();
let payload = { price: total }
paypalCont.style.display = "none";
form.action = "https://test.authorize.net/payment/payment";
ifrm.style.width = "442px";
ifrm.style.height = "578px";
shopApi.controllerAjaxRequest(aNetUrl, payload, csrfParam, csrfToken).
then(function(response){
$("#popupToken").val(response);
setTimeout(form.submit(), 2);
});
popup.style.display = "";
popupScreen.style.display = "";
centerPopup();
};
AuthorizeNetPopup.closePopup = function () {
document.getElementById("divAuthorizeNetPopupScreen").style.display = "none";
document.getElementById("divAuthorizeNetPopup").style.display = "none";
document.getElementById("iframeAuthorizeNet").src="empty.html";
document.getElementById("btnOpenAuthorizeNetPopup").disabled = false;
if (AuthorizeNetPopup.options.onPopupClosed) AuthorizeNetPopup.options.onPopupClosed();
};
AuthorizeNetPopup.openPopup = function () {
var popup = document.getElementById("divAuthorizeNetPopup");
var popupScreen = document.getElementById("divAuthorizeNetPopupScreen");
var ifrm = document.getElementById("iframeAuthorizeNet");
var form = document.forms["formAuthorizeNetPopup"];
let paypalCont = document.getElementById("paypalContainer");
let aNetUrl = "/actions/cls-lms/shop/shop-anet-token",
total = "{{ totalPrice }}"
csrfToken = "{{ csrfToken }}",
csrfParam = "{{ csrfParam }}",
shopApi = new craftApi();
let payload = { price: total }
paypalCont.style.display = "none";
form.action = "https://test.authorize.net/payment/payment";
ifrm.style.width = "442px";
ifrm.style.height = "578px";
shopApi.controllerAjaxRequest(aNetUrl, payload, csrfParam, csrfToken).
then(function(response){
$("#popupToken").val(response);
setTimeout(form.submit(), 2);
});
popup.style.display = "";
popupScreen.style.display = "";
centerPopup();
};
AuthorizeNetPopup.onReceiveCommunication = function (querystr) {
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;
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;
}
};
function centerPopup() {
var d = document.getElementById("divAuthorizeNetPopup");
d.style.left = "50%";
d.style.top = "50%";
var left = -Math.floor(d.clientWidth / 2);
var top = -Math.floor(d.clientHeight / 2);
d.style.marginLeft = left.toString() + "px";
d.style.marginTop = top.toString() + "px";
d.style.zIndex = "2";
if (d.offsetLeft < 16) {
d.style.left = "16px";
d.style.marginLeft = "0px";
}
if (d.offsetTop < 16) {
d.style.top = "16px";
d.style.marginTop = "0px";
}
}
function parseQueryString(str) {
var vars = [];
var arr = str.split('&');
var pair;
for (var i = 0; i < arr.length; i++) {
pair = arr[i].split('=');
vars.push(pair[0]);
vars[pair[0]] = unescape(pair[1]);
}
return vars;
}
12-30-2021 12:58 PM