Hello my fellow Code Monkeys!
Recently I was tasked with building web services/API for my companies brand new eCommerce iPad app which was meant to be an iPad friendly interface to our web site. Features include browsing our inventory, seeing order history, and placing orders. This also meant incorporating the API for Authorize.net.
I was very happy with the Auth.net SDK for PHP. We already had a module for our shopping cart (X-Cart) that does AIM processing for us, but it is encoded and thus could not be reused. No big deal because of the excellent SDK that Authorize.net provides.
However, I did run into a snag along the way. It seemed that certain characters in input fields were causing errors and making it so that it never got to the point of submitting the information to the API. After some trial and error, I figured out that it was a period in the address that was causing the problem. It took a lot of digging and putting in some debug loggers all around the code to figure out where the program was dieing at. The particular spot it was dieing was in the function _setPostString() around line 361 of lib/AuthorizeNetAIM.php. I went back, and just did a str_replace on the appropriate fields to get rid of periods and problem solved, no more issues reported. Fast forward about a month and we're launching and doing our final Beta testing and this problem starts popping up again, only this time it's hyphens (-) in the phone number.
Now, I'm a mostly self-taught programmer and I don't pretend to know everything so I discussed it with my iPad developer. We looked a bit closer at the code and logged what $this->_post_string ended up being and going through the urlencoded string that was being generated for the post fields. He poked around and brought up that RFC3986 lists hyphens (and periods for that matter) as unreserved characters. So, there shouldn't be a problem. Except that when I went to the PHP Manual, I noticed another function with urlencode... and that was rawurlencode which was specifically meant to encode using RFC3986.
This is what _setPostString() in lib/AuthorizeNetAIM.php looked like before...
protected function _setPostString() { $this->_x_post_fields['login'] = $this->_api_login; $this->_x_post_fields['tran_key'] = $this->_transaction_key; $this->_post_string = ""; foreach ($this->_x_post_fields as $key => $value) { $this->_post_string .= "x_$key=" . urlencode($value) . "&"; } // Add line items foreach ($this->_additional_line_items as $key => $value) { $this->_post_string .= "x_line_item=" . urlencode($value) . "&"; } // Add custom fields foreach ($this->_custom_fields as $key => $value) { $this->_post_string .= "$key=" . urlencode($value) . "&"; } $this->_post_string = rtrim($this->_post_string, "& "); }
and this is what it looks like after...
protected function _setPostString() { $this->_x_post_fields['login'] = $this->_api_login; $this->_x_post_fields['tran_key'] = $this->_transaction_key; $this->_post_string = ""; foreach ($this->_x_post_fields as $key => $value) { $this->_post_string .= "x_$key=" . rawurlencode($value) . "&"; } // Add line items foreach ($this->_additional_line_items as $key => $value) { $this->_post_string .= "x_line_item=" . rawurlencode($value) . "&"; } // Add custom fields foreach ($this->_custom_fields as $key => $value) { $this->_post_string .= "$key=" . rawurlencode($value) . "&"; } $this->_post_string = rtrim($this->_post_string, "& "); }
From my limited testing after making this change, it appears to be working fine and the information is coming through correctly when I look at the transaction in Authorize.net.
Now, my question... does anyone see any unintended side effects from doing this? Am I breaking something else by doing this? If I'm not, is there a place for me to communicate directly with the correct people with Authorize.net about or submitting a proposed change for future iterations of the SDK?
Thanks for your time! It's been frustrating, but educational doing this project and I've learned a lot along the way.
-George
04-23-2013 02:19 PM
Hi George,
Using rawurlencode instead of urlencode shouldn't break anything for you. However, it also shouldn't fix anything either. From my understanding, the only difference between the urlencode and rawurlencode is how spaces are treated. Specifically, urlencode converts spaces to + symbols, rawurlencode converts them to the escape character format of %20. Our system will readily accept either of these formats.
Additionally, I just ran a quick test and confirmed that neither of these methods escapes periods or hyphens. So while I'm glad that the SDK is working for you, I can't see how the changes that you made below would have affected the communication at all.
05-10-2013 01:53 PM