Making Your First Request
Ready to make your first API call? This guide walks you through authentication setup and making your first requests to the Wallet API.
Before starting, ensure you have:
- ✅ Obtained your API credentials
- ✅ Read API Fundamentals
- ✅ Chosen your authentication method (MAC or SSL Certificate)
Quick Start Overview
Making an API call involves three steps:
Let's go through each step with practical examples.
Step 1: Prepare Your Credentials
First, gather your credentials based on your authentication method.
- MAC Authentication
- SSL Certificate
MAC Credentials
You should have received:
const credentials = {
client_id: 'wkVd93h2uS', // Your client ID
mac_key: 'IrdTc8uQodU7PRpLzzLTW6wqZAO6tAMU', // Secret key
mac_algorithm: 'hmac-sha-256' // Algorithm
};
Never commit mac_key to version control or share it publicly!
SSL Certificate Setup
You should have:
- ✅ Signed certificate file (
.crtor.pem) - ✅ Private key file (
.key) - ✅ Certificate authority file (optional)
File locations example:
/path/to/certs/
├── client.crt (your signed certificate)
├── client.key (your private key)
└── ca.crt (CA certificate, optional)
Step 2: Test with a Simple GET Request
Let's start with the simplest possible request - getting server time (no authentication required).
Why Start Here?
- ✅ No authentication needed
- ✅ Quick to test
- ✅ Verifies API connectivity
- ✅ Good for clock synchronization
- cURL
- PHP
- JavaScript
- Python
curl -X GET https://wallet.paysera.com/rest/v1/server
Response:
{
"time": 1698675600
}
<?php
$ch = curl_init('https://wallet.paysera.com/rest/v1/server');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$data = json_decode($response, true);
echo "Server time: " . $data['time'] . "\n";
echo "Local time: " . time() . "\n";
echo "Difference: " . ($data['time'] - time()) . " seconds\n";
// Using fetch API
fetch('https://wallet.paysera.com/rest/v1/server')
.then(response => response.json())
.then(data => {
console.log('Server time:', data.time);
console.log('Local time:', Math.floor(Date.now() / 1000));
console.log('Difference:', data.time - Math.floor(Date.now() / 1000), 'seconds');
})
.catch(error => console.error('Error:', error));
import requests
import time
response = requests.get('https://wallet.paysera.com/rest/v1/server')
data = response.json()
print(f"Server time: {data['time']}")
print(f"Local time: {int(time.time())}")
print(f"Difference: {data['time'] - int(time.time())} seconds")
If you got a JSON response with a time field, congratulations! Your connection to the API works. 🎉
Step 3: Make an Authenticated Request
Now let's make a request that requires authentication. We'll get server configuration.
Understanding MAC Authentication:
MAC authentication requires calculating a signature for each request:
timestamp + nonce + HTTP_METHOD + REQUEST_URI + HOST + PORT + ext_params
- PHP
- JavaScript
- Python
MAC Authentication Example:
<?php
// Your credentials
$clientId = 'wkVd93h2uS';
$macKey = 'IrdTc8uQodU7PRpLzzLTW6wqZAO6tAMU';
// Request details
$method = 'GET';
$uri = '/rest/v1/configuration';
$host = 'wallet.paysera.com';
$port = 443;
// Generate timestamp and nonce
$timestamp = time();
$nonce = bin2hex(random_bytes(16));
// Build normalized request string
$normalizedString = implode("\n", [
$timestamp,
$nonce,
$method,
$uri,
$host,
$port,
'' // ext params (empty for this request)
]) . "\n";
// Calculate MAC
$mac = base64_encode(hash_hmac('sha256', $normalizedString, $macKey, true));
// Build authorization header
$authHeader = sprintf(
'MAC id="%s", ts="%s", nonce="%s", mac="%s"',
$clientId,
$timestamp,
$nonce,
$mac
);
// Make request
$ch = curl_init("https://{$host}{$uri}");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: {$authHeader}",
'User-Agent: MyApp/1.0'
]
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode === 200) {
$data = json_decode($response, true);
echo "Minimum password length: " . $data['minimum_password_length'] . "\n";
} else {
echo "Error: HTTP {$httpCode}\n";
echo $response . "\n";
}
curl_close($ch);
SSL Certificate Example:
<?php
$ch = curl_init('https://wallet.paysera.com/rest/v1/configuration');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSLCERT => '/path/to/client.crt',
CURLOPT_SSLKEY => '/path/to/client.key',
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
echo "Min password: " . $data['minimum_password_length'];
MAC Authentication Example:
const crypto = require('crypto');
const clientId = 'wkVd93h2uS';
const macKey = 'IrdTc8uQodU7PRpLzzLTW6wqZAO6tAMU';
const method = 'GET';
const uri = '/rest/v1/configuration';
const host = 'wallet.paysera.com';
const port = 443;
const timestamp = Math.floor(Date.now() / 1000);
const nonce = crypto.randomBytes(16).toString('hex');
const normalizedString = [
timestamp, nonce, method, uri, host, port, ''
].join('\n') + '\n';
const mac = crypto.createHmac('sha256', macKey)
.update(normalizedString).digest('base64');
const authHeader = `MAC id="${clientId}", ts="${timestamp}", nonce="${nonce}", mac="${mac}"`;
fetch(`https://${host}${uri}`, {
headers: { 'Authorization': authHeader }
})
.then(res => res.json())
.then(data => console.log('Min password:', data.minimum_password_length));
SSL Certificate Example:
const https = require('https');
const fs = require('fs');
const options = {
hostname: 'wallet.paysera.com',
path: '/rest/v1/configuration',
cert: fs.readFileSync('/path/to/client.crt'),
key: fs.readFileSync('/path/to/client.key')
};
https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => data += chunk);
res.on('end', () => {
const config = JSON.parse(data);
console.log('Min password:', config.minimum_password_length);
});
}).end();
MAC Authentication Example:
import requests
import hmac
import hashlib
import base64
import time
import secrets
# Your credentials
client_id = 'wkVd93h2uS'
mac_key = 'IrdTc8uQodU7PRpLzzLTW6wqZAO6tAMU'
# Request details
method = 'GET'
uri = '/rest/v1/configuration'
host = 'wallet.paysera.com'
port = 443
# Generate timestamp and nonce
timestamp = str(int(time.time()))
nonce = secrets.token_hex(16)
# Build normalized request string
normalized_parts = [
timestamp,
nonce,
method,
uri,
host,
str(port),
'' # ext params (empty for this request)
]
normalized_string = '\n'.join(normalized_parts) + '\n'
# Calculate MAC
mac = base64.b64encode(
hmac.new(
mac_key.encode('utf-8'),
normalized_string.encode('utf-8'),
hashlib.sha256
).digest()
).decode('utf-8')
# Build authorization header
auth_header = f'MAC id="{client_id}", ts="{timestamp}", nonce="{nonce}", mac="{mac}"'
# Make request
response = requests.get(
f'https://{host}{uri}',
headers={
'Authorization': auth_header,
'User-Agent': 'MyApp/1.0'
}
)
if response.status_code == 200:
data = response.json()
print(f"Minimum password length: {data['minimum_password_length']}")
else:
print(f"Error: HTTP {response.status_code}")
print(response.text)
SSL Certificate Example:
curl https://wallet.paysera.com/rest/v1/configuration \
--cert /path/to/client.crt \
--key /path/to/client.key
{
"minimum_password_length": 8
}
Step 4: Make a POST Request
Let's create a simple transaction to see POST requests in action.
- PHP with MAC Auth
- JavaScript
<?php
$clientId = 'wkVd93h2uS';
$macKey = 'IrdTc8uQodU7PRpLzzLTW6wqZAO6tAMU';
// Request data
$requestData = [
'payments' => [
[
'description' => 'Test payment',
'price' => 1000, // 10.00 EUR in cents
'currency' => 'EUR'
]
],
'redirect_uri' => 'https://yoursite.com/return'
];
$requestBody = json_encode($requestData);
// Request details
$method = 'POST';
$uri = '/rest/v1/transaction';
$host = 'wallet.paysera.com';
$port = 443;
// Generate timestamp and nonce
$timestamp = time();
$nonce = bin2hex(random_bytes(16));
// Calculate body hash for POST requests
$bodyHash = base64_encode(hash('sha256', $requestBody, true));
$ext = 'body_hash=' . urlencode($bodyHash);
// Build normalized request string
$normalizedString = implode("\n", [
$timestamp,
$nonce,
$method,
$uri,
$host,
$port,
$ext
]) . "\n";
// Calculate MAC
$mac = base64_encode(hash_hmac('sha256', $normalizedString, $macKey, true));
// Build authorization header
$authHeader = sprintf(
'MAC id="%s", ts="%s", nonce="%s", mac="%s", ext="%s"',
$clientId,
$timestamp,
$nonce,
$mac,
$ext
);
// Make request
$ch = curl_init("https://{$host}{$uri}");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $requestBody,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: {$authHeader}",
'Content-Type: application/json',
'User-Agent: MyApp/1.0'
]
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode === 200) {
$transaction = json_decode($response, true);
echo "Transaction created!\n";
echo "Transaction key: " . $transaction['transaction_key'] . "\n";
echo "Status: " . $transaction['status'] . "\n";
} else {
echo "Error: HTTP {$httpCode}\n";
$error = json_decode($response, true);
echo "Error: " . ($error['error'] ?? 'Unknown') . "\n";
echo "Description: " . ($error['error_description'] ?? 'No description') . "\n";
}
curl_close($ch);
const crypto = require('crypto');
const clientId = 'wkVd93h2uS';
const macKey = 'IrdTc8uQodU7PRpLzzLTW6wqZAO6tAMU';
// Request data
const requestData = {
payments: [{
description: 'Test payment',
price: 1000, // 10.00 EUR in cents
currency: 'EUR'
}],
redirect_uri: 'https://yoursite.com/return'
};
const requestBody = JSON.stringify(requestData);
// Request details
const method = 'POST';
const uri = '/rest/v1/transaction';
const host = 'wallet.paysera.com';
const port = 443;
// Generate timestamp and nonce
const timestamp = Math.floor(Date.now() / 1000);
const nonce = crypto.randomBytes(16).toString('hex');
// Calculate body hash
const bodyHash = crypto
.createHash('sha256')
.update(requestBody)
.digest('base64');
const ext = `body_hash=${encodeURIComponent(bodyHash)}`;
// Build normalized request string
const normalizedString = [
timestamp,
nonce,
method,
uri,
host,
port,
ext
].join('\n') + '\n';
// Calculate MAC
const mac = crypto
.createHmac('sha256', macKey)
.update(normalizedString)
.digest('base64');
// Build authorization header
const authHeader = `MAC id="${clientId}", ts="${timestamp}", nonce="${nonce}", mac="${mac}", ext="${ext}"`;
// Make request
fetch(`https://${host}${uri}`, {
method: 'POST',
headers: {
'Authorization': authHeader,
'Content-Type': 'application/json',
'User-Agent': 'MyApp/1.0'
},
body: requestBody
})
.then(response => response.json())
.then(transaction => {
console.log('Transaction created!');
console.log('Transaction key:', transaction.transaction_key);
console.log('Status:', transaction.status);
})
.catch(error => console.error('Error:', error));
Troubleshooting Common Errors
❌ Error: unauthorized (401)
Cause: Authentication failed
Solutions:
- ✅ Verify your credentials are correct
- ✅ Check timestamp isn't too far from server time (max ±5 minutes)
- ✅ Ensure MAC signature calculation is correct
- ✅ Verify nonce is randomly generated and unique
Check Time Synchronization:
# Check server time
curl https://wallet.paysera.com/rest/v1/server
# Compare with your local time
date +%s
# If difference > 300 seconds, sync your clock
Debug MAC Calculation:
// Output normalized string for debugging
echo "Normalized string:\n";
echo $normalizedString;
echo "\n\nMAC: " . $mac . "\n";
❌ Error: forbidden (403)
Cause: No permission for this action
Solutions:
- ✅ Verify your client has necessary permissions
- ✅ Check if using correct
project_idin ext parameter - ✅ Ensure you're accessing resources you own
- ✅ Contact support if permissions seem incorrect
Example with project_id:
$ext = 'project_id=123'; // Add your project ID
❌ Error: invalid_parameters (400)
Cause: Request parameters are invalid
Solutions:
- ✅ Check request JSON syntax is valid
- ✅ Verify all required fields are present
- ✅ Ensure correct data types (string vs number)
- ✅ Check parameter formats (e.g., currency codes must be 3 letters)
Example Error Response:
{
"error": "invalid_parameters",
"error_description": "Currency must be 3-letter code (e.g., EUR)",
"errors": [
{
"field": "currency",
"message": "Invalid format"
}
]
}
❌ SSL Certificate Errors
Error: SSL certificate problem: unable to get local issuer certificate
Solutions:
- ✅ Verify certificate file paths are correct
- ✅ Check certificate hasn't expired
- ✅ Ensure private key matches certificate
- ✅ Verify server certificate validation is enabled
- ✅ Update CA bundle if needed
PHP Solutions:
// Option 1: Specify CA bundle (recommended)
curl_setopt($ch, CURLOPT_CAINFO, '/path/to/cacert.pem');
// Option 2: Update PHP's default CA bundle
// Download from: https://curl.se/docs/caextract.html
Node.js Solutions:
// Specify CA bundle
const options = {
ca: fs.readFileSync('/path/to/ca-bundle.crt')
};
Never disable SSL verification in production:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // DANGEROUS!
❌ Error: invalid_grant
Cause: Token refresh failed or authorization code already used
Solutions:
- ✅ Ensure authorization code hasn't been used before
- ✅ Check refresh token is still valid
- ✅ Verify code hasn't expired
- ✅ Request new authorization if needed
❌ Timeout Errors
Cause: Request took too long or network issues
Solutions:
- ✅ Increase timeout settings (default 30s)
- ✅ Check network connectivity
- ✅ Implement retry logic with exponential backoff
- ✅ Monitor API status page
PHP Timeout Configuration:
curl_setopt($ch, CURLOPT_TIMEOUT, 60); // 60 seconds
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // 10s to connect
Retry Logic Example:
function makeRequestWithRetry($url, $maxRetries = 3) {
$attempt = 0;
while ($attempt < $maxRetries) {
try {
return makeRequest($url);
} catch (TimeoutException $e) {
$attempt++;
if ($attempt >= $maxRetries) throw $e;
// Exponential backoff: 1s, 2s, 4s
sleep(pow(2, $attempt - 1));
}
}
}
Using Libraries
Instead of implementing authentication manually, use official libraries:
PHP Library:
composer require paysera/lib-wallet-php-client
<?php
require 'vendor/autoload.php';
use Paysera\WalletApi\WalletApi;
use Paysera\WalletApi\Util\Router;
$api = new WalletApi(
'wkVd93h2uS', // client_id
'IrdTc8uQodU7PRpLzzLTW6wqZAO6tAMU', // mac_key
Router::createForProduction() // Production environment
);
// Get server time
$server = $api->walletClient()->getServerInformation();
echo "Server time: " . $server->getTime() . "\n";
// Get configuration
$config = $api->walletClient()->getConfiguration();
echo "Min password length: " . $config->getMinimumPasswordLength() . "\n";
What's Next?
Now that you can make API requests, explore specific features:
For User Information:
- 📖 User Information Guide - Get user data and permissions
- 🔐 OAuth Integration - Implement OAuth flow
For Payments:
- 💳 Payments Overview - Learn about payment features (see Payments section in sidebar)
- 📝 Payment Examples - See practical examples (see Payments > Payment Basics in sidebar)
Advanced Topics:
- 🔒 Security Best Practices - Secure your integration
- 📚 Full API Reference - Explore all endpoints
- 💡 More Examples - Advanced use cases
Need Help?
Stuck on something?
- 💬 API Support: tech_support@paysera.com
- 📖 Documentation: Full Wallet API Docs
- 🐛 Issues: Check error codes in API Fundamentals
Keep your first successful request code as a reference. It's helpful for troubleshooting future issues!