Allowance Resource
The Allowance Resource enables automatic recurring payments without user interaction for each charge. Once a user approves an allowance, you can charge their wallet automatically as long as the payment stays within the predefined limits.
Perfect for subscriptions, recurring billing, and automated charges. See Payment Concepts for basics.
Allowance Object
Structure
{
"id": 12345,
"transaction_key": "pDAlAZ3z",
"created_at": 1698675600,
"confirmed_at": 1698675680,
"valid": {
"from": 1698675680,
"until": 1701267680
},
"description": "Premium Subscription",
"max_price": 999,
"currency": "EUR",
"limits": [
{
"max_price": 999,
"period": 2592000 // 30 days
}
]
}
View Fields Reference
| Field | Type | Description |
|---|---|---|
id | integer | Allowance ID (unique) |
transaction_key | string | Transaction that created allowance |
created_at | timestamp | When allowance was created |
confirmed_at | timestamp | When user confirmed allowance |
canceled_at | timestamp | When allowance was canceled (if canceled) |
valid | object | Validity period |
valid.from | timestamp | Valid from this time |
valid.until | timestamp | Valid until this time |
description | string | Required. Allowance description |
max_price | integer | Required. Maximum price in cents (total) |
currency | string | Required. Currency code (e.g., "EUR") |
limits | array | Time-based limits (optional) |
optional | boolean | Whether allowance is optional |
Creating an Allowance
View Creation Examples
Basic Allowance
POST /rest/v1/transaction
{
"allowance": {
"description": "Premium Subscription - Monthly",
"max_price": 999,
"currency": "EUR",
"valid": {
"for": 31536000 // 1 year in seconds
}
}
}
User flow:
- Redirect user to confirmation
- User approves allowance
- User returns to your site
- Confirm transaction
- Allowance is now active
Allowance with Payment
Create allowance together with first payment:
{
"payments": [{
"description": "First month - Premium",
"price": 999,
"currency": "EUR"
}],
"allowance": {
"description": "Premium Subscription",
"max_price": 999,
"currency": "EUR",
"valid": {
"for": 31536000 // 1 year
}
}
}
User approves both payment and allowance in one action.
Allowance Limits
View Limit Types
Total Limit Only
Simple total limit:
{
"description": "Service Credits",
"max_price": 10000, // 100 EUR total
"currency": "EUR",
"valid": {
"for": 7776000 // 90 days
}
}
Usage: 100 EUR total over 90 days, any distribution.
Time-Based Limits
Add recurring limits:
{
"description": "Monthly Subscription",
"max_price": 11988, // 119.88 EUR total (12 months)
"currency": "EUR",
"valid": {
"for": 31536000 // 1 year
},
"limits": [
{
"max_price": 999, // 9.99 EUR
"period": 2592000 // per 30 days
}
]
}
Usage: Max 9.99 EUR per month, 119.88 EUR total per year.
Multiple Time Limits
Stack different period limits:
{
"description": "Flexible Billing",
"max_price": 50000, // 500 EUR total
"currency": "EUR",
"limits": [
{
"max_price": 5000, // 50 EUR
"period": 86400 // per day
},
{
"max_price": 20000, // 200 EUR
"period": 604800 // per week
}
]
}
Usage: Max 50 EUR/day AND 200 EUR/week AND 500 EUR total.
Using an Allowance
Once user has approved an allowance, use it for automatic payments.
// 1. Create transaction with allowance
const tx = await createTransaction({
payments: [{
description: 'Monthly Subscription - Premium',
price: 999
}],
allowance_id: userAllowanceId
});
// 2. Reserve using allowance (automatic acceptance)
await reserveWithAllowance(tx.transaction_key, userWalletId);
// 3. Confirm
await confirmTransaction(tx.transaction_key);
// Done! No user interaction needed.
Allowance Lifecycle
States
Created → Accepted → Active → Expired/Canceled
| State | Description | Can Use? |
|---|---|---|
| Created | Just created, not yet confirmed | ❌ No |
| Accepted | User confirmed, not yet active | ❌ No |
| Active | Confirmed and within validity period | ✅ Yes |
| Expired | Validity period ended | ❌ No |
| Canceled | Manually canceled | ❌ No |
Allowance Rules
One Active Allowance Per Wallet/Client
- ❌ Cannot have: Multiple active allowances from same client for same wallet
- ✅ Can have: Allowances from different clients
- ✅ Can have: Allowances for different wallets
New Allowance Cancels Previous
When user confirms new allowance, previous allowance (if exists) is canceled.
Validity Period
- Starts: When user confirms allowance
- Ends:
valid.untiltimestamp - Cannot extend once set
- Must create new to continue
Advanced Topics
Limit Checking
How Limits Are Checked
Before allowing payment with allowance:
- ✅ Total limit: Sum of all charges ≤
max_price - ✅ Period limits: For each limit, sum within period ≤
limit.max_price - ✅ Validity: Current time is within
valid.fromandvalid.until - ✅ Balance: Wallet has sufficient balance
Limit Calculation Example
Allowance:
- Max 100 EUR total
- Max 30 EUR per week
Usage:
- Week 1: 25 EUR (✅ OK - within weekly limit)
- Week 1: 10 EUR (❌ FAIL - exceeds weekly 30 EUR)
- Week 2: 30 EUR (✅ OK - new week starts)
- Week 3: 30 EUR (✅ OK)
- Week 4: 20 EUR (❌ FAIL - exceeds total 100 EUR)
Handling Limit Exceeded
{
"error": "invalid_allowance",
"error_description": "Allowance limit would be exceeded by this payment"
}
Solutions: Reduce payment amount, Wait for next period, Request new allowance
Common Patterns
Pattern 1: Monthly Subscription
// Setup (once)
const setupAllowance = async () => {
const tx = await createTransaction({
allowance: {
description: 'Premium Subscription - Monthly',
max_price: 11988, // 12 months × 9.99
currency: 'EUR',
valid: { for: 31536000 }, // 1 year
limits: [
{
max_price: 999, // 9.99 per month
period: 2592000 // 30 days
}
]
},
redirect_uri: 'https://myapp.com/subscription-setup'
});
return tx.transaction_key;
};
// Monthly charge (automatic)
const chargeMonthly = async (allowanceId, walletId) => {
const tx = await createTransaction({
payments: [{
description: `Premium - ${currentMonth}`,
price: 999
}],
allowance_id: allowanceId
});
await reserveWithAllowance(tx.transaction_key, walletId);
await confirmTransaction(tx.transaction_key);
};
Pattern 2: Usage-Based Billing
// Charge for usage (as needed)
const chargeForUsage = async (amount) => {
const tx = await createTransaction({
payments: [{
description: `API Usage: ${apiCallCount} calls`,
price: amount
}],
allowance_id: userAllowanceId
});
await reserveWithAllowance(tx.transaction_key, walletId);
await confirmTransaction(tx.transaction_key);
};
Pattern 3: Subscription with Trial
// Month 1: Trial with allowance setup
const setupTrial = async () => {
const tx = await createTransaction({
payments: [{
description: 'Premium - Trial Month',
price: 99 // Discounted trial price
}],
allowance: {
description: 'Premium Subscription',
max_price: 11988, // Full year
currency: 'EUR',
valid: { for: 31536000 },
limits: [{
max_price: 999, // Regular price
period: 2592000
}]
}
});
return tx;
};
Monitoring & Tracking
Track Allowance Usage
Store in your database:
{
user_id: 12345,
allowance_id: 67890,
wallet_id: 14471,
created_at: '2024-01-01T00:00:00Z',
valid_until: '2025-01-01T00:00:00Z',
total_charged: 5994, // 59.94 EUR so far
total_limit: 11988, // 119.88 EUR total
last_charge: '2024-07-01T00:00:00Z',
charges_count: 6
}
Check Before Charging
const canCharge = (allowanceData, amount) => {
if (Date.now() > new Date(allowanceData.valid_until)) {
return { ok: false, reason: 'expired' };
}
if (allowanceData.total_charged + amount > allowanceData.total_limit) {
return { ok: false, reason: 'total_limit' };
}
return { ok: true };
};
Handle Renewals
const renewAllowance = async (userId) => {
const oldAllowance = await getAllowance(userId);
const daysLeft = (oldAllowance.valid_until - Date.now()) / 86400000;
if (daysLeft < 7) {
const tx = await createTransaction({
allowance: {
description: 'Premium Subscription - Renewal',
max_price: 11988,
currency: 'EUR',
valid: { for: 31536000 }
}
});
await notifyUser(userId, 'subscription_renewal', tx.transaction_key);
}
};
Error Handling
Common Errors
Allowance Limit Exceeded
{
"error": "invalid_allowance",
"error_description": "Payment would exceed allowance limit"
}
Solution: Wait for next period or create new allowance
Allowance Expired
{
"error": "invalid_allowance",
"error_description": "Allowance has expired"
}
Solution: Create new allowance
No Active Allowance
{
"error": "invalid_allowance",
"error_description": "User has no active allowance for this client"
}
Solution: User needs to create/approve allowance first
Insufficient Balance
{
"error": "insufficient_funds",
"error_description": "Wallet balance insufficient"
}
Solution: User needs to add funds (allowance doesn't guarantee balance)
Security Considerations
User Control
- Users can view all active allowances
- Users can cancel allowances anytime
- Users receive notifications when charged
- Users see transaction history
Your Responsibilities
- Store allowance IDs securely
- Validate before charging
- Notify users when charging
- Handle errors gracefully
- Respect limits
- Don't abuse allowance privileges
API Reference
| Method | Endpoint | Description |
|---|---|---|
POST | /rest/v1/transaction | Create transaction with allowance |
PUT | /rest/v1/transaction/{key}/reserve/{wallet} | Reserve using allowance |
GET | /rest/v1/transaction/{key} | Get allowance details |
Full API reference: Wallet API Endpoints
What's Next?
Learn more about related topics:
- Payment Resource - Understanding payments
- Transaction Resource - Transaction management
- Samples & Examples - See allowance in action
Need Help?
- Questions? → tech_support@paysera.com
- Concepts → Payment Concepts
- Examples → Code Samples
Perfect for: Subscriptions, recurring billing, usage-based charges
Key benefit: No user interaction for each charge
Important: One active allowance per wallet/client
Remember: Allowance ≠ guaranteed balance