Skip to main content

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
Transition Account

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"
}
warning

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
Paysera Provides Allowance

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:

  1. No Money Storage - Funds must flow through immediately
  2. Allowance Required - Cannot create your own allowance
  3. Paysera Ownership - Account belongs to Paysera
  4. No Direct Deposits - Only via API transactions

Allowance Rules:

  1. One Active - Only one active allowance per wallet
  2. Cannot Exceed - Cannot charge more than max_price
  3. Time Expiry - Expires after specified duration
  4. 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);
}