Запрос токена PayPal для отдыха: api.paypal.com Хорошо, api-m терпит неудачу

#paypal #paypal-sandbox #paypal-rest-sdk

Вопрос:

Добавление 2:Поведение Mozilla зависит от того, к какому хосту относится URL-адрес; Я добавил сценарий curl, показывающий это в конце вопроса.

Добавление: Это ушло примерно через 8 часов или около того и работало в течение нескольких дней. Но неделю спустя я повторно запускаю страницу, просто чтобы проверить, и она снова снова терпит неудачу: api.paypal работает, api-m.paypal не работает.

Я получаю разные результаты, запрашивая токен доступа к сайту в реальном времени от api-m.paypal.com и api.paypal.com. Если я обращусь с просьбой к api.paypal.com, это работает, и возвращается токен. Если я попрошу об этом у api-m.paypal.com, Я получаю запрещенную ошибку 403. Как это возможно? В целом и для запросов токенов документация, по-видимому, использует api и api-m взаимозаменяемо. В чем разница между ними и тем, какие вызовы следует направлять в api vs api-m? Когда я запускаю весь свой магазин в песочнице, все переходит в api-m и работает нормально. В тестовой программе, которая просто повторно запрашивает токены, последовательность через api, api-m, api.песочницу и api-m.песочницу — только api-m терпит неудачу, остальные 3 случая хороши. Однажды я видел обсуждение api vs api-m, но не могу найти его снова; почти уверен, что в нем об этом не упоминалось!

 lt;?php  include("../_private/ppinfo.php");  header('Content-type: text/plain'); $sandbox = 0; echo "sandbox $sandbox rv " . GetNewPPToken($sandbox) . "n"; $sandbox = 1; echo "sandbox $sandbox rv " . GetNewPPToken($sandbox) . "n"; $sandbox = 2; echo "sandbox $sandbox rv " . GetNewPPToken($sandbox) . "n"; $sandbox = -1; echo "sandbox $sandbox rv " . GetNewPPToken($sandbox) . "n"; $sandbox = 0; echo "sandbox $sandbox rv " . GetNewPPToken($sandbox) . "n"; $sandbox = -1; echo "sandbox $sandbox rv " . GetNewPPToken($sandbox) . "n"; $sandbox = 1; echo "sandbox $sandbox rv " . GetNewPPToken($sandbox) . "n"; $sandbox = 0; echo "sandbox $sandbox rv " . GetNewPPToken($sandbox) . "n"; $sandbox = 2; echo "sandbox $sandbox rv " . GetNewPPToken($sandbox) . "n";  // Get a paypal REST token to use for the rest of our transactions. // See https://developer.paypal.com/docs/business/get-started/  function GetNewPPToken($sandbox)  {  global $G, $ppinfo;   $headers = array(  "Accept: application/json",  "Accept-Language: en_US",  "Content-Type: application/x-www-form-urlencoded"  );  if ($sandbox gt; 1)  {  $clid = $ppinfo['sb_acct'];  $secret = $ppinfo['sb_secr'];  $url = "https://api.sandbox.paypal.com/v1/oauth2/token";  }  else if ($sandbox gt; 0)  {  $clid = $ppinfo['sb_acct'];  $secret = $ppinfo['sb_secr'];  $url = "https://api-m.sandbox.paypal.com/v1/oauth2/token";  }  else if ($sandbox lt; 0)  {  $clid = $ppinfo['acct'];  $secret = $ppinfo['secr'];  $url = "https://api.paypal.com/v1/oauth2/token";  }  else  {  $clid = $ppinfo['acct'];  $secret = $ppinfo['secr'];  $url = "https://api-m.paypal.com/v1/oauth2/token";  };   $cvt = "grant_type=client_credentials";  $curl = newPPcurl($url, $cvt, $headers);  curl_setopt($curl, CURLOPT_USERPWD, "$clid:$secret");  $resp = curl_exec($curl);  $err = curl_error($curl) ;  $json = json_decode($resp, true);   if (0)  {  echo "response:n";  print_r($resp);  echo "err:n";  print_r($err);  echo "token '" . $ppinfo['token'] . "'n";  };   $ppinfo['token'] = $json['access_token'];  return ($ppinfo['token'] != '' ? 1 : 0); }    function newPPcurl($url, $flds, $hdrs) {  $user_agent = "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)";   $curl = curl_init();  curl_setopt($curl, CURLOPT_URL, $url);  curl_setopt($curl, CURLOPT_POST, 1);  if ($flds != '')  curl_setopt($curl, CURLOPT_POSTFIELDS, $flds);  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);  curl_setopt($curl, CURLOPT_FORBID_REUSE, 1);  curl_setopt($curl, CURLOPT_USERAGENT, $user_agent);  curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); // or 2?  curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, TRUE);  //curl_setopt($curl, CURLOPT_SSLCERT, $pem); // pem file name  curl_setopt($curl, CURLOPT_TIMEOUT, 30);  curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);  if ($hdrs != "")  curl_setopt($curl, CURLOPT_HTTPHEADER, $hdrs);   return $curl; }  

