API reference
Base URL: https://admin.onepay.tabsystems.tech/api/v1
Every endpoint requires the Authorization header. Amounts are validated against item sums and status transitions are enforced server-side — invalid requests return the error codes described on the overview page.
Invoices
Lifecycle: draft → pending (payment link generated) → captured (paid) → fulfilled (confirmed by the merchant). canceled and expired are final. Amounts are always validated against the item sums; every status change is recorded in the invoice status log.
/invoicesList invoices (paginated, optional created-at date range)Paginated by pageIndex/limit (max 100 per page); optionally filtered by a createdAt range via startDate/endDate (ISO strings) and by externalReference (exact match).
Parameters
| Name | Location | Type | Required |
|---|---|---|---|
| pageIndex | query | number | |
| search | query | string | |
| limit | query | number | |
| startDate | query | string | |
| endDate | query | string | |
| externalReference | query | string |
curl -X GET https://admin.onepay.tabsystems.tech/api/v1/invoices \
-H "Authorization: Bearer psk_your_token_here"{
"invoices": [
{
"id": "string",
"title": "string",
"description": "string",
"currency": "MNT",
"language": "en",
"status": "draft",
"customerFallbackEmail": "string",
"customerFallbackName": "string",
"items": [
{
"id": null,
"merchantId": null,
"name": null,
"description": null,
"price": null,
"currency": null,
"taxRate": null,
"isTaxIncluded": null,
"hasQuantity": null,
"quantity": null
}
],
"totalAmount": 0,
"taxAmount": 0,
"createdById": "string",
"createdByFallbackEmail": "string",
"createdBy": {
"id": "string",
"firstname": "string",
"lastname": "string",
"email": "string",
"hashedPassword": "string",
"mustChangePassword": false,
"roleId": "string",
"isActive": false,
"role": {
"id": null,
"name": null,
"description": null,
"merchantId": null
},
"merchantId": "string",
"invoices": [
null
],
"merchant": {
"id": null,
"name": null,
"email": null,
"phone": null,
"description": null,
"address": null,
"website": null,
"logoUrl": null
}
},
"customerId": "string",
"customer": {
"id": "string",
"name": "string",
"email": "email",
"phone": "string",
"merchantId": "string",
"deletedAt": "date-time",
"createdAt": "date-time",
"updatedAt": "date-time"
},
"paymentProviderInvoices": [
{
"provider": null,
"merchantReference": null,
"gatewayReference": null,
"redirectUrl": null,
"expiresAt": null,
"providerExtra": null,
"paymentStatus": null,
"paidAmount": null,
"paidAt": null,
"convertedAmount": null
}
],
"externalReference": "string",
"metadata": "object",
"merchantId": "string",
"expiresAt": "date-time",
"paymentLink": {
"expiresAt": "date-time",
"url": "string"
},
"createdAt": "date-time",
"updatedAt": "date-time"
}
],
"pagination": {
"page": 0,
"limit": 0,
"total": 0,
"totalPages": 0,
"hasNext": false,
"hasPrev": false
}
}/invoicesCreate a draft invoice (registered customer or guest fallback)Creates a DRAFT invoice for a registered customer (customerId) or a guest (customerFallbackEmail / customerFallbackName). expiresAt must be an ISO 8601 datetime string. totalAmount and taxAmount must equal the sums computed from items — otherwise 422 invalidAmount. Catalog items are referenced by id and priced from the database; custom one-off items supply their own price, taxRate and isTaxIncluded. Optional externalReference (your own id, max 255 chars) and metadata (a JSON object, max 8192 bytes as UTF-8 JSON — larger is rejected with 400) are stored as-is and returned on every read and in webhook payloads. The invoice remembers which API key created it, so that key's webhook receives its events.
Request body
| Name | Type | Required |
|---|---|---|
| title | string | required |
| description | string | required |
| currency | MNT | USD | JPY | required |
| language | en | mn | ja | required |
| items | array | required |
| totalAmount | number | required |
| taxAmount | number | required |
| customerId | string | |
| externalReference | string | |
| metadata | object | |
| expiresAt | string | required |
| customerFallbackEmail | string | |
| customerFallbackName | string |
curl -X POST https://admin.onepay.tabsystems.tech/api/v1/invoices \
-H "Authorization: Bearer psk_your_token_here" \
-H "Content-Type: application/json" \
-d '{ ... }'{
"id": "string",
"title": "string",
"description": "string",
"currency": "MNT",
"language": "en",
"status": "draft",
"customerFallbackEmail": "string",
"customerFallbackName": "string",
"items": [
{
"id": "string",
"merchantId": "string",
"name": "string",
"description": "string",
"price": 0,
"currency": "MNT",
"taxRate": 0,
"isTaxIncluded": false,
"hasQuantity": false,
"quantity": 0
}
],
"totalAmount": 0,
"taxAmount": 0,
"createdById": "string",
"createdByFallbackEmail": "string",
"createdBy": {
"id": "string",
"firstname": "string",
"lastname": "string",
"email": "string",
"hashedPassword": "string",
"mustChangePassword": false,
"roleId": "string",
"isActive": false,
"role": {
"id": "string",
"name": "string",
"description": "string",
"merchantId": "string"
},
"merchantId": "string",
"invoices": [
"string"
],
"merchant": {
"id": "string",
"name": "string",
"email": "string",
"phone": "string",
"description": "string",
"address": "string",
"website": "string",
"logoUrl": "string"
}
},
"customerId": "string",
"customer": {
"id": "string",
"name": "string",
"email": "email",
"phone": "string",
"merchantId": "string",
"deletedAt": "date-time",
"createdAt": "date-time",
"updatedAt": "date-time"
},
"paymentProviderInvoices": [
{
"provider": "qpay",
"merchantReference": "string",
"gatewayReference": "string",
"redirectUrl": "string",
"expiresAt": "date-time",
"providerExtra": null,
"paymentStatus": "string",
"paidAmount": 0,
"paidAt": "date-time",
"convertedAmount": 0
}
],
"externalReference": "string",
"metadata": "object",
"merchantId": "string",
"expiresAt": "date-time",
"paymentLink": {
"expiresAt": "date-time",
"url": "string"
},
"createdAt": "date-time",
"updatedAt": "date-time"
}/invoices/{invoiceId}Get one invoice with customer and merchant detailsParameters
| Name | Location | Type | Required |
|---|---|---|---|
| invoiceId | path | string | required |
curl -X GET https://admin.onepay.tabsystems.tech/api/v1/invoices/{invoiceId} \
-H "Authorization: Bearer psk_your_token_here"{
"id": "string",
"title": "string",
"description": "string",
"currency": "MNT",
"language": "en",
"status": "draft",
"customerFallbackEmail": "string",
"customerFallbackName": "string",
"items": [
{
"id": "string",
"merchantId": "string",
"name": "string",
"description": "string",
"price": 0,
"currency": "MNT",
"taxRate": 0,
"isTaxIncluded": false,
"hasQuantity": false,
"quantity": 0
}
],
"totalAmount": 0,
"taxAmount": 0,
"createdById": "string",
"createdByFallbackEmail": "string",
"createdBy": {
"id": "string",
"firstname": "string",
"lastname": "string",
"email": "string",
"hashedPassword": "string",
"mustChangePassword": false,
"roleId": "string",
"isActive": false,
"role": {
"id": "string",
"name": "string",
"description": "string",
"merchantId": "string"
},
"merchantId": "string",
"invoices": [
"string"
],
"merchant": {
"id": "string",
"name": "string",
"email": "string",
"phone": "string",
"description": "string",
"address": "string",
"website": "string",
"logoUrl": "string"
}
},
"customerId": "string",
"customer": {
"id": "string",
"name": "string",
"email": "email",
"phone": "string",
"merchantId": "string",
"deletedAt": "date-time",
"createdAt": "date-time",
"updatedAt": "date-time"
},
"paymentProviderInvoices": [
{
"provider": "qpay",
"merchantReference": "string",
"gatewayReference": "string",
"redirectUrl": "string",
"expiresAt": "date-time",
"providerExtra": null,
"paymentStatus": "string",
"paidAmount": 0,
"paidAt": "date-time",
"convertedAmount": 0
}
],
"externalReference": "string",
"metadata": "object",
"merchantId": "string",
"expiresAt": "date-time",
"paymentLink": {
"expiresAt": "date-time",
"url": "string"
},
"createdAt": "date-time",
"updatedAt": "date-time"
}/invoices/{invoiceId}Delete an invoice (draft/canceled/expired only)Only draft, canceled or expired invoices with no payment link and no status history can be hard-deleted (audit trail) — otherwise 422. Cancel an acted-on invoice via PUT /invoices/{invoiceId}/status instead.
Parameters
| Name | Location | Type | Required |
|---|---|---|---|
| invoiceId | path | string | required |
curl -X DELETE https://admin.onepay.tabsystems.tech/api/v1/invoices/{invoiceId} \
-H "Authorization: Bearer psk_your_token_here"{
"id": "string",
"title": "string",
"description": "string",
"currency": "MNT",
"language": "en",
"status": "draft",
"customerFallbackEmail": "string",
"customerFallbackName": "string",
"items": [
{
"id": "string",
"merchantId": "string",
"name": "string",
"description": "string",
"price": 0,
"currency": "MNT",
"taxRate": 0,
"isTaxIncluded": false,
"hasQuantity": false,
"quantity": 0
}
],
"totalAmount": 0,
"taxAmount": 0,
"createdById": "string",
"createdByFallbackEmail": "string",
"createdBy": {
"id": "string",
"firstname": "string",
"lastname": "string",
"email": "string",
"hashedPassword": "string",
"mustChangePassword": false,
"roleId": "string",
"isActive": false,
"role": {
"id": "string",
"name": "string",
"description": "string",
"merchantId": "string"
},
"merchantId": "string",
"invoices": [
"string"
],
"merchant": {
"id": "string",
"name": "string",
"email": "string",
"phone": "string",
"description": "string",
"address": "string",
"website": "string",
"logoUrl": "string"
}
},
"customerId": "string",
"customer": {
"id": "string",
"name": "string",
"email": "email",
"phone": "string",
"merchantId": "string",
"deletedAt": "date-time",
"createdAt": "date-time",
"updatedAt": "date-time"
},
"paymentProviderInvoices": [
{
"provider": "qpay",
"merchantReference": "string",
"gatewayReference": "string",
"redirectUrl": "string",
"expiresAt": "date-time",
"providerExtra": null,
"paymentStatus": "string",
"paidAmount": 0,
"paidAt": "date-time",
"convertedAmount": 0
}
],
"externalReference": "string",
"metadata": "object",
"merchantId": "string",
"expiresAt": "date-time",
"paymentLink": {
"expiresAt": "date-time",
"url": "string"
},
"createdAt": "date-time",
"updatedAt": "date-time"
}/invoices/{invoiceId}/statusUpdate invoice status (transitions are service-enforced)Lifecycle: draft → pending → captured → fulfilled. Allowed transitions: captured → fulfilled only; fulfilled → canceled only; canceled and expired are final (422 invoiceNotEditable). Setting fulfilled requires the invoice to be captured first (422 onlyCapturedCanFulfill). Setting captured or fulfilled sends the corresponding notification emails.
Parameters
| Name | Location | Type | Required |
|---|---|---|---|
| invoiceId | path | string | required |
Request body
| Name | Type | Required |
|---|---|---|
| status | draft | pending | captured | fulfilled | canceled | expired |
curl -X PUT https://admin.onepay.tabsystems.tech/api/v1/invoices/{invoiceId}/status \
-H "Authorization: Bearer psk_your_token_here" \
-H "Content-Type: application/json" \
-d '{ ... }'{
"id": "string",
"title": "string",
"description": "string",
"currency": "MNT",
"language": "en",
"status": "draft",
"customerFallbackEmail": "string",
"customerFallbackName": "string",
"items": [
{
"id": "string",
"merchantId": "string",
"name": "string",
"description": "string",
"price": 0,
"currency": "MNT",
"taxRate": 0,
"isTaxIncluded": false,
"hasQuantity": false,
"quantity": 0
}
],
"totalAmount": 0,
"taxAmount": 0,
"createdById": "string",
"createdByFallbackEmail": "string",
"createdBy": {
"id": "string",
"firstname": "string",
"lastname": "string",
"email": "string",
"hashedPassword": "string",
"mustChangePassword": false,
"roleId": "string",
"isActive": false,
"role": {
"id": "string",
"name": "string",
"description": "string",
"merchantId": "string"
},
"merchantId": "string",
"invoices": [
"string"
],
"merchant": {
"id": "string",
"name": "string",
"email": "string",
"phone": "string",
"description": "string",
"address": "string",
"website": "string",
"logoUrl": "string"
}
},
"customerId": "string",
"customer": {
"id": "string",
"name": "string",
"email": "email",
"phone": "string",
"merchantId": "string",
"deletedAt": "date-time",
"createdAt": "date-time",
"updatedAt": "date-time"
},
"paymentProviderInvoices": [
{
"provider": "qpay",
"merchantReference": "string",
"gatewayReference": "string",
"redirectUrl": "string",
"expiresAt": "date-time",
"providerExtra": null,
"paymentStatus": "string",
"paidAmount": 0,
"paidAt": "date-time",
"convertedAmount": 0
}
],
"externalReference": "string",
"metadata": "object",
"merchantId": "string",
"expiresAt": "date-time",
"paymentLink": {
"expiresAt": "date-time",
"url": "string"
},
"createdAt": "date-time",
"updatedAt": "date-time"
}/invoices/{invoiceId}/payment-linkGenerate (or return the cached) payment link without sending emailMoves a draft invoice to pending. Requires at least one enabled payment provider (422 noPaymentProvider). Idempotent — returns the cached link unless forceRefresh or expiresInMinutes is passed. Returns { url, expiresAt }.
Parameters
| Name | Location | Type | Required |
|---|---|---|---|
| invoiceId | path | string | required |
Request body
| Name | Type | Required |
|---|---|---|
| forceRefresh | boolean | |
| expiresInMinutes | integer |
curl -X POST https://admin.onepay.tabsystems.tech/api/v1/invoices/{invoiceId}/payment-link \
-H "Authorization: Bearer psk_your_token_here" \
-H "Content-Type: application/json" \
-d '{ ... }'{
"expiresAt": "date-time",
"url": "string"
}/invoices/{invoiceId}/sendSend (or resend with isForce) the payment link by emailGenerates the payment link if needed and emails it to the invoice recipient. Pass isForce to resend an already-sent invoice; expiresIn (minutes) overrides the link validity.
Parameters
| Name | Location | Type | Required |
|---|---|---|---|
| invoiceId | path | string | required |
Request body
| Name | Type | Required |
|---|---|---|
| isForce | boolean | |
| expiresIn | number |
curl -X POST https://admin.onepay.tabsystems.tech/api/v1/invoices/{invoiceId}/send \
-H "Authorization: Bearer psk_your_token_here" \
-H "Content-Type: application/json" \
-d '{ ... }'{
"success": false,
"message": "string"
}Customers
Customers belong to the merchant that owns the API token. Deleting a customer is a soft delete — invoices keep referencing it.
/customersList customers (paginated, optional search text)search matches customer name and email, case-insensitively.
Parameters
| Name | Location | Type | Required |
|---|---|---|---|
| pageIndex | query | number | |
| search | query | string | |
| limit | query | number |
curl -X GET https://admin.onepay.tabsystems.tech/api/v1/customers \
-H "Authorization: Bearer psk_your_token_here"{
"customers": [
{
"id": "string",
"name": "string",
"email": "email",
"phone": "string",
"merchantId": "string",
"deletedAt": "date-time",
"createdAt": "date-time",
"updatedAt": "date-time"
}
],
"pagination": {
"pageIndex": 0,
"page": 0,
"limit": 0,
"total": 0,
"totalPages": 0,
"hasNext": false,
"hasPrev": false
}
}/customersCreate a customerRequest body
| Name | Type | Required |
|---|---|---|
| name | string | required |
| string | required | |
| phone | string |
curl -X POST https://admin.onepay.tabsystems.tech/api/v1/customers \
-H "Authorization: Bearer psk_your_token_here" \
-H "Content-Type: application/json" \
-d '{ ... }'{
"id": "string",
"name": "string",
"email": "email",
"phone": "string",
"merchantId": "string",
"deletedAt": "date-time",
"createdAt": "date-time",
"updatedAt": "date-time"
}/customers/{customerId}Get one customerParameters
| Name | Location | Type | Required |
|---|---|---|---|
| customerId | path | string | required |
curl -X GET https://admin.onepay.tabsystems.tech/api/v1/customers/{customerId} \
-H "Authorization: Bearer psk_your_token_here"{
"id": "string",
"name": "string",
"email": "email",
"phone": "string",
"merchantId": "string",
"deletedAt": "date-time",
"createdAt": "date-time",
"updatedAt": "date-time"
}/customers/{customerId}Update a customerParameters
| Name | Location | Type | Required |
|---|---|---|---|
| customerId | path | string | required |
Request body
| Name | Type | Required |
|---|---|---|
| name | string | |
| string | ||
| phone | string |
curl -X PUT https://admin.onepay.tabsystems.tech/api/v1/customers/{customerId} \
-H "Authorization: Bearer psk_your_token_here" \
-H "Content-Type: application/json" \
-d '{ ... }'{
"id": "string",
"name": "string",
"email": "email",
"phone": "string",
"merchantId": "string",
"deletedAt": "date-time",
"createdAt": "date-time",
"updatedAt": "date-time"
}/customers/{customerId}Soft-delete a customerThe customer is deactivated, not removed — existing invoices keep referencing it and history stays intact.
Parameters
| Name | Location | Type | Required |
|---|---|---|---|
| customerId | path | string | required |
curl -X DELETE https://admin.onepay.tabsystems.tech/api/v1/customers/{customerId} \
-H "Authorization: Bearer psk_your_token_here"{
"id": "string",
"name": "string",
"email": "email",
"phone": "string",
"merchantId": "string",
"deletedAt": "date-time",
"createdAt": "date-time",
"updatedAt": "date-time"
}Items
Catalog items are priced from the database when invoicing. One-off custom items are supplied inline on the invoice instead and are not stored here.
/itemsList catalog items (paginated, optional active filter)Parameters
| Name | Location | Type | Required |
|---|---|---|---|
| pageIndex | query | number | |
| search | query | string | |
| limit | query | number | |
| where | query | object |
curl -X GET https://admin.onepay.tabsystems.tech/api/v1/items \
-H "Authorization: Bearer psk_your_token_here"{
"items": [
{
"id": "string",
"merchantId": "string",
"name": "string",
"description": "string",
"price": 0,
"currency": "MNT",
"taxRate": 0,
"isTaxIncluded": false,
"hasQuantity": false,
"quantity": 0,
"isActive": false,
"createdAt": "date-time",
"updatedAt": "date-time"
}
],
"total": 0
}/itemsCreate a catalog itemCatalog items carry their own price, taxRate and isTaxIncluded — invoices referencing the item always read the current values from the database, never from the request.
Request body
| Name | Type | Required |
|---|---|---|
| name | string | required |
| description | string | required |
| price | number | required |
| currency | MNT | USD | JPY | |
| taxRate | number | required |
| isTaxIncluded | boolean | required |
| hasQuantity | boolean | |
| quantity | string | |
| isActive | boolean |
curl -X POST https://admin.onepay.tabsystems.tech/api/v1/items \
-H "Authorization: Bearer psk_your_token_here" \
-H "Content-Type: application/json" \
-d '{ ... }'{
"id": "string",
"merchantId": "string",
"name": "string",
"description": "string",
"price": 0,
"currency": "MNT",
"taxRate": 0,
"isTaxIncluded": false,
"hasQuantity": false,
"quantity": 0,
"isActive": false,
"createdAt": "date-time",
"updatedAt": "date-time"
}/items/{itemId}Update a catalog itemParameters
| Name | Location | Type | Required |
|---|---|---|---|
| itemId | path | string | required |
Request body
| Name | Type | Required |
|---|---|---|
| name | string | |
| description | string | |
| price | number | |
| currency | MNT | USD | JPY | |
| taxRate | number | |
| isTaxIncluded | boolean | |
| hasQuantity | boolean | |
| quantity | string | |
| isActive | boolean |
curl -X PUT https://admin.onepay.tabsystems.tech/api/v1/items/{itemId} \
-H "Authorization: Bearer psk_your_token_here" \
-H "Content-Type: application/json" \
-d '{ ... }'{
"id": "string",
"merchantId": "string",
"name": "string",
"description": "string",
"price": 0,
"currency": "MNT",
"taxRate": 0,
"isTaxIncluded": false,
"hasQuantity": false,
"quantity": 0,
"isActive": false,
"createdAt": "date-time",
"updatedAt": "date-time"
}/items/{itemId}Delete a catalog itemParameters
| Name | Location | Type | Required |
|---|---|---|---|
| itemId | path | string | required |
curl -X DELETE https://admin.onepay.tabsystems.tech/api/v1/items/{itemId} \
-H "Authorization: Bearer psk_your_token_here"{
"id": "string",
"merchantId": "string",
"name": "string",
"description": "string",
"price": 0,
"currency": "MNT",
"taxRate": 0,
"isTaxIncluded": false,
"hasQuantity": false,
"quantity": 0,
"isActive": false,
"createdAt": "date-time",
"updatedAt": "date-time"
}Users
Users of the merchant dashboard. A token inherits its creator’s role: manager tokens can only act on their own account, admin tokens on any user of the merchant.
/rolesList the merchant's roles (for the roleId field of user endpoints)Returns { id, name, description } per role. Use the id as roleId when creating or updating users.
curl -X GET https://admin.onepay.tabsystems.tech/api/v1/roles \
-H "Authorization: Bearer psk_your_token_here"[
{
"id": "string",
"name": "string",
"description": "string",
"merchantId": "string"
}
]/usersList users (paginated)Parameters
| Name | Location | Type | Required |
|---|---|---|---|
| pageIndex | query | number | |
| search | query | string | |
| limit | query | number |
curl -X GET https://admin.onepay.tabsystems.tech/api/v1/users \
-H "Authorization: Bearer psk_your_token_here"{
"users": [
{
"id": "string",
"firstname": "string",
"lastname": "string",
"email": "string",
"mustChangePassword": false,
"roleId": "string",
"isActive": false,
"role": {
"id": "string",
"name": "string",
"description": "string",
"merchantId": "string"
},
"merchantId": "string"
}
],
"pagination": {
"pageIndex": 0,
"page": 0,
"limit": 0,
"total": 0,
"totalPages": 0,
"hasNext": false,
"hasPrev": false
}
}/usersCreate a user (sends a welcome email)The user is always created under the merchant that owns the API token — a merchant can never add users to another merchant. roleId must be an id returned by GET /roles (roles are merchant-scoped too). The new user receives a welcome email with initial credentials.
Request body
| Name | Type | Required |
|---|---|---|
| firstname | string | required |
| lastname | string | |
| string | required | |
| roleId | string | required |
curl -X POST https://admin.onepay.tabsystems.tech/api/v1/users \
-H "Authorization: Bearer psk_your_token_here" \
-H "Content-Type: application/json" \
-d '{ ... }'{
"id": "string",
"firstname": "string",
"lastname": "string",
"email": "string",
"mustChangePassword": false,
"roleId": "string",
"isActive": false,
"role": {
"id": "string",
"name": "string",
"description": "string",
"merchantId": "string"
},
"merchantId": "string"
}/users/{userId}Update a userManager-role tokens may update only their own account; admin tokens may update any user of the merchant (403 otherwise). A user's merchant cannot be changed. Fields outside the caller's permitted set are ignored rather than applied.
Parameters
| Name | Location | Type | Required |
|---|---|---|---|
| userId | path | string | required |
Request body
| Name | Type | Required |
|---|---|---|
| firstname | string | |
| lastname | string | |
| string | ||
| roleId | string | |
| isActive | boolean | |
| password | string |
curl -X PUT https://admin.onepay.tabsystems.tech/api/v1/users/{userId} \
-H "Authorization: Bearer psk_your_token_here" \
-H "Content-Type: application/json" \
-d '{ ... }'{
"id": "string",
"firstname": "string",
"lastname": "string",
"email": "string",
"mustChangePassword": false,
"roleId": "string",
"isActive": false,
"role": {
"id": "string",
"name": "string",
"description": "string",
"merchantId": "string"
},
"merchantId": "string"
}/users/{userId}Delete a userManager-role tokens may delete only their own account; admin tokens any user of the merchant. Deleting the last remaining admin is rejected.
Parameters
| Name | Location | Type | Required |
|---|---|---|---|
| userId | path | string | required |
curl -X DELETE https://admin.onepay.tabsystems.tech/api/v1/users/{userId} \
-H "Authorization: Bearer psk_your_token_here"{
"id": "string",
"firstname": "string",
"lastname": "string",
"email": "string",
"mustChangePassword": false,
"roleId": "string",
"isActive": false,
"role": {
"id": "string",
"name": "string",
"description": "string",
"merchantId": "string"
},
"merchantId": "string"
}Webhook
The webhook of the API key making the request — never another key's. Invoices created with that key POST their events (see webhooks) to it, signed with its whsec_ secret. Same setting as Profile → API Tokens in the admin UI.
/webhookGet the webhook of the calling API keyURL, enabled flag and lastDelivery — the state of the most recent delivery (delivered | pending | retrying | failed | none), the same indicator the admin UI shows; null while the webhook is off. The signing secret is never returned.
curl -X GET https://admin.onepay.tabsystems.tech/api/v1/webhook \
-H "Authorization: Bearer psk_your_token_here"{
"url": "string",
"enabled": false,
"lastDelivery": {
"state": "delivered",
"deliveryId": "string",
"eventType": "string",
"occurredAt": "date-time",
"retry": 0,
"maxRetries": 0,
"failureReason": "http",
"lastStatus": 0,
"lastError": "string"
}
}/webhookSet the webhook URL and/or enable or disable itThe URL must be https and resolve to a public address (422 webhookUrlNotHttps / webhookUrlNotPublic). Omitted fields keep their current value; a first-time webhook starts enabled, and omitting url before one is set is 422 webhookNotConfigured. secret (whsec_…) is returned only when this call creates it — the first time the key gets a URL — and is null otherwise. Store it: it cannot be read again.
Request body
| Name | Type | Required |
|---|---|---|
| url | string | |
| enabled | boolean |
curl -X PUT https://admin.onepay.tabsystems.tech/api/v1/webhook \
-H "Authorization: Bearer psk_your_token_here" \
-H "Content-Type: application/json" \
-d '{ ... }'{
"webhook": {
"url": "string",
"enabled": false,
"lastDelivery": {
"state": "delivered",
"deliveryId": "string",
"eventType": "string",
"occurredAt": "date-time",
"retry": 0,
"maxRetries": 0,
"failureReason": "http",
"lastStatus": 0,
"lastError": "string"
}
},
"secret": "string"
}/webhookRemove the webhookClears the URL; deliveries still queued are given up. The signing secret is kept, so setting a URL again reuses it and returns none — only the key owner can replace it, in the admin UI.
curl -X DELETE https://admin.onepay.tabsystems.tech/api/v1/webhook \
-H "Authorization: Bearer psk_your_token_here"{
"url": "string",
"enabled": false,
"lastDelivery": {
"state": "delivered",
"deliveryId": "string",
"eventType": "string",
"occurredAt": "date-time",
"retry": 0,
"maxRetries": 0,
"failureReason": "http",
"lastStatus": 0,
"lastError": "string"
}
}/webhook/secretRequest a secret rotation (the key owner confirms it in the admin)Does not rotate. Records a pending request (it lapses after 30 minutes; a new request replaces a pending one) and emails the key owner a link to the admin UI, where they confirm or reject it while signed in. The new whsec_… secret is shown only there, once — never in this response — so a leaked API key alone cannot swap the signing secret. The current secret keeps working until confirmation. 422 webhookNotConfigured when no URL is set.
curl -X POST https://admin.onepay.tabsystems.tech/api/v1/webhook/secret \
-H "Authorization: Bearer psk_your_token_here"{
"status": "string",
"expiresAt": "date-time",
"emailSent": false
}/webhook/testSend a webhook.test event nowOne signed attempt, never retried, listed among the latest deliveries; the receiver has 10 seconds to answer 2xx. Works while the webhook is disabled. Rate-limited per key (429 webhookTestRateLimited).
curl -X POST https://admin.onepay.tabsystems.tech/api/v1/webhook/test \
-H "Authorization: Bearer psk_your_token_here"{
"deliveryId": "string",
"delivered": false,
"status": 0,
"error": "string",
"durationMs": 0
}/webhook/deliveriesList the latest 5 deliveriesThe latest 5 deliveries, newest first, without payloads — a connection check, not a full log, so there is no paging. Each row: event type, invoice id, state (pending | retrying | delivered | failed), attempts, last status and error, next attempt.
curl -X GET https://admin.onepay.tabsystems.tech/api/v1/webhook/deliveries \
-H "Authorization: Bearer psk_your_token_here"[
{
"id": "string",
"eventType": "string",
"invoiceId": "string",
"state": "delivered",
"attempts": 0,
"lastStatus": 0,
"lastError": "string",
"nextAttemptAt": "date-time",
"deliveredAt": "date-time",
"createdAt": "date-time"
}
]Merchant
Your own merchant profile. Every other payload is already merchant-scoped, so the merchant object is not repeated on individual records — read it here when you need it.
/merchantGet the merchant profile that owns the API tokenName, contact details and logo of your own merchant. User and invoice payloads deliberately omit this object — fetch it here once instead of receiving it on every record.
curl -X GET https://admin.onepay.tabsystems.tech/api/v1/merchant \
-H "Authorization: Bearer psk_your_token_here"{
"id": "string",
"name": "string",
"email": "string",
"phone": "string",
"description": "string",
"address": "string",
"website": "string",
"logoUrl": "string"
}