Setup & Installation
Get Sandbox Credentials
Contact your Ealyx account manager or email info@ealyx.com with:
- Company name and technical contact
- Webhook base URL (staging/production)
- Integration timeline
You'll receive:
- Sandbox environment URL
ClientIdandClientSecretUsernameandPassword
Keep your credentials secure and do not expose them to the public. Once you have completed the integration, you can request production credentials from your Ealyx account manager.
Store Configuration Values
You'll need to store the credentials and configuration values you received. How you store them is entirely up to you—environment variables, .env file, configuration database, encrypted storage, or any other secure method. The important part is that you keep them secure and accessible for use in the API calls that follow.
Configuration values to save
{CLIENT_ID}- Your platform's unique identifier{CLIENT_SECRET}- Your secure key for authentication{USERNAME}- Admin account username{PASSWORD}- Admin account password{API_BASE_URL}- API base URL (Sandbox:https://api.stg.ealyx.techor Production:https://api.ealyx.tech){ASSETS_URL}- CDN base URL (Sandbox:https://cdn.stg.ealyx.techor Production:https://cdn.ealyx.tech)
Example storage options
Environment Variables (if using .env file or system variables)
EALYX_CLIENT_ID="your_client_id"
EALYX_CLIENT_SECRET="your_client_secret"
EALYX_USERNAME="your_username"
EALYX_PASSWORD="your_password"
EALYX_API_BASE_URL="https://api.stg.ealyx.tech"
EALYX_ASSETS_URL="https://cdn.stg.ealyx.tech"
Configuration File (JSON, YAML, etc.)
{
"ealyx": {
"clientId": "your_client_id",
"clientSecret": "your_client_secret",
"username": "your_username",
"password": "your_password",
"apiBaseUrl": "https://api.stg.ealyx.tech",
"assetsUrl": "https://cdn.stg.ealyx.tech"
}
}
Secure Storage (secrets management, encrypted database, etc.)
Choose your preferred secure storage method and load the values at runtime.
Frontend Installation
Add this to your base template before </body>:
<script>
window.ealyxConfiguration = {
merchantId: '{MERCHANT_ID}',
browserCallbackBase: '{MERCHANT_CALLBACKS_BASE}',
confirmUrl: '{MERCHANT_SUCCESS_URL}',
products: 'valuations+ep1' // Default is just 'valuations'
};
import('{ASSETS_URL}/v1/main.js')
.then(module => { window.Ealyx = module.Ealyx; })
.catch(err => console.error('Error loading Ealyx:', err));
</script>
Note: For production, replace
{ASSETS_URL}withhttps://cdn.ealyx.tech
The frontend SDK will automatically:
- Load trade-in teasers on your pages
- Handle the valuation modal
- Manage the Ealyx Pay modal
- Emit events for your backend to listen to (see Available SDK Events for complete reference)
Authentication
Overview
Ealyx uses two layers of authentication to secure API access. Understanding the difference is crucial for proper integration.
Layer 1: Credentials (Client ID + Secret + Username + Password)
What are credentials?
These are your permanent, master credentials that identify your application and account:
| Credential | Purpose |
|---|---|
CLIENT_ID | Uniquely identifies your application/merchant account |
CLIENT_SECRET | Secret key paired with CLIENT_ID for secure identification |
USERNAME | Your administrative user account in Ealyx |
PASSWORD | Your administrative user password |
When are credentials used?
Only during the initial authentication step to obtain temporary tokens. You send credentials to Ealyx's OAuth server exactly twice:
- Initial login - To get access_token and refresh_token
- Token refresh - To get a new access_token when it expires
Security considerations:
- Never hardcode credentials in your application
- Never expose in API calls (except the initial OAuth request)
- Store securely in environment variables or secrets management system
- Rotate regularly as a security best practice
Layer 2: OAuth 2.0 Tokens (Access Token + Refresh Token)
What are tokens?
Tokens are temporary credentials issued by Ealyx after you successfully authenticate with your credentials:
| Token | Duration | Purpose |
|---|---|---|
access_token | 1 hour | Used to authenticate all API requests |
refresh_token | Long-lived | Used to obtain new access tokens without re-authenticating |
expires_in | 3600 seconds | Time until access_token expires |
When are tokens used?
Every API call to Ealyx (after initial authentication) uses the access_token:
curl -X GET '{API_BASE_URL}/core/merchants/' \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json'
Token Lifecycle:
- Initial login → Obtain
access_token+refresh_token - Store tokens → Save in your database
- Make API calls → Use
access_tokenin Authorization header - Token expires → etect expiration using
expires_inand the timestamp when the token was obtained, userefresh_tokento get newaccess_token - Continue → Use new
access_tokenfor subsequent calls and replace the newrefresh_token - Refresh fails → Re-authenticate using credentials again
Security benefits:
- Time-limited - Tokens expire after 1 hour, limiting damage if compromised
- Revocable - Tokens automatically become invalid after expiration
- Renewable - Get new tokens without exposing credentials repeatedly
- Separable - Credentials stay secure; only temporary tokens are transmitted
Why This Two-Layer Approach?
Credentials alone would be unsafe:
- Sending username/password with every API call = huge security risk
- If credentials leak, attacker has permanent access
Tokens provide security:
- Only credentials are sent once (in OAuth request)
- Tokens are sent in every API call, but they expire automatically
- If a token leaks, it's only valid for 1 hour
Analogy:
Credentials = Master key to your house (stored safely at home)
Access Token = Day pass valid for 1 hour (carried with you)
You use the master key once to get the day pass (setup).
You use the day pass all day long (every API call).
At the end of the day, the pass expires and becomes useless.
Tomorrow, you use the master key to get a new day pass.
Token Management
Since you're making HTTP API calls directly, you need to manage OAuth 2.0 tokens programmatically. This involves storing tokens, handling authentication, and managing token lifecycle.
Token Storage
You need to store OAuth tokens persistently between requests. The storage mechanism is flexible and depends on your infrastructure:
- Relational Database (MySQL, PostgreSQL, etc.)
- NoSQL Database (MongoDB, DynamoDB, etc.)
- Key-Value Store (Redis, Memcached)
- File System (with proper locking mechanisms)
- Any other persistent storage you already use
The key requirements are:
- Persistence: Tokens must survive server restarts
- Atomic Updates: Concurrent requests must not corrupt token data
- Security: Tokens must be protected at rest (encryption recommended)
- Access Speed: Lookups should be fast (tokens are checked on every API call)
Option A: MySQL
CREATE TABLE ealyx_tokens (
id INT PRIMARY KEY AUTO_INCREMENT,
access_token VARCHAR(2048) NOT NULL,
refresh_token VARCHAR(2048) NOT NULL,
token_type VARCHAR(50) NOT NULL DEFAULT 'Bearer',
expires_at DATETIME NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY unique_latest (id)
);
To retrieve the latest token:
SELECT * FROM ealyx_tokens ORDER BY id DESC LIMIT 1;
To update (refresh) the token:
INSERT INTO ealyx_tokens (access_token, refresh_token, token_type, expires_at)
VALUES (?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
access_token = VALUES(access_token),
refresh_token = VALUES(refresh_token),
expires_at = VALUES(expires_at),
updated_at = NOW();
Option B: PostgreSQL
CREATE TABLE ealyx_tokens (
id SERIAL PRIMARY KEY,
access_token VARCHAR(2048) NOT NULL,
refresh_token VARCHAR(2048) NOT NULL,
token_type VARCHAR(50) NOT NULL DEFAULT 'Bearer',
expires_at TIMESTAMP NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE UNIQUE INDEX idx_latest_token ON ealyx_tokens (id DESC);
To retrieve the latest token:
SELECT * FROM ealyx_tokens ORDER BY id DESC LIMIT 1;
To update (refresh) the token (using INSERT with conflict handling):
INSERT INTO ealyx_tokens (access_token, refresh_token, token_type, expires_at)
VALUES (?, ?, ?, ?)
ON CONFLICT (id) DO UPDATE SET
access_token = EXCLUDED.access_token,
refresh_token = EXCLUDED.refresh_token,
expires_at = EXCLUDED.expires_at,
updated_at = CURRENT_TIMESTAMP;
Or simply insert new records and always query the latest:
INSERT INTO ealyx_tokens (access_token, refresh_token, token_type, expires_at)
VALUES (?, ?, ?, ?);
SELECT * FROM ealyx_tokens ORDER BY id DESC LIMIT 1;
Token Lifecycle
- Initial Login: Obtain
access_tokenandrefresh_tokenusing your credentials - Store Tokens: Save them in your persistent storage
- Use Access Token: Include it in all API requests
- Check Expiration: Before each request, verify if token is still valid
- Refresh if Needed: When expired, use
refresh_tokento get a newaccess_token - Re-authenticate if Refresh Fails: If refresh fails, perform login again
Initial Login
Perform a one-time authentication to obtain initial tokens:
# 1. Set your credentials and API base URL
# For staging: API_BASE_URL="https://api.stg.ealyx.tech"
# For production: API_BASE_URL="https://api.ealyx.tech"
CLIENT_ID="your_client_id"
CLIENT_SECRET="your_client_secret"
USERNAME="your_username"
PASSWORD="your_password"
API_BASE_URL="{API_BASE_URL}"
# 2. Authenticate
curl -X POST "$API_BASE_URL/oauth2/token/" \
-H "Authorization: Basic $(echo -n "$CLIENT_ID:$CLIENT_SECRET" | base64)" \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=password' \
-d "username=$USERNAME" \
-d "password=$PASSWORD" \
-d 'scope=core payments valuations'
Expected response:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"expires_in": 3600,
"token_type": "Bearer",
"refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"merchant_id": "merchant_67890",
"user_id": "user_12345"
}
| Check | Expected | If it fails |
|---|---|---|
access_token | Not null | Check CLIENT_ID/SECRET are correct |
user_id | Not null | Check USERNAME/PASSWORD are correct |
merchant_id | Not null | Contact Ealyx - credentials may not be activated |
Store in your database: access_token, refresh_token, expires_at (now + expires_in), merchant_id, user_id
Save user_id and merchant_id - needed later for webhook signature validation.
Important:
- Perform this initial login only once during setup, not on every request
- Keep
CLIENT_SECRETsecure and never expose it to the frontend- The
access_tokenexpires afterexpires_inseconds (typically 3600 seconds = 1 hour)- Use the
refresh_tokento obtain new access tokens without re-authenticating
Token Refresh
When the access_token is about to expire (or has expired), use the refresh_token:
# Use the stored refresh_token from initial login
CLIENT_ID="your_client_id"
CLIENT_SECRET="your_client_secret"
REFRESH_TOKEN="your_stored_refresh_token"
API_BASE_URL="{API_BASE_URL}"
# Request a new token
curl -X POST "$API_BASE_URL/oauth2/token/" \
-H "Authorization: Basic $(echo -n "$CLIENT_ID:$CLIENT_SECRET" | base64)" \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=refresh_token' \
-d "refresh_token=$REFRESH_TOKEN"
Expected response (same format as initial login):
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"expires_in": 3600,
"token_type": "Bearer",
"refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"merchant_id": "merchant_67890",
"user_id": "user_12345"
}
| Check | Expected | If it fails |
|---|---|---|
New access_token | Not null | Refresh token may be expired - re-authenticate |
New refresh_token | Not null | Store this new refresh token immediately |
Update your database with the new tokens and recalculate expires_at.
Using Bearer Tokens in API Requests
Include the access_token in the Authorization header for all API calls:
ACCESS_TOKEN="your_valid_access_token"
API_BASE_URL="{API_BASE_URL}"
curl -X GET "$API_BASE_URL/core/merchants/" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json'
| Check | Expected | If it fails |
|---|---|---|
| HTTP status | 200 OK | Token may be expired - refresh it |
| Response | Merchant JSON object | Check Authorization: Bearer header format |
| HTTP 401 | - | Token expired - use Token Refresh above |
Token Management Bash Scripts
For production use, implement these bash functions to automatically manage token lifecycle. These scripts handle authentication, expiration checking, and token refresh:
ealyx-token-manager.sh - Complete token management script:
#!/bin/bash
# Token Management for Ealyx API
# Source this file in your scripts: source ealyx-token-manager.sh
set -e
# Configuration (customize these)
EALYX_CONFIG_FILE="${EALYX_CONFIG_FILE:-.ealyx-config}"
EALYX_TOKEN_FILE="${EALYX_TOKEN_FILE:-.ealyx-tokens}"
API_BASE_URL="${API_BASE_URL:-{API_BASE_URL}}"
# Load credentials from config file if it exists
if [ -f "$EALYX_CONFIG_FILE" ]; then
source "$EALYX_CONFIG_FILE"
fi
# Function: Authenticate and get initial tokens
ealyx_authenticate() {
local client_id="$1"
local client_secret="$2"
local username="$3"
local password="$4"
if [ -z "$client_id" ] || [ -z "$client_secret" ] || [ -z "$username" ] || [ -z "$password" ]; then
echo "Usage: ealyx_authenticate <CLIENT_ID> <CLIENT_SECRET> <USERNAME> <PASSWORD>"
return 1
fi
local basic_auth=$(echo -n "$client_id:$client_secret" | base64 | tr -d '\n')
local response=$(curl -s -X POST "$API_BASE_URL/oauth2/token/" \
-H "Authorization: Basic $basic_auth" \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=password' \
-d "username=$username" \
-d "password=$password" \
-d 'scope=core payments valuations')
# Check for errors
if echo "$response" | grep -q '"error"'; then
echo "❌ Authentication failed:"
echo "$response" | jq .
return 1
fi
# Calculate and add expires_at timestamp (as epoch seconds)
# Using epoch timestamp is portable across all platforms (no date -d needed)
local expires_in=$(echo "$response" | jq -r '.expires_in')
local now=$(date +%s)
local expires_at=$((now + expires_in))
# Add expires_at to JSON and save
echo "$response" | jq --argjson expires_at "$expires_at" '. + {expires_at: $expires_at}' > "$EALYX_TOKEN_FILE"
echo "✓ Authentication successful. Tokens saved to $EALYX_TOKEN_FILE"
return 0
}
# Function: Get a valid access token (refreshes if expired)
ealyx_get_token() {
local scope="${1:-core payments valuations}"
# Check if token file exists
if [ ! -f "$EALYX_TOKEN_FILE" ]; then
echo "❌ Token file not found: $EALYX_TOKEN_FILE"
echo "Run: ealyx_authenticate <CLIENT_ID> <CLIENT_SECRET> <USERNAME> <PASSWORD>"
return 1
fi
# Read token data
local access_token=$(jq -r '.access_token' "$EALYX_TOKEN_FILE")
local refresh_token=$(jq -r '.refresh_token' "$EALYX_TOKEN_FILE")
local expires_at=$(jq -r '.expires_at' "$EALYX_TOKEN_FILE")
# Check if token is expired (with 5-minute buffer)
# Note: expires_at should be stored as epoch timestamp (seconds since 1970)
# This avoids date -d which is GNU-specific and fails on macOS
local now=$(date +%s)
local expires_timestamp="${expires_at:-$((now + 3600))}" # Default to 1 hour if not set
local buffer=$((5 * 60)) # 5 minute buffer
if [ $now -gt $((expires_timestamp - buffer)) ]; then
echo "⟳ Token expired, refreshing..." >&2
ealyx_refresh_token "$scope" || return 1
access_token=$(jq -r '.access_token' "$EALYX_TOKEN_FILE")
fi
echo "$access_token"
return 0
}
# Function: Refresh the access token
ealyx_refresh_token() {
local scope="${1:-core payments valuations}"
local client_id="${CLIENT_ID:-}"
local client_secret="${CLIENT_SECRET:-}"
if [ -z "$client_id" ] || [ -z "$client_secret" ]; then
echo "❌ CLIENT_ID and CLIENT_SECRET must be set"
return 1
fi
# Read refresh token from file
if [ ! -f "$EALYX_TOKEN_FILE" ]; then
echo "❌ Token file not found: $EALYX_TOKEN_FILE"
return 1
fi
local refresh_token=$(jq -r '.refresh_token' "$EALYX_TOKEN_FILE")
# Request new token
local response=$(curl -s -X POST "$API_BASE_URL/oauth2/token/" \
-H "Authorization: Basic $(echo -n "$client_id:$client_secret" | base64)" \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=refresh_token' \
-d "refresh_token=$refresh_token" \
-d "scope=$scope")
# Check for errors
if echo "$response" | grep -q '"error"'; then
echo "❌ Token refresh failed:"
echo "$response" | jq .
return 1
fi
# Calculate and add expires_at timestamp (as epoch seconds)
# Using epoch timestamp is portable across all platforms (no date -d needed)
local expires_in=$(echo "$response" | jq -r '.expires_in')
local now=$(date +%s)
local expires_at=$((now + expires_in))
# Save updated tokens with expires_at as epoch timestamp
echo "$response" | jq --arg exp "$expires_at" '. + {expires_at: $exp | tonumber}' > "$EALYX_TOKEN_FILE"
echo "✓ Token refreshed successfully" >&2
return 0
}
# Function: Make an authenticated API call
ealyx_api() {
local method="$1"
local endpoint="$2"
shift 2
local curl_args=("$@")
if [ -z "$method" ] || [ -z "$endpoint" ]; then
echo "Usage: ealyx_api <METHOD> <ENDPOINT> [CURL_ARGS...]"
echo "Example: ealyx_api GET /core/merchants/"
return 1
fi
# Get valid token
local access_token=$(ealyx_get_token) || return 1
# Build URL
local url="$API_BASE_URL$endpoint"
# Make request with token
curl -s -X "$method" "$url" \
-H "Authorization: Bearer $access_token" \
"${curl_args[@]}"
return 0
}
# Export functions for use in other scripts
export -f ealyx_authenticate
export -f ealyx_get_token
export -f ealyx_refresh_token
export -f ealyx_api
Important: Token Storage Format
The token manager stores expires_at as an epoch timestamp (seconds since January 1, 1970). This approach:
- ✅ Works on macOS, Linux, and all Unix-like systems (no
date -dneeded) - ✅ Simple arithmetic comparison:
if [ $now -gt $expires_timestamp ] - ✅ No string parsing or date format conversion needed
When you run ealyx_authenticate or ealyx_refresh_token, the token file looks like:
{
"access_token": "...",
"refresh_token": "...",
"expires_in": 3600,
"token_type": "Bearer",
"merchant_id": "merchant_123",
"user_id": "user_456",
"expires_at": 1734896400
}
The expires_at field is a number (epoch timestamp), not a string. This makes expiration checks trivial:
current=$(date +%s)
if [ $current -gt $expires_at ]; then
echo "Token expired"
fi
Usage Example:
These functions are included in the ealyx-token-manager.sh:
# Source the token manager in your scripts
source ealyx-token-manager.sh
# Initial authentication
ealyx_authenticate "your_client_id" "your_client_secret" "username" "password"
# Get a valid token (automatically refreshes if needed)
TOKEN=$(ealyx_get_token) || exit 1
# Make API calls
ealyx_api GET "/core/merchants/" \
-H "Content-Type: application/json"
# For order updates, get token with 'updates' scope
TOKEN=$(ealyx_get_token "updates") || exit 1
Here are additional utility functions to append into ealyx-token-manager.sh:
# Function: Validate webhook signature
ealyx_validate_signature() {
local received_signature="$1"
local request_body="$2"
local user_id="${USER_ID:-}"
local merchant_id="${MERCHANT_ID:-}"
if [ -z "$user_id" ] || [ -z "$merchant_id" ]; then
echo "❌ USER_ID and MERCHANT_ID must be set"
return 1
fi
if [ -z "$received_signature" ] || [ -z "$request_body" ]; then
echo "Usage: ealyx_validate_signature <SIGNATURE> <REQUEST_BODY>"
return 1
fi
local secret="$user_id-$merchant_id"
local expected_signature=$(echo -n "$request_body" | openssl dgst -sha256 -hmac "$secret" | cut -d' ' -f2)
if [ "$received_signature" = "$expected_signature" ]; then
echo "✓ Signature valid"
return 0
else
echo "❌ Signature invalid"
echo "Received: $received_signature"
echo "Expected: $expected_signature"
return 1
fi
}
# Export functions for use in other scripts
export -f ealyx_validate_signature
Usage Examples:
# 1. Source the script
source ealyx-token-manager.sh
# 2. Set credentials (or load from ealyx-config)
export CLIENT_ID="your_client_id"
export CLIENT_SECRET="your_client_secret"
export USERNAME="your_username"
export PASSWORD="your_password"
export USER_ID="from_initial_auth_response"
export MERCHANT_ID="from_initial_auth_response"
# 3. Authenticate once
ealyx_authenticate "$CLIENT_ID" "$CLIENT_SECRET" "$USERNAME" "$PASSWORD"
# 4. Make API calls (tokens handled automatically)
ealyx_api GET "/core/merchants/" -H 'Content-Type: application/json' | jq .
# 5. For POST requests with data
ealyx_api POST "/payments/orders/update" \
-H 'Content-Type: application/json' \
-d '{"order_id":"ORD-123","update_type":"shipped"}' | jq .
# 6. Validate webhook signatures
request_body='{"data":{"cart_id":"cart_123","status":"pending"}}'
received_sig="from_header: X-Ealyx-Signature"
ealyx_validate_signature "$received_sig" "$request_body"
✓ Benefits of using these scripts:
- Automatic token expiration detection
- Transparent token refresh on first request
- Consistent error handling
- Webhook signature validation helper
- Reusable across multiple scripts
Token Scope Management
Different Ealyx API operations require different OAuth scopes. The Ealyx OAuth server validates that your token has the required scope for each endpoint:
| Operation | Required Scope | Endpoint |
|---|---|---|
| Valuation, Trade-in queries, Merchant info | core payments valuations | /core/merchants/, /core/sessions/, /core/tradeinitems/ |
| Order status updates | updates | POST /payments/orders/update |
Important: Scopes Cannot Be Combined
You cannot request multiple scopes in a single token request like scope=core payments valuations updates. The Ealyx OAuth server validates scopes strictly - you must request tokens with the exact scopes needed:
- Initial login scope:
core payments valuations(for all standard operations) - Order update scope:
updates(explicitly, for order updates only)
If you try to use a token with the wrong scope on an endpoint, you'll get a 403 Forbidden error.
Recommended Strategy: Single Token + Refresh for Updates
Store one primary token and refresh it with the updates scope only when needed:
# Initial login - store this token and its refresh_token
curl -X POST '{API_BASE_URL}/oauth2/token/' \
-H 'Authorization: Basic '$(echo -n "{CLIENT_ID}:{CLIENT_SECRET}" | base64) \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=password' \
-d 'username={USERNAME}' \
-d 'password={PASSWORD}' \
-d 'scope=core payments valuations'
# Response includes:
# {
# "access_token": "primary_token_abc123...",
# "refresh_token": "refresh_abc123...",
# "expires_in": 3600
# }
# Later, when you need to update an order, obtain a NEW token with updates scope
curl -X POST '{API_BASE_URL}/oauth2/token/' \
-H 'Authorization: Basic '$(echo -n "{CLIENT_ID}:{CLIENT_SECRET}" | base64) \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=refresh_token' \
-d 'refresh_token={REFRESH_TOKEN}' \
-d 'scope=updates'
# Response includes update_token with limited scope:
# {
# "access_token": "update_token_xyz789...",
# "refresh_token": "refresh_xyz789...",
# "expires_in": 3600
# }
# Use this update_token ONLY for POST /payments/orders/update
curl -X POST '{API_BASE_URL}/payments/orders/update' \
-H 'Authorization: Bearer update_token_xyz789...' \
-H 'Content-Type: application/json' \
-d '{"order_id":"ORD-123","update_type":"shipped"}'
# After update completes, return to using your primary_token for other operations with other refresh token and scope `core payments valuations`
Why Separate Scopes?
Security isolation - each token type has minimal permissions. If a token leaks:
- Leaked
core payments valuationstoken: Attacker can query valuations, read merchant data (not payment-related) - Leaked
updatestoken: Attacker can only update order status (cannot read customer data)
How the Token Manager Handles This
The ealyx_get_token function supports this pattern:
# Default: Get token with standard scope
TOKEN=$(ealyx_get_token)
# For order updates: Explicitly request updates scope
UPDATE_TOKEN=$(ealyx_get_token "updates")
# Use the right token for each operation
curl -X GET '{API_BASE_URL}/core/merchants/' \
-H "Authorization: Bearer $TOKEN"
curl -X POST '{API_BASE_URL}/payments/orders/update' \
-H "Authorization: Bearer $UPDATE_TOKEN" \
-d '{"order_id":"ORD-123","update_type":"shipped"}'
Note: The PHP SDK uses this pattern - it obtains a fresh token with
updatesscope for each order update call, using therefresh_tokenfrom the primary login. This is the recommended approach for security and clarity.