Authorising Transactions
Learn all the methods for authorising (accepting) payment transactions, from user-driven confirmations to automatic allowance-based payments.
Already know the basics? Jump to Method Comparison to choose the right approach.
Overview
After creating a transaction, it must be authorised (accepted) by the payer before funds can be transferred. There are three main methods:
Authorization Methods
🔗 Method 1: User Redirect (Most Common)
Redirect the user to Paysera's confirmation page where they select their wallet and confirm.
How It Works
- Create transaction
- Redirect user to confirmation URL
- User selects wallet and enters PIN
- User redirected back to your site
- Confirm transaction
Implementation
// 1. Create transaction
const tx = await createTransaction({
payments: [{
description: 'Order #1234',
price: 2999,
currency: 'EUR'
}],
redirect_uri: 'https://yoursite.com/payment-return'
});
// 2. Build confirmation URL
const confirmUrl = `https://www.paysera.com/frontend/en/wallet/confirm/${tx.transaction_key}`;
// 3. Redirect user
window.location.href = confirmUrl;
// 4. User returns to redirect_uri
// Check transaction status
const status = await getTransaction(tx.transaction_key);
if (status.status === 'waiting') {
// 5. Confirm transaction
await confirmTransaction(tx.transaction_key);
}
Confirmation URL Formats
For specific language:
https://www.paysera.com/frontend/{lang}/wallet/confirm/{transaction_key}
Available languages: en, lt, lv, et, ru, pl, bg, ro
Auto-detect language (from browser):
https://www.paysera.com/wallet/confirm/{transaction_key}
User Flow
🔑 Method 2: PIN via API
Provide the user's wallet ID and PIN directly via API (no redirect needed).
How It Works
- Create transaction
- User provides PIN on your site
- Send PIN to API
- Transaction automatically accepted
- Confirm transaction
Implementation
// 1. Create transaction
const tx = await createTransaction({
payments: [{
description: 'Order #1234',
price: 2999
}]
});
// 2. User enters PIN on your form
const userPin = '1234'; // From your form
const userWalletId = 14471; // User's wallet ID
// 3. Accept transaction with PIN
try {
await acceptTransactionWithPin({
transaction_key: tx.transaction_key,
wallet_id: userWalletId,
pin: userPin
});
// 4. Confirm transaction
await confirmTransaction(tx.transaction_key);
console.log('Payment successful!');
} catch (error) {
if (error.code === 'invalid_pin') {
console.error('Incorrect PIN');
}
}
API Call
POST /rest/v1/transaction/{transaction_key}/reserve
{
"wallet_id": 14471,
"pin": "1234"
}
- HTTPS only - Always use HTTPS when handling PINs
- Never log PINs - Don't store or log PIN codes
- Encrypt transmission - Use secure connections
- Rate limiting - Implement attempt limits
- Clear from memory - Don't keep PINs in memory
When to Use
✅ Good for: Mobile apps, Point of sale systems, Kiosk systems
❌ Not recommended for: Web applications, Public computers
🔄 Method 3: Allowance (No User Interaction)
Use a pre-approved allowance for automatic payment acceptance.
How It Works
- User has approved allowance (one-time setup)
- Create transaction with allowance
- Accept using allowance (automatic)
- Confirm transaction
- No user interaction needed!
Implementation
// Prerequisites: User has approved allowance
const userAllowanceId = 12345;
const userWalletId = 14471;
// 1. Create transaction with allowance
const tx = await createTransaction({
payments: [{
description: 'Monthly subscription',
price: 999
}],
allowance_id: userAllowanceId
});
// 2. Accept using allowance (automatic, no user needed)
await acceptTransactionWithAllowance({
transaction_key: tx.transaction_key,
wallet_id: userWalletId
});
// 3. Confirm transaction
await confirmTransaction(tx.transaction_key);
// Done! User wasn't involved at all
API Call
PUT /rest/v1/transaction/{transaction_key}/reserve/{wallet_id}
Perfect For
✅ Monthly subscriptions, Recurring payments, Usage-based billing, Automatic renewals
Requirements: User must have approved allowance, Payment within limits, Not expired, Sufficient balance
Method Comparison
| Feature | User Redirect | PIN via API | Allowance |
|---|---|---|---|
| User interaction | Yes, on Paysera | Yes, on your site | No |
| Security | ⭐⭐⭐⭐⭐ Highest | ⭐⭐⭐ Medium | ⭐⭐⭐⭐ High |
| Implementation | Easy | Medium | Complex |
| Mobile UX | Redirect required | Good | Best |
| Web UX | Good | Medium | Best |
| Recurring payments | ❌ No | ❌ No | ✅ Yes |
| One-time payments | ✅ Yes | ✅ Yes | ✅ Yes |
| Setup required | None | None | Allowance approval |
| Best for | E-commerce checkout | Mobile apps, POS | Subscriptions |
Choosing the Right Method
Decision Tree
Recommendations
- E-Commerce Website: User Redirect
- Mobile App: PIN via API (or Allowance for subscriptions)
- Subscription Service: Allowance
- Point of Sale: PIN via API
Advanced Topics
Handling Errors
Insufficient Balance
{
"error": "insufficient_funds",
"error_description": "Wallet balance insufficient for this payment"
}
Solution: Ask user to add funds or choose different wallet
Invalid PIN
{
"error": "invalid_pin",
"error_description": "Provided PIN is incorrect"
}
Solution: Let user try again (with attempt limit)
Allowance Limit Exceeded
{
"error": "invalid_allowance",
"error_description": "Payment would exceed allowance limit"
}
Solution: Wait for next period or request new allowance
Transaction Expired
{
"error": "invalid_state",
"error_description": "Transaction reservation has expired"
}
Solution: Create new transaction
Best Practices
General
- Always use HTTPS for all payment operations
- Implement timeouts for user redirects
- Handle all error cases gracefully
- Provide clear feedback to users
- Log transactions (but never PINs)
- Test thoroughly with small amounts in production
For User Redirect
- Set redirect_uri always
- Handle return properly - check status
- Support all languages or use auto-detect
- Mobile-friendly confirmation pages
- Clear instructions for users
For PIN via API
- Never store PINs anywhere
- Use HTTPS only for transmission
- Implement rate limiting (max 3 attempts)
- Clear PIN from memory after use
- Validate format before sending
For Allowances
- Check limits before charging
- Handle expired allowances gracefully
- Notify users when charging
- Store allowance IDs securely
- Monitor usage and limits
Implementation Examples
E-Commerce Flow
class PaymentHandler {
async processCheckout(cart) {
const transaction = await this.createTransaction({
payments: [{
description: `Order #${cart.orderId}`,
price: cart.total,
items: cart.items
}],
redirect_uri: `${this.siteUrl}/payment-return`
});
await this.saveOrderTransaction(cart.orderId, transaction.transaction_key);
const confirmUrl = this.getConfirmationUrl(transaction.transaction_key);
return { redirect: confirmUrl };
}
async handleReturn(transactionKey) {
const transaction = await this.getTransaction(transactionKey);
if (transaction.status === 'waiting') {
await this.confirmTransaction(transactionKey);
await this.markOrderPaid(transactionKey);
return { success: true };
}
return { success: false };
}
}
Subscription with Allowance
class SubscriptionManager {
async setupSubscription(userId, plan) {
const transaction = await createTransaction({
allowance: {
description: `${plan.name} Subscription`,
max_price: plan.yearlyTotal,
currency: 'EUR',
valid: { for: 31536000 }, // 1 year
limits: [{
max_price: plan.monthlyPrice,
period: 2592000 // 30 days
}]
},
redirect_uri: `${this.siteUrl}/subscription-setup`
});
return { confirmUrl: this.getConfirmUrl(transaction.transaction_key) };
}
async chargeMonthly(userId) {
const subscription = await this.getSubscription(userId);
const tx = await createTransaction({
payments: [{
description: `${subscription.plan} - Monthly`,
price: subscription.monthlyPrice
}],
allowance_id: subscription.allowanceId
});
await acceptWithAllowance(tx.transaction_key, subscription.walletId);
await confirmTransaction(tx.transaction_key);
await this.recordPayment(userId, tx.transaction_key);
return { success: true };
}
}
What's Next?
Now that you understand authorization, learn about:
- Callbacks - Handle payment notifications (coming soon)
- Transaction Requests - Request payments from users (coming soon)
- Reservation Codes - Generate payment codes (coming soon)
Need Help?
- Questions? → tech_support@paysera.com
- Transaction Guide → Transaction Resource
- Examples → Code Samples
Redirect: Best for web e-commerce
PIN API: Best for mobile apps
Allowance: Best for subscriptions
Always: Use HTTPS and handle errors