# Partner SSO

{% hint style="warning" %}
Note that this is not for integrating enterprise SSO providers such as Okta or Azure AD for partner or merchant accounts, if you want to enable enterprise SSO login options please contact support.
{% endhint %}

These are instructions on how to generate Single Sign-On tokens on your server. These token can be used to authenticate your users into our merchant dashboard for your organisations.

### 1. Generate your Partner SSO Key

You can do this by logging into your partner dashboard and under **Settings > Single Sign-On (SSO) for Organisations** and generate a key. Store this key in a secure environment variable on your server. Do not expose this key in any frontend interface.

### 2. Get your Partner ID

From your partner dashboard grab the first ID in the URL. For example:

<pre><code><strong>https://dashboard.chargebackstop.com/partners/ptnr_T1Ng7EgYrY7uaKMgPsASE/settings
</strong></code></pre>

In this case <mark style="color:green;">**ptnr\_T1Ng7EgYrY7uaKMgPsASE**</mark> would be your Partner ID.

### 3. Generate your SSO Token

You can do this using all major programming languages, see below for common examples:

{% stepper %}
{% step %}

#### Install a JWT Library

We use JSON Web Tokens to securely authenticate your users. First, install the appropriate JWT library for your server.

{% tabs %}
{% tab title="Python" %}

```
pip install PyJWT
```

{% endtab %}

{% tab title="Node.js" %}

```
npm install --save jsonwebtoken
```

{% endtab %}

{% tab title="C#" %}

```
dotnet add package System.IdentityModel.Tokens.Jwt
```

{% endtab %}

{% tab title="Go" %}

```
go get github.com/golang-jwt/jwt
```

{% endtab %}

{% tab title="Java" %}

```
implementation 'com.auth0:java-jwt:4.4.0'
```

{% endtab %}

{% tab title="Ruby" %}

```
sudo gem install jwt
```

{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

#### Generate Tokens on your Server

**These tokens must be used within 15 minutes of issuance (UTC timezone)**

{% hint style="warning" %}
Make sure to thoroughly read through the appropriate documentation for your library and ensure the right security methods are used such as setting appropriate expiries on JWT tokens.
{% endhint %}

{% tabs %}
{% tab title="Python" %}

```python
import jwt
from datetime import datetime, timezone

private_key = 'YOUR_PRIVATE_PARTNER_SSO_KEY'

def create_chargebackstop_sso_token(email):
  user_data = {
      "iat": datetime.now(tz=timezone.utc),
      "user_email": email,
  }
  return jwt.encode(user_data, private_key, algorithm='HS256')
```

{% endtab %}

{% tab title="Node.js" %}

```javascript
const jwt = require('jsonwebtoken');

const privateKey = 'YOUR_PRIVATE_PARTNER_SSO_KEY';

function createChargebackstopSsoToken(email) {
  const userData = {
    iat: Math.floor(Date.now() / 1000),
    user_email: email,
  };

  return jwt.sign(userData, privateKey, { algorithm: 'HS256' });
}
```

{% endtab %}

{% tab title="C#" %}

```csharp
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using System.Security.Claims;

public class JwtTokenGenerator
{
    private const string PrivateKey = "YOUR_PRIVATE_PARTNER_SSO_KEY";

    public static string CreateChargebackstopSsoToken(string email)
    {
        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(PrivateKey));
        var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

        var claims = new[]
        {
            new Claim("user_email", email),
            new Claim(JwtRegisteredClaimNames.Iat, 
                new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64)
        };

        var token = new JwtSecurityToken(
            claims: claims,
            signingCredentials: credentials);

        return new JwtSecurityTokenHandler().WriteToken(token);
    }
}

```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
	"fmt"
	"time"

	"github.com/golang-jwt/jwt"
)

var privateKey = []byte("YOUR_PRIVATE_PARTNER_SSO_KEY")

func createChargebackstopSsoToken(email string) (string, error) {
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
		"iat":        time.Now().Unix(),
		"user_email": email,
	})

	tokenString, err := token.SignedString(privateKey)
	if err != nil {
		return "", err
	}

	return tokenString, nil
}

```

{% endtab %}

{% tab title="Java" %}

```java
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;

import java.time.Instant;
import java.util.Date;

public class JwtGenerator {
    private static final String PRIVATE_KEY = "YOUR_PRIVATE_PARTNER_SSO_KEY";

    public static String createChargebackstopSsoToken(String email) {
        Algorithm algorithm = Algorithm.HMAC256(PRIVATE_KEY);

        return JWT.create()
                .withClaim("user_email", email)
                .withIssuedAt(Date.from(Instant.now()))
                .sign(algorithm);
    }
}
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
require 'jwt'

PRIVATE_KEY = 'YOUR_PRIVATE_PARTNER_SSO_KEY'

def create_chargebackstop_sso_token(email)
  payload = {
    iat: Time.now.to_i,
    user_email: email
  }

  JWT.encode(payload, PRIVATE_KEY, 'HS256')
end

```

{% endtab %}
{% endtabs %}
{% endstep %}
{% endstepper %}

### 4. Redirect your user

Your user must already be a member of an organisation with your partner account. If the user is not a member the SSO will fail, and due to security implications you cannot SSO a user that is a member of an organisation outside of your partner account.

{% hint style="success" %}
The token you generate must be used within 15 minutes of creation, so we recommend only creating these tokens when the user wants to be redirected rather than ahead of time
{% endhint %}

Your <mark style="color:green;">**Base URL**</mark> will be either **<https://dashboard.chargebackstop.com>,** or your own white label instance such **<https://chargebacks.example.com>**, make sure to redirect your customer to the right one.

Your <mark style="color:green;">**Partner ID**</mark> will be the ID we retrieved earlier such as **ptnr\_T1Ng7EgYrY7uaKMgPsASE**

Your <mark style="color:green;">**SSO Token**</mark> will be the token we generated above. You need to generate this token each time.

**Putting it all together**

```
{Base URL}/auth/partner-organisation-sso?partner_id={Partner ID}&token={SSO Token}
```

**For example**

<https://dashboard.chargebackstop.com/auth/partner-organisation-sso?partner\\_id=ptnr\\_T1Ng7xxxxx\\&token=eyJhbGciOiJIUzI1NiIsInR5cCIyyyyy>

If you have any questions, please let our customer success team know and we'll do our best to help you.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.chargebackstop.com/platform/partner-sso.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
