PayPal Pro doesn't seem to work when the total price is $200 but it works with other amounts

TheOutlier
Contributor
Contributor

I'm using PayPal Pro on OpenCart 2.3.0.2.  For some strange reason, when the cart total (the total amount to be passed to PayPal) is exactly $200, then it doesn't get past the page asking for credit card details (it'll wait a few minutes, then give an "Internal Error" popup).  Most other amounts work fine.  I tested with a $300 total and it was fine.  When I tested with a $100 total, it worked most of the time but every now and then it gave the same "Internal Error" popup.  The simplest solution is not to make final prices equal to $100 or $200.  I'm currently changing prices to $99 or $199 instead.  But I would still like to know what the cause of this is, if it's OpenCart related or PayPal related, or if it can happen again with a different value than $200. 

 

I'm tending to think it's PayPal related because a few weeks ago I was able to do a test checkout with a $200 total.  I haven't changed any OpenCart files related to PayPal and this appears to have started recently.  By the way, there's no problem with any amount with PayPal Standard.  It's the $200 total with PayPal Pro (and sometimes $100) that is the issue.  Does anyone have any idea what could be causing this?

Login to Me Too
13 REPLIES 13

MTS_Ciaran
Moderator
Moderator

Are you seeing this on live or sandbox, and is there anyway you can send over API responses? Or PM me the PayPal account email address of the seller account. 

Login to Me Too

angelleye
Advisor
Advisor
I'm assuming you're in the sandbox..?? It's had a lot of issues lately, unfortunately. One thing you might want to check is that you're always passing 2 decimals even if they're zeros.
Angell EYE - www.angelleye.com
PayPal Partner and Certified Developer - Kudos are Greatly Appreciated!
Login to Me Too

TheOutlier
Contributor
Contributor

Yes, everything I mentioned above was done in the sandbox.  I just tried it in the Live setting and the $200 product worked!  So that tells me that there's an issue with the PayPal sandbox.  Regarding the 2 decimal places, I do see 2 decimal places in the shopping cart when I check out.  Also, $300.00 works and $100.00 works (most of the time). 

 

Note, a $200 test product worked in the sandbox on June 10, 2017.  I did a test transaction on that date and see it in my order history.  So something happened between then and now to have caused this.  I hope PayPal developers read these forums and take input from them.

Login to Me Too

angelleye
Advisor
Advisor
Sounds like it's just a sandbox issue then, but I'd still double check your actual API request for the decimals. Just because it displays 2 decimals on your cart page during checkout doesn't mean the API request is using 2 decimals. It really shouldn't matter, but in the past I've seen PayPal act funny when whole numbers were passed without decimals.
Angell EYE - www.angelleye.com
PayPal Partner and Certified Developer - Kudos are Greatly Appreciated!
Login to Me Too

TheOutlier
Contributor
Contributor

Ok, here's some more information that might be helpful.  In the sandbox, when I tested with $300, it worked 100% of the time.  When I tested with $100, it worked maybe 95% of the time (for some reason it takes longer when $100 is the total amount).  So if the cause was decimal places, I would have thought that those values would have issues too but they didn't (for the most part). 

Login to Me Too

angelleye
Advisor
Advisor
The quickest way to eliminate the possibility is to look at the API request and verify how it's getting sent.

The sandbox can be funny. I think you're just running into chance with some of this, and maybe a little bit of sandbox quirkiness.

Saying that it works 100% of the time with $300...how many times did you try it? The sandbox just acts up in general and you could be just running into coincidence that it feels like it never fails with 300 but does with others.

That said, I know that sometimes if the same value is sent to PayPal's sandbox a bunch of times it can be screwy. For example, many of the test credit card numbers they document don't work anymore because they've been used so much in the system. The same sort of thing could be happening with round numbers, especially 100.00 because that's probably a common amount people use.

Maybe try switching to amounts like 99.99 and see if you notice any difference. Again, though, I feel like you're probably just running into the normal Sandbox inconsistencies.
Angell EYE - www.angelleye.com
PayPal Partner and Certified Developer - Kudos are Greatly Appreciated!
Login to Me Too

TheOutlier
Contributor
Contributor

There might be other dollar amounts that act the same way but $200 (and $100 and $300) are the ones I tested the most frequently.  The $200 value failed 100% of the time.  I switched prices to $99.95 or $199.95 and those ones are working fine in the sandbox.

 

I've used PayPal Pro for a long time but I've never had to fiddle with it so I'm relatively new at this.  Can you walk me through how I can check the API request and verify how it's getting sent?  

Login to Me Too

angelleye
Advisor
Advisor

Somewhere in your code you must be generating an NVP or XML request that gets sent to PayPal via HTTP request.  We would need to get a look at the raw NVP or XML value that you're sending.

Angell EYE - www.angelleye.com
PayPal Partner and Certified Developer - Kudos are Greatly Appreciated!
Login to Me Too

TheOutlier
Contributor
Contributor

I tried posting the entire code but it looks like it didn't get posted.  So here's just some of it:

	public function send() {
		if (!$this->config->get('pp_pro_transaction')) {
			$payment_type = 'Authorization';
		} else {
			$payment_type = 'Sale';
		}

		$this->load->model('checkout/order');

		$order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);

		$request  = 'METHOD=DoDirectPayment';
		$request .= '&VERSION=51.0';
		$request .= '&USER=' . urlencode($this->config->get('pp_pro_username'));
		$request .= '&PWD=' . urlencode($this->config->get('pp_pro_password'));
		$request .= '&SIGNATURE=' . urlencode($this->config->get('pp_pro_signature'));
		$request .= '&CUSTREF=' . (int)$order_info['order_id'];
		$request .= '&PAYMENTACTION=' . $payment_type;
		$request .= '&AMT=' . $this->currency->format($order_info['total'], $order_info['currency_code'], false, false);
		$request .= '&CREDITCARDTYPE=' . $this->request->post['cc_type'];
		$request .= '&ACCT=' . urlencode(str_replace(' ', '', $this->request->post['cc_number']));
		$request .= '&CARDSTART=' . urlencode($this->request->post['cc_start_date_month'] . $this->request->post['cc_start_date_year']);
		$request .= '&EXPDATE=' . urlencode($this->request->post['cc_expire_date_month'] . $this->request->post['cc_expire_date_year']);
		$request .= '&CVV2=' . urlencode($this->request->post['cc_cvv2']);

		if ($this->request->post['cc_type'] == 'SWITCH' || $this->request->post['cc_type'] == 'SOLO') {
			$request .= '&ISSUENUMBER=' . urlencode($this->request->post['cc_issue']);
		}

		$request .= '&FIRSTNAME=' . urlencode($order_info['payment_firstname']);
		$request .= '&LASTNAME=' . urlencode($order_info['payment_lastname']);
		$request .= '&EMAIL=' . urlencode($order_info['email']);
		$request .= '&PHONENUM=' . urlencode($order_info['telephone']);
		$request .= '&IPADDRESS=' . urlencode($this->request->server['REMOTE_ADDR']);
		$request .= '&STREET=' . urlencode($order_info['payment_address_1']);
		$request .= '&CITY=' . urlencode($order_info['payment_city']);
		$request .= '&STATE=' . urlencode(($order_info['payment_iso_code_2'] != 'US') ? $order_info['payment_zone'] : $order_info['payment_zone_code']);
		$request .= '&ZIP=' . urlencode($order_info['payment_postcode']);
		$request .= '&COUNTRYCODE=' . urlencode($order_info['payment_iso_code_2']);
		$request .= '&CURRENCYCODE=' . urlencode($order_info['currency_code']);
		$request .= '&BUTTONSOURCE=' . urlencode('OpenCart_2.0_WPP');

		if ($this->cart->hasShipping()) {
			$request .= '&SHIPTONAME=' . urlencode($order_info['shipping_firstname'] . ' ' . $order_info['shipping_lastname']);
			$request .= '&SHIPTOSTREET=' . urlencode($order_info['shipping_address_1']);
			$request .= '&SHIPTOCITY=' . urlencode($order_info['shipping_city']);
			$request .= '&SHIPTOSTATE=' . urlencode(($order_info['shipping_iso_code_2'] != 'US') ? $order_info['shipping_zone'] : $order_info['shipping_zone_code']);
			$request .= '&SHIPTOCOUNTRYCODE=' . urlencode($order_info['shipping_iso_code_2']);
			$request .= '&SHIPTOZIP=' . urlencode($order_info['shipping_postcode']);
		} else {
			$request .= '&SHIPTONAME=' . urlencode($order_info['payment_firstname'] . ' ' . $order_info['payment_lastname']);
			$request .= '&SHIPTOSTREET=' . urlencode($order_info['payment_address_1']);
			$request .= '&SHIPTOCITY=' . urlencode($order_info['payment_city']);
			$request .= '&SHIPTOSTATE=' . urlencode(($order_info['payment_iso_code_2'] != 'US') ? $order_info['payment_zone'] : $order_info['payment_zone_code']);
			$request .= '&SHIPTOCOUNTRYCODE=' . urlencode($order_info['payment_iso_code_2']);
			$request .= '&SHIPTOZIP=' . urlencode($order_info['payment_postcode']);
		}

		if (!$this->config->get('pp_pro_test')) {
			$curl = curl_init('https://api-3t.paypal.com/nvp');
		} else {
			$curl = curl_init('https://api-3t.sandbox.paypal.com/nvp');
		}

		curl_setopt($curl, CURLOPT_PORT, 443);
		curl_setopt($curl, CURLOPT_HEADER, 0);
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($curl, CURLOPT_FORBID_REUSE, 1);
		curl_setopt($curl, CURLOPT_FRESH_CONNECT, 1);
		curl_setopt($curl, CURLOPT_POST, 1);
		curl_setopt($curl, CURLOPT_POSTFIELDS, $request);

		$response = curl_exec($curl);

		curl_close($curl);

Let me know if you want to see the rest of it.  Please keep in mind this code worked two weeks ago when $200 test payments were working fine.  It also works now for other values in the sandbox and as far as I know it works fine in the Live environment.

 

Login to Me Too

Haven't Found your Answer?

It happens. Hit the "Login to Ask the community" button to create a question for the PayPal community.