Frequently Asked Questions
Common questions and answers about implementing and using the Paysera Delivery API.
All API requests require MAC (Message Authentication Code) authentication using your project_id and sign_password.
For complete authentication implementation with working code examples in JavaScript, PHP, and Python, see API Fundamentals - Authentication.
Use the tabs below to find answers by category. Click any question to expand the answer.
- 🔰 General & Getting Started
- ⚙️ Technical & Integration
- 💰 Billing & Pricing
- 🛠️ Troubleshooting & Support
General Questions
What is the Paysera Delivery API?
The Paysera Delivery API is a unified logistics platform that allows you to integrate multiple courier services through a single API. Instead of managing separate integrations with DPD, DHL, Omniva, and other carriers, you can use one API to:
- Create and manage shipments
- Track packages in real-time
- Generate shipping labels
- Handle returns
- Access pre-negotiated rates
This saves development time and provides access to competitive shipping rates without individual courier contracts.
Which countries and couriers are supported?
Supported Countries
The API primarily operates in:
- Baltic States: Lithuania, Latvia, Estonia
- European Union: All EU countries for international shipping
- United Kingdom: Available for cross-border deliveries
Available Couriers
| Courier | Coverage | Services |
|---|---|---|
| DPD | Europe-wide | Standard, Express, Saturday |
| DHL | Global | Express, Economy, Same-day |
| Omniva | Baltics | Parcel machines, Home delivery |
| LP Express | Lithuania | Next-day, Parcel lockers |
| Venipak | Baltics + Poland | Standard, Express, C.O.D. |
The API automatically selects the best courier based on destination, package specs, and your preferences.
Do I need separate contracts with each courier?
No! This is one of the main benefits of using Paysera Delivery API. We have pre-existing agreements with all supported couriers, so you can:
- Access multiple courier services immediately
- Benefit from our negotiated bulk rates
- Avoid lengthy contract negotiations
- Skip individual courier onboarding processes
- Receive consolidated billing through Paysera
You only need a Paysera partner account to access all courier services.
Getting Started
How do I get API credentials?
Follow these steps to obtain your API credentials:
-
Create Paysera Account
- Register at www.paysera.com
- Complete identity verification (KYC)
-
Apply for Partner Status
- Go to account settings
- Select "Online payment collection"
- Apply for delivery partner status
-
Create Project
- Navigate to "My Projects"
- Create new project with type "Delivery"
- Configure your business details
-
Receive Credentials
project_id: Your unique identifierapi_key: For API authentication (starts withpk_live_)webhook_secret: For webhook signature verification
-
Start Integration
- Implement API endpoints
- Test with small real orders
- Scale up when validated
How do I verify the integration?
Verifying in Production (No Test Environment)
Delivery API operates in production mode only. There is no sandbox or test environment. All orders created are real and will be processed by actual couriers.
Recommended Verification Approach:
-
Create Small Real Orders
- Use lightweight, minimal value items
- Ship to your own address or office
- Start with 1-2 orders to validate the entire flow
-
Use Your Own Addresses for Verification
const verificationOrder = {
order_id: `VERIFY-${Date.now()}`,
pickup: {
name: 'Your Office',
address: 'Your Office Address',
// ... your details
},
delivery: {
name: 'Your Name',
address: 'Your Home or Office Address',
// ... address you control
},
parcel: {
weight: 500, // grams (0.5 kg)
dimensions: { length: 100, width: 100, height: 100 }, // mm
value: 5.00, // EUR - low value item
description: 'Integration verification package'
}
}; -
Order Management
- Orders can sometimes be cancelled shortly after creation
- Contact support about cancellation policies
- Cancelled orders may still incur minimal fees
-
Track Verification Orders
- Use clear naming convention (e.g., VERIFY-xxx)
- Monitor webhook responses
- Keep separate records for verification orders
How long does the integration typically take?
Integration timeline depends on your requirements:
Basic Integration (1-2 days)
- Create delivery orders
- Track packages
- Basic webhook handling
Standard Integration (3-5 days)
- All basic features
- Label generation
- Returns management
- Error handling
- Verification with real orders
Advanced Integration (1-2 weeks)
- Custom courier selection logic
- Batch operations
- Advanced webhook processing
- Multiple pickup locations
- Custom reporting
- Production optimization
Most merchants complete a functional integration in 3-5 days.
Technical Questions
What authentication method does the API use?
The API uses MAC (Message Authentication Code) authentication based on OAuth 2.0 specification.
Authorization: MAC id="123456", ts="1700574800", nonce="abc123", mac="signature"
Required Credentials
- project_id - Your project identifier (used as
mac_id) - sign_password - Your project password (used as
mac_secret)
Security Best Practices
- Never expose
sign_passwordin client-side code - Store credentials in environment variables
- Generate a unique nonce for each request
- Use current timestamp (servers may reject old requests)
- Monitor API usage in partner portal
How to Get Credentials
Navigate to: Project and Activities → My Projects → [Your Project] → General project settings
Implementation
For working code examples in JavaScript, PHP, and Python, see: API Fundamentals - Authentication
How do I handle webhook events?
Webhooks notify you of delivery status changes in real-time:
1. Configure Webhook URL
Set your endpoint in the partner portal or via API.
2. Verify Signatures
All webhooks include HMAC-SHA256 signature:
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
return signature === expectedSignature;
}
3. Handle Events
| Event Type | Description | Action Required |
|---|---|---|
delivery.created | Order confirmed | Update order status |
delivery.status_changed | Status update | Notify customer |
delivery.delivered | Successfully delivered | Mark as complete |
delivery.failed | Delivery failed | Handle retry/return |
delivery.returned | Package returned | Process refund |
4. Respond Quickly
- Process webhooks asynchronously
- Return 200 OK immediately
- Retry logic for failed processing
What are the API rate limits?
Rate limits depend on your account tier:
| Tier | Per Minute | Per Hour | Daily Orders | Concurrent |
|---|---|---|---|---|
| Standard | 100 | 3,000 | 1,000 | 10 |
| Business | 300 | 10,000 | 5,000 | 25 |
| Enterprise | Custom | Custom | Unlimited | Custom |
Rate Limit Headers
Monitor your usage via response headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 85
X-RateLimit-Reset: 1697197200
Handling Rate Limits
async function handleRateLimit(response) {
if (response.status === 429) {
const resetTime = response.headers['x-ratelimit-reset'];
const waitTime = resetTime - Date.now() / 1000;
console.log(`Rate limited. Waiting ${waitTime}s`);
await new Promise(resolve =>
setTimeout(resolve, waitTime * 1000)
);
// Retry request
return makeRequest();
}
}
Best Practices
- Implement exponential backoff
- Cache frequently accessed data
- Batch operations when possible
- Monitor rate limit headers
- Use webhooks instead of polling
Integration Issues
Why is my order creation failing?
Common causes and solutions:
1. Invalid Address Format
// ❌ Wrong
{
country: "Lithuania", // Should be ISO code
phone: "860000001" // Missing country code
}
// ✅ Correct
{
country: "LT", // ISO 3166-1 alpha-2
phone: "+37060000001" // E.164 format
}
2. Missing Required Fields
Required fields for order creation:
order_id(unique)pickupaddress objectdeliveryaddress objectparcelspecifications
3. Duplicate Order ID
// Generate unique order IDs
const orderId = `ORD-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
4. Invalid Parcel Specifications
// Check parcel limits
const validateParcel = (parcel) => {
const errors = [];
if (parcel.weight > 30) {
errors.push('Weight exceeds 30kg limit');
}
if (parcel.dimensions.length > 120) {
errors.push('Length exceeds 120cm limit');
}
const girth = 2 * (parcel.dimensions.width + parcel.dimensions.height);
if (parcel.dimensions.length + girth > 300) {
errors.push('Size exceeds maximum girth');
}
return errors;
};
5. Authentication Issues
- Verify
project_idandsign_passwordare correct - Verify you're using correct production credentials
- Ensure MAC authentication signature is correctly generated
How do I handle failed deliveries?
Failed deliveries are handled automatically with retry attempts, but you can customize the process:
Automatic Retry Logic
- First attempt: Original delivery date
- Second attempt: Next business day
- Third attempt: Following business day
- After 3 attempts: Package returned
Webhook Notification
// Handle delivery failure webhook
app.post('/webhook/delivery', (req, res) => {
const event = req.body;
if (event.type === 'delivery.failed') {
const { id, reason, attempts } = event.data;
if (attempts < 3) {
// Will be retried automatically
notifyCustomer('Delivery rescheduled for tomorrow');
} else {
// Final failure - initiate return
initiateReturn(id);
processRefund(event.data.order_id);
}
}
res.status(200).send('OK');
});
Common Failure Reasons
| Reason | Description | Recommended Action |
|---|---|---|
recipient_not_available | Nobody at address | Schedule retry |
address_not_found | Invalid address | Contact customer |
refused_by_recipient | Package refused | Process return |
damaged_in_transit | Package damaged | File claim & refund |
customs_issue | Held at customs | Provide documentation |
Can I use custom shipping labels?
The API generates standard courier labels, but you can customize certain elements:
Label Generation
GET /rest/v1/orders/{order_id}/label
Authorization: MAC id="123456", ts="1700574800", nonce="abc123", mac="..."
Accept: application/pdf
Response: Binary PDF file
For MAC authentication implementation, see API Fundamentals.
Customization Options
- Reference Numbers: Add your order reference
- Special Instructions: Include handling notes
- Sender Logo: Some couriers support sender branding
- Additional Barcodes: Add your internal tracking codes
Label Formats
- PDF (default)
- PNG image
- ZPL for Zebra printers
- Base64 encoded for direct printing
Note: Full custom labels aren't supported as they must meet courier specifications.
Billing & Pricing
How does pricing work?
Pricing Structure
Delivery costs are calculated based on:
- Base Rate: Fixed cost per shipment
- Weight: Actual or volumetric (whichever is greater)
- Distance: Zone-based pricing
- Service Type: Standard, Express, Same-day
- Additional Services: Insurance, COD, signature
Volumetric Weight Calculation
// Formula: Length × Width × Height / 5000
const volumetricWeight = (30 * 20 * 15) / 5000; // = 1.8 kg
// Chargeable weight is the greater of:
const chargeableWeight = Math.max(actualWeight, volumetricWeight);
Sample Pricing
| Service | Base | Per kg | Per zone |
|---|---|---|---|
| Standard | €5 | €2 | €0.50 |
| Express | €10 | €3 | €1.00 |
| Same-day | €20 | €5 | €2.00 |
Billing
- Monthly invoicing
- Consolidated billing for all couriers
- Volume discounts available
- No setup or monthly fees
Are there any hidden fees?
No hidden fees! All costs are transparent:
Included in Standard Pricing
✅ Label generation ✅ Basic tracking ✅ Email notifications ✅ Standard insurance (up to €100) ✅ One redelivery attempt ✅ API access
Optional Paid Services
| Service | Cost |
|---|---|
| Extended insurance | 1% of declared value |
| Cash on delivery (COD) | €2 + 2% of amount |
| Saturday delivery | +€5 |
| Signature confirmation | +€1 |
| Return labels | Same as outbound |
No Charges For
- Failed delivery attempts (first 3)
- Address validation
- Tracking requests
- Webhook notifications
- Customer support
Troubleshooting
Common Error Codes and Solutions
| Error Code | Description | Solution |
|---|---|---|
| 400 | Bad Request | Check request format and required fields |
| 401 | Unauthorized | Verify API key is correct and active |
| 403 | Forbidden | Check account permissions and service activation |
| 404 | Not Found | Verify endpoint URL and resource ID |
| 409 | Conflict | Order ID already exists, use unique identifier |
| 422 | Validation Error | Review field formats (phone, postal code, country) |
| 429 | Rate Limited | Implement backoff and retry logic |
| 500 | Server Error | Temporary issue, retry with exponential backoff |
Where can I get help?
📚 Documentation
- API Reference - Complete endpoint documentation
- Getting Started Guide - Step-by-step integration
- Code Examples - Ready-to-use samples
🛠️ Developer Resources
- Postman Collection - Pre-configured requests
- GitHub SDKs - Official client libraries
- Status Page - Service availability
💬 Support Channels
Technical Support
- Email: tech_support@paysera.com
- Response time: 1-2 business days
Partner Support
- Portal: partners.paysera.com
Emergency Support
- Phone: +44 20 80996963
- Available for critical production issues
🐛 Reporting Issues
When contacting support, include:
- Your project ID
- Request/response examples
- Error messages
- Timestamp of occurrence
- Steps to reproduce
Still have questions?
Can't find an answer to your question?
- 📚 Documentation: API Reference | Getting Started | Code Examples
- 📧 Email: tech_support@paysera.com
- 📞 Phone: +44 20 80996963
- 🛠️ Partner Portal: partners.paysera.com