eBay oauth token and refresh tokens
Asked Answered
C

5

29

been struggling for couple of days with eBay token authentication. I am finding it hard to understand how to fetch new tokens, after signing up for a developer program account, I requested the key-set and got them, afterwards I grant access on Auth'n'Auth token which promises to last for 18 months, and yes the token works only on Trading, Shopping and Finding api.

But when you need to perform Buy, Sell and Commerce api's you have to obtain oauth tokens. And you can do the so called "Single User app" style and signin on oauth from User Token Tool, and get an oauth with 2 hours expiry.

Later on the token expires and you kinda lose the access to the api's mentioned above. I tried fetching tokens from Trading > Get session ID, Trading > Fetch token, but after providing session id to Fetch token it says: "The end user has not completed Auth & Auth sign in flow." while there is a valid 18 months token, it keeps returning this error.

Is there any example article on this, which anyone might have read or wrote?

Capriccio answered 17/6, 2017 at 11:4 Comment(3)
You can look into this node module which simplifies all your questions regarding generating access token, using all ebay api's github.com/ajay2507/ebay-node-apiFourdimensional
We are burninating the "ebay" tag, which is why I removed the tag from your question. May you please rollback your rollback to contribute?Brecciate
To any software engineers stumbling upon: nango.dev/blog/why-is-oauth-still-hardCapriccio
I
68

This details the OAuth process of the "New Sell" API, not auth 'n' auth or the legacy Trading API. It is also for the sandbox, although the procedure for Production is the same.

Your confusion is not unwarranted. My own experiences with this API flow, along with those of a large portion of the official dev forums, has been stressful. The below details the procedure to generate an oauth irrelevant of whether you are connecting to a single, dedicated, account or multiple user accounts.

There is the official guide, which does explain the whole process, so I'm hesitant to recreate entire guide here. I can provide a summary though (I advise following the below using Postman before attempting through your app):

  1. Gather your client ID and Client Secret from here (do not share these publicly)

  2. Generate an RuName (Redirect URL Name) from here by clicking "Get a Token from eBay via Your Application" and filling out the form. This form is for building the look of the login page that users will be redirected to allow your application access to their account. The RuName will then appear directly underneath the column header " RuName (eBay Redirect URL name)"

  3. Gather the list of scopes you require. Each API endpoint requires an OAuth token with the appropriate scope permissions. The Create or Replace Inventory Item endpoint, for instance, requires the https://api.ebay.com/oauth/api_scope/sell.inventory scope. Figure out what endpoints you will need and go to the API doc for each and find the scope section.

  4. The get request now looks like this:

    `https://signin.sandbox.ebay.com/authorize?
    client_id=<your-client-id-value>&
    redirect_uri=<your-RuName-value>&
    response_type=code&
    scope=https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.account%20
    https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.inventory`
    

    It is also recommended you add astate query string, which I have omitted for ease of use, but you should research what they are and why they are recommended for OAuth.

  5. This URL in a browser will redirect you to a sign-in page for the user to allow your application access to their account, but only for the scopes in the URL. Dumped from a PHP curl request you will get the redirect URL itself. Important: A sign by the end user is needed even if your application will only have one user. For instance, you have an e-commerce site for a client and you want to send their products to their singular eBay account. You will still need to do this process at least once every 18 months (find out why soon).

  6. Once the user has logged in and confirmed, the browser will display a "you can close this window now" page. The authorization code you need for the next step is in the URL of this page as the code query string. If you are developing an application for multiple users and plan to actually have them sign in on this page then you need to configure your app to grab the confirmation response, which will be the aforementioned URL, and extract the code from it. This code is very short-lived. If you are manually retrieving it via a browser you need to progress through the next steps quickly.

  7. You now need to perform a POST request to https://api.sandbox.ebay.com/identity/v1/oauth2/token. See the structure below:

    HTTP method:   POST
    URL (Sandbox): https://api.sandbox.ebay.com/identity/v1/oauth2/token
    
    HTTP headers:
    Content-Type = application/x-www-form-urlencoded
    Authorization = Basic <B64-encoded-oauth-credentials> (A base64-encoded value made from your client ID and client secret, separated by colon. For example, in PHP you could generate it with: `base64_encode ("fakeclientid123:fakeclientsecret123")`)
    
    Request body (wrapped for readability):
    grant_type=authorization_code& (literally the string "authorization_code")
    code=<authorization-code-value>& (code retreived in previous step)
    redirect_uri=<RuName-value> (same RuName as earlier)
    

    If successful this request will return something like the below:

    {
        "access_token": "v^1.1#i^1#p^3#r^1...XzMjRV4xMjg0",
        "token_type": "User token",
        "expires_in": 7200,
        "refresh_token": "v^1.1#i^1#p^3#r^1...zYjRV4xMjg0",
        "refresh_token_expires_in": 47304000
      }
    

    There's the oauth token we're after, which will last 2 hours. The second token is a refresh token, which will last ~18 months. Keep this token safe and do not share it, nor hard-code it in your app. From this point onwards your app should perform refresh calls, using this token, to get a new oauth whenever it needs to. Once the 18 months is up, or if the user goes through the "Allow Access" procedure again, you will need to do all of the above to generate a new refresh token. Assuming the API has not changed by that point.

    It is worth noting that the 18 month lifespan is not a normal procedure for OAuth refreshing, which normally should return a new refresh token each time the old one is used.

  8. To refresh an oauth:

      HTTP method:   POST
      URL (Sandbox): https://api.sandbox.ebay.com/identity/v1/oauth2/token
    
      HTTP headers:
        Content-Type = application/x-www-form-urlencoded
        Authorization = Basic <B64-encoded-oauth-credentials>
    
       Request body (wrapped for readability):
          grant_type=refresh_token&
          refresh_token=<your-refresh-token-value>&
          scope=https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.account%20
          https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.inventory
    

