Transaction Lifecycle & Status Flow
Learn how transactions move through different states from creation to completion, and how to manage each stage effectively.
New to payments? Start with Payment Concepts to understand the basics.
Transaction Lifecycle Overview
Every payment transaction follows a defined lifecycle with specific states:
The Four Phases
1️⃣ Phase 1: Creation
What happens: Transaction is created with payment details.
Status: new
Characteristics:
- ❌ No money transferred
- ❌ No funds reserved
- ✅ Information saved
- ✅ Transaction key generated
Your actions:
- Create transaction via API
- Redirect user to confirmation page
- OR use allowance for auto-accept
POST /rest/v1/transaction
{
"payments": [{
"description": "Order #1234",
"price": 2999,
"currency": "EUR"
}],
"redirect_uri": "https://yoursite.com/return"
}
// Response
{
"transaction_key": "pDAlAZ3z",
"status": "new",
"payments": [...]
}
2️⃣ Phase 2: Acceptance (User Confirmation)
What happens: User accepts transaction and links it to their wallet.
Status: new → waiting
Characteristics:
- ✅ Funds reserved in payer's account
- ❌ NOT yet visible to beneficiary
- ✅ Money secured but not transferred
- ⏱️ Reservation has time limit
Acceptance Methods:
Method 1: Redirect to Confirmation Page
https://www.paysera.com/frontend/en/wallet/confirm/{transaction_key}
User flow:
- User redirected to Paysera
- User selects wallet
- User enters PIN
- Redirected back to your site
Method 2: Use Allowance (No Redirect)
PUT /rest/v1/transaction/{key}/reserve/{wallet_id}
// Automatic acceptance using pre-approved allowance
// No user interaction needed!
Method 3: Provide PIN via API
POST /rest/v1/transaction/{key}/reserve
{
"wallet_id": 14471,
"pin": "1234"
}
Transactions have a reserveUntil time. If not confirmed by this time, funds are automatically released!
3️⃣ Phase 3: Confirmation
What happens: You confirm the transaction to complete the payment.
Status: waiting → reserved or confirmed
Characteristics:
- ✅ Payments visible to beneficiary
- ✅ Money transferred (or frozen)
- ✅ Service can be provided
- ⏱️ Optional freeze period
Why confirm?:
- ✅ Shows your system is operational
- ✅ Service can still be provided
- ✅ Allows price adjustments if needed
- ✅ Prevents automatic expiration
Confirmation:
PUT /rest/v1/transaction/{transaction_key}/confirm
// Optional: Reduce payment amount
PUT /rest/v1/transaction/{transaction_key}/confirm
{
"payments": [{
"id": 2988,
"price": 2500 // Reduced from 2999
}]
}
Auto-Confirm Option:
// Set when creating transaction
{
"payments": [...],
"auto_confirm": true // Confirms automatically after acceptance
}
Only use auto_confirm: true when:
- No service is provided (transfers, donations)
- Service cannot fail
- You can't be online to confirm manually
4️⃣ Phase 4: Finalization (Optional)
What happens: Frozen payments are finalized or cancelled.
Applicable when: Payment has freezeUntil set
Characteristics:
- ✅ Can reduce payment amount
- ✅ Can cancel completely
- ⏱️ Auto-finalizes at
freezeUntiltime
Use cases:
- Hotel reservations (reserve at booking, charge at checkout)
- Car rentals (reserve deposit, finalize after return)
- Pre-authorizations (hold amount, charge actual)
Finalize Payment:
PUT /rest/v1/payment/{payment_id}/finalize
// Optional: Reduce amount
PUT /rest/v1/payment/{payment_id}/finalize
{
"price": 2000 // Reduced from original
}
Cancel Payment:
DELETE /rest/v1/payment/{payment_id}
Complete Status Reference
| Status | Description | Next States | User Sees Money? |
|---|---|---|---|
new | Just created | waiting, failed | ❌ No |
waiting | Accepted, funds reserved | reserved, failed, canceled | 🟡 Reserved (payer) |
reserved | Confirmed, visible to beneficiary | done, canceled | 🟡 Reserved or ✅ Done |
confirmed | Completed successfully | - | ✅ Yes |
done | Payment finalized | - | ✅ Yes |
canceled | Cancelled or revoked | - | ❌ No (refunded) |
failed | Failed to process | - | ❌ No |
Detailed Flow Diagrams
View Flow Diagrams
Standard Payment Flow
Allowance Payment Flow
Frozen Payment Flow
Advanced Topics
Time Limits & Expiration
Reserve Time Limit
Set when creating transaction:
{
"payments": [...],
"reserve": {
"for": 1800 // 30 minutes in seconds
}
}
What happens:
- If confirmed before time: ✅ Payment proceeds
- If NOT confirmed: ❌ Funds automatically released
Freeze Time Limit
Set per payment:
{
"payments": [{
"price": 10000,
"freeze_until": 1735689600 // Unix timestamp
}]
}
What happens:
- Before time: Can finalize or cancel
- After time: Automatically finalized
Error States & Recovery
Failed Transaction
Causes: Insufficient balance, Invalid wallet, Permission denied, Network error
Status: failed
Recovery: Create new transaction
// Check failure reason
GET /rest/v1/transaction/{key}
{
"status": "failed",
"error": "insufficient_funds",
"error_description": "Wallet balance insufficient"
}
Cancelled Transaction
Causes: User cancelled, You revoked it, Expired without confirmation
Status: canceled
Recovery: Create new transaction if needed
// Revoke transaction
PUT /rest/v1/transaction/{key}/revoke
Best Practices
✅ Timing
- Confirm quickly - Don't wait until last minute
- Set appropriate reserve times - 30 min for checkout, longer for services
- Use freezeUntil wisely - For deposits, pre-auth, etc.
- Monitor expiration - Set up alerts
✅ Error Handling
try {
const transaction = await createTransaction(data);
window.location = getConfirmUrl(transaction.transaction_key);
} catch (error) {
if (error.code === 'insufficient_funds') {
showError('Please add funds to your wallet');
} else if (error.code === 'invalid_wallet') {
showError('Please select a valid wallet');
} else {
showError('Payment failed. Please try again');
}
}
❌ Common Mistakes
- ❌ Not confirming transactions
- ❌ Ignoring
reserveUntiltime - ❌ Using auto-confirm inappropriately
- ❌ Not handling failed states
- ❌ Polling too frequently
- ❌ Forgetting to finalize frozen payments
Real-World Scenarios
Scenario 1: E-Commerce Checkout
// 1. Create
const tx = await createTransaction({
payments: [{
description: 'Order #1234',
price: 4999
}],
reserve: { for: 1800 } // 30 min
});
// 2. Redirect user
redirectTo(getConfirmUrl(tx.transaction_key));
// 3. User returns after accepting - Confirm immediately
await confirmTransaction(tx.transaction_key);
// 4. Ship order
Scenario 2: Hotel Reservation
// 1. Reserve with freeze
const tx = await createTransaction({
payments: [{
description: 'Hotel Deposit',
price: 10000,
freeze_until: checkoutDate // Hold until checkout
}]
});
// 2-3. User accepts, you confirm
// 4. At checkout: Finalize
await finalizePayment(paymentId, {
price: actualAmount // Can reduce
});
Scenario 3: Subscription
// Using allowance - no user interaction!
// 1. Create with allowance
const tx = await createTransaction({
payments: [{
description: 'Monthly Subscription',
price: 999
}],
allowance_id: userAllowanceId
});
// 2. Accept using allowance
await reserveWithAllowance(tx.transaction_key, walletId);
// 3. Confirm
await confirmTransaction(tx.transaction_key);
// Done! No user interaction needed.
What's Next?
Now that you understand transaction flow:
- Samples & Examples - See complete implementations
- Transaction Resource - API reference (see API Resources in sidebar)
- Authorising Transactions - All acceptance methods (see Integration Guides in sidebar)
- Callbacks - Handle notifications (see Integration Guides in sidebar)
Need Help?
- Questions? → tech_support@paysera.com
- API Reference → Wallet API Endpoints
- Concepts → Payment Concepts
Save this flow diagram - it's handy when debugging payment issues!
new → waiting → reserved → done ✅
↓ ↓ ↓
failed canceled canceled ❌