Skip to content

Server API Reference

The Zirzir server exposes a REST API for initiating payments, managing merchants, and configuring providers. All responses are JSON.

Base URL: https://your-zirzir-server.com (or http://localhost:8080 in development).


The API uses two authentication methods:

MethodHeaderUsed by
Merchant API keyAuthorization: Bearer zz_test_...SDK / your backend
Admin API keyAuthorization: Bearer <admin-key>Server administration

API keys prefixed with zz_test_ route to sandbox environments. Keys prefixed with zz_live_ route to production.


No authentication required.

Terminal window
curl http://localhost:8080/health
{ "status": "ok" }

These endpoints require a merchant API key.

POST /api/v1/payments

Terminal window
curl -X POST http://localhost:8080/api/v1/payments \
-H "Authorization: Bearer zz_test_..." \
-H "Content-Type: application/json" \
-d '{
"provider": "chapa",
"amount": 500,
"currency": "ETB",
"reference": "order-123",
"customer_email": "[email protected]",
"customer_name": "Abebe Bikila",
"return_url": "https://yoursite.com/thank-you",
"callback_url": "https://yoursite.com/webhooks"
}'

Request body:

FieldTypeRequiredDescription
providerstringyesProvider code (chapa, telebirr, etc.)
amountnumberyesPayment amount (> 0)
currencystringnoISO 4217 code. Defaults to ETB
referencestringyesYour unique transaction reference
customer_emailstringnoCustomer email
customer_namestringnoCustomer name
customer_phonestringnoCustomer phone (required for USSD providers)
return_urlstringnoRedirect URL after payment
callback_urlstringnoWebhook URL for this transaction
metadataobjectnoArbitrary key-value pairs

Response 201 Created:

{
"id": "txn_01HX...",
"merchant_id": "mrc_...",
"provider": "chapa",
"provider_txn_id": "chapa_abc123",
"reference": "order-123",
"amount": 500,
"currency": "ETB",
"status": "pending",
"payment_url": "https://checkout.chapa.co/...",
"customer_email": "[email protected]",
"customer_name": "Abebe Bikila",
"environment": "test",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z"
}

GET /api/v1/payments/:id

Terminal window
curl http://localhost:8080/api/v1/payments/txn_01HX... \
-H "Authorization: Bearer zz_test_..."

Add ?refresh=true to query the provider for the latest status instead of returning the cached value.


GET /api/v1/payments

Terminal window
curl "http://localhost:8080/api/v1/payments?status=completed&provider=chapa&limit=10&offset=0" \
-H "Authorization: Bearer zz_test_..."

Query parameters:

ParamTypeDefaultDescription
statusstringFilter by status (pending, completed, failed, cancelled)
providerstringFilter by provider code
start_datestringFilter from date (YYYY-MM-DD)
end_datestringFilter to date (YYYY-MM-DD)
limitint20Results per page (max 100)
offsetint0Pagination offset

Response:

{
"transactions": [ ... ],
"total": 42,
"limit": 20,
"offset": 0
}

Public endpoints — no authentication required.

GET /api/v1/providers

Returns all registered providers (built-in and plugins).

[
{
"code": "chapa",
"name": "Chapa",
"version": "1.0.0",
"description": "Ethiopian online payment gateway",
"countries": ["ET"],
"currencies": ["ETB", "USD"],
"payment_types": ["web_checkout"],
"config_fields": [
{ "name": "secret_key", "label": "Secret Key", "type": "password", "required": true }
]
}
]

GET /api/v1/providers/:code

Returns metadata for a single provider.


POST /api/v1/webhooks/:provider

No authentication — called by payment providers (Chapa, Telebirr, etc.) to notify Zirzir of payment status changes.

Zirzir parses the provider-specific payload, updates the transaction status, and forwards a normalized webhook to your callback_url.


All admin endpoints require the admin API key set in security.admin_api_key.

MethodEndpointDescription
POST/admin/merchantsCreate a merchant
GET/admin/merchantsList all merchants
GET/admin/merchants/:idGet a merchant
PUT/admin/merchants/:idUpdate a merchant
DELETE/admin/merchants/:idDelete a merchant

Create merchant:

Terminal window
curl -X POST http://localhost:8080/admin/merchants \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "My App",
"webhook_url": "https://yoursite.com/webhooks/zirzir"
}'

MethodEndpointDescription
POST/admin/merchants/:id/providersConfigure a provider
GET/admin/merchants/:id/providersList configured providers
DELETE/admin/merchants/:id/providers/:providerRemove a provider

Configure provider:

Terminal window
curl -X POST http://localhost:8080/admin/merchants/$MERCHANT_ID/providers \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"provider": "chapa",
"environment": "test",
"config": {
"secret_key": "CHASECK_TEST-..."
}
}'

The config object is provider-specific. See the config_fields in each provider’s metadata (GET /api/v1/providers/:code) for the required fields.


MethodEndpointDescription
POST/admin/merchants/:id/api-keysCreate an API key
GET/admin/merchants/:id/api-keysList API keys
DELETE/admin/merchants/:id/api-keys/:keyIdRevoke an API key

Create API key:

Terminal window
curl -X POST http://localhost:8080/admin/merchants/$MERCHANT_ID/api-keys \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"environment": "test", "label": "Backend service"}'

Response:

{
"id": "key_...",
"key": "zz_test_abc123...",
"environment": "test",
"label": "Backend service",
"created_at": "2025-01-15T10:30:00Z"
}

The key value is only returned once at creation time. Store it securely.


These endpoints are used by the built-in React dashboard and require a user auth token (cookie-based, set after login).

MethodEndpointDescription
GET/api/auth/setupCheck if initial setup is needed
POST/api/auth/signupCreate a user account
POST/api/auth/loginLog in
GET/api/auth/meGet current user
POST/api/auth/logoutLog out
MethodEndpointDescription
GET/api/projectsList user’s projects
POST/api/projectsCreate a project
GET/api/projects/:idGet project details
GET/api/projects/:id/api-keysList project API keys
POST/api/projects/:id/api-keysCreate a project API key
GET/api/projects/:id/providersList project providers
POST/api/projects/:id/providersConfigure a provider for the project

All errors follow this format:

{
"message": "provider is required"
}

Common HTTP status codes:

CodeMeaning
400Bad request (missing fields, invalid data)
401Unauthorized (missing or invalid API key)
404Resource not found
500Internal server error

StatusDescription
pendingPayment initiated, awaiting customer action
completedPayment confirmed by the provider
failedPayment failed or was declined
cancelledCustomer cancelled the payment