This document explains how iaptic manages access control for Stripe subscriptions, including user association and entitlement strategies.
Access Control Model
graph TB
subgraph Access Verification
A[Client] -- Access Key --> B[API]
B -- Verify --> C[Subscription]
C -- Check --> D[Entitlement]
end
subgraph User Association
E[Subscription] -- Metadata --> F[Username]
F -- Strategy --> G[Access Rights]
end
Entitlement Strategies
ALL_CLAIMERS (Default)
// Multiple users can access the same subscription
const subscription = {
metadata: {
application_username: 'user123,user456,user789'
}
};
// Any user with valid credentials gets access
const hasAccess = true; // If access key is valid
Benefits:
- Perfect for family plans
- Supports team subscriptions
- No transfer process needed
- Simple to implement
LAST_CLAIMER
// Only the most recent user has access
const subscription = {
metadata: {
application_username: 'user789', // Latest user
previous_username: 'user456' // Previous user lost access
}
};
// Only current user gets access
const hasAccess = currentUser === subscription.metadata.application_username;
Benefits:
- Clear ownership model
- Easy subscription transfers
- Automatic access revocation
- Good for individual licenses
User Association
During Checkout
// Create checkout session with user
const session = await iaptic.createStripeCheckout({
offerId: 'stripe:prod_xyz#price_xyz',
applicationUsername: 'user123',
successUrl: '...',
cancelUrl: '...'
});
Update Association
// Transfer to new user
await stripe.subscriptions.update('sub_xyz', {
metadata: {
application_username: 'newuser123',
previous_username: 'user123',
transferred_at: new Date().toISOString()
}
});
Multiple Users
// With ALL_CLAIMERS strategy
const subscription = {
metadata: {
application_username: 'user1,user2,user3'
}
};
// Add user
const users = subscription.metadata.application_username.split(',');
users.push('user4');
await stripe.subscriptions.update('sub_xyz', {
metadata: {
application_username: users.join(',')
}
});
Access Verification
Client-side
// Check subscription status
const { purchases } = await iaptic.getPurchases(
subscriptionId,
accessKey
);
// Verify access
if (purchases.length > 0) {
const purchase = purchases[0];
// Check status
const isActive = new Date(purchase.expirationDate) > new Date();
// Check user (if using LAST_CLAIMER)
const hasAccess = purchase.applicationUsername === currentUser;
// Enable features
if (isActive && hasAccess) {
enablePremiumFeatures();
}
}
Server-side
// Verify subscription server-side
app.post('/api/verify', async (req, res) => {
try {
const response = await fetch(
'https://validator.iaptic.com/v3/stripe/purchases/' +
req.body.subscriptionId,
{
headers: {
'Authorization': `Basic ${btoa('app:key')}`,
},
body: JSON.stringify({
access_key: req.body.accessKey
})
}
);
const { purchases } = await response.json();
// Process verification result
} catch (error) {
// Handle error
}
});
Access Patterns
1. Individual License
// Use LAST_CLAIMER strategy
const subscription = {
metadata: {
application_username: 'user123'
}
};
// Only current user has access
const hasAccess = currentUser === subscription.metadata.application_username;
2. Team License
// Use ALL_CLAIMERS strategy
const subscription = {
metadata: {
application_username: 'team/user1,team/user2',
team_id: 'team123'
}
};
// Any team member has access
const hasAccess = subscription.metadata.application_username
.includes(`team/${currentUser}`);
3. Family Sharing
// Use ALL_CLAIMERS with family prefix
const subscription = {
metadata: {
application_username: 'family/parent,family/child1,family/child2',
family_id: 'family123'
}
};
// Any family member has access
const hasAccess = subscription.metadata.application_username
.includes(`family/${currentUser}`);
Best Practices
1. User Management
- Use consistent username format
- Validate usernames
- Track ownership changes
- Handle user deletion
2. Access Control
- Choose appropriate strategy
- Implement proper validation
- Handle edge cases
- Log access attempts
3. Error Handling
- Invalid access keys
- Expired subscriptions
- User not found
- Transfer failures
4. Monitoring
- Track access patterns
- Monitor transfers
- Log ownership changes
- Alert on anomalies
Common Issues
1. Access Lost
- Check subscription status
- Verify user association
- Validate access key
- Check entitlement strategy
2. Multiple Users
- Verify strategy setting
- Check username format
- Validate access rights
- Monitor usage patterns
3. Transfer Problems
- Validate new username
- Check current ownership
- Handle concurrent transfers
- Update access keys