Skip to main content

Authorising Transactions

Learn all the methods for authorising (accepting) payment transactions, from user-driven confirmations to automatic allowance-based payments.

Quick Start

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

  1. Create transaction
  2. Redirect user to confirmation URL
  3. User selects wallet and enters PIN
  4. User redirected back to your site
  5. 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

  1. Create transaction
  2. User provides PIN on your site
  3. Send PIN to API
  4. Transaction automatically accepted
  5. 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"
}
Security Warning
  • 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

  1. User has approved allowance (one-time setup)
  2. Create transaction with allowance
  3. Accept using allowance (automatic)
  4. Confirm transaction
  5. 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

FeatureUser RedirectPIN via APIAllowance
User interactionYes, on PayseraYes, on your siteNo
Security⭐⭐⭐⭐⭐ Highest⭐⭐⭐ Medium⭐⭐⭐⭐ High
ImplementationEasyMediumComplex
Mobile UXRedirect requiredGoodBest
Web UXGoodMediumBest
Recurring payments❌ No❌ No✅ Yes
One-time payments✅ Yes✅ Yes✅ Yes
Setup requiredNoneNoneAllowance approval
Best forE-commerce checkoutMobile apps, POSSubscriptions

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:

  1. Callbacks - Handle payment notifications (coming soon)
  2. Transaction Requests - Request payments from users (coming soon)
  3. Reservation Codes - Generate payment codes (coming soon)

Need Help?

Quick Reference

Redirect: Best for web e-commerce
PIN API: Best for mobile apps
Allowance: Best for subscriptions
Always: Use HTTPS and handle errors