I hope this helps!

Indusium answered 26/7, 2017 at 15:6 Comment(20)
Thanks for the detailed instructions! Appreciating it, will give a try ASAP.Capriccio
No problems. Let me know if you have any issues with the process. My app is using github.com/davidtsadler/ebay-sdk-php to interact with the API, so I can help with that too.Indusium
The word "session" happens to be a key piece of the puzzle but it's not mentioned once in your answer. You've glossed over how a client app (not a web app) should pass the session ID to the sign-in page.Mcauliffe
@tar, at the time of writing, passing a session id was not part of the process to retrieving an oauth token and refresh token. Nor at any point of my own development with the api did i need to consider a session ID. If this has changed, or if i somehow successfully used the api without this critical part, please point me towards the relevant docs.Indusium
Turns out ebay's oauth doesn't support session ids like their auth&auth does. It's the dumbest thing because it means that it's incompatible with desktop clients that can't accept a URL. Sorry about that.Mcauliffe
No problimo bud :)Indusium
Hi @FullStackFool, I have tried your flow but at the 4th point I didn't got the response (Means blank response). Can you please help me for the same ?Thirtytwo
Hi @ChetanNakum, would you be above to open a new question, with your attempted code and steps done, then link to it here?Indusium
#50641352Thirtytwo
For step 6. Which part of this example URL is the code? ?code=v%5E1.1%23i%5E1%23I%5E3%23f%5E0%23p%5E3%23r%5E1%23t%5EUl41XzEwOkVFNzVDOEIxOUY1QjExNDlBRkM5REQ2RDc2MTUwQjc3XzFfMSNFXjI2MA%3D%3D&expires_in=299 Is it everything after code= and everything before &expires_in=299 ?Washhouse
@Washhouse that should do it, although it's been a while since i've looked at this :)Indusium
@Indusium I know it's been a while, but: is it important that the scope be the same as in the original request when refreshing a token?Engulf
Official guide is a dead linkSteeplebush
I wish I found this guide before I spent 15 hours doing it myself! This might as well be the "official" guide...Evolution
Sometimes the refresh_token gets invalidated much much before the 18 months have passed. eBay API is so bad...Tableau
I am not sure, why eBay made it so complicated? There should be a simple way to get an app token and access connected accounts with that token. Just like many other systems work with token.Venice
If you are doing it manually, Make sure to URL decode code, and then use it to get refresh token.Venice
@ZaidPathan how could I get this code programmatically without any human intervention??? I have a full importation process, but when I need the code it only works for one api call. If I use more than one time the an error of use of token was return by EbayCowey
@AnibalMauricio You might need to do something like this.Venice
@ZaidPathan thanks a lot for your answer. Well, I struggling with this: I need to get product's videos. First we are getting the list of all products and run an importation in a cron. The process runs well with the same token (We are using Auth n' Auth). But to get the videos we must use OAuth2, and to do that we need to allow access open a new window and get the "code" param. But do this in a console that's our problem. I don't know if you could provide some guidance o maybe (I know it is) we are doing something wrong. Thanks in advanceCowey
M
11

