| 
 | 
  Joel Fischer - 2021-07-10 23:43:26  
Thank you for developing this library. It has been immensely useful for me. I do have one question going forward. 
 
Since Etsy is moving to its v3/Oauth2 API and discontinuing v2/Oauth1 in 2022, according to their timeline, I was wondering if you are planning on including Etsy v3/Oauth2 access as a built in function?  
 
If not, could you provide some guidance or a tutorial on how to access their Oauth2 v3 API with this library?  
 
I have the current API v2 working with the built in Etsy function but I do not know enough about Oauth2 to successfully connect to their v3 with this library. 
 
Any help would be appreciated. 
  
  Manuel Lemos - 2021-07-11 00:51:08 -  In reply to message 1 from Joel Fischer 
Hello Joel, 
Adding support to make the class work with OAuth 2 is relatively easy.
 
It may be a matter of adding a few lines of configuration to the oauth_configuration.json file .
 
Take a look at this tutorial article to get the guidance that you need:
 phpclasses.org/blog/package/7700/po ...
 
Would you like to try adding Etsy API V3 OAuth support doing that and then share the lines that you will add to the oauth_configuration.json file?
  
  
  Joel Fischer - 2021-07-11 03:08:28 -  In reply to message 2 from Manuel Lemos 
Following the link you provided I added the following to the oauth_configuration.json file. 
 
"Etsy2": 
{ 
        "oauth_version": "2.0", 
	"dialog_url": "https://www.etsy.com/oauth/connect?response_type=code&scope={SCOPE}&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&state={STATE}", 
	"access_token_url": "https://api.etsy.com/v3/public/oauth/token"		 
}, 
 
I get an error in my redirect url: ../login_with_etsy.php?error=invalid_request&error_description=code_challenge+is+required&state=1625970501-a03889 
 
Etsy v3 API is requiring a PKCE code challenge.  
How would I implement that?  
  
  Joel Fischer - 2021-07-13 21:10:40 -  In reply to message 1 from Joel Fischer 
Ok finally got it to work. 
 
Here are the changes I made: 
 
(1) Added to oauth_configuration.json 
 
"Etsy2": 
{ 
"oauth_version": "2.0", 
"dialog_url": "https://www.etsy.com/oauth/connect?response_type=code&scope={SCOPE}&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&state={STATE}&code_challenge={CODE_CHALLENGE}&code_challenge_method=S256", 
"access_token_url": "https://api.etsy.com/v3/public/oauth/token"		 
}, 
 
(2) Changed oauth_client.php at line 1284  
 
from: 
'{REALM}', UrlEncode($this->realm), 
$url))))))); 
to: 
'{REALM}', UrlEncode($this->realm), str_replace( 
			'{CODE_CHALLENGE}',UrlEncode($this->code_challenge), 
$url)))))))); 
 
(3) Modified login_with_etsy.php 
 
