Authentication

Learn how authentication works in Stash Webshop. This guide covers client-side bearer token authentication, when API keys might be needed, and webhook signature verification.

Stash Webshop primarily uses client-side authentication (bearer tokens) for player-facing operations. Unlike Stash Pay and Stash Launcher, API keys are typically not required for most Webshop operations.

Authentication Methods

Stash Webshop uses different authentication methods depending on the operation:

  1. Bearer Tokens - For client-side player authentication (primary method)
  2. API Keys - For webhook verification and server-side operations (when applicable)
  3. HMAC Signatures - For webhook callbacks from Stash to your backend (when applicable)

Client-Side Authentication (Primary Method)

Bearer Token Authentication

Most Webshop operations use bearer tokens for player authentication. Players authenticate through your game's authentication system, and Stash validates these tokens.

How It Works

  1. Player Authenticates: Player logs into your game using your authentication system
  2. Token Generation: Your game generates a JWT or similar token
  3. Token Validation: Stash validates the token and extracts player information
  4. Webshop Access: Player can access the webshop with their authenticated session

Client-Side Integration

Client-Side Integration
// Your game's authentication flow
// 1. Player logs in to your game
const playerToken = await authenticatePlayer(playerCredentials);

// 2. Initialize Stash SDK with player's token
// The SDK handles token passing automatically
stashSDK.initialize({
  shopHandle: 'your-shop-handle',
  // SDK automatically includes player's auth token in requests
});

// 3. Player can now access webshop
// All requests are authenticated using the player's token
const catalog = await stashSDK.getCatalog();

For standard Webshop operations, you do not need API keys. All operations use the player's bearer token for authentication.

Operations That Don't Require API Keys

These standard Webshop operations use bearer tokens:

  • Browsing catalog
  • Adding items to cart
  • Viewing cart
  • Checkout process
  • Payment processing
  • Viewing purchase history

When API Keys Are Needed

While most Webshop operations don't require API keys, there are specific scenarios where they may be needed:

1. Webhook Verification

If you configure webhooks for Webshop events (e.g., purchase completed, cart updated), you may need to verify webhook signatures. However, webhooks typically use HMAC signatures rather than API keys for verification.

2. Server-Side Analytics or Reporting

If you're querying Webshop data server-side for analytics or reporting, you might need API keys. However, most Webshop endpoints are designed for client-side use.

3. Custom Backend Tools

If you're building custom admin tools or server-side integrations that interact with Webshop, API keys may be required.

Most Webshop endpoints are designed for client-side use and may not support API key authentication. Check the API documentation for specific endpoints.

Webhook Authentication (If Applicable)

If you configure webhooks for Webshop events, Stash will authenticate webhook requests using HMAC signatures.

Verifying Webhook Signatures

Node.js Example

Node.js - Webhook Signature Verification
const crypto = require('crypto');

function verifyWebhookSignature(requestBody, signature, webhookSecret) {
  const receivedSignature = Buffer.from(signature, 'base64');
  
  const expectedSignature = crypto
    .createHmac('sha256', webhookSecret)
    .update(requestBody, 'utf8')
    .digest();
  
  return crypto.timingSafeEqual(receivedSignature, expectedSignature);
}

// Express.js middleware
function verifyWebshopWebhook(req, res, next) {
  const signature = req.headers['stash-webhook-signature'];
  const webhookSecret = process.env.STASH_WEBHOOK_SECRET;
  
  if (!signature) {
    return res.status(401).json({ error: 'Missing webhook signature' });
  }
  
  const body = JSON.stringify(req.body);
  
  if (!verifyWebhookSignature(body, signature, webhookSecret)) {
    return res.status(401).json({ error: 'Invalid webhook signature' });
  }
  
  next();
}

// Use middleware
app.post('/stash/webshop/webhook', verifyWebshopWebhook, (req, res) => {
  const event = req.body;
  
  switch (event.type) {
    case 'purchase.completed':
      handlePurchaseCompleted(event.data);
      break;
    case 'cart.updated':
      handleCartUpdated(event.data);
      break;
  }
  
  res.json({ received: true });
});

Python Example

Python - Webhook Signature Verification
import hmac
import hashlib
import base64
import os
from flask import Flask, request, jsonify

def verify_webhook_signature(request_body, signature, webhook_secret):
    """Verify webhook signature from Stash"""
    received_signature = base64.b64decode(signature)
    
    expected_signature = hmac.new(
        webhook_secret.encode('utf-8'),
        request_body.encode('utf-8'),
        hashlib.sha256
    ).digest()
    
    return hmac.compare_digest(received_signature, expected_signature)

app = Flask(__name__)

@app.route('/stash/webshop/webhook', methods=['POST'])
def webshop_webhook():
    signature = request.headers.get('stash-webhook-signature')
    webhook_secret = os.environ['STASH_WEBHOOK_SECRET']
    
    if not signature:
        return jsonify({'error': 'Missing webhook signature'}), 401
    
    request_body = request.get_data(as_text=True)
    
    if not verify_webhook_signature(request_body, signature, webhook_secret):
        return jsonify({'error': 'Invalid webhook signature'}), 401
    
    # Process webhook event
    event = request.get_json()
    # ...
    
    return jsonify({'received': True})

Webhook secrets are different from API keys and are configured separately in your webhook settings in Stash Studio.

Server-Side Operations (If Needed)

When You Might Need Server-Side Access

While uncommon, there are scenarios where you might need server-side access to Webshop data:

  1. Analytics and Reporting: Querying purchase data server-side
  2. Inventory Management: Updating catalog items programmatically
  3. Custom Integrations: Building custom tools that interact with Webshop

