Just when I though I was home free ...
Test mode is working fine. Switching to production mode, I:
1. generated all new keys for my client, and put those into the application
2. Switched to the production version of the js
4. Made sure "live" is checked in the client admin
4. Double checked all my keys ...
However, when submitting a payment in production, the nonce dataValue is being generated, the dataDescriptor is correct, but the transaction itself generates "Transaction Failed Error Code : E00001". Looking that up, not much help "... an unexpected system error".
Switching my keys back to the test ID, and switching the js version back to sandbox ... works again.
Just to make sure I've got the js correct:
Sandbox: https://js.authorize.net/v3/AcceptUI.js
Production: https://jstest.authorize.net/v3/AcceptUI.js
And I've double checked and triple checked all the key values ...
If I purposely put in something that I know will fail like a mangled zip code, my "Your Transaction Failed" script triggers, so THAT is making it through processing on the authorize.net side of things.
Entering in card information that I know to be good however, generates the E00001 error.
I'm not even sure where to start looking for this, as the error code isn't helping me much ...
Suggestions?
06-26-2019 03:21 PM
One more quick thing - if I purposely mangle the data-clientKey value, I'll get a "invalid authentication values" message in the console.
If I put in the correct data-clientKey value, nothing is returned in the console - I just get the "Transaction Failed Error Code : E00001" returned by the app itself.
Still searching for clues. No luck yet ...
06-26-2019 04:22 PM
One more note - in the OLD payment system that's still using the MD5 hash that I'm trying to replace, the new key numbers work.
Authorize.net disabled my old keys WAY before 24 hours were up, panic mode kicked in, I replaced the old keys with the new and poof ... transactions started working again.
Meanwhile, back in my new accept.js version app, sandbox still works great, production ... nope.
I'm stuck.
06-26-2019 05:36 PM
I've kinda run out of ideas. I've triple checked everything.
New keys for production version WORK in an older version of the payment system, so the keys I'm using are good. I'm referencing the correct accept.js versions for sandbox and production.
I've checked that I've got my response and receipt URLs defined in the client admin for the production version. Exact same addresses as the sandbox, so those should work as well.
Code below works fine when pointing to sandbox versions of everything.
Not so much production ...
The relevant parts of my payment page:
<form id="paymentForm" method="POST" action="https://mysite.com/account/order_receipt.php" > <input type="hidden" name="dataValue" id="dataValue" /> <input type="hidden" name="dataDescriptor" id="dataDescriptor" /> <input type="hidden" name="enrid" value="<?php echo $tE['id']; ?>"> <button type="button" class="AcceptUI btn-success btn-lg" data-billingAddressOptions='{"show":true, "required":false}' data-apiLoginID="****DQvr7k" data-clientKey=" ** production key here ** " data-acceptUIFormBtnTxt="Submit" data-acceptUIFormHeaderTxt="Card Information" data-responseHandler="responseHandler">Pay </button> </form> <script type="text/javascript"> function responseHandler(response) { if (response.messages.resultCode === "Error") { var i = 0; while (i < response.messages.message.length) { console.log( response.messages.message[i].code + ": " + response.messages.message[i].text ); i = i + 1; } } else { paymentFormUpdate(response.opaqueData); } } function paymentFormUpdate(opaqueData) { document.getElementById("dataDescriptor").value = opaqueData.dataDescriptor; document.getElementById("dataValue").value = opaqueData.dataValue; document.getElementById("paymentForm").submit(); } </script>
Here's the relevant parts of my receipt page. Test display code included. Hopefully commented well enough so that you can tell what's going on:
<?php echo '<p>Debug mode on. Errors listed below:<br> '; error_reporting( E_ALL ); ini_set( 'display_errors', '1' ); echo '<hr></p>'; require 'anet_php_sdk/autoload.php'; require_once 'SampleCodeConstants.php'; // contains: const MERCHANT_LOGIN_ID = "****DQvr7k"; const MERCHANT_TRANSACTION_KEY = "****75EGraAR93x7"; use net\ authorize\ api\ contract\ v1 as AnetAPI; use net\ authorize\ api\ controller as AnetController; include( 'qry/config.php' ); // CODE HERE GETS A RECORD FROM THE DATABASE FOR SOME NEEDED VALUES AND POPULATES A VARIABLE FOR THE NONCE VALUE $theNONCE = $dataValue; // BLOCK BELOW PURELY FOR TESTING TO SEE IF VALUES ARE POPULATED<br> // ALL VALUE ARE BEING CORRECTLY RETURNED FOR THE RECORD echo 'handling fee '.$handlingFEE.'<br>'; echo 'pamount '.$pamount.'<br>'; echo 'pfirstName '.$pfirstName.'<br>'; echo 'plastName '.$plastName.'<br>'; echo 'theNONCE '.$theNONCE.'<br>'; echo 'addr '.$paddr.'<br>'; echo 'city '.$pcity.'<br>'; echo 'state '.$pstate.'<br>'; echo 'postal '.$ppostal.'<br>'; echo 'countrh '.$pcountry.'<br>'; echo 'email '.$pemail.'<br>'; // OK, EVERYTHING IS CORRECT TO CREATE THE TRANSACTION function createAnAcceptPaymentTransaction( $amount ) { // VARIABLES WON'T WORK UNLESS DEFINED AS GLOBAL. THANKS Renaissance ...<br> global $pfirstName, $plastName, $enrID, $theNONCE, $pamount, $paddr, $pcity, $pstate, $ppostal, $pcountry, $pemail, $transCODE; /* Create a merchantAuthenticationType object with authentication details retrieved from the constants file */ $merchantAuthentication = new AnetAPI\ MerchantAuthenticationType( $pamount ); $merchantAuthentication->setName( \SampleCodeConstants::MERCHANT_LOGIN_ID ); $merchantAuthentication->setTransactionKey( \SampleCodeConstants::MERCHANT_TRANSACTION_KEY ); // Set the transaction's refId $refId = 'ref' . time(); // Create the payment object for a payment nonce $opaqueData = new AnetAPI\ OpaqueDataType(); $opaqueData->setDataDescriptor( "COMMON.ACCEPT.INAPP.PAYMENT" ); $opaqueData->setDataValue( "$theNONCE" ); // Add the payment data to a paymentType object $paymentOne = new AnetAPI\ PaymentType(); $paymentOne->setOpaqueData( $opaqueData ); // Create order information $order = new AnetAPI\ OrderType(); $order->setInvoiceNumber( "$enrID" ); $order->setDescription( "Enrollment Payment for HMT$enrID" ); // Set the customer's Bill To address prim_email, prim_fname, prim_lname $customerAddress = new AnetAPI\ CustomerAddressType(); $customerAddress->setFirstName( "$pfirstName" ); $customerAddress->setLastName( "$plastName" ); $customerAddress->setCompany( "" ); $customerAddress->setAddress( "$paddr" ); $customerAddress->setCity( "$pcity" ); $customerAddress->setState( "$pstate" ); $customerAddress->setZip( "$ppostal" ); $customerAddress->setCountry( "$pcountry" ); // Set the customer's identifying information $customerData = new AnetAPI\ CustomerDataType(); $customerData->setType( "individual" ); $customerData->setId( "" ); $customerData->setEmail( "$pemail" ); // Add values for transaction settings $duplicateWindowSetting = new AnetAPI\ SettingType(); $duplicateWindowSetting->setSettingName( "duplicateWindow" ); $duplicateWindowSetting->setSettingValue( "60" ); // Create a TransactionRequestType object and add the previous objects to it $transactionRequestType = new AnetAPI\ TransactionRequestType(); $transactionRequestType->setTransactionType( "authCaptureTransaction" ); $transactionRequestType->setAmount( $amount ); $transactionRequestType->setOrder( $order ); $transactionRequestType->setPayment( $paymentOne ); $transactionRequestType->setBillTo( $customerAddress ); $transactionRequestType->setCustomer( $customerData ); $transactionRequestType->addToTransactionSettings( $duplicateWindowSetting ); // Assemble the complete transaction request $request = new AnetAPI\ CreateTransactionRequest(); $request->setMerchantAuthentication( $merchantAuthentication ); $request->setRefId( $refId ); $request->setTransactionRequest( $transactionRequestType ); // Create the controller and get the response $controller = new AnetController\ CreateTransactionController( $request ); $response = $controller->executeWithApiResponse( \net\ authorize\ api\ constants\ ANetEnvironment::SANDBOX ); if ( $response != null ) { // Check to see if the API request was successfully received and acted upon if ( $response->getMessages()->getResultCode() == "Ok" ) { // Since the API request was successful, look for a transaction response and parse it to display the results of authorizing the card $tresponse = $response->getTransactionResponse(); if ( $tresponse != null && $tresponse->getMessages() != null ) { echo " Successfully created transaction with Transaction ID: " . $tresponse->getTransId() . "\n"; echo " Transaction Response Code: " . $tresponse->getResponseCode() . "\n"; $transCODE = $tresponse->getResponseCode(); echo " Message Code: " . $tresponse->getMessages()[0]->getCode() . "\n"; echo " Auth Code: " . $tresponse->getAuthCode() . "\n"; echo " Description: " . $tresponse->getMessages()[0]->getDescription() . "\n"; $transCODE = $tresponse->getResponseCode(); $authCODE = $tresponse->getTransId(); } else { echo "Transaction Failed \n"; if ( $tresponse->getErrors() != null ) { echo " Error Code : " . $tresponse->getErrors()[0]->getErrorCode() . "\n"; echo " Error Message : " . $tresponse->getErrors()[0]->getErrorText() . "\n"; } } // Or, print errors if the API request wasn't successful } else { echo "Transaction Failed \n"; $tresponse = $response->getTransactionResponse(); if ( $tresponse != null && $tresponse->getErrors() != null ) { echo " Error Code : " . $tresponse->getErrors()[0]->getErrorCode() . "\n"; echo " Error Message : " . $tresponse->getErrors()[0]->getErrorText() . "\n"; } else { echo " Error Code : " . $response->getMessages()->getMessage()[0]->getCode() . "\n"; echo " Error Message : " . $response->getMessages()->getMessage()[0]->getText() . "\n"; } } // THIS EMAILS A BUNCH OF FOLKS, OR DISPLAYS AN ERROR PAGE. WORKS FINE IN THE SANDBOX. NOT FINAL VERSION OF THESE YET if ( $transCODE == 1 ) { include( 'qry/_inc_receipt_body.php' ); } else { include( 'failed.php' ); } } else { //echo "No response returned \n"; } return $response; } if ( !defined( 'DONT_RUN_SAMPLES' ) ) { createAnAcceptPaymentTransaction( "$pamount" ); }
When run - the nonce value is displayed for testing purposes - so I know it's there
$dataValue = eyJjb2RlIjoiNTBfMl8wNjAwMDUyQ0I0RjQ1QkVFNzhCN0I5NTM1OENCNkQ0RDJEQTVBMDRGNjM2RTEwNDNBNjQ2N0ZCQjNCNzZFRTkyNDIyNDZENDEwRTVGMzY2NEFFOEVDNTlBMEFCQzc1MTM2MzlDOUI2IiwidG9rZW4iOiI5NTYxNjA0NTcwMjMwODgxMTA0ODA1IiwidiI6IjEuMSJ9
$dataDescriptor = COMMON.ACCEPT.INAPP.PAYMENT
But, it fails when in productioin mode:
Transaction Failed Error Code : E00001 Error Message : An error occurred during processing. Please try again.
06-26-2019 08:51 PM
06-26-2019 09:28 PM
Jezz, how did I miss that. Thanks ...
Now I'm getting: Transaction Failed Error Code : E00007 Error Message : User authentication failed due to invalid authentication values.
At least I've got something to work with now though. But, the keys DO work in the older version of the app. Go figure.
I think I'll give it a rest for the evening, create all new keys from scratch again in the morning, and pick back up from there.
I'll keep you posted. Thank you so much for your assistance.
06-26-2019 09:55 PM
Hello @LGMizzell
If your successfully creating the nonce using the API Login and Client Key, but then getting an E00007 when submitting the transaction, it suggests the Transaction Key you're using in production are not correct.
Richard
06-27-2019 08:07 AM - edited 06-27-2019 08:08 AM
The thing is - the SAME key numbers are working in an older version of the app that's still using the MD5 Hash ...
But, I'm going to generate all new keys in just a bit and see what happens from there.
Thanks
06-27-2019 09:50 AM
06-27-2019 10:20 AM
06-27-2019 10:26 AM