Creating a Transfer
This guide walks you through the complete process of creating a transfer from start to finish.
Overview​
Creating a transfer is a multi-step process that involves:
- Creating the transfer - Initialize the transfer with basic details
- Reserving funds (optional) - Reserve the amount in your account
- Signing the transfer (if required) - Digitally sign the transfer for additional security
Prerequisites​
- MAC authentication credentials (
client_id,mac_key,mac_algorithm) - see Authentication - Sufficient account balance
- Valid beneficiary account details
Step-by-Step Guide​
- Step 1: Create Transfer
- Step 2: Reserve Transfer
- Step 3: Sign Transfer
- Step 4: Register Transfer
Initialize a new transfer by providing the basic transfer details.
Request:
POST /transfer/rest/v1/transfers HTTP/1.1
Host: wallet.paysera.com
Authorization: MAC id="wkVd93h2uS", ts="1343811600", nonce="nQnNaSNyubfPErjRO55yaaEYo9YZfKHN", mac="Bp22nWw9qFsz7ux5xOYkCIYJjXAz8mhxTSfJsoOKV3A="
Content-Type: application/json
{
"amount": {
"amount": "100.00",
"currency": "EUR"
},
"beneficiary": {
"type": "paysera",
"name": "John Doe",
"paysera_account": {
"account_number": "EVP1234567890"
}
},
"payer": {
"account_number": "EVP9876543210"
},
"purpose": {
"details": "Payment for invoice #12345"
}
}
Response:
{
"id": "123456",
"status": "new",
"amount": {
"amount": "100.00",
"currency": "EUR"
},
"beneficiary": {
"type": "paysera",
"name": "John Doe",
"paysera_account": {
"account_number": "EVP1234567890"
}
},
"payer": {
"account_number": "EVP9876543210"
},
"purpose": {
"details": "Payment for invoice #12345"
},
"created_at": 1729425600,
"reserve_until": 1729429200,
"out_commission": {
"amount": "0.00",
"currency": "EUR"
}
}
Key Response Fields:
id- Transfer ID (use this in subsequent steps)status- Current transfer status (new)reserve_until- Timestamp until which funds will be reservedoutgoing_commission- Commission charged for the transfer
Reserve the transfer funds in your account. This prevents the funds from being used for other transfers.
Request:
PUT /transfer/rest/v1/transfers/{transferId}/reserve HTTP/1.1
Host: wallet.paysera.com
Authorization: MAC id="wkVd93h2uS", ts="1343811601", nonce="hs6hfk3fgFd73hKsh3FDfk4hFKfh4hHk", mac="BfnUvh8Wb8hFks73HfKs83hFkd73HfKs83hFkd73HfKs="
Path Parameters:
transferId- The transfer ID from Step 1 (e.g.,123456)
Response:
{
"id": "123456",
"status": "reserved",
"amount": {
"amount": "100.00",
"currency": "EUR"
},
"payer": {
"account_number": "EVP9876543210"
},
"beneficiary": {
"type": "paysera",
"name": "John Doe",
"paysera_account": {
"account_number": "EVP1234567890"
}
},
"reserved_until": 1729429200
}
Status Change: new → reserved
The funds are now reserved and cannot be used for other transactions until the reservation expires or the transfer is completed/cancelled.
For high-value transfers or additional security requirements, you may need to digitally sign the transfer.
Request:
PUT /transfer/rest/v1/transfers/{transferId}/sign HTTP/1.1
Host: wallet.paysera.com
Authorization: MAC id="wkVd93h2uS", ts="1343811603", nonce="Fk83hFkd73HfKs83hFkd73HfKs83hFkd", mac="Hf73HfKs83hFkd73HfKs83hFkd73HfKs83hFkd73Hf="
Content-Type: application/json
Response:
{
"id": "123456",
"status": "signed",
"amount": {
"amount": "100.00",
"currency": "EUR"
},
"signature_status": "confirmed",
"signed_at": 1729426800
}
Status Change: reserved → signed
After all required authentication steps, register the transfer to process it.
Request:
PUT /transfer/rest/v1/transfers/{transferId}/register HTTP/1.1
Host: wallet.paysera.com
Authorization: MAC id="wkVd93h2uS", ts="1343811604", nonce="Ks83hFkd73HfKs83hFkd73HfKs83hFkd", mac="Hf83hFkd73HfKs83hFkd73HfKs83hFkd73HfKs83Hf="
Response:
{
"id": "123456",
"status": "done",
"amount": {
"amount": "100.00",
"currency": "EUR"
},
"payer": {
"account_number": "EVP9876543210"
},
"beneficiary": {
"type": "paysera",
"name": "John Doe",
"paysera_account": {
"account_number": "EVP1234567890"
}
},
"performed_at": 1729426900
}
Status Change: signed → done
Status Change: signed → done
The transfer is now complete!
Complete Workflow Example​
Here's a complete example using JavaScript/Node.js with MAC authentication:
const axios = require('axios');
const crypto = require('crypto');
const API_BASE = 'https://wallet.paysera.com/transfer/rest/v1';
const CLIENT_ID = 'wkVd93h2uS';
const MAC_KEY = 'your_mac_key';
const MAC_ALGORITHM = 'hmac-sha-256';
// Helper function to generate MAC authorization header
function generateMacAuth(method, uri, host) {
const timestamp = Math.floor(Date.now() / 1000);
const nonce = crypto.randomBytes(16).toString('hex');
const normalizedString = [
timestamp,
nonce,
method,
uri,
host,
'443',
''
].join('\n') + '\n';
const mac = crypto
.createHmac('sha256', MAC_KEY)
.update(normalizedString)
.digest('base64');
return `MAC id="${CLIENT_ID}", ts="${timestamp}", nonce="${nonce}", mac="${mac}"`;
}
async function createAndProcessTransfer() {
try {
// Step 1: Create transfer
const createResponse = await axios.post(
`${API_BASE}/transfers`,
{
amount: {
amount: '100.00',
currency: 'EUR'
},
beneficiary: {
type: 'paysera',
name: 'John Doe',
paysera_account: {
account_number: 'EVP1234567890'
}
},
payer: {
account_number: 'EVP9876543210'
},
purpose: {
details: 'Payment for invoice #12345'
}
},
{
headers: {
'Authorization': generateMacAuth('POST', '/transfer/rest/v1/transfers', 'wallet.paysera.com'),
'Content-Type': 'application/json'
}
}
);
const transferId = createResponse.data.id;
console.log('Transfer created:', transferId);
// Step 2: Reserve transfer
const reserveResponse = await axios.put(
`${API_BASE}/transfer/${transferId}/reserve`,
{},
{
headers: {
'Authorization': generateMacAuth('PUT', `/transfer/rest/v1/transfers/${transferId}/reserve`, 'wallet.paysera.com')
}
}
);
console.log('Transfer reserved:', reserveResponse.data.status);
// Step 3: Register transfer
const registerResponse = await axios.put(
`${API_BASE}/transfer/${transferId}/register`,
{},
{
headers: {
'Authorization': generateMacAuth('PUT', `/transfer/rest/v1/transfers/${transferId}/register`, 'wallet.paysera.com')
}
}
);
console.log('Transfer completed:', registerResponse.data.status);
return registerResponse.data;
} catch (error) {
console.error('Error:', error.response?.data || error.message);
throw error;
}
}
createAndProcessTransfer();
We recommend using the official Paysera PHP library which handles MAC authentication automatically. For other languages, refer to the Authentication guide for implementation details.
Transfer Status Flow​
new → reserved → signed → done
↓
cancelled (if cancelled)
Common Errors​
- Insufficient Funds
- Invalid Beneficiary
- Transfer Already Processed
{
"error": "insufficient_funds",
"error_description": "Not enough funds in account",
"available_balance": "50.00",
"required_amount": "100.00"
}
Solution: Ensure account has sufficient balance before creating the transfer.
{
"error": "invalid_beneficiary",
"error_description": "Beneficiary account number is invalid"
}
Solution: Verify the beneficiary account number format and validity.
{
"error": "transfer_already_processed",
"error_description": "Transfer has already been completed"
}
Solution: Check transfer status before attempting to modify it.
Next Steps​
- Learn about Bank Transfers
- Explore Batch Transfers
- Review the API Reference