These practices apply to any integration that accesses the Paisr API on behalf of merchants. Following them ensures your integration is identifiable in merchant audit logs, operates securely, and is easier to support when issues arise.
User-Agent Header
Every API request your integration makes must include a User-Agent header that identifies it. Paisr records the user agent on every request, and merchants can see this in their API Logs in the dashboard — so they know exactly which integration triggered each call.
Format
Name/Version PaisrIntegration/IdentifierA valid user agent must contain at least two identifiers separated by a space:
- Your integration name and version — e.g.
AcmeShop/2.4.1 - A Paisr-prefixed identifier — must start with
Paisrso it's immediately recognisable in logs
Examples
WooCommerce-Paisr/1.3.0 PaisrWooCommerce/wooAcmePlatform/4.1.0 PaisrAcme/acmeShopifyPaisrApp/2.0.1 PaisrShopify/shopifyThe Paisr-prefixed identifier helps merchants, our support team, and our monitoring systems quickly pinpoint which integration made a given request. A single opaque identifier is not sufficient.
What merchants see
Every API call you make is recorded in the merchant's API Logs section in the dashboard. The log entry shows the method, route, timestamp, response status, and the user agent your integration sent. A clear, well-structured user agent makes it easy for a merchant to understand what their integration is doing — and easy for our team to support them if something goes wrong.
Server-to-Server Calls Only
All Paisr API requests must originate from your server, never from the merchant's browser or a client-side environment.
- API credentials and access tokens must never be exposed in browser JavaScript, mobile app bundles, or any environment accessible to end users
- Your integration backend is responsible for making API calls and returning only the data the frontend needs
- Requests made from the browser will expose the merchant's token
Minimal Scopes
When guiding merchants to create an access token for your integration, request only the permission scopes your integration actually uses. The Permissions page lists every available scope.
For example, an invoicing plugin needs invoices.read and invoices.write — it does not need wallets.read or transfers.initiate. Requesting unnecessary scopes creates unnecessary risk for the merchant and will raise questions during any security review.
Build Against the OpenAPI Spec
The Paisr API is fully described in a publicly available OpenAPI 3.1 spec:
https://github.com/paisrtechnologies/pcb-openapiBuild your client against this spec rather than hand-coding request shapes. This gives you:
- Type safety — generated models that match the exact request and response shapes
- Automatic updates — regenerate your client when the spec is updated to stay current
- Less maintenance — no need to manually track field changes or new endpoints
Use a generator like Swagger to produce a typed client in your language of choice.
Error Handling
The API returns structured errors with a type field that classifies the failure:
| Type | Meaning |
|---|---|
authentication_error | Invalid or expired token — re-authenticate |
authorization_error | Token lacks the required scope |
request_error | Malformed request or resource not found |
card_error | Card was declined by the issuer |
processing_error | Downstream processing failure — safe to retry |
server_error | Unexpected server error — contact support |
Always surface meaningful error messages to the merchant rather than generic failures. Where the error type is processing_error or server_error, implement exponential backoff before retrying.
Idempotency
For any operation that moves money or creates a record (transfers, invoices, payments), generate a unique idempotency key per attempt and include it in your request logic. This prevents duplicate records if a network timeout causes your integration to retry a request that already succeeded on the server.
Versioning
Always target a specific API version (/v2/) in your base URL rather than relying on a versionless endpoint. When a new version is released, test against it in your sandbox before migrating production merchants.