For those who struggles with it - make sure that you are using the code / token encoded.

I almost lost my mind trying to figure out what is wrong because ebay returns the refresh token decoded

Mellon answered 15/8, 2017 at 18:18 Comment(1)
If you are doing this manually, it might be handy to quickly decode the percent format/url format by using urldecoder.orgSubtype
T
3

if you are new in this API staffs, to not spend much times like me to find some errors, please be careful that in the header section, <client_id:client_secret> should be encoded with base64.

And also, in the body section, after you get code from the permission page URL, you should decoding that code with URL Decoding.

One more thing, if you couldn't get the code, or couldn't see the acceptance page that including this code, in the RuName page that you get your RuName, click the OAuth and then click Test Sign-In. Then you will go to acceptance permissions page and can get the code there from the URL. Actually ı got my code from here and it works.

I found a good github issue that explains all these very well : github/ebay-sdk-php

enter image description here

Tacy answered 8/7, 2022 at 20:49 Comment(0)
S
2

For anyone who struggles, please note the URL in step 4 is different from the URL given on eBay. The URL on eBay begins with https://auth.sandbox.ebay.com/oauth2/authorize, but the URL in step 4 begins with https://signin.sandbox.ebay.com/authorize

Salazar answered 27/2, 2019 at 3:53 Comment(1)
eBay changed the sign in URL somewhere in 2018 and in docs it appeared only in 2019. Feel free to propose edit that fixes outdated information to the answerBirth
U
1

I found @FullStackFool's post above very helpful. Based on that, I've built a class that gets the current token from the local DB, refreshes the token if required, displays instructions for getting a new refresh token, or processes the code to generate the new refresh token.

Class is written in PHP 5.6 (apologies - old internal order management system), but could easily be upgraded to PHP 7 / Laravel etc.

The constructor only takes one optional value - this is the URL string that's generated by ebay when you authenticate / signin to get a new token. If you feed this into the constructor it will parse it, get the 'code' part and then go and get a new token and refresh token.

Hopefully the code is self explanatory - i've tried to comment it well. Hope someone else finds this useful.

Database table (EbayTokens):

CREATE TABLE IF NOT EXISTS `EbayTokens` (
  `TokenID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `TokenValue` text,
  `TokenCreated` datetime DEFAULT NULL,
  `TokenLifetime` int(11) unsigned DEFAULT NULL,
  `RefreshTokenValue` text,
  `RefreshTokenCreated` datetime DEFAULT NULL,
  `RefreshTokenLifetime` int(11) unsigned DEFAULT NULL,
  `TokenType` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`TokenID`),
  UNIQUE KEY `TokenID` (`TokenID`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

The PHP Class (ebaytoken.php):

<?php

class EbayToken {

  //Set variables.
  public $success = false; //Default.
  public $messages = []; //All messages.
  public $db_token = null; //The actuasl token.

  private $string; //String to update the token.

  private $access_token_expired = true; //Dfault to expired.
  private $refresh_token_expired = true;
  private $refresh_token_almost_expired = true; //Flag to display a warning message.

  private $client_id = 'your_client_id';
  private $secret = 'your_secret'; //API key. https://developer.ebay.com/my/keys
  private $ru_name_value = 'your_ru';
  private $scope = 'https://api.ebay.com/oauth/api_scope/sell.fulfillment';
  private $base64_encoded_credentials = null; //Initialise this in a mo.

  function __construct($string = null) {
    //Save the string.
    $this->string = $string;

    //Ininitalise the credentials.
    $this->base64_encoded_credentials = base64_encode($this->client_id . ':' . $this->secret);

    //Get any existing token from db.
    $this->get_token_from_db();

    //Check if it's expired - or almost expired. If there is no token this will not do anything.
    $this->check_db_token();

    //Has the current token expired??
    if(($this->access_token_expired == true) && ($this->refresh_token_expired == true)) {
      //Uh oh. Gonna have to get a new token - or display instructions on how to. Has the user entered the URL string to parse?
      if((isset($this->string)) && ($this->string != '')) {
        $this->get_new_tokens($this->string);
      } else {
        $this->get_new_tokens_instructions();
      }
    } else if($this->access_token_expired == true) {
      //Just the access token. Get a fresh one. If the refresh token has almost expired, display the instuctions.
      if($this->refresh_token_almost_expired == true) {
        $this->need_new_tokens_almost_instructions();
      }
      $this->refresh_token(); //Just the access token expired - go and refresh it using the refresh token.
    } else {
      //All fine. If the refresh token has almost expired, display the instructions.
      if($this->refresh_token_almost_expired == true) {
        $this->need_new_tokens_almost_instructions();
      }

    }
  }

  //Get the current token information from the DB. Should only be 1.
  private function get_token_from_db() {
    //Get token(s). Should only be 1. But loop anyhow.
    $sql = "SELECT * FROM EbayTokens";
    $res = @mysql_query($sql);
    $count = 0;
    if($res) {
      $count = mysql_num_rows($res);
      while ($rec = mysql_fetch_assoc($res)) {
         $this->db_token = $rec;
      }
      $this->messages[] = '<span style="color:limegreen;"><strong>Access token loaded from database...</strong></span>';
    } else {
      $this->messages[] = '<span style="color:red;"><strong>No token found in database!</strong></span>';
    }

    return null;
  }

  //Has the access token expired?
  private function check_db_token() {
    //Do we even have a token from the db?
    if($this->db_token != null) {

      //Access token expired?
      $now = new DateTime();
      $now_plus_30_days = new DateTime();
      $now_plus_30_days->add(DateInterval::createFromDateString('30 days'));

      $date_created = DateTime::createFromFormat('Y-m-d H:i:s', $this->db_token['TokenCreated']);
      $date_expires = DateTime::createFromFormat('Y-m-d H:i:s', $this->db_token['TokenCreated']); //Make a new object.
      $date_expires->add(DateInterval::createFromDateString($this->db_token['TokenLifetime'] . ' seconds'));

      //Refresh token expired?
      $refresh_date_created = DateTime::createFromFormat('Y-m-d H:i:s', $this->db_token['RefreshTokenCreated']);
      $refresh_date_expires = DateTime::createFromFormat('Y-m-d H:i:s', $this->db_token['RefreshTokenCreated']); //Make a new object.
      $refresh_date_expires->add(DateInterval::createFromDateString($this->db_token['RefreshTokenLifetime'] . ' seconds'));

      //Check access token.
      $this->messages[] = 'Access token created on: ' . $date_created->format('d/m/Y H:i:s') . ', expires: ' . $date_expires->format('d/m/Y H:i:s');
      if($date_expires < $now) {
        $this->messages[] = ' <span style="color:red;"><strong>Access token expired!</strong></span>';
      } else {
        $this->messages[] = ' <span style="color:limegreen;"><strong>Access token valid!</strong></span>';
        $this->access_token_expired = false;
      }

      //Check refresh token.
      $this->messages[] = 'Refresh token created on: ' . $refresh_date_created->format('d/m/Y H:i:s') . ', expires: ' . $refresh_date_expires->format('d/m/Y H:i:s');
      if($refresh_date_expires < $now) {
        $this->messages[] = '<span style="color:red;"><strong>Refresh token expired!</strong></span>';
      } else if($refresh_date_expires < $now_plus_30_days) {
        $this->messages[] = ' <span style="color:darkorange;"><strong>Refresh token valid! But expires within 30 days. INFORM ADMIN TO GENERATE A NEW REFRESH TOKEN.</strong></span>';
        $this->refresh_token_expired = false;
      } else {
        $this->messages[] = '<span style="color:limegreen;"><strong>Refresh token valid!</strong></span>';
        $this->refresh_token_almost_expired = false;
        $this->refresh_token_expired = false;
      }

      //Was it all ok?
      if(($this->refresh_token_expired == false) && ($this->access_token_expired == false)) {
        $this->messages[] = '<span style="color:limegreen;"><strong>All tokens valid!</strong></span>';
        $this->success = true;
      }

    }

    return null;
  }

  //Go and get a new token using the refresh token. Save it to the db.
  private function refresh_token() {
    $this->messages[] = 'OAUTH token expired - refreshing token...';
    // $this->messages[] = 'Using refresh token: ' . $this->db_token['RefreshTokenValue'];

    //Connect to Ebay API and refresh the existing oauth token.
    $url_get_token = 'https://api.ebay.com/identity/v1/oauth2/token';
    $port = 443;

    $headers = array(
      'Content-Type: application/x-www-form-urlencoded',
      'Authorization: Basic ' . $this->base64_encoded_credentials
    );

    $payload = array(
        'grant_type' => 'refresh_token',
        'refresh_token' => $this->db_token['RefreshTokenValue'],
        'scope=' . urlencode($this->scope),
    );
    $payload_string = http_build_query($payload);

    //Setting the curl parameters.
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_PORT, $port);
    curl_setopt($ch, CURLOPT_URL, $url_get_token);
    curl_setopt($ch, CURLOPT_POST, true);
    // curl_setopt($ch, CURLOPT_SSLVERSION, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 300);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $payload_string);

    $data = curl_exec($ch);
    curl_close($ch);

    //Convert the JSON result into array
    $array_data = json_decode($data, true);

    //Did we get an access token?
    $access_token = null;
    if((is_array($array_data)) && (isset($array_data['access_token']))) {

      //Save the tokens to the database. Set variables.
      $access_token = mysql_real_escape_string($array_data['access_token']);
      $expires_in = mysql_real_escape_string($array_data['expires_in']);
      $token_type = mysql_real_escape_string($array_data['token_type']);

      //Update. This will only be run if there is already a token in the DB. So no need to truncate.
      $now = new DateTime();
      $now_mysql = $now->format('Y-m-d H:i:s');
      $existing_token_id = $this->db_token['TokenID'];

      $sql = sprintf("UPDATE EbayTokens SET TokenValue = '%s', TokenCreated = '%s', TokenLifetime = %s, TokenType = '%s' WHERE TokenID = %d", $access_token, $now_mysql, $expires_in, $token_type, $existing_token_id);

      // $this->messages[] = 'SQL: ' . $sql;
      if (@executeSQL($sql)) {
        $this->messages[] = '<span style="color:limegreen;"><strong>Success! Token refreshed and saved to database.</strong></span>';
      }

      //Update the token in this object from the freshly saved data.
      $this->get_token_from_db();
      $this->check_db_token(); //Re-check - this will mark the success flag in this object.

    } else {
      $this->messages[] = '<span style="color:red;"><strong>Failed to get OAUTH token! Aborting</strong></span>.';
      $this->messages[] =  'Reply was:' . '<br><pre>' . print_r($array_data) . '</pre>';
    }

    return null;
  }

  //Get new tokens using the string supplied.
  private function get_new_tokens($string) {

    //Parse the URL string supplied and get the 'code'.
    $auth_code = null;
    $parameters = parse_url($string);
    $query_array = explode('&', $parameters['query']);
    //Loop through and get code. Just in case the 'code' moves to another position.
    foreach ($query_array as $parameter) {
      $parameter_array = explode('=', $parameter);
      if($parameter_array[0] == 'code') {
        $auth_code = $parameter_array[1];
        break; //Got what we want.
      }
    }

    /***********************************************************************/

    $this->messages[] = "Getting eBay Oauth token using URL string...";
    $this->messages[] = 'Using auth code: ' . $auth_code;

    //Connect to Ebay API and get an oath using authorisation code.
    $url_get_token = 'https://api.ebay.com/identity/v1/oauth2/token';
    $port = 443;

    $headers = array(
      'Content-Type: application/x-www-form-urlencoded',
      'Authorization: Basic ' . $this->base64_encoded_credentials
    );

    $payload = array(
        'grant_type' => 'authorization_code',
        'code' => urldecode($auth_code), //Get from step one.
        'redirect_uri' => $this->ru_name_value, //Same as used in part one.
    );
    $payload_string = http_build_query($payload);

    //Setting the curl parameters.
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_PORT, $port);
    curl_setopt($ch, CURLOPT_URL, $url_get_token);
    curl_setopt($ch, CURLOPT_POST, true);
    // curl_setopt($ch, CURLOPT_SSLVERSION, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 300);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $payload_string);

    $data = curl_exec($ch);
    curl_close($ch);

    //Convert the JSON result into array
    $array_data = json_decode($data, true);

    //Did we get an access token?
    $access_token = null;
    if((is_array($array_data)) && (isset($array_data['access_token']))) {

      //Save the tokens to the database. Set variables.
      $access_token = mysql_real_escape_string($array_data['access_token']);
      $expires_in = mysql_real_escape_string($array_data['expires_in']);
      $refresh_token = mysql_real_escape_string($array_data['refresh_token']);
      $refresh_token_expires_in = mysql_real_escape_string($array_data['refresh_token_expires_in']);
      $token_type = mysql_real_escape_string($array_data['token_type']);

      //Truncate and then insert. There may or may not be an existing token in the db.
      $this->truncate_db();
      $now = new DateTime();
      $now_mysql = $now->format('Y-m-d H:i:s');

      $sql = sprintf("INSERT INTO EbayTokens SET TokenValue = '%s', TokenCreated = '%s', TokenLifetime = %d, RefreshTokenValue = '%s', RefreshTokenCreated = '%s', RefreshTokenLifetime = %d, TokenType = '%s' ", $access_token, $now_mysql, $expires_in, $refresh_token, $now_mysql, $refresh_token_expires_in, $token_type);

      if (@executeSQL($sql)) {
        $this->messages[] = '<span style="color:limegreen;"><strong>Success! New token aquired and saved to database.</strong></span>';
      } else {
        $this->messages[] = '<span style="color:red;"><strong>Error saving new token to database!</strong></span>';
      }

      //Update the token in the object from the freshly saved data.
      $this->get_token_from_db();
      $this->check_db_token(); //Re-check - this will mark the success flag.

    } else {
      $this->messages[] = '<span style="color:red;"><strong>Failed to get OAUTH token! Aborting</strong></span>.';
      $this->messages[] =  'Reply was:' . '<br><pre>' . print_r($array_data) . '</pre>';
    }

    return null;
  }

  //Instructions to get a new refresh token.
  private function get_new_tokens_instructions() {
    $this->messages[] = '<span style="color:red;">Tokens expired! Admin action required</span>';

    $this->messages[] = "In order to get a fresh oauth token (and more importantly a refresh token), click on the URL below (it will open in a new window) and login as.";

    //Connect to Ebay API and get consent. The authorization code grant flow. https://developer.ebay.com/api-docs/static/oauth-authorization-code-grant.html
    $url_get_consent = 'https://auth.ebay.com/oauth2/authorize';

    $payload = array(
      'client_id=' . $this->client_id,
      'redirect_uri=' . $this->ru_name_value,
      'response_type=code',
      'scope=' . urlencode($this->scope),
    );
    $payload_string = implode('&', $payload);

    $url_get_consent_full = $url_get_consent . '?' . $payload_string;
    $this->messages[] = 'URL: <a href="' . $url_get_consent_full . '" target="_blank">' . $url_get_consent_full . '</a><br>';

    $this->messages[] = "Once you have completed the login and see the window saying you can close the page, <strong>copy the URL</strong>. It will contain a 'code' parameter.";
    $this->messages[] = "Insert the coppied URL in the form below and click submit. The new code will be used and a new oauth and refresh token will be obtained and stored in the database.";

    $this->messages[] = '
    <form>
      URL string: 
      <input type="text" name="string" size="50">
      <input type="submit" value="Submit">
    </form>
    ';

    return null;
  }

  //Instructions to get a new refresh token - refresh token has ALMOST expired.
  private function need_new_tokens_almost_instructions() {
    $this->messages[] = '<span style="color:darkorange;">Tokens ALMOST expired! Admin action required</span>';

    $this->messages[] = "In order to get a fresh oauth token (and more importantly a refresh token), click on the URL below (it will open in a new window) and login.";

    //Connect to Ebay API and get consent. The authorization code grant flow. https://developer.ebay.com/api-docs/static/oauth-authorization-code-grant.html
    $url_get_consent = 'https://auth.ebay.com/oauth2/authorize';

    $payload = array(
      'client_id=' . $this->client_id,
      'redirect_uri=' . $this->ru_name_value,
      'response_type=code',
      'scope=' . urlencode($this->scope),
    );
    $payload_string = implode('&', $payload);

    $url_get_consent_full = $url_get_consent . '?' . $payload_string;
    $this->messages[] = 'URL: <a href="' . $url_get_consent_full . '" target="_blank">' . $url_get_consent_full . '</a><br>';

    $this->messages[] = "Once you have completed the login and see the window saying you can close the page, <strong>copy the URL</strong>. It will contain a 'code' parameter.";
    $this->messages[] = "Insert the coppied URL in the form below and click submit. The new code will be used and a new oauth and refresh token will be obtained and stored in the database.";

    $this->messages[] = '
    <form>
      URL string: 
      <input type="text" name="string" size="50">
      <input type="submit" value="Submit">
    </form>
    ';

    return null;
  }

  //Delete any tokens from the database. Use cautiously.
  private function truncate_db() {

    $sql = "TRUNCATE TABLE EbayTokens";
    if (@executeSQL($sql)) {
      $this->messages[] = '<span style="color:limegreen;"><strong>Existing tokens deleted from database.</strong></span>';
    }

    return null;

  }
}

?>

And a little script to test / use:

<?php
require_once("classes/ebaytoken.php");

$thispage = new Page();

//Is there a string in the $_GET array? If so, feed it into the constructor.
$string = null;
if((isset($_GET['string'])) && ($_GET['string'] != '')) {
    $string = $_GET['string'];
}
$token = new EbayToken($string);

echo "<h3>Current eBay Tokens</h3>";

$messages = $token->messages;
if(count($messages) > 0) {
    echo '<ul>';
        foreach ($messages as $message) {
            echo '<ul>' . $message . '</ul>';
        }
    echo '</ul>';
}

//Is the token valid?
if($token->success == true) {
    get_orders($token->db_token);
}

//Get ebay orders.
function get_orders($token_data) {
    echo "<h3>Getting Ebay Orders</h3>";

    //Start the main request now we have the token. https://developer.ebay.com/api-docs/sell/static/orders/discovering-unfulfilled-orders.html
    $url_get_orders = 'https://api.ebay.com/sell/fulfillment/v1/order';
    $port = 443;
    $headers = array(
        'Authorization: Bearer ' . $token_data['TokenValue'],
        'X-EBAY-C-MARKETPLACE-ID: EBAY_GB',
    );

    $payload = array(
        'filter=orderfulfillmentstatus:' . urlencode('{NOT_STARTED|IN_PROGRESS}'),
        'limit=100',
        'offset=0',
    );

    $payload_string = implode('&', $payload);
    $url_get_orders_full = $url_get_orders . '?' . $payload_string;

    //Setting the curl parameters.
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url_get_orders_full); //For 'get', add query string to end of URL.
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 300);

    $data = curl_exec($ch);
    curl_close($ch);

    //Convert the JSON result into array
    $array_data = json_decode($data, true);

    print_r('<pre>');
    print_r($array_data);
    print_r('</pre>');

    return null;
}

?>
Underlayer answered 6/2, 2020 at 10:4 Comment(2)
Thanks @Dharman - i'm aware of that. This is a bit of sample code from an internal app that i knocked together very quickly. Plus, there are no real external inputs - only the data returned by ebay. Anyhoo... I'll update...Underlayer
Sorry @Dharman - i'd only half done the job. Added mysql_real_escape_string to all parameters returned by ebay. It's not prepared statements - but it adds a reasonable level of protection.Underlayer

© 2022 - 2024 — McMap. All rights reserved.