Getting Started
The PaySafer API is a RESTful interface that lets you accept payments, manage customers, and handle payouts programmatically. All requests use JSON and return JSON responses.
Get API Keys
Create an account and grab your test and live keys from the Dashboard.
Make a Test Payment
Use your test key to create a payment in sandbox mode.
Go Live
Switch to your live key and start accepting real payments.
Your first API call
curl https://api.paysafer.me/v1/payments \-H "Authorization: Bearer {YOUR_SECRET_KEY}" \-H "Content-Type: application/json" \-d '{"amount": 5000,"currency": "aed","description": "Order #1234","customer": "cus_9s6XKzkNRiz8i3"}'
Test mode
Use sk_test_* keys to make test API calls without processing real payments. Switch to sk_live_* when you're ready to go live.
Authentication
The PaySafer API uses API keys to authenticate requests. You get two types of keys — include them in theAuthorization header as a Bearer token.
pk_live_51NRv2H2eZvKYlo2C...Used in client-side code (checkout forms, SDKs). Safe to expose in the browser. Can only create tokens and confirm payments.
sk_live_••••••••••••••••••••••••Used in server-side code only. Has full access to your account. Never expose in client-side code.
curl https://api.paysafer.me/v1/payments \-H "Authorization: Bearer {YOUR_SECRET_KEY}"
Security best practices
- · Never commit API keys to version control
- · Use environment variables to store secret keys
- · Restrict keys to specific IP addresses in production
- · Rotate keys immediately if you suspect a leak
API Reference
Complete reference for the PaySafer REST API. All endpoints accept and return JSON. Amounts are in the smallest currency unit (e.g. fils for AED — 100 fils = AED 1).
Payments
Payments represent a charge to a customer's payment method. Create a payment to collect money, then capture it to transfer funds to your account.
| Method | Endpoint |
|---|---|
| POST | /v1/payments |
| GET | /v1/payments/:id |
| GET | /v1/payments |
| POST | /v1/payments/:id/capture |
| POST | /v1/payments/:id/cancel |
| POST | /v1/payments/:id/refund |
curl -X POST https://api.paysafer.me/v1/payments \-H "Authorization: Bearer sk_live_..." \-H "Content-Type: application/json" \-d '{"amount": 15000,"currency": "aed","payment_method": "pm_card_visa","description": "Invoice #INV-2025-0042","customer": "cus_9s6XKzkNRiz8i3"}'
{"id": "pay_1NRv2H2eZvKYlo2CkMzPF4fS","object": "payment","amount": 15000,"amount_received": 15000,"currency": "aed","status": "succeeded","description": "Invoice #INV-2025-0042","payment_method": "pm_card_visa","customer": "cus_9s6XKzkNRiz8i3","metadata": {"order_id": "order_1234","product": "Premium Plan"},"receipt_email": "customer@example.com","created": 1709472000,"livemode": true}
Customers
Customer objects allow you to save payment methods, track payment history, and manage recurring billing for returning customers.
| Method | Endpoint |
|---|---|
| POST | /v1/customers |
| GET | /v1/customers/:id |
| PATCH | /v1/customers/:id |
| DELETE | /v1/customers/:id |
| GET | /v1/customers |
{"id": "cus_9s6XKzkNRiz8i3","object": "customer","email": "customer@example.com","name": "Ahmed Al Maktoum","phone": "+971501234567","metadata": {},"created": 1709472000,"livemode": true}
Webhook Endpoints
Configure endpoints to receive real-time event notifications when things happen in your account (payments, refunds, disputes, etc.).
| Method | Endpoint |
|---|---|
| POST | /v1/webhook-endpoints |
| GET | /v1/webhook-endpoints |
| GET | /v1/webhook-endpoints/:id |
| DELETE | /v1/webhook-endpoints/:id |
Code Examples
Complete, copy-pasteable integration examples in multiple languages. Each example shows the full flow — from creating a payment to handling the response.
Create a Payment
1curl https://api.paysafer.me/v1/payments \2 -H "Authorization: Bearer {YOUR_SECRET_KEY}" \3 -H "Content-Type: application/json" \4 -H "Idempotency-Key: order_1234_attempt_1" \5 -d '{6 "amount": 15000,7 "currency": "aed",8 "payment_method": "pm_card_visa",9 "description": "Invoice #INV-2025-0042",10 "customer": "cus_9s6XKzkNRiz8i3",11 "metadata": {12 "order_id": "order_1234",13 "product": "Premium Plan"14 },15 "receipt_email": "customer@example.com"16 }'
Handle Errors
try {const payment = await paysafer.payments.create({amount: 15000,currency: 'aed',payment_method: 'pm_card_visa',});console.log('Success:', payment.id);} catch (error) {if (error.type === 'card_error') {// Card was declinedconsole.error('Card declined:', error.message);} else if (error.type === 'rate_limit_error') {// Too many requests — retry with backoffconsole.error('Rate limited. Retrying...');} else if (error.type === 'invalid_request_error') {// Invalid parametersconsole.error('Invalid request:', error.message);} else {// Unexpected errorconsole.error('Unexpected error:', error);}}
Webhooks
Webhooks notify your server in real-time when events happen in your PaySafer account. Use them to trigger fulfillment, update your database, or send notifications.
Configure
Register a webhook URL in the Dashboard or via the API.
Receive
PaySafer sends a POST request with the event payload.
Verify
Validate the signature to confirm it came from PaySafer.
Event Types
| Event | Description |
|---|---|
payment.created | A payment has been created |
payment.completed | Payment successfully captured and funds received |
payment.failed | Payment attempt failed |
payment.refunded | A refund has been issued for a payment |
customer.created | A new customer was created |
customer.updated | Customer details were updated |
payout.completed | Funds have been sent to the merchant bank account |
payout.failed | A payout attempt failed |
dispute.created | A dispute has been opened by the cardholder |
dispute.resolved | A dispute has been resolved |
Webhook Payload
1{2 "id": "evt_1NRv2H2eZvKYlo2CkMzPF4fS",3 "object": "event",4 "type": "payment.completed",5 "api_version": "2026-01-15",6 "created": 1709472000,7 "data": {8 "id": "pay_1NRv2H2eZvKYlo2CkMzPF4fS",9 "object": "payment",10 "amount": 15000,11 "currency": "aed",12 "status": "succeeded",13 "customer": "cus_9s6XKzkNRiz8i3"14 }15}
Signature Verification
Every webhook request includes a PaySafer-Signature header. Verify it to ensure the request came from PaySafer and wasn't tampered with.
1import PaySafer from '@paysafer/node';2import express from 'express';34const app = express();5const webhookSecret = 'whsec_5Oe0jJkCfhF1...';67app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {8 const signature = req.headers['paysafer-signature'];910 let event;11 try {12 event = PaySafer.webhooks.verify(13 req.body,14 signature,15 webhookSecret,16 );17 } catch (err) {18 console.error('Webhook signature verification failed:', err.message);19 return res.status(400).send('Invalid signature');20 }2122 // Handle the event23 switch (event.type) {24 case 'payment.completed':25 const payment = event.data;26 console.log(`Payment ${payment.id} completed for ${payment.amount}`);27 // Fulfill the order...28 break;29 case 'payment.failed':30 console.log('Payment failed:', event.data.failure_reason);31 break;32 default:33 console.log('Unhandled event type:', event.type);34 }3536 res.json({ received: true });37});3839app.listen(3000);
Retry Policy
If your endpoint returns a non-2xx response, PaySafer retries with exponential backoff:
After 6 failed attempts, the event is marked as failed. You can manually retry from the Dashboard.
SDKs & Libraries
Official client libraries for quick integration. All SDKs support auto-pagination, idempotent requests, and automatic retries with exponential backoff.
@paysafer/nodenpm install @paysafer/nodepaysaferpip install paysaferpaysafer/paysafer-phpcomposer require paysafer/paysafer-phpgithub.com/paysafer/paysafer-gogo get github.com/paysafer/paysafer-gopaysafergem install paysaferErrors & Rate Limits
The API uses conventional HTTP status codes. Errors include a JSON body with atype,code, andmessage.
{"error": {"type": "invalid_request_error","code": "parameter_missing","message": "Missing required parameter: amount","param": "amount","doc_url": "https://docs.paysafer.me/errors#parameter_missing"}}
HTTP Status Codes
| Code | Name | Description |
|---|---|---|
| 400 | Bad Request | The request is malformed or missing required parameters. |
| 401 | Unauthorized | Invalid or missing API key. Check your Authorization header. |
| 402 | Payment Required | The payment cannot be processed (e.g. insufficient funds, card declined). |
| 404 | Not Found | The requested resource does not exist. |
| 409 | Conflict | Idempotency conflict — a request with the same idempotency key already exists. |
| 422 | Unprocessable | The request parameters are valid but cannot be processed in the current state. |
| 429 | Rate Limited | Too many requests. See rate limits below. |
| 500 | Server Error | An unexpected error on our end. Retry with exponential backoff. |
Rate Limits
| Mode | Limit | Window |
|---|---|---|
| Test mode | 100 requests | Per minute |
| Live mode | 1,000 requests | Per minute |
| Live mode (Enterprise) | 10,000 requests | Per minute |
Rate limit headers are included in every response:X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset.
Need higher limits?
Enterprise customers can request custom rate limits. Contact us at api@paysafer.me or visit the Business page.
Ready to integrate?
Create a free account, grab your API keys, and start accepting payments in minutes. Our SDKs make it even easier.