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.

1

Get API Keys

Create an account and grab your test and live keys from the Dashboard.

2

Make a Test Payment

Use your test key to create a payment in sandbox mode.

3

Go Live

Switch to your live key and start accepting real payments.

Your first API call

Create a payment
curl
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.

Publishable Key
pk_live_51NRv2H2eZvKYlo2C...

Used in client-side code (checkout forms, SDKs). Safe to expose in the browser. Can only create tokens and confirm payments.

Secret Key
sk_live_••••••••••••••••••••••••

Used in server-side code only. Has full access to your account. Never expose in client-side code.

Header authentication
curl
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.

MethodEndpoint
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
Request
curl
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"
}'
Response
json
{
"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.

MethodEndpoint
POST/v1/customers
GET/v1/customers/:id
PATCH/v1/customers/:id
DELETE/v1/customers/:id
GET/v1/customers
Customer object
json
{
"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.).

MethodEndpoint
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 declined
console.error('Card declined:', error.message);
} else if (error.type === 'rate_limit_error') {
// Too many requests — retry with backoff
console.error('Rate limited. Retrying...');
} else if (error.type === 'invalid_request_error') {
// Invalid parameters
console.error('Invalid request:', error.message);
} else {
// Unexpected error
console.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.

1

Configure

Register a webhook URL in the Dashboard or via the API.

2

Receive

PaySafer sends a POST request with the event payload.

3

Verify

Validate the signature to confirm it came from PaySafer.

Event Types

EventDescription
payment.createdA payment has been created
payment.completedPayment successfully captured and funds received
payment.failedPayment attempt failed
payment.refundedA refund has been issued for a payment
customer.createdA new customer was created
customer.updatedCustomer details were updated
payout.completedFunds have been sent to the merchant bank account
payout.failedA payout attempt failed
dispute.createdA dispute has been opened by the cardholder
dispute.resolvedA dispute has been resolved

Webhook Payload

Event object
json
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';
3
4const app = express();
5const webhookSecret = 'whsec_5Oe0jJkCfhF1...';
6
7app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
8 const signature = req.headers['paysafer-signature'];
9
10 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 }
21
22 // Handle the event
23 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 }
35
36 res.json({ received: true });
37});
38
39app.listen(3000);

Retry Policy

If your endpoint returns a non-2xx response, PaySafer retries with exponential backoff:

Retry 1: 1 minRetry 2: 5 minRetry 3: 30 minRetry 4: 2 hrsRetry 5: 8 hrsRetry 6: 24 hrs

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.

Node.jsv1.0.0
@paysafer/node
npm install @paysafer/node
GitHub Docs
PythonComing Soon
paysafer
pip install paysafer
GitHub Docs
PHPComing Soon
paysafer/paysafer-php
composer require paysafer/paysafer-php
GitHub Docs
GoComing Soon
github.com/paysafer/paysafer-go
go get github.com/paysafer/paysafer-go
GitHub Docs
RubyComing Soon
paysafer
gem install paysafer
GitHub Docs

Errors & Rate Limits

The API uses conventional HTTP status codes. Errors include a JSON body with atype,code, andmessage.

Error response
json
{
"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

CodeNameDescription
400Bad RequestThe request is malformed or missing required parameters.
401UnauthorizedInvalid or missing API key. Check your Authorization header.
402Payment RequiredThe payment cannot be processed (e.g. insufficient funds, card declined).
404Not FoundThe requested resource does not exist.
409ConflictIdempotency conflict — a request with the same idempotency key already exists.
422UnprocessableThe request parameters are valid but cannot be processed in the current state.
429Rate LimitedToo many requests. See rate limits below.
500Server ErrorAn unexpected error on our end. Retry with exponential backoff.

Rate Limits

ModeLimitWindow
Test mode100 requestsPer minute
Live mode1,000 requestsPer minute
Live mode (Enterprise)10,000 requestsPer 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.