Transfer via Transition Account
Collect money from multiple payers and distribute it to multiple receivers using a Paysera transition account.
Use Case Overview
Transition account allows you to:
- Collect payments from multiple customers
- Pool funds temporarily
- Distribute to multiple beneficiaries
- Split payments efficiently
A transition account is owned by Paysera and cannot store money permanently. It's used only for passing through funds.
Implementation Steps
Step 1: Create User Allowance
Customer must create an allowance to authorize automatic payments.
POST /rest/v1/allowance HTTP/1.1
Host: wallet.paysera.com
Content-Type: application/json
Authorization: MAC id="...", ...
{
"description": "Weekly subscription - 5 weeks",
"currency": "EUR",
"max_price": 1500,
"valid": {
"for": 3110400
}
}
Response:
{
"id": 2987,
"transaction_key": "pDAlAZ3z",
"status": "new",
"description": "Weekly subscription - 5 weeks",
"currency": "EUR",
"max_price": 1500,
"max_price_decimal": "15.00"
}
User must confirm this allowance via confirmation page before it can be used.
Step 2: Collect Payment to Transition Account
Use allowance to automatically charge customer.
POST /rest/v1/transaction HTTP/1.1
Host: wallet.paysera.com
Content-Type: application/json
Authorization: MAC id="...", ...
{
"payments": [
{
"description": "Weekly payment",
"price": 300,
"currency": "EUR"
}
],
"allowance": {
"id": 2987,
"optional": true
}
}
Reserve & Confirm:
PUT /rest/v1/transaction/{transaction_key}/reserve/{wallet_id}
PUT /rest/v1/transaction/{transaction_key}/confirm
Step 3: Distribute from Transition Account
You cannot create allowance for transition account yourself. Paysera will provide one.
POST /rest/v1/transaction HTTP/1.1
Host: wallet.paysera.com
Content-Type: application/json
Authorization: MAC id="...", ...
{
"payments": [
{
"description": "Payment to provider",
"price": 100,
"currency": "EUR",
"beneficiary": "EVP1234567890"
}
],
"allowance": {
"id": 784,
"optional": true
}
}
Complete Example
class TransitionAccountManager {
async collectFromCustomers(customers) {
const transactions = [];
for (const customer of customers) {
const tx = await api.createTransaction({
payments: [{
description: `Payment from ${customer.name}`,
price: customer.amount * 100,
currency: 'EUR'
}],
allowance: {
id: customer.allowanceId,
optional: true
}
});
await api.reserveTransaction(tx.transaction_key, customer.walletId);
await api.confirmTransaction(tx.transaction_key);
transactions.push(tx);
}
return transactions;
}
async distributeToProviders(providers, transitionAllowanceId) {
const distributions = [];
for (const provider of providers) {
const tx = await api.createTransaction({
payments: [{
description: `Payment to ${provider.name}`,
price: provider.amount * 100,
currency: 'EUR',
beneficiary: provider.walletCode
}],
allowance: {
id: transitionAllowanceId,
optional: true
}
});
await api.reserveTransaction(tx.transaction_key, transitionWalletId);
await api.confirmTransaction(tx.transaction_key);
distributions.push(tx);
}
return distributions;
}
}
// Usage
const manager = new TransitionAccountManager();
// 1. Collect from customers
const customers = [
{ name: 'Alice', amount: 10, allowanceId: 1001, walletId: 14471 },
{ name: 'Bob', amount: 15, allowanceId: 1002, walletId: 14472 }
];
await manager.collectFromCustomers(customers);
// 2. Distribute to providers
const providers = [
{ name: 'Provider A', amount: 12, walletCode: 'EVP001' },
{ name: 'Provider B', amount: 13, walletCode: 'EVP002' }
];
await manager.distributeToProviders(providers, 784);
Use Case Examples
Example 1: Subscription Service
// Collect monthly subscriptions
const subscriptions = await collectFromCustomers([
{ amount: 9.99, allowanceId: 1001, walletId: 14471 },
{ amount: 9.99, allowanceId: 1002, walletId: 14472 }
]);
// Pay service providers
await distributeToProviders([
{ amount: 20.00, walletCode: 'EVP_HOSTING' }
]);
Example 2: Split Bill
// Collect from group
await collectFromCustomers([
{ amount: 25.00, allowanceId: 2001, walletId: 15001 },
{ amount: 25.00, allowanceId: 2002, walletId: 15002 }
]);
// Pay restaurant
await distributeToProviders([
{ amount: 50.00, walletCode: 'EVP_RESTAURANT' }
]);
Advanced Topics
Allowance Limits
Time-Based Limits:
const allowance = {
description: 'Monthly subscription',
currency: 'EUR',
max_price: 10000,
limits: [
{
max_price: 2500,
time: 604800
}
]
};
This allows:
- Maximum €100 total
- Maximum €25 per week
Best Practices
1. Allowance Management
async function createUserAllowance(userId, maxAmount, duration) {
const allowance = await api.createAllowance({
description: `Auto-payment for ${userId}`,
currency: 'EUR',
max_price: maxAmount * 100,
valid: { for: duration }
});
return api.getAllowanceConfirmationUrl(allowance.transaction_key);
}
2. Balance Verification
async function verifyTransitionBalance(expectedAmount) {
const balance = await api.getWalletBalance(transitionWalletId);
if (balance.available < expectedAmount) {
throw new Error('Insufficient funds in transition account');
}
}
3. Error Handling
async function safeTransfer(transaction) {
try {
await api.reserveTransaction(transaction.key, walletId);
await api.confirmTransaction(transaction.key);
return { success: true };
} catch (error) {
await api.revokeTransaction(transaction.key);
return { success: false, error };
}
}
Security Considerations
Do:
- ✅ Validate all allowances before use
- ✅ Set reasonable limits on allowances
- ✅ Monitor transition account balance
- ✅ Log all transactions for audit
- ✅ Implement retry logic with backoff
Don't:
- ❌ Don't exceed allowance limits
- ❌ Don't store money in transition account
- ❌ Don't skip transaction confirmation
Limitations
Transition Account Rules:
- No Money Storage - Funds must flow through immediately
- Allowance Required - Cannot create your own allowance
- Paysera Ownership - Account belongs to Paysera
- No Direct Deposits - Only via API transactions
Allowance Rules:
- One Active - Only one active allowance per wallet
- Cannot Exceed - Cannot charge more than max_price
- Time Expiry - Expires after specified duration
- Auto Confirmation - Requires user confirmation first
Troubleshooting
"Allowance Limit Exceeded"
const allowance = await api.getAllowance(allowanceId);
if (allowance.remaining < amount) {
// Request new allowance or reduce amount
}
"Insufficient Funds"
const balance = await api.getTransitionBalance();
console.log(`Available: ${balance.available}`);
"Allowance Not Active"
const allowance = await api.getAllowance(allowanceId);
if (allowance.status !== 'active') {
redirectToConfirmation(allowance.transaction_key);
}
Related Documentation
- Payments - Payment integration
- Authentication - API authentication
- Distribute Payments - Multiple beneficiaries