E-shop verification using OAuth

If you need to authenticate Shoptet administrator users using Shoptet login credentials, for example to save the settings for the individual installation of your addon, you can use the OAuth server functionality.

By using this user authentication mechanism, you will be sure that the user is the actual administrator of the e-shop and you do not need to address its access credentials and authorization to edit the settings of your addon.

This is only a verification mechanism and does not allow you to save data (typically addon settings) – you must save the data yourself in your data structure.

The procedure assumes that you have an e-shop number stored in your API access token database. In other words, you need to use the correct API access token from the e-shop number shopId.

The first step to identify a user and their e-shop is to determine the hostname OAuth server, against which you will validate the user’s identity.

1. Obtaining OAuth server address

Fill in your settings URL into addons settings » tab “Description” » field “Addon settings url”.

If you use placeholder #SHOP_ID# into the URL, it will be replaced by the actual e-shop id. For example https://www.my-server.com/shoptet/addons/my-addon/settings?eshopId=#SHOP_ID# will be replaced by https://www.my-server.cz/shoptet/addons/my-addon/settings?eshopId=12345

If you enter #LANGUAGE# into the URL, this will be replaced by the actual e-shop language. For example https://www.my-server.com/shoptet/addons/my-addon/settings?language=#LANGUAGE# will be replaced by https://www.my-server.com/shoptet/addons/my-addon/setting?language=cs

From the eshopId you receive, you will find the corresponding API access token in your database and call the endpoint Eshop info. In the response, check array data.urls[] and look for object with ident having value oauth and use the value of url field as an OAuth server address of the user, who was logged in.

Please be aware, that domain can change, so it is recommended to register eshop:projectDomain webhook and update the domain in your system if needed.

<?php
$baseOAuthUrl = current(array_filter($response['data']['urls'], function ($url) {
    return $url['ident'] == 'oauth';
}, ARRAY_FILTER_USE_BOTH))['url'];

This will be something like https://example.myshoptet.com/action/OAuthServer/

2. Obtaing oauth code (one-time challenge code)

There are two ways used in Shoptet:

2.1 Full OAuth with redirect

You will redirect the e-shop user to the Oauth server.

$_SESSION['base_oauth_url'] = $baseOAuthUrl;

Save URL to current user (e.g. into session) – the value will be needed in the next step.

Assemble url to redirect the user to.

// $_SESSION['base_oauth_url'] contains the ending slash
$url = $_SESSION['base_oauth_url'] . 'authorize';

Add GET parameters to url:

// Your client id in OAuth server
// This is an example only, the specific value can be found in
// the e-shop administration -> Link -> API partner -> Access to API
$param['client_id'] = 'wae54...slekn';
// authorization group in OAuth server, enter 'basic_eshop'
$param['scope'] = 'basic_eshop';

To increase the security, add state parameter.

$state = uniqid();
$_SESSION["state"] = $state;
$param['state'] = $state;

The state parameter is not mandatory, it is used as protection against XSRF attacks. The state value must be generated and saved to the user. When you add state to the request to the OAuth server, the parameter and its value will be added to the reply from authorization server. To check, see below.

Then you add response_type and redirect_uri parameters.

// response_type is always 'code'
$param['response_type'] = 'code';
// returning url (to your server), to which the OAuth server redirects the user after sucessful verification
// redirect_uri must be entered in addon settins as "URL for user authorization".
// The OAuth server inspects whether the addresses are matching;
// if the address entered in administration does not match with address sent,
// the OAuth server responds with error
$param['redirect_uri'] = 'https://www.my-server.com/shoptet/addon/my-addon/code';
// Then create the url and redirect the user to OAuth server
$url = $url . "?" . http_build_query($param);
header("Location: " . $url);

The OAuth server authenticates the user and redirects it to your redirect_uri.
In GET parameters, you get the value code and optionally also the state.

$code = $_GET['code'];
$state = $_GET['state'];
// Check state parameters. When the values are different, someone other than you
// initiated the request and your code should not continue.
if ($state != $_SESSION['state]) {
    die('State parameters do not macth');
}

2.2 Getting oauth code directly

In this case you obtain the oauth code simply from the the URL, typically GET parameters (depends on where you place the #OAUTH_CODE# placeholder), for example:

$code = $_GET['code'];

3. Getting the OAuth access token

Next step is to get the OAuth access token, which will provide you with the identity of the user or e-shop. ATTENTION: This OAuth access token is different from the OAuth access token you get when you install the addon.

The request is sent in the background, without the user’s knowledge.

$data = [
    // $code is the value from the GET parameter
    'code' => $code,
    // grant_type is always 'authorization_code'
    'grant_type' => 'authorization_code',
    // Your client id in OAuth server
    // This is an example only, the specific value can be found in
    // e-shop administration -> Link -> API partner -> Access to API
    'client_id' => '<your client id>',
    // Your secret string for communication with OAuth server.
    // The specific value can be found in e-shop administration -> Link -> API partner -> Access to API.
    // Contact Shoptet, if client_secret is not available (for older API partners, it was not generated automatically)
    'client_secret' => '<your client secret>',
    // redirect_uri must be entered in addon settings as "URL for user authorization".
    // The OAuth server inspects whether the addresses are matching;
    // if the address entered in administration does not match with address sent, the OAuth server responds with error
    'redirect_uri' => 'https://www.my-server.com/shoptet/addon/my-addon/code',
    // Enter 'basic_eshop'
    'scope' => 'basic_eshop'
];
$url = $_SESSION['base_oauth_url'] . 'token';

Send POST request:

$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);

if ($err) {
    die("CURL Error: " . $err);
}

The reply will contain the access_token in JSON format:

{
    "access_token": "90r3azmxy6dbxzpjfxj237cjt8rp0f4hq6uygone78i4n4zk47xb649pls1097fc0xs501hjhpv9tlj2k9hc6xhutymtthet8dzx0sm1ih7r6ml6gf6hc4dixqn48l0r5qk1ynqp0fvojief30b2f70rnedfcy2zyqhkin326ynvdv404hn1xw8nqct6rkn9h4xm9za2i53pbb8hqkmz37qdpol5yr3dciftn0vl04jfvpxg4l36lnw9vsqdyke",
    "expires_in": 43200,
    "token_type": "bearer",
    "scope": "basic_eshop"
}
$response = json_decode($response, TRUE);
$accessToken = $response['access_token'];

4. Getting the e-shop’s identity

The e-shop’s identity is obtained from the OAuth server response.

Submit a request to the OAuth server with an authorization header having the OAuth access token value.

Assemble the url you will be sending the request to:

$url = $_SESSION['base_oauth_url'] . 'resource?method=getBasicEshop';

The OAuth access token is sent in the request header:

$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . $accessToken]);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
$response = curl_exec($curl);
curl_close($curl);

If the request is processed OK, it contains $response key success with value true.

{
    "success":true,
    "data": {
        "user": {
            "email": "novak@fenix.myshoptet.com",
            "name": "Jan Novak"
        },
        "project": {
            "id": 159834,
            "url": "https://fenix.myshoptet.com/",
            "name": "Fenix"
        }
    }
}

In $response in the data object is theid and url, which identifies the e-shop.

$response = json_decode($response, TRUE);
$_SESSION['project_id'] = $response['data']['project']['id'];

Getting the project_id gives you the linked current user of your pages with the e-shop administrator.

Error identification
If the error occurs, in the $response key, there is an error and error_description

{
    "error": "You must use `client_secret`. Please contact us to obtain one.",
    "error_description": null
}