Authorization Ticket Integration¶
Target Audience: Developers implementing Tulo Shop integration for sites not using Tulo Payway SSO2
Overview¶
Authorization tickets enable seamless Single Sign-On (SSO) between your site and Tulo Shop, allowing users to:
- Log into Tulo Shop from your site without re-entering credentials
- Return to your site after purchase automatically logged in
This guide is for sites that manage their own authentication and do not use Tulo Payway SSO2 for login.
When to Use Authorization Tickets
Use this integration method when:
- Your site has its own authentication system (not Tulo Payway SSO2)
- You want seamless SSO between your site and Tulo Shop
- Users should be able to move between systems without re-logging in
How It Works¶
Authorization tickets are short-lived, one-time use codes that can be exchanged for a Payway access token tied to a user's identity. These tickets are generated via the Payway API.
Detailed Documentation
For a comprehensive technical reference on authorization tickets, see Ticket Authentication in the Payway documentation.
The flow consists of two scenarios:
Scenario 1: Sending Users to Tulo Shop¶
When a logged-in user on your site wants to make a purchase:
graph LR
A[Your Site<br/>User logged in] --> B[Generate Ticket<br/>via Payway API]
B --> C[Redirect to Shop<br/>with ticket in URL]
C --> D[Tulo Shop<br/>User automatically logged in]
Scenario 2: Receiving Users Back After Purchase¶
When a user completes a purchase and returns to your site:
graph LR
A[User completes purchase<br/>in Tulo Shop] --> B[Shop generates ticket<br/>for your domain]
B --> C[User redirected to<br/>your site with ticket]
C --> D[Your site validates ticket<br/>User automatically logged in]
Prerequisites¶
Before implementing authorization ticket integration, ensure you have:
1. Payway API Access¶
- API Client ID (for your site)
- API Client Secret
- Server-to-server access token capability
- Access to Payway Authorization API endpoints
2. Tulo Shop Configuration¶
Contact Tulo support to configure your domain in Tulo Shop's TicketConfiguration. You'll need to choose an integration mode:
Option A: ReturnUrl Mode (Recommended) : Tickets are appended directly to your return URL as a query parameter : Best for simple integrations where your site handles ticket validation on the main domain
Option B: SeparateTicketAuth Mode
: Tickets are sent to a separate authentication endpoint with the final destination in a returnUrl parameter
: Best for centralized authentication servers or when using a separate auth subdomain
Provide to Tulo support:
- Your domain name (e.g.,
news.example.com) - Your Payway Client ID
- Preferred integration mode
- Auth endpoint URL (if using SeparateTicketAuth mode)
3. HTTPS Certificate¶
All ticket exchanges must use HTTPS for security.
Implementation: Sending Users to Tulo Shop¶
Step 1: Generate Authorization Ticket¶
When a logged-in user needs to visit Tulo Shop, generate an authorization ticket via the Payway API.
Detailed API Documentation
For complete details on generating authorization tickets, including request/response formats and error handling, see Ticket Authentication - Origin Application.
Key points:
- Use an access token tied to the user's identity (not a server-to-server token)
- The access token must have the
/api/authorization/ticketscope - Send the Tulo Shop client_id as the only parameter
- The user's identity comes from the access token itself
- Tickets are short-lived and can only be used once
- Generate tickets just-in-time before redirecting the user
Step 2: Redirect User to Tulo Shop¶
Build the Tulo Shop URL with the ticket in the at query parameter and include a returnUrl parameter so the user can return to your site after purchase.
URL Format:
https://shop.example.com/marketplace/{groupId}/{marketplaceId}?at={ticket}&returnUrl={your_site_url}
Parameters:
| Parameter | Required | Description |
|---|---|---|
at |
Yes | The authorization ticket |
returnUrl |
Recommended | URL where the user should return after purchase |
campaign |
Optional | Pre-select a campaign |
period |
Optional | Pre-select a payment period |
Always Include returnUrl
The returnUrl parameter is essential for Scenario 2 (receiving users back). Always include it so users can seamlessly return to your site after purchase.
Implementation: Receiving Users Back from Tulo Shop¶
After completing a purchase, Tulo Shop will redirect the user back to your site with an authorization ticket. Your site must validate this ticket and create a session.
Understanding the Return Flow¶
When Tulo Shop redirects the user:
- User completes purchase - User selects a product, creates account (if new), and completes payment
- Automatic login in Shop - If the user created a new account, they are automatically logged into Tulo Shop
- Order confirmation - User sees "Thank you" page with a "Return" button
- Ticket generation - When user clicks "Return", Shop generates a ticket for your domain
- Redirect to your site - User is redirected to your
returnUrlwith the ticket
Receiving the Ticket¶
The URL format depends on the integration mode configured:
ReturnUrl Mode (Recommended)¶
User arrives directly at your return URL with the ticket:
https://yoursite.com/welcome-back?ticket={authorization_ticket}
SeparateTicketAuth Mode¶
User arrives at your dedicated auth endpoint:
https://auth.yoursite.com/ticket-login?ticket={ticket}&returnUrl=https://yoursite.com/welcome-back
Your auth endpoint validates the ticket, then redirects to the returnUrl.
Step 1: Validate Ticket with Payway¶
Exchange the ticket for an access token using the Payway API:
POST https://payway-api.example.com/api/authorization/access_token
Content-Type: application/json
{
"grant_type": "ticket",
"ticket": "{received_ticket}",
"client_id": "{your_client_id}",
"client_secret": "{your_client_secret}"
}
Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "..."
}
Step 2: Get User Account Information¶
Use the access token to fetch user details:
GET https://payway-api.example.com/external/api/v1/me/
Authorization: Bearer {access_token}
Response:
{
"id": "account_123",
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe",
"customerNumber": "CUST001"
}
Step 3: Create Session and Log In User¶
After successfully validating the ticket and retrieving user information, your site needs to:
- Create a session for the user using your site's session management
- Store user information in the session (user ID, email, name, Payway account ID, etc.)
- Optionally store the access token if you need to make future API calls to Payway on behalf of the user
- Redirect the user to the final destination or remove the ticket from the URL for cleaner URLs
Implementation details will vary based on your technology stack and existing authentication system. The key is to establish an authenticated session that integrates with your site's existing user management.
Complete Round-Trip Example¶
Here's how the complete flow works when a user comes from your site, purchases a subscription, and returns:
1. User on Your Site (Logged In)¶
User is logged into: https://yoursite.com
User clicks: "Upgrade to Premium"
2. Your Site Generates Ticket¶
// Generate ticket via Payway API
const ticket = await generateTicket(user.paywayAccountId);
// Redirect to Shop with ticket and returnUrl
const shopUrl = `https://shop.example.com/marketplace/group1/market1` +
`?at=${ticket}` +
`&returnUrl=${encodeURIComponent('https://yoursite.com/welcome-back')}`;
res.redirect(shopUrl);
Result: https://shop.example.com/marketplace/group1/market1?at=xyz123...&returnUrl=https://yoursite.com/welcome-back
3. User in Tulo Shop (Automatically Logged In)¶
- User lands in Tulo Shop already logged in (via ticket)
- User selects subscription product
- User completes payment
- User sees order confirmation: "Thank you for your purchase!"
- User sees "Return to yoursite.com" button
4. User Clicks "Return" Button¶
Tulo Shop:
- Checks if user is logged in: ✓
- Looks up yoursite.com in its TicketConfiguration
- Generates authorization ticket for your domain
- Redirects to: https://yoursite.com/welcome-back?ticket=abc789...
5. Your Site Receives User with Ticket¶
// GET /welcome-back?ticket=abc789...
app.get('/welcome-back', async (req, res) => {
const ticket = req.query.ticket;
if (ticket) {
// Validate ticket and create session
await handleTicketLogin(req, ticket);
// User is now logged in on your site
return res.redirect('/welcome-back'); // Remove ticket from URL
}
// Show welcome page
res.render('welcome-back', { user: req.session.user });
});
Result¶
✅ User upgraded subscription in Tulo Shop ✅ User is logged into Tulo Shop ✅ User is logged into your site ✅ User can access premium content
Security Best Practices¶
Ticket Handling¶
Critical Security Measures
- Use tickets immediately - Tickets are short-lived
- One-time use only - Each ticket can only be exchanged once
- Never log tickets - Tickets are sensitive credentials (like passwords)
- HTTPS only - All ticket exchanges must use HTTPS
- Validate quickly - Don't delay between receiving ticket and validation
Prevent Ticket Reuse¶
Implement ticket reuse prevention to avoid security vulnerabilities:
// In-memory cache for processed tickets (use Redis in production)
const processedTickets = new Set();
async function handleTicketLogin(req, ticket) {
// Check if ticket already used
if (processedTickets.has(ticket)) {
throw new Error('Ticket already used');
}
try {
// Validate ticket with Payway
const accessToken = await validateTicket(ticket);
// Mark ticket as processed
processedTickets.add(ticket);
// Set timeout to clean up old tickets (tickets are short-lived anyway)
setTimeout(() => processedTickets.delete(ticket), 120000);
// Create session...
} catch (error) {
// Don't mark as processed if validation fails
throw error;
}
}
Session Security¶
Configure secure session settings:
// Express.js example
app.use(session({
secret: process.env.SESSION_SECRET,
name: 'yoursite.sid',
cookie: {
httpOnly: true, // Prevents JavaScript access
secure: true, // HTTPS only
sameSite: 'lax', // CSRF protection
maxAge: 1800000 // 30 minutes
},
resave: false,
saveUninitialized: false
}));
Error Handling¶
Ticket Validation Errors¶
Handle common error scenarios gracefully:
async function handleTicketLogin(req, ticket) {
try {
// Validate ticket...
return true;
} catch (error) {
if (error.response?.status === 401) {
// Invalid or expired ticket
console.error('Ticket validation failed: Invalid or expired ticket');
return false;
}
if (error.response?.status === 400) {
// Malformed ticket
console.error('Ticket validation failed: Malformed ticket');
return false;
}
// Other errors (network, server errors)
console.error('Ticket validation failed:', error.message);
return false;
}
}
User-Facing Error Messages¶
Provide clear, actionable error messages:
app.get('/welcome-back', async (req, res) => {
const ticket = req.query.ticket;
if (ticket) {
const loginSuccess = await handleTicketLogin(req, ticket);
if (!loginSuccess) {
// Show error message to user
return res.render('error', {
title: 'Login Failed',
message: 'Your login link has expired or is invalid. Please log in again.',
actionLink: '/login',
actionText: 'Go to Login'
});
}
}
// Continue...
});
Testing¶
Test Checklist¶
- [ ] Generate ticket - Your site can successfully generate tickets via Payway API
- [ ] Redirect to Shop - User redirects to Tulo Shop with ticket in URL
- [ ] Auto-login in Shop - User lands in Shop already logged in
- [ ] Complete purchase - User can select and purchase products
- [ ] Return with ticket - User returns to your site with ticket in URL
- [ ] Validate ticket - Your site successfully validates ticket with Payway API
- [ ] Create session - User session is created on your site
- [ ] Access content - User can access protected content
- [ ] Ticket expiry - Expired tickets are properly rejected
- [ ] Ticket reuse - Used tickets cannot be reused
- [ ] HTTPS enforcement - All ticket exchanges use HTTPS
- [ ] Error handling - Invalid tickets show user-friendly error messages
Testing Environments¶
Stage Environment:
- Tulo Shop: https://shop-stage.example.com
- Payway API: https://payway-api-stage.example.com
Production Environment:
- Tulo Shop: https://shop.example.com
- Payway API: https://payway-api.example.com
Test with Stage First
Always test the complete integration in the stage environment before deploying to production.
Troubleshooting¶
Issue: User Not Logged Into Shop¶
Symptoms: User arrives at Shop but is not logged in
Possible Causes:
- Ticket expired (generated too early)
- Ticket malformed or missing from URL
- Wrong Client ID used when generating ticket
- Ticket already used (clicked link twice)
Solutions:
- Generate tickets just-in-time before redirect
- Verify ticket is correctly appended to URL
- Confirm you're using the correct Tulo Shop Client ID
- Implement ticket reuse prevention
Issue: User Returns Without Ticket¶
Symptoms: User returns to your site but URL has no ticket parameter
Possible Causes:
- Your domain not configured in Tulo Shop's
TicketConfiguration - User not logged into Shop when clicking "Return"
- Wrong integration mode configured
Solutions:
- Contact Tulo support to verify your domain is configured
- Ensure user completed purchase and was auto-logged in
- Verify configuration mode (ReturnUrl vs SeparateTicketAuth) matches your implementation
Issue: Ticket Validation Fails¶
Symptoms: Your site receives ticket but Payway API returns 401 Unauthorized
Possible Causes:
- Wrong Client ID or Client Secret
- Ticket expired before validation
- Ticket already used
- Network/connectivity issues
Solutions:
- Verify Payway API credentials (Client ID and Secret)
- Minimize time between receiving ticket and validation
- Check if ticket was already processed (implement reuse prevention)
- Check network connectivity to Payway API
Issue: Session Not Created¶
Symptoms: Ticket validates successfully but user not logged in
Possible Causes:
- Session save failing silently
- Cookie domain mismatch
- CORS issues (if using separate auth endpoint)
- Session not persisted to storage
Solutions:
- Add detailed logging to session creation
- Verify cookie configuration (domain, secure, httpOnly)
- Check browser console for errors
- Ensure session storage (Redis, database) is working
API Reference¶
Generate Ticket¶
Generate an authorization ticket for a user.
Endpoint: POST /api/authorization/ticket
Headers:
Authorization: Bearer {s2s_access_token}
Content-Type: application/json
Request Body:
{
"accountId": "string",
"clientId": "string"
}
Response:
{
"ticket": "string"
}
Status Codes:
- 200 OK - Ticket generated successfully
- 401 Unauthorized - Invalid access token
- 400 Bad Request - Invalid accountId or clientId
Exchange Ticket for Access Token¶
Exchange an authorization ticket for an access token.
Endpoint: POST /api/authorization/access_token
Headers:
Content-Type: application/json
Request Body:
{
"grant_type": "ticket",
"ticket": "string",
"client_id": "string",
"client_secret": "string"
}
Response:
{
"access_token": "string",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "string"
}
Status Codes:
- 200 OK - Token issued successfully
- 401 Unauthorized - Invalid ticket, client_id, or client_secret
- 400 Bad Request - Malformed request
Get User Account¶
Retrieve the authenticated user's account information.
Endpoint: GET /external/api/v1/me/
Headers:
Authorization: Bearer {access_token}
Response:
{
"id": "string",
"email": "string",
"firstName": "string",
"lastName": "string",
"customerNumber": "string",
"address": {
"street": "string",
"zipCode": "string",
"city": "string",
"countryCode": "string"
}
}
Status Codes:
- 200 OK - User information retrieved successfully
- 401 Unauthorized - Invalid or expired access token
Support¶
For assistance with authorization ticket integration:
- Configuration Issues - Contact Tulo support to verify your domain configuration
- Technical Implementation - Refer to code examples in this guide
- Payway API Issues - Contact Tulo Payway API support
When contacting support, include:
- Your domain name
- Integration mode (ReturnUrl or SeparateTicketAuth)
- Error messages or logs (without sensitive data like tickets or tokens)
- Steps to reproduce the issue
- Environment (stage or production)
Related Documentation¶
- Ticket Authentication - Comprehensive technical reference for authorization tickets in Payway
- Redirect vs Embed Integration - Choose between redirect and embed methods
- Tulo Shop Analytics - Track user behavior with Google Tag Manager
- Tulo Payway SSO2 Documentation - For sites using Payway SSO2 (alternative to authorization tickets)