I'm trying to connect to the Authorize API to use hosted payments. I have downloaded the demo App and from there started integrating the basic connection code into my App.
However, i cannot get an active connection using my credentials in either the demo app or my own code. I have dumped out the response from the initial Curl request and it is FALSE.
I am developing on osx 10.10 using apache2.4, openssl 1.0.2h, TLS1.2, PHP7.0.12
I have used your "Try It" facility using my API credentials on: http://developer.authorize.net/api/reference/#payment-transactions-get-an-accept-payment-page
and get a result code "Ok"
As I saw on another post, I tried the command curl https://secure.authorize.net/gateway/transact.dll
and get an error message back.
I'm using the testing url: "https://apitest.authorize.net/xml/v1/request.api"
What am I missing?
my basic app code follows:-
<?php namespace common\models\PaymentProcessor; use yii\base\Component; class AuthorizeHosted extends Component { private $url = "https://apitest.authorize.net/xml/v1/request.api"; public function getFormToken() { $xmlStr = <<<XML <?xml version="1.0" encoding="utf-8"?> <getHostedPaymentPageRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd"> <merchantAuthentication></merchantAuthentication> <transactionRequest> <transactionType>authCaptureTransaction</transactionType> <amount>0.50</amount> <order> <invoiceNumber>INV-12345</invoiceNumber> <description>Product Description</description> </order> <lineItems> <lineItem> <itemId>1</itemId> <name>vase</name> <description>Cannes logo </description> <quantity>18</quantity> <unitPrice>45.00</unitPrice> </lineItem> </lineItems> <tax> <amount>4.26</amount> <name>level2 tax name</name> <description>level2 tax</description> </tax> <duty> <amount>8.55</amount> <name>duty name</name> <description>duty description</description> </duty> <shipping> <amount>4.26</amount> <name>level2 tax name</name> <description>level2 tax</description> </shipping> <poNumber>456654</poNumber> <customer> <id>99999456654</id> <email>my@email.com</email> </customer> <billTo> <firstName>Ellen</firstName> <lastName>Johnson</lastName> <company>Souveniropolis</company> <address>14 Main Street</address> <city>Pecan Springs</city> <state>TX</state> <zip>44628</zip> <country>USA</country> <phoneNumber>1231231234</phoneNumber> </billTo> <customerIP>192.168.1.1</customerIP> <userFields> <userField> <name>sessionID</name> <value>ABC123</value> </userField> </userFields> </transactionRequest> <hostedPaymentSettings> <setting> <settingName>hostedPaymentIFrameCommunicatorUrl</settingName> </setting> <setting> <settingName>hostedPaymentButtonOptions</settingName> <settingValue>{"text": "Pay"}</settingValue> </setting> <setting> <settingName>hostedPaymentReturnOptions</settingName> </setting> <setting> <settingName>hostedPaymentOrderOptions</settingName> <settingValue>{"show": false}</settingValue> </setting> <setting> <settingName>hostedPaymentPaymentOptions</settingName> <settingValue>{"cardCodeRequired": true}</settingValue> </setting> <setting> <settingName>hostedPaymentShippingAddressOptions</settingName> <settingValue>{"show": false, "required":true}</settingValue> </setting> <setting> <settingName>hostedPaymentBillingAddressOptions</settingName> <settingValue>{"show": true, "required":true}</settingValue> </setting> <setting> <settingName>hostedPaymentSecurityOptions</settingName> <settingValue>{"captcha": false}</settingValue> </setting> <setting> <settingName>hostedPaymentStyleOptions</settingName> <settingValue>{"bgColor": "green"}</settingValue> </setting> <setting> <settingName>hostedPaymentCustomerOptions</settingName> <settingValue>{"showEmail": true, "requiredEmail":true}</settingValue> </setting> </hostedPaymentSettings> </getHostedPaymentPageRequest> XML; $xml = simplexml_load_string($xmlStr,'SimpleXMLElement', LIBXML_NOWARNING); // $xml = new SimpleXMLElement($xmlStr); //SetEnv API_LOGIN_ID "62rmM3KT" //SetEnv TRANSACTION_KEY "" $xml->merchantAuthentication->addChild('name',"62rmM3KT"); $xml->merchantAuthentication->addChild('transactionKey',"my-key-here"); $commUrl = json_encode(array('url' => $this->thisPageURL()."iCommunicator.html" ),JSON_UNESCAPED_SLASHES); $xml->hostedPaymentSettings->setting[0]->addChild('settingValue',$commUrl); $retUrl = json_encode(array("showReceipt" => false ,'url' => $this->thisPageURL()."return.html","urlText"=>"Continue to site", "cancelUrl" => $this->thisPageURL()."return.html", "cancelUrlText" => "Cancel" ),JSON_UNESCAPED_SLASHES); $xml->hostedPaymentSettings->setting[2]->addChild('settingValue',$retUrl); var_dump( $xml ); $url = $this->url; try{ //setting the curl parameters. $ch = curl_init(); if (FALSE === $ch) throw new Exception('failed to initialize'); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/xml')); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml->asXML()); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 900); // The following two curl SSL options are to "false" for ease of development/debug purposes only. // Any code used in production should either remove these lines or set them to the appropriate // values to properly use secure connections for PCI-DSS compliance. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //for production, set value to true or 1 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //for production, set value to 2 curl_setopt($ch, CURLOPT_DNS_USE_GLOBAL_CACHE, false ); //curl_setopt($ch, CURLOPT_PROXY, 'userproxy.visa.com:80'); $content = curl_exec($ch); // for debugging return $content; $content = str_replace('xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd"', '', $content); $hostedPaymentResponse = new \SimpleXMLElement($content); if (FALSE === $content) throw new Exception(curl_error($ch), curl_errno($ch)); curl_close($ch); }catch(Exception $e) { trigger_error(sprintf('Curl failed with error #%d: %s', $e->getCode(), $e->getMessage()), E_USER_ERROR); } return $hostedPaymentResponse; } function thisPageURL() { $pageURL = 'http'; if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";} $pageURL .= "://"; if ($_SERVER["SERVER_PORT"] != "80") { $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"]; } else { $pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"]; } $pageLocation = str_replace('index.php', '', $pageURL); return $pageLocation; } } ?>
Solved! Go to Solution.
08-15-2017 07:15 AM
Testing a hosted payment form should definitely work locally, with the caveat that our server won't be able to load the URL you pass as the "hostedPaymentIFrameCommunicatorUrl", since that's on your local machine. So, you can't test any of the iframe communication, but you could at least load the form in your browser and work with it. But, it sounds like you weren't even getting that far, and you weren't even getting the token, right?
You said if you just do a curl request to us, you get an error. What error?
If you do something like
curl https://apitest.authorize.net/xml/v1/request.api
from the command line, with no other parameters, you should get an error from our end that looks like this:
{"messages":{"resultCode":"Error","message":[{"code":"E00003","text":"Root element is missing."}]}}
If you don't get that, you've got some sort of problem at the curl/openSSL/TLS level. If you do get that from the command line, you'd also want to do it with curl_exec in PHP to make sure that your PHP/Apache config is using the same curl/openSSL/TLS config as the command line.
If you get the expected response from PHP as well, but aren't getting a token, then we would move on to troubleshooting the PHP code.
08-16-2017 06:51 PM
It seems as though it won't run on my local machine. I don't know whether this is a setup error in Apache, SSL or TLS or whether it's becauase it is local.
Anyway, I uploaded it to my testing server and it works fine there.
It would be really nice to know whether it should work on my local machine as this will make development a lot quicker and easier.
Just as an aside, it seems really messy that the demo app uses getenv to get the login details and that these are dotted around in various files. Why not set a constant on app instantiation, whether hard coded (great for development) or from getenv or perhaps even from a CMS. But my server doesn't support putenv so I had to change the app in 2 or 3 places...
08-16-2017 03:30 AM
Testing a hosted payment form should definitely work locally, with the caveat that our server won't be able to load the URL you pass as the "hostedPaymentIFrameCommunicatorUrl", since that's on your local machine. So, you can't test any of the iframe communication, but you could at least load the form in your browser and work with it. But, it sounds like you weren't even getting that far, and you weren't even getting the token, right?
You said if you just do a curl request to us, you get an error. What error?
If you do something like
curl https://apitest.authorize.net/xml/v1/request.api
from the command line, with no other parameters, you should get an error from our end that looks like this:
{"messages":{"resultCode":"Error","message":[{"code":"E00003","text":"Root element is missing."}]}}
If you don't get that, you've got some sort of problem at the curl/openSSL/TLS level. If you do get that from the command line, you'd also want to do it with curl_exec in PHP to make sure that your PHP/Apache config is using the same curl/openSSL/TLS config as the command line.
If you get the expected response from PHP as well, but aren't getting a token, then we would move on to troubleshooting the PHP code.
08-16-2017 06:51 PM
Aaron, thanks for your reply.
Yes, I am getting a response from the curl command on the command line, as I mentioned above. And that was what was confuisng me.
But as you pointed out and dawned on me eventually, was that I'm not going to be able to test the iCommunicator on my local server, so I need to sync my dev environment with my testing environment to be able to run through testing on a visible web server.
I'm not going to follow through getting the test App running on my local machine as there won't be any benefit anyway.
Though, do you know if it's possible to use ngrok or similar service to forward the iCommunicator requests?
08-16-2017 11:51 PM
@sudwebdesign77 wrote:
Though, do you know if it's possible to use ngrok or similar service to forward the iCommunicator requests?
I've personally never seen it done, but it seems like something that should work, in theory.
08-22-2017 04:57 PM
Thanks for the reply.
It's all working on a remote machine now so I'll stick with that and rsync!
08-23-2017 12:01 AM