<?php 
/* 
 * login_with_etsy2.php 
 * 
 * 
 * 
 */ 
 
	/* 
	 *  Get the http.php file from http://www.phpclasses.org/httpclient 
	 */ 
	require('./http.php'); 
	require('oauth_client.php'); 
	session_start(); 
	 
	function base64url_encode($plainText) 
    { 
        $base64 = base64_encode($plainText); 
        $base64 = trim($base64, "="); 
        $base64url = strtr($base64, '+/', '-_'); 
        return ($base64url); 
    } 
	 
	$random = bin2hex(openssl_random_pseudo_bytes(64)); 
	 
	if(!isset($_SESSION['verifier'])){ 
		$verifier = base64url_encode(pack('H*', $random)); 
		$_SESSION['verifier'] = $verifier; 
	} else { 
		$verifier = $_SESSION['verifier']; 
	} 
	 
	if(!isset($_SESSION['challenge'])){ 
		$challenge = base64url_encode(pack('H*', hash('sha256', $verifier))); 
		$_SESSION['challenge'] = $challenge; 
	} else { 
		$challenge = $_SESSION['challenge']; 
	} 
	 
	$client = new oauth_client_class; 
	$client->debug = false; 
	$client->debug_http = true; 
	$client->server = 'Etsy2'; 
	$client->redirect_uri = 'https://'.$_SERVER['HTTP_HOST']. 
		dirname(strtok($_SERVER['REQUEST_URI'],'?')).'/login_with_etsy.php'; 
	$client->client_id = ''; $application_line = __LINE__; 
	$client->client_secret = ''; 
	$client->authorization_header = true; 
	$client->scope = 'email_r'; 
	$client->code_challenge = $challenge;	 
	$client->code_verifier = $verifier; 
	 
	if(strlen($client->client_id) == 0 
	|| strlen($client->client_secret) == 0) 
		die('Please go to Etsy Developers page https://www.etsy.com/developers/register , '. 
			'create an application, and in the line '.$application_line. 
			' set the client_id to key string and client_secret with shared secret. '. 
			'The Callback URL must be '.$client->redirect_uri); 
 
	if(($success = $client->Initialize())) 
	{ 
		if(($success = $client->Process())) 
		{ 
			if(strlen($client->access_token)) 
			{ 
				$user_id = explode(".", $client->access_token)[0]; 
				$success = $client->CallAPI( 
					'https://openapi.etsy.com/v3/application/users/'.$user_id,  
					'GET', array(), array('FailOnAccessError'=>true,'RequestHeaders'=>array('Authorization'=>'Bearer '.$client->access_token,'x-api-key'=>$client->client_id)), $user); 
					 
			} 
		} 
		$success = $client->Finalize($success); 
	} 
	if($client->exit) 
		exit; 
	if($success) 
	{ 
		 
		 
		 
?> 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html> 
<head> 
<title>Etsy OAuth client results</title> 
</head> 
<body> 
<?php 
		echo '<h1> you have logged in successfully with Etsy!</h1>'; 
		echo '<pre>', HtmlSpecialChars(print_r($user, 1)), '</pre>';		 
?> 
</body> 
</html> 
<?php 
	} 
	else 
	{ 
?> 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html> 
<head> 
<title>OAuth client error</title> 
</head> 
<body> 
<h1>OAuth client error</h1> 
<pre>Error: <?php echo HtmlSpecialChars($client->error); ?></pre> 
 
</body> 
</html> 
<?php 
	} 
 
?> 
 
 
  
  Joel Fischer - 2021-07-14 10:04:48 -  In reply to message 4 from Joel Fischer 
Forgot  
 
add to oauth_client.php around line 2055 
 
from: 
case 'authorization_code': 
					$values = array( 
						'code'=>$code, 
						'redirect_uri'=>$redirect_uri, 
						'grant_type'=>'authorization_code' 
					); 
 
to: 
 
case 'authorization_code': 
					$values = array( 
						'code'=>$code, 
						'redirect_uri'=>$redirect_uri, 
						'grant_type'=>'authorization_code', 
						'code_verifier'=>$this->code_verifier		 
					); 
 
 
  
  Manuel Lemos - 2021-07-18 23:43:11 -  In reply to message 4 from Joel Fischer 
Great. Is that code challenge feature that you added is based on a standard aspect of the OAuth specification? 
  
  Joel Fischer - 2021-07-21 02:15:08 -  In reply to message 6 from Manuel Lemos 
  
  Manuel Lemos - 2021-07-21 07:03:24 -  In reply to message 7 from Joel Fischer 
Hello Joel, 
 
Thanks for sharing that documentation. I am very busy this week but I will try to update the class into this in the upcoming weekend to support better that part of the standard. Can you please reply here if I do not reply until next Monday? 
  
 
  
  Joel Fischer - 2021-07-27 02:52:09 -  In reply to message 8 from Manuel Lemos 
Hey Manuel, Just a friendly check in for the update status for this class. 
  
  Andrew Leonard - 2023-01-07 20:52:56 -  In reply to message 9 from Joel Fischer 
Joel, thanks for posting this. 
 
 
I have implemented your code, however, once the initial token expires I get the following error: 
 
Error: it was not possible to access the OAuth refresh token: it was returned an unexpected response status 401 Response: {"error":"invalid_token","error_description":"access token is expired"} 
 
Do you know how to get the refresh token? 
 
Andrew 
  
   |