Cash-in with Code
Accept cash from customers and deposit it into their Paysera wallet using a cash-in code.
Use Case Overview
Customer provides cash, you scan their cash-in code and deposit funds into their wallet using background payment with allowance.
Implementation Steps
1. Extract Wallet ID from Code
Cash-in code format: EVP000000000001 (wallet ID padded with zeros to 12 characters)
function extractWalletId(cashInCode) {
const paddedId = cashInCode.replace(/^EVP/, '');
const walletId = parseInt(paddedId, 10);
return walletId;
}
// Example: EVP000000014471 → 14471
2. Create Transaction with Allowance
Paysera provides the allowance for cash-in operations. You don't need to create one.
Request:
POST /rest/v1/transaction HTTP/1.1
Host: wallet.paysera.com
Content-Type: application/json
Authorization: MAC id="...", ...
{
"payments": [
{
"description": "Cash deposit",
"price": 5000,
"currency": "EUR"
}
],
"allowance": {
"id": 784,
"optional": true
}
}
Response:
{
"transaction_key": "pDAlAZ3z",
"status": "new",
"payments": [
{
"id": 2988,
"price": 5000,
"currency": "EUR",
"price_decimal": "50.00"
}
],
"allowance": {
"optional": true,
"data": {
"id": 784,
"max_price": 1500
}
}
}
3. Reserve Transaction with Wallet
Request:
PUT /rest/v1/transaction/pDAlAZ3z/reserve/14471 HTTP/1.1
Host: wallet.paysera.com
Authorization: MAC id="...", ...
Response:
{
"transaction_key": "pDAlAZ3z",
"status": "reserved",
"type": "automatic",
"wallet": 14471,
"payments": [
{
"id": 2988,
"status": "reserved",
"price_decimal": "50.00",
"wallet": 14471
}
]
}
4. Confirm Transaction
Request:
PUT /rest/v1/transaction/pDAlAZ3z/confirm HTTP/1.1
Host: wallet.paysera.com
Authorization: MAC id="...", ...
Response:
{
"transaction_key": "pDAlAZ3z",
"status": "confirmed",
"confirmed_at": 1355314392,
"wallet": 14471,
"payments": [
{
"id": 2988,
"status": "confirmed",
"confirmed_at": 1355314392,
"price_decimal": "50.00"
}
]
}
Complete Example
async function processCashIn(cashInCode, amount, allowanceId) {
// 1. Extract wallet ID from code
const walletId = extractWalletId(cashInCode);
console.log(`Wallet ID: ${walletId}`);
// 2. Create transaction with allowance
const transaction = await api.createTransaction({
payments: [{
description: 'Cash deposit',
price: amount * 100,
currency: 'EUR'
}],
allowance: {
id: allowanceId,
optional: true
}
});
console.log(`Transaction created: ${transaction.transaction_key}`);
// 3. Reserve with wallet ID
const reserved = await api.reserveTransaction(
transaction.transaction_key,
walletId
);
if (reserved.status !== 'reserved') {
throw new Error('Failed to reserve transaction');
}
console.log('Transaction reserved');
// 4. Confirm transaction
const confirmed = await api.confirmTransaction(
transaction.transaction_key
);
if (confirmed.status !== 'confirmed') {
throw new Error('Failed to confirm transaction');
}
console.log('✅ Cash deposited successfully');
return confirmed;
}
// Usage
const code = scanCashInCode();
await processCashIn(code, 50.00, 784);
Advanced Topics
Error Handling
Invalid Cash-in Code
{
"error": "invalid_request",
"error_description": "Invalid cash-in code format"
}
Solution: Verify code format starts with "EVP".
Wallet Not Found
{
"error": "not_found",
"error_description": "Wallet not found"
}
Solution: Ask customer to generate new code.
Allowance Limit Exceeded
{
"error": "allowance_limit_exceeded",
"error_description": "Amount exceeds allowance limit"
}
Solution: Reduce amount or split into multiple deposits.
Best Practices
1. Validate Cash-in Code
function validateCashInCode(code) {
if (!code.startsWith('EVP')) {
throw new Error('Invalid code format');
}
if (code.length !== 15) {
throw new Error('Invalid code length');
}
const walletId = extractWalletId(code);
if (walletId <= 0) {
throw new Error('Invalid wallet ID');
}
return true;
}
2. Verify Cash Amount
function verifyCashAmount(receivedCash, transactionAmount) {
if (receivedCash !== transactionAmount) {
throw new Error('Cash amount mismatch');
}
return true;
}
3. Set Deposit Limits
const DEPOSIT_LIMITS = {
min: 5.00,
max: 1000.00,
daily: 5000.00
};
function checkDepositLimit(amount) {
if (amount < DEPOSIT_LIMITS.min) {
throw new Error(`Minimum deposit: €${DEPOSIT_LIMITS.min}`);
}
if (amount > DEPOSIT_LIMITS.max) {
throw new Error(`Maximum deposit: €${DEPOSIT_LIMITS.max}`);
}
}
Security Considerations
Do:
- ✅ Verify customer identity for large deposits
- ✅ Count cash accurately before processing
- ✅ Log all transactions for audit trail
- ✅ Implement daily deposit limits per customer
- ✅ Use secure cash handling procedures
- ✅ Verify code hasn't been used previously
Don't:
- ❌ Don't accept cash without valid code
- ❌ Don't process deposits without cash verification
Cash Handling Procedure
1. Receive Cash
- Count cash in front of customer
- Verify denominations
- Check for counterfeit bills
2. Scan Code
- Ask customer to show cash-in code
- Scan with barcode reader
- Verify code format
3. Process Transaction
- Create and confirm transaction
- Wait for confirmation
4. Provide Receipt
- Print transaction receipt
- Include transaction ID, wallet ID, timestamp
Receipt Template:
================================
PAYSERA CASH DEPOSIT
================================
Transaction ID: 2988
Wallet ID: 14471
Date: 2025-10-31 11:00:00
Amount Deposited: €50.00
Fee: €0.00
--------------------------------
Total: €50.00
Status: CONFIRMED
Thank you!
================================
Related Documentation
- Payments - Payment integration
- Authentication - API authentication
- Cash-out with Code - Reverse operation