Тестовый выход:

 sandbox 0 rv 0 sandbox 1 rv 1 sandbox 2 rv 1 sandbox -1 rv 1 sandbox 0 rv 0 sandbox -1 rv 1 sandbox 1 rv 1 sandbox 0 rv 0 sandbox 2 rv 1  

Вот несколько команд curl, которые показывают такое поведение. Когда api-m.paypal.com разрешение составляет 184.87.90.6, токен извлекается нормально с помощью агента Mozilla (cmd #1). Когда IP-адрес изменяется на 151.101.1.35, запрос не выполняется для Mozilla (cmd#2), передается для curl (cmd#3). Обратите внимание, что для тестирования вам придется указать свои собственные строки id:pwd.

 curl -v https://api-m.paypal.com/v1/oauth2/token   --user-agent "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"   --resolve api-m.paypal.com:443:184.87.90.6   -H "Accept: application/json"   -H "Accept-Language: en_US"   -u "lt;id:pwdgt;"   -d "grant_type=client_credentials" curl -v https://api-m.paypal.com/v1/oauth2/token   --user-agent "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"   --resolve api-m.paypal.com:443:151.101.1.35   -H "Accept: application/json"   -H "Accept-Language: en_US"   -u "lt;id:pwdgt;"   -d "grant_type=client_credentials" curl -v https://api-m.paypal.com/v1/oauth2/token   --user-agent "curl/7.55.1"   --resolve api-m.paypal.com:443:151.101.1.35   -H "Accept: application/json"   -H "Accept-Language: en_US"   -u "lt;id:pwdgt;"   -d "grant_type=client_credentials"  

Комментарии:

1. Можете ли вы воспроизвести поведение с помощью curl командной строки (без PHP) ? Или в PHP с такой библиотекой, как Guzzle?

2. Хорошая идея, завиток работал… до тех пор, пока я не установил пользовательский агент.

Ответ №1:

Пользовательский агент запроса на токен PayPal REST должен быть идентификатором curl, например «curl/7.55.1». Использование пользовательского агента Mozilla вызывает 403 ЗАПРЕЩЕННЫХ на api-m.paypal.com, хотя это, по-видимому, будет работать на api.paypal.com, api.sandbox.paypal.com, и api-m.sandbox.paypal.com

Комментарии:

1. Какой пользовательский агент вы использовали? Тестирование с помощью curl 7.64.1 и флага -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:94.0) Gecko/20100101 Firefox/94.0" для URL https://api-m.paypal.com/v1/oauth2/token -адреса , для меня это отлично работает.

2. Тот, что в источнике выше «Mozilla/4.0 (совместим; MSIE 5.01; Windows NT 5.0)»

3. Я вижу разные ответы в зависимости от того, к какому серверу относится URL-адрес. Работает нормально с Mozilla: 184.87.90.6.. Не работает: 151.101.1.35. Я смог проверить это с помощью керла … —решайся. (Добавление завитка к Q выше)

4. @PrestonPHX Играя с tracert, я нашел дополнительные IP-адреса, которые не работают с Mozilla, проходят с помощью строк агента пользователя Curl: 151.101.1.35 151.101.65.35 Тот, который проходит с Mozilla, является зеркалом akamai, те, которые не работают, являются api-m-fastly.glb.paypal.com адреса.

5. Интересно, что это только Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0) то, что терпит неудачу, особенно из-за MSIE 5.01. Это довольно старый пользовательский агент! Похоже, что MSIE должно быть не менее 6 или выше, но даже это было бы страшно старым.