Reputation: 3058
Going nuts here with Authorize.Net extremely POOR documentation and error reporting. I am trying to implement an Accept Hosted
page to process credit cards. I am able to generate the token but when I pass the token into the form (in the iFrame) I am getting an error MISSING OR INVALID TOKEN
The token is getting created without issue, but when trying to use it is when things go sideways.
And in the chrome inespector console I am getting two javascript errors returned:
ERROR TypeError: Cannot read property 'billTo' of null
ERROR TypeError: Cannot read property 'offsetHeight' of null
So, printing out my $request
json I am able to validate my json object that is being passed to create the token is correct:
{
"merchantAuthentication": {"name":"xxxxxxxx","transactionKey":"yyyyyyyyyyyy"},
"clientId":"sdk-php-2.0.0-ALPHA",
"refId":"ref1608564012",
"transactionRequest": {
"transactionType":"authCaptureTransaction",
"amount":"360.00",
"order": {"invoiceNumber":"11373-0","description":"2020-11-01 bill for All Regions\/All Sites"},
"customer":{"type":"business","id":"1002","email":"[email protected]"},
"billTo":{"firstName":"Preston","lastName":"Johnson","company":"Backyard Grill","address":"123 Main St","city":"Tampa","state":"FL","zip":"33611","country":"USA"},
"shipTo":{"firstName":"Preston","lastName":"Johnson","company":"Backyard Grill","address":"123 Main St","city":"Tampa","state":"FL","zip":"33611","country":"USA"}
},
"hostedPaymentSettings":
{"setting":[
{"settingName":"hostedPaymentReturnOptions","settingValue":"{ \"url\": \"https:\/\/portal.attendago.com\/adminInvoicePaid.html\", \"cancelUrl\": \"https:\/\/portal.attendago.com\/adminInvoicePay.html?invID=11373-0\", \"showReceipt\":true }"},
{"settingName":"hostedPaymentButtonOptions","settingValue":"{ \"text\": \"Submit Payment\" }"},
{"settingName":"hostedPaymentStyleOptions","settingValue":"{ \"bgColor\": \"#192a67\" }"},
{"settingName":"hostedPaymentPaymentOptions","settingValue":"{ \"cardCodeRequired\":true, \"showCreditCard\":true, \"showBankAccount\":true }"},
{"settingName":"hostedPaymentShippingAddressOptions","settingValue":"{ \"show\":false, \"required\":true }"},
{"settingName":"hostedPaymentBillingAddressOptions","settingValue":"{ \"show\":true, \"required\":true }"},
{"settingName":"hostedPaymentCustomerOptions","settingValue":"{ \"showEmail\":true, \"requiredEmail\":true, \"addPaymentProfile\":false }"},
{"settingName":"hostedPaymentOrderOptions","settingValue":"{ \"show\":false }"},
{"settingName":"hostedPaymentIFrameCommunicatorUrl","settingValue":"{ \"url\": \"https:\/\/portal.attendago.com\/adminInvoiceFrame.html\" }"}
]}
}
Here is my function to create the token:
function getCustomerToken($ss) {
$ii = $ss['invoiceData'] ;
if (isSet($ss['payMethods'])) {
$pp = $ss['payMethods'] ;
}
////////////////////////////////////////////////
/// global objects needed for all transactions
////////////////////////////////////////////////
// Create a merchantAuthenticationType, pulled from constants file
$merchantAuthentication = new AnetAPI\MerchantAuthenticationType();
$merchantAuthentication->setName(\AuthorizeConstants::sandboxID); // loginID / sandboxID
$merchantAuthentication->setTransactionKey(\AuthorizeConstants::sandboxKey); // loginKey / sandboxKey
// Set the transaction's refId
$refId = 'ref' . time();
// Set order information
$order = new AnetAPI\OrderType();
$order->setInvoiceNumber($ss['invoiceID']);
if (strpos($ii['invName'], "S") !== false) {
$invDesc = $ii['servMonth']. " bill for Site " .$ii['venue'] ;
} else if (strpos($ii['invName'], "R") !== false) {
$invDesc = $ii['servMonth']. " bill for Region " .$ii['venue'] ;
} else {
$invDesc = $ii['servMonth']. " bill for " .$ii['venue'] ;
}
$order->setDescription($invDesc);
// Set the customer's identifying information
$customerData = new AnetAPI\CustomerDataType();
$customerData->setType("business");
$customerData->setId($ii['cID']);
$customerData->setEmail($ii['cEmail']);
// Set the Bill To info for new payment type
$billTo = new AnetAPI\CustomerAddressType();
$billTo->setFirstName($ii['cFirstName']);
$billTo->setLastName($ii['cLastName']);
$billTo->setCompany($ii['cName']);
$billTo->setAddress($ii['cAddress']. " " .$ii['cAddress1']);
$billTo->setCity($ii['cCity']);
$billTo->setState($ii['cState']);
$billTo->setZip($ii['cZip']);
$billTo->setCountry("USA");
//$billTo->setFaxNumber('8005551212') ;
//$billTo->setPhoneNumber($ii['cPhone']);
// set shipping profile
$shippingProfiles[] = $billTo ;
//create a transaction
$transactionRequestType = new AnetAPI\TransactionRequestType();
$transactionRequestType->setTransactionType("authCaptureTransaction");
$transactionRequestType->setAmount($ss['balance']);
$transactionRequestType->setCustomer($customerData) ;
$transactionRequestType->setOrder($order) ;
if (isSet($ss['authMerchID'])) {
$profileType = new AnetAPI\CustomerProfilePaymentType();
$profileType->setCustomerProfileId($ss['authMerchID']) ;
$transactionRequestType->setProfile($profileType) ;
} else {
$transactionRequestType->setBillTo($billTo) ;
$transactionRequestType->setShipTo($billTo) ;
}
// Set Hosted Form options
$setting0 = new AnetAPI\SettingType();
$setting0->setSettingName("hostedPaymentReturnOptions");
$setting0->setSettingValue( "{ \"url\": \"https://portal.mysdomain.com/adminInvoicePaid.html\", \"cancelUrl\": \"https://portal.mydomain.com/adminInvoicePay.html?invID=" .$ss['invoiceID']. "\", \"showReceipt\":true }" );
$setting1 = new AnetAPI\SettingType();
$setting1->setSettingName("hostedPaymentButtonOptions");
$setting1->setSettingValue("{ \"text\": \"Submit Payment\" }");
$setting2 = new AnetAPI\SettingType();
$setting2->setSettingName("hostedPaymentStyleOptions");
$setting2->setSettingValue("{ \"bgColor\": \"#192a67\" }");
$setting3 = new AnetAPI\SettingType();
$setting3->setSettingName("hostedPaymentPaymentOptions");
$setting3->setSettingValue("{ \"cardCodeRequired\":true, \"showCreditCard\":true, \"showBankAccount\":true }");
$setting4 = new AnetAPI\SettingType();
$setting4->setSettingName("hostedPaymentShippingAddressOptions");
$setting4->setSettingValue("{ \"show\":false, \"required\":true }");
$setting5 = new AnetAPI\SettingType();
$setting5->setSettingName("hostedPaymentBillingAddressOptions");
$setting5->setSettingValue("{ \"show\":true, \"required\":true }");
$setting6 = new AnetAPI\SettingType();
$setting6->setSettingName("hostedPaymentCustomerOptions");
$setting6->setSettingValue("{ \"showEmail\":true, \"requiredEmail\":true, \"addPaymentProfile\":false }");
$setting7 = new AnetAPI\SettingType();
$setting7->setSettingName("hostedPaymentOrderOptions");
$setting7->setSettingValue("{ \"show\":false }");
$setting8 = new AnetAPI\SettingType();
$setting8->setSettingName("hostedPaymentIFrameCommunicatorUrl");
$setting8->setSettingValue("{ \"url\": \"https://portal.mydomain.com/adminInvoiceFrame.html\" }");
// Build transaction request
$request = new AnetAPI\GetHostedPaymentPageRequest();
$request->setMerchantAuthentication($merchantAuthentication);
$request->setRefId($refId);
$request->setTransactionRequest($transactionRequestType);
$request->addToHostedPaymentSettings($setting0);
$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);
$gToken=[] ;
if (($response != null) && ($response->getMessages()->getResultCode() == "Ok")) {
//echo $response->getToken()."\n";
$gToken["Error"] = 0 ;
$gToken["Token"] = $response->getToken() ;
} else {
//echo "ERROR : Failed to get hosted payment page token\n";
$errorMessages = $response->getMessages()->getMessage();
//echo "RESPONSE : " . $errorMessages[0]->getCode() . " " .$errorMessages[0]->getText() . "\n";
$gToken["Error"] = 1 ;
$gToken["errMsg"] = $errorMessages[0]->getCode() . ": " .$errorMessages[0]->getText() ;
}
return array($gToken,$request);
}
*** UPDATE***
Looking at the network console logs, there is a request going out to https://test.authorize.net/payment/payment
- but the key token
is empty, which would appear to be the reason for the error Missing or Invalid Token
. In my form, I can validate the TOKEN is there. But when I click the trigger popup iFrame
button, I can visually see the token
being deleted from the hidden form field.
Upvotes: 0
Views: 1750
Reputation: 3058
The code to open the popup iframe, copied verbatim from the Authorize.net code sample had this bit of code $("#popupToken").val($("#inputtoken").val());
- this is erasing/deleting the token value before it was being submitted to payment gateway - what the heck?! Why would their own example code do that? Commenting this out fixed it.
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()); // WTH authorize????
form.action = "https://test.authorize.net/payment/payment";
ifrm.style.width = "442px";
ifrm.style.height = "578px";
form.submit();
popup.style.display = "";
popupScreen.style.display = "";
centerPopup();
};
Upvotes: 1