Customer Authorization

Overview

Slope's Customer Authorization flow allows your customers to grant your application permission to access certain account information and initiate Slope.js flows on their behalf without requiring them to log in every time. This provides a smoother, "remember me" style experience.

Implementing this flow is optional. It is designed for platforms and merchants where users are already securely logged into your application and you want to reduce friction by eliminating the need for repeated Slope logins.

When authorized, you can:

  • Retrieve specific customer information via the Slope API (e.g., available credit).
  • Initialize Slope.js frontend flows (like Checkout or Draw Funds) pre-authenticated for the customer.

This guide walks you through obtaining authorization and using it to streamline the user experience.

Authorization Flow

The authorization process involves capturing a short-lived code when a user logs into Slope through your integration and exchanging it for a long-lived access token.

1. Capturing the Authorization Code

When a customer completes a Slope.js flow that involves logging into their Slope account (such as Checkout or Pre-Qualify), the onSuccess callback will include an authorizationCode if the authorization was successful.

You need to listen for this code in your onSuccess handler and send it to your backend server.

// Example Slope.js Initialization
window.SlopeJs.start({
  // ... other parameters like 'code' for checkout
  publicKey: 'YOUR_PUBLIC_API_KEY',

  onSuccess: response => {
    console.log('Slope flow successful.')

    if (response.authorizationCode) {
      console.log('Authorization code received:', response.authorizationCode)
      // Send response.authorizationCode to your backend server
      // Example: sendAuthCodeToBackend(response.authorizationCode);
    }

    // Handle other success data like order or customer details
    if (response.order) {
      // ... handle order success
    }
  },

  onClose: () => {
    console.log('Slope modal closed.')
  },

  onFailure: error => {
    console.error('Slope flow failed:', error.errorMessage)
  }
})

// Example function to send the code to your backend
async function sendAuthCodeToBackend(authCode) {
  try {
    await fetch('/your-backend-endpoint-for-auth-code', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ authorizationCode: authCode })
    })
    console.log('Authorization code sent to backend.')
  } catch (error) {
    console.error('Failed to send authorization code:', error)
  }
}

The authorizationCode is short-lived and intended for immediate exchange. Ensure your backend handles this promptly.

2. Exchanging for an Access Token

Once your backend receives the authorizationCode, exchange it for a long-lived accessToken by making a POST request to the /v4/auth/token endpoint. This request must be authenticated using your secret API key.

# Example backend request using cURL
# Replace YOUR_API_KEYS and the authorizationCode

curl -X POST https://api.slopepay.com/v4/auth/token \
  -H "Authorization: Basic YOUR_API_KEYS" \
  -H "Content-Type: application/json" \
  -d '{
    "authorizationCode": "auth_code_from_frontend_123abc"
  }'

A successful response will contain the accessToken:

// Example Response (201 Created)
{
  "accessToken": "XXXXXXXXXXXXXXXXXXXXXXXX"
}

Storing the Access Token:

  • The accessToken is long-lived and acts as a credential granting access to the customer's data and the ability to act on their behalf within Slope.
  • Store the accessToken securely in your backend database, associated with the corresponding user in your system.
  • Never expose the accessToken on the frontend. It should only be used server-side.
  • Each user within a customer's organization should ideally have their own accessToken if they log in separately through your platform. Map tokens based on your internal user ID and the Slope userId and customerId associated with the token (you can retrieve these details using the token, e.g., via a /me endpoint if available, or store them alongside the token upon exchange).

Using the Access Token

The primary uses for the accessToken are making server-side API calls on behalf of the customer and generating short-lived frontend session tokens.

Making API Calls (Server-Side)

When making Slope API calls specific to an authorized customer (e.g., fetching their available credit), include the accessToken in the Slope-Access-Token header along with your standard Authorization header containing your secret API key.

# Example API call using cURL to fetch customer details (Illustrative Endpoint)
# Replace YOUR_API_KEYS and the stored accessToken

curl https://api.slopepay.com/v4/customers/cust_abc123 \
  -H "Authorization: Basic YOUR_API_KEYS" \
  -H "Slope-Access-Token: XXXXXXXXXXXXXXXXXXXXXXXX"

Generating Frontend Session Tokens

To initiate a Slope.js flow (like Checkout) without requiring the customer to log in again, generate a short-lived sessionToken.

Make a POST request from your backend to /v4/auth/session. This request requires both your secret API key (Authorization header) and the customer's accessToken (Slope-Access-Token header).

# Example backend request using cURL to generate a session token
# Replace YOUR_SECRET_API_KEY and the stored accessToken

curl -X POST https://api.slopepay.com/v4/auth/session \
  -H "Authorization: Bearer YOUR_SECRET_API_KEY" \
  -H "Slope-Access-Token: slo_access_XXXXXXXXXXXXXXXXXXXXXXXX"

A successful response contains the sessionToken and its expiry time:

// Example Response (201 Created)
{
  "sessionToken": "XXXXXXXXXXXXXXXXXXXXXXXX",
  "expiresAt": "2024-01-01T16:00:00.000Z" // ISO 8601 timestamp
}

The sessionToken expires after 4 hours. You should generate a new one each time you need to initialize an authenticated Slope.js flow.

Initializing Slope.js with a Session Token

Pass the obtained sessionToken to the Slope.js start method using the accessToken parameter. This bypasses the login screen for the customer.

🚧

Deprecation of accessToken

The accessToken parameter will soon be deprecated in favor of sessionToken. Both parameters will be accepted until further notice.

// Example Slope.js initialization with a session token

// Fetch sessionToken from your backend just before starting the flow
const sessionToken = await fetchSessionTokenFromBackend()

if (sessionToken) {
  window.SlopeJs.start({
    // ... other parameters (e.g., 'code' for checkout)
    publicKey: 'YOUR_PUBLIC_API_KEY',
    sessionToken: sessionToken, // Pass the session token here

    onSuccess: response => {
      // Handle success - user did not need to log in
      console.log('Authenticated Slope flow successful.')
      // Note: authorizationCode will not be present on subsequent runs using sessionToken
    },
    onClose: () => {
      /* ... */
    },
    onFailure: error => {
      /* ... */
    }
  })
} else {
  // Handle case where session token couldn't be generated
  // Potentially fall back to starting Slope.js without sessionToken
  // which would prompt the user to log in as normal.
}

async function fetchSessionTokenFromBackend() {
  try {
    const response = await fetch('/your-backend-endpoint-for-session-token')
    if (!response.ok) throw new Error('Failed to fetch session token')
    const data = await response.json()
    return data.sessionToken // Assuming your backend returns { sessionToken: '...' }
  } catch (error) {
    console.error('Error fetching session token:', error)
    return null
  }
}