Using API Keys (If Applicable)

If you need to make server-side requests to Webshop-related endpoints:

Node.js - Server-Side Request (If Endpoint Supports It)
const axios = require('axios');

async function getWebshopData() {
  const response = await axios.get(
    'https://api.stash.gg/api/v1/webshop/data',
    {
      headers: {
        'X-Stash-Api-Key': process.env.STASH_API_KEY
      }
    }
  );
  return response.data;
}

Important: Most Webshop endpoints are designed for client-side use and may not support API key authentication. Check the API documentation for specific endpoints.

Comparison with Other Products

Stash Pay vs. Stash Webshop

FeatureStash PayStash Webshop
Primary AuthAPI Keys (server-side)Bearer Tokens (client-side)
API Keys RequiredYes (for checkout links, Quick Pay)No (for standard operations)
Client-Side AuthNoYes (bearer tokens)
Webhook AuthHMAC SignaturesHMAC Signatures (if configured)

Stash Launcher vs. Stash Webshop

FeatureStash LauncherStash Webshop
Primary AuthAPI Keys (server-side)Bearer Tokens (client-side)
API Keys RequiredYes (for build management)No (for standard operations)
Use CaseBuild artifact managementPlayer-facing shop

Security Best Practices

For Client-Side Operations

DO:

  • Store bearer tokens securely
  • Use HTTPS for all requests
  • Implement token refresh mechanisms
  • Never expose tokens in client-side code logs
  • Validate player identity before allowing webshop access
  • Use secure token storage (keychain, secure storage)

DON'T:

  • Expose API keys in client-side code
  • Store tokens in plain text
  • Send tokens over unencrypted connections

For Webhook Verification (If Applicable)

DO:

  • Always verify webhook signatures
  • Use constant-time comparison for signature verification
  • Store webhook secrets securely
  • Use HTTPS for webhook endpoints
  • Implement rate limiting
  • Log all webhook requests
  • Monitor for suspicious activity

DON'T:

  • Trust webhook requests without signature verification
  • Use regular string comparison for signature verification

Common Integration Patterns

Pattern 1: Standard Client-Side Integration

// 1. Player authenticates in your game
const playerAuth = await authenticatePlayer();

// 2. Initialize Stash SDK
stashSDK.initialize({
  shopHandle: 'your-shop-handle',
  authToken: playerAuth.token
});

// 3. Player uses webshop
// All operations authenticated via bearer token
// No API keys needed

Pattern 2: Webhook Integration (If Needed)

// 1. Configure webhook in Studio
// 2. Receive webhook events
app.post('/stash/webshop/webhook', verifyWebhookSignature, (req, res) => {
  const event = req.body;
  
  switch (event.type) {
    case 'purchase.completed':
      handlePurchaseCompleted(event.data);
      break;
    case 'cart.updated':
      handleCartUpdated(event.data);
      break;
  }
  
  res.json({ received: true });
});

Common Pitfalls

Client-Side vs Server-Side Confusion

Common Mistake: Trying to use API keys for standard Webshop operations

Solution: Webshop uses bearer tokens for client-side authentication. API keys are only needed for specific server-side operations (webhooks, analytics, custom tools).

Common Mistake: Embedding API keys in mobile apps or web browsers

Solution: Never use API keys in client-side code. Use bearer tokens for client-side authentication instead.

Bearer Token Issues

Common Mistake: Not passing bearer token to Stash SDK

Solution: Ensure the player's bearer token is passed when initializing the Stash SDK. The SDK handles token passing automatically.

Common Mistake: Using expired or invalid bearer tokens

Solution: Implement token refresh mechanisms and ensure tokens are valid before SDK initialization.

When API Keys Are Actually Needed

Common Mistake: Creating API keys for Webshop when they're not needed

Solution: Most Webshop operations don't require API keys. Only create them if you need:

  • Webhook verification (though webhooks typically use separate secrets)
  • Server-side analytics (if endpoints support it)
  • Custom backend tools

Common Mistake: Using API keys for catalog browsing or checkout

Solution: These operations use bearer tokens, not API keys. API keys are for server-side operations only.

Troubleshooting

Player Cannot Access Webshop

Possible Causes:

  • Invalid or expired bearer token
  • Token not being passed correctly
  • Player not authenticated in your game

Solutions:

  • Verify player is authenticated in your game
  • Check that token is being passed to Stash SDK
  • Ensure token is valid and not expired
  • Review SDK initialization

Webhook Verification Failing

Possible Causes:

  • Incorrect webhook secret
  • Signature verification not implemented
  • Request body modified before verification

Solutions:

  • Verify webhook secret in Studio settings
  • Ensure signature verification is implemented
  • Verify request body is not modified before verification
  • Check signature header name matches expected format

When to Use API Keys

Use API Keys For:

  • Webhook Verification (though webhooks typically use separate secrets)
  • Server-Side Analytics (if endpoints support it)
  • Custom Backend Tools (if building admin tools)

Don't Use API Keys For:

  • Standard Player Operations (use bearer tokens)
  • Client-Side Requests (never expose API keys)
  • Catalog Browsing (client-side operation)
  • Checkout Process (uses player's bearer token)

Summary

Key Takeaway: Stash Webshop is designed for client-side use with bearer token authentication. API keys are not required for standard Webshop operations. If you need server-side access or webhook verification, follow the patterns outlined in this guide, but most integrations will only need client-side bearer token authentication.

How is this guide?