paypal / ipn-code-samples

Other
562 stars 486 forks source link

Unable to verify IPN when using utf-8 characters in sandbox #90

Closed furai closed 7 years ago

furai commented 7 years ago

Environment: Sandbox Language: PHP Version 5.6.30-7+deb.sury.org~xenial+1

Apparently whenever I try to use in sandbox names with some special characters like "łęąë" the verification fails. I tried changing urlencode/decode to rawurlencode/decode. That didn't help. Later after investigating the sent back and forth post varaibles it seems that %u was unnecessarily encoded to %25u. It might be that I'm doing something completely wrong.

Can anyone help me here?

randstraw commented 7 years ago

I've seen good results in my IPN handling when I submit the raw request body for verification prior to decoding it. ?cmd=_notify-validate can be added to the IPN verification URL instead of adding to the request body itself.

randstraw commented 7 years ago

@furai did the above suggestion work for you?

furai commented 7 years ago

@pp-randy haven't got time yet to look at it. Will let you know but I think that should work.

overint commented 7 years ago

@pp-randy I'm going to have a look through the code again soon as I will be needing it for a project. Do you mean posting the php://input directly without any manipulation?

randstraw commented 7 years ago

That method should help with most of the one off encoding issues but I have not tested with php yet. I've had better success with language encoding and other decode issues sending the IPN data directly back.

furai commented 7 years ago

So, today I finally found time to test it - just sent back raw data that I got from paypal. If I use any utf8 characters in ipn simulator and just send the raw data back then it fails. If I fill out the test ipn form without utf8 chareacters then all gets successfully verified.

php://input: payment_type=echeck&payment_date=Fri%20Jun%2009%202017%2015%3A13%3A22%20GMT%2B0200%20%28CEST%29&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=%u0141ukasz%u0119%E9%EBs&last_name=Smith&payer_email=test@test.com&payer_id=TESTBUYERID01&address_name=John%20Smith&address_country=United%20States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San%20Jose&address_street=123%20any%20street&business=seller@paypalsandbox.com&receiver_email=test@test.com&receiver_id=seller@paypalsandbox.com&residence_country=US&item_name=something&item_number=1000&quantity=1&shipping=3.04&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&txn_type=web_accept&txn_id=932222820&notify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31AVuIQuORgdXWD8FFs5wqjTVbOPNA

My prepended response: cmd=_notify-validate&payment_type=echeck&payment_date=Fri%20Jun%2009%202017%2015%3A13%3A22%20GMT%2B0200%20%28CEST%29&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=%u0141ukasz%u0119%E9%EBs&last_name=Smith&payer_email=test@test.com&payer_id=TESTBUYERID01&address_name=John%20Smith&address_country=United%20States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San%20Jose&address_street=123%20any%20street&business=seller@paypalsandbox.com&receiver_email=test@test.com&receiver_id=seller@paypalsandbox.com&residence_country=US&item_name=something&item_number=1000&quantity=1&shipping=3.04&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&txn_type=web_accept&txn_id=932222820&notify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31AVuIQuORgdXWD8FFs5wqjTVbOPNA

Code responsible for receiving and sending it back:

    $raw_post_data = file_get_contents('php://input');
    $raw_post_response = 'cmd=_notify-validate&' . $raw_post_data;
    $ch = curl_init($this->getPaypalUri());
    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $raw_post_response);
    curl_setopt($ch, CURLOPT_SSLVERSION, 6);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);

    // This is often required if the server is missing a global cert bundle, or is using an outdated one.
    if ($this->use_local_certs) {
      curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . "/cert/cacert.pem");
    }
    curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
    $res = curl_exec($ch);
    if ( ! ($res)) {
      $errno = curl_errno($ch);
      $errstr = curl_error($ch);
      curl_close($ch);
      throw new Exception("cURL error: [$errno] $errstr");
    }

    $info = curl_getinfo($ch);
    $http_code = $info['http_code'];
    if ($http_code != 200) {
      throw new Exception("PayPal responded with http code $http_code");
    }

    curl_close($ch);

It's just modified PHP IPN from Paypal.

As I said before - it goes through without utf8 characters but fails if any is used. No idea what's wrong.

jifyinc commented 7 years ago

@furai

The easiest solution is to sign in to your account on PayPal.com, select "Profile and Settings" > select"My selling tools" > select "PayPal button language encoding" at the bottom of the screen > select "More Options" then select UTF-8 here for both encoding on your website (if you use it for your website, and calls to PayPal) and UTF-8 for IPNs. PayPal will then expect UTF-8, and send UTF-8.

furai commented 7 years ago

I'm pretty sure I have that checked all the time. It was the first thing to do when I run into issues.

Also, the account I'm testing on is not business account. But to my understanding snadbox should work in utf8 mode.

xiaoleih41 commented 7 years ago

If you are not testing on a business account, I wonder if your account has the access to the IPN full function correctly. As it is not SDK issue, Please contact PayPal merchant technical support here and provide debugId for the engineer check the case for you.

furai commented 7 years ago

I'll appreciate if you leave this issue open as open question until I really resolve it.

I should be able to test on the business account. I'll have to check in few places if I have access to it.

xiaoleih41 commented 7 years ago

I am closing this issue due to inactivity.

MESWEB commented 6 years ago

Yes I got this same issue when I testing IPN with special characters. When we can expect update?

xiaoleih41 commented 6 years ago

Did you follow the instruction below and configured the setting? There's no outstanding issue with this part of IPN.

MESWEB commented 6 years ago

image Yes my settings is ok. My account is bussines.

xiaoleih41 commented 6 years ago

Are you using the SDK? if not, you may contact www.paypal-techsupport.com and submit a support ticket. The support team can help address the account specific issue for you.

MESWEB commented 6 years ago

Nope I'm using this sample code - php IPN

xiaoleih41 commented 6 years ago

Please file a ticket with the support team on this. They can look into your setting for you.