Skip to main content

Payofy API

Payments for any small business: restaurants, salons, gyms, shops, schools, and service businesses.

Base URLs

  • https://api.payofy.si/v1 Production
  • https://api.dev.payofy.si/v1 Development
  • http://localhost:3000/v1 Local

Authentication

Send your secret API key in the Authorization header: Authorization: Bearer pfy_test_…. Use pfy_test_ keys while building; pfy_live_ keys move real money. Keep keys on your server.

Try it

Set a server and paste a pfy_test_ key in Authorize (left), then use Send request on any endpoint. Live keys are blocked here.

Tenants

Retrieve a tenant

GET/v1/tenants/{id}

Returns the partner account (tenant) that owns the API key.

Path parameters

FieldTypeDetails
idrequiredstring
Tenant ID

Response

200 The tenant.

FieldTypeDetails
idrequiredstring
namerequiredstring
statusrequiredstring

Errors

  • 400 The request was invalid.
  • 401 Missing or invalid API key.
  • 500 Unexpected server error.

Errors return { statusCode, error, message }.

curl -X GET 'https://api.dev.payofy.si/v1/tenants/{id}' \
-H "Authorization: Bearer $PAYOFY_SECRET_KEY"

Set PAYOFY_SECRET_KEY in your server environment. Samples never include your key.

Try it
Set a server and test key in Authorize (left).
Example response
{
"id": "string",
"name": "Jane Smith",
"status": "string"
}

Merchants

Create a merchant

POST/v1/merchants

Registers a business that will take payments through your app, and starts its application with the payment processor.

Request body

FieldTypeDetails
schoolNamerequiredstring
Min length 2
contactEmailrequiredstring (email)
businessRegistrationNumberoptionalstring

Response

201 The new merchant.

FieldTypeDetails
idrequiredstring (uuid)
tenantIdrequiredstring (uuid)
schoolNamerequiredstring
Min length 2
contactEmailrequiredstring (email)
kurvMidoptionalstring | null
statusrequiredstring
One of: "pending_onboarding", "under_review", "approved", "rejected", "suspended"
feeScheduleIdoptionalstring (uuid)
createdAtrequiredstring (date-time)
updatedAtrequiredstring (date-time)

Errors

  • 400 The request was invalid.
  • 401 Missing or invalid API key.
  • 500 Unexpected server error.

Errors return { statusCode, error, message }.

curl -X POST 'https://api.dev.payofy.si/v1/merchants' \
-H "Authorization: Bearer $PAYOFY_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"schoolName":"Blue Door Café","contactEmail":"owner@bluedoorcafe.example","businessRegistrationNumber":"12-3456789"}'

Set PAYOFY_SECRET_KEY in your server environment. Samples never include your key.

Try it
Idempotency-Key header (optional)
Set a server and test key in Authorize (left).
Example response
{
"id": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"tenantId": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"schoolName": "Blue Door Café",
"contactEmail": "owner@bluedoorcafe.example",
"kurvMid": "string",
"status": "pending_onboarding",
"feeScheduleId": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"createdAt": "2026-01-15T10:00:00.000Z",
"updatedAt": "2026-01-15T10:00:00.000Z"
}

Retrieve a merchant

GET/v1/merchants/{id}

Path parameters

FieldTypeDetails
idrequiredstring
Merchant ID

Response

200 The merchant.

FieldTypeDetails
idrequiredstring (uuid)
tenantIdrequiredstring (uuid)
schoolNamerequiredstring
Min length 2
contactEmailrequiredstring (email)
kurvMidoptionalstring | null
statusrequiredstring
One of: "pending_onboarding", "under_review", "approved", "rejected", "suspended"
feeScheduleIdoptionalstring (uuid)
createdAtrequiredstring (date-time)
updatedAtrequiredstring (date-time)

Errors

  • 400 The request was invalid.
  • 401 Missing or invalid API key.
  • 500 Unexpected server error.

Errors return { statusCode, error, message }.

curl -X GET 'https://api.dev.payofy.si/v1/merchants/{id}' \
-H "Authorization: Bearer $PAYOFY_SECRET_KEY"

Set PAYOFY_SECRET_KEY in your server environment. Samples never include your key.

Try it
Set a server and test key in Authorize (left).
Example response
{
"id": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"tenantId": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"schoolName": "Blue Door Café",
"contactEmail": "owner@bluedoorcafe.example",
"kurvMid": "string",
"status": "pending_onboarding",
"feeScheduleId": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"createdAt": "2026-01-15T10:00:00.000Z",
"updatedAt": "2026-01-15T10:00:00.000Z"
}

Onboarding

Submit a merchant application

POST/v1/onboarding/{merchantId}/submit

Sends the merchant's business details for review.

Path parameters

FieldTypeDetails
merchantIdrequiredstring
Merchant ID

Request body

Any JSON object.

Response

201 The application was received.

FieldTypeDetails
applicationIdrequiredstring (uuid)
merchantIdrequiredstring
statusrequiredstring
receivedFieldsrequiredstring[]

Errors

  • 400 The request was invalid.
  • 401 Missing or invalid API key.
  • 500 Unexpected server error.

Errors return { statusCode, error, message }.

curl -X POST 'https://api.dev.payofy.si/v1/onboarding/{merchantId}/submit' \
-H "Authorization: Bearer $PAYOFY_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{}'

Set PAYOFY_SECRET_KEY in your server environment. Samples never include your key.

Try it
Idempotency-Key header (optional)
Set a server and test key in Authorize (left).
Example response
{
"applicationId": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"merchantId": "string",
"status": "string",
"receivedFields": [
"string"
]
}

Customers

Create a customer

POST/v1/customers

Saves a payer for a merchant.

Request body

FieldTypeDetails
merchantIdrequiredstring (uuid)
namerequiredstring
Min length 1
emailrequiredstring (email)
phoneoptionalstring

Response

201 The new customer.

FieldTypeDetails
idrequiredstring (uuid)
tenantIdrequiredstring (uuid)
merchantIdrequiredstring (uuid)
namerequiredstring
Min length 1
emailrequiredstring (email)
phoneoptionalstring | null
kurvVaultTokenoptionalstring | null
createdAtrequiredstring (date-time)
updatedAtrequiredstring (date-time)

Errors

  • 400 The request was invalid.
  • 401 Missing or invalid API key.
  • 500 Unexpected server error.

Errors return { statusCode, error, message }.

curl -X POST 'https://api.dev.payofy.si/v1/customers' \
-H "Authorization: Bearer $PAYOFY_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"merchantId":"3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b","name":"Jane Smith","email":"owner@bluedoorcafe.example","phone":"+15555550123"}'

Set PAYOFY_SECRET_KEY in your server environment. Samples never include your key.

Try it
Idempotency-Key header (optional)
Set a server and test key in Authorize (left).
Example response
{
"id": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"tenantId": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"merchantId": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"name": "Jane Smith",
"email": "owner@bluedoorcafe.example",
"phone": "+15555550123",
"kurvVaultToken": "tok_test_4242",
"createdAt": "2026-01-15T10:00:00.000Z",
"updatedAt": "2026-01-15T10:00:00.000Z"
}

Retrieve a customer

GET/v1/customers/{id}

Path parameters

FieldTypeDetails
idrequiredstring
Customer ID

Response

200 The customer.

FieldTypeDetails
idrequiredstring (uuid)
tenantIdrequiredstring (uuid)
merchantIdrequiredstring (uuid)
namerequiredstring
Min length 1
emailrequiredstring (email)
phoneoptionalstring | null
kurvVaultTokenoptionalstring | null
createdAtrequiredstring (date-time)
updatedAtrequiredstring (date-time)

Errors

  • 400 The request was invalid.
  • 401 Missing or invalid API key.
  • 500 Unexpected server error.

Errors return { statusCode, error, message }.

curl -X GET 'https://api.dev.payofy.si/v1/customers/{id}' \
-H "Authorization: Bearer $PAYOFY_SECRET_KEY"

Set PAYOFY_SECRET_KEY in your server environment. Samples never include your key.

Try it
Set a server and test key in Authorize (left).
Example response
{
"id": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"tenantId": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"merchantId": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"name": "Jane Smith",
"email": "owner@bluedoorcafe.example",
"phone": "+15555550123",
"kurvVaultToken": "tok_test_4242",
"createdAt": "2026-01-15T10:00:00.000Z",
"updatedAt": "2026-01-15T10:00:00.000Z"
}

Payments

Create a payment

POST/v1/payments/intents

Charges a tokenized payment method. Send a unique `idempotencyKey` so a retried request never charges twice. Amounts are in cents.

Request body

FieldTypeDetails
merchantIdrequiredstring (uuid)
customerIdoptionalstring (uuid)
amountCentsrequiredinteger
Greater than 0
currencyoptionalstring
Exactly 3 characters
Default "USD"
paymentMethodTokenrequiredstring
Min length 1
idempotencyKeyrequiredstring
Min length 1

Response

201 The payment.

FieldTypeDetails
idrequiredstring (uuid)
tenantIdrequiredstring (uuid)
merchantIdrequiredstring (uuid)
customerIdoptionalstring (uuid) | null
amountCentsrequiredinteger
currencyrequiredstring
Exactly 3 characters
statusrequiredstring
One of: "pending", "processing", "succeeded", "failed", "voided", "refunded"
kurvTransactionIdoptionalstring | null
idempotencyKeyrequiredstring
createdAtrequiredstring (date-time)
updatedAtrequiredstring (date-time)

Errors

  • 400 The request was invalid.
  • 401 Missing or invalid API key.
  • 500 Unexpected server error.

Errors return { statusCode, error, message }.

curl -X POST 'https://api.dev.payofy.si/v1/payments/intents' \
-H "Authorization: Bearer $PAYOFY_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"merchantId":"3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b","customerId":"3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b","amountCents":1250,"currency":"USD","paymentMethodToken":"tok_test_4242","idempotencyKey":"order-1042-attempt-1"}'

Set PAYOFY_SECRET_KEY in your server environment. Samples never include your key.

Try it
Idempotency-Key header (optional)
Set a server and test key in Authorize (left).
Example response
{
"id": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"tenantId": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"merchantId": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"customerId": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"amountCents": 1250,
"currency": "USD",
"status": "pending",
"kurvTransactionId": "string",
"idempotencyKey": "order-1042-attempt-1",
"createdAt": "2026-01-15T10:00:00.000Z",
"updatedAt": "2026-01-15T10:00:00.000Z"
}

Retrieve a payment

GET/v1/payments/{id}

Path parameters

FieldTypeDetails
idrequiredstring
Payment ID

Response

200 The payment.

FieldTypeDetails
idrequiredstring (uuid)
tenantIdrequiredstring (uuid)
merchantIdrequiredstring (uuid)
customerIdoptionalstring (uuid) | null
amountCentsrequiredinteger
currencyrequiredstring
Exactly 3 characters
statusrequiredstring
One of: "pending", "processing", "succeeded", "failed", "voided", "refunded"
kurvTransactionIdoptionalstring | null
idempotencyKeyrequiredstring
createdAtrequiredstring (date-time)
updatedAtrequiredstring (date-time)

Errors

  • 400 The request was invalid.
  • 401 Missing or invalid API key.
  • 500 Unexpected server error.

Errors return { statusCode, error, message }.

curl -X GET 'https://api.dev.payofy.si/v1/payments/{id}' \
-H "Authorization: Bearer $PAYOFY_SECRET_KEY"

Set PAYOFY_SECRET_KEY in your server environment. Samples never include your key.

Try it
Set a server and test key in Authorize (left).
Example response
{
"id": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"tenantId": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"merchantId": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"customerId": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"amountCents": 1250,
"currency": "USD",
"status": "pending",
"kurvTransactionId": "string",
"idempotencyKey": "order-1042-attempt-1",
"createdAt": "2026-01-15T10:00:00.000Z",
"updatedAt": "2026-01-15T10:00:00.000Z"
}

Refunds

Refund a payment

POST/v1/refunds/{paymentId}

Returns money from a payment to the customer, fully or partly. Amounts are in cents.

Path parameters

FieldTypeDetails
paymentIdrequiredstring
Payment ID

Request body

FieldTypeDetails
amountCentsrequiredinteger
Greater than 0

Response

201 The refund.

FieldTypeDetails
refundIdrequiredstring (uuid)
statusrequiredstring
One of: "succeeded", "failed"
amountCentsrequiredinteger

Errors

  • 400 The request was invalid.
  • 401 Missing or invalid API key.
  • 500 Unexpected server error.

Errors return { statusCode, error, message }.

curl -X POST 'https://api.dev.payofy.si/v1/refunds/{paymentId}' \
-H "Authorization: Bearer $PAYOFY_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"amountCents":1250}'

Set PAYOFY_SECRET_KEY in your server environment. Samples never include your key.

Try it
Idempotency-Key header (optional)
Set a server and test key in Authorize (left).
Example response
{
"refundId": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"status": "succeeded",
"amountCents": 1250
}

Payouts

List a merchant's payouts

GET/v1/payouts/merchant/{merchantId}

Money sent to the merchant's bank account.

Path parameters

FieldTypeDetails
merchantIdrequiredstring
Merchant ID

Response

200 The merchant's payouts.

See the example.

Errors

  • 400 The request was invalid.
  • 401 Missing or invalid API key.
  • 500 Unexpected server error.

Errors return { statusCode, error, message }.

curl -X GET 'https://api.dev.payofy.si/v1/payouts/merchant/{merchantId}' \
-H "Authorization: Bearer $PAYOFY_SECRET_KEY"

Set PAYOFY_SECRET_KEY in your server environment. Samples never include your key.

Try it
Set a server and test key in Authorize (left).
Example response
[
{
"id": "3f2b8c1e-4a5d-4e6f-9a7b-1c2d3e4f5a6b",
"merchantId": "string",
"amountCents": 1250,
"currency": "USD",
"status": "string",
"settledAt": "2026-01-15T10:00:00.000Z"
}
]

Reports

Get a merchant summary

GET/v1/reports/merchants/{id}/summary

Payment totals for a merchant.

Path parameters

FieldTypeDetails
idrequiredstring
Merchant ID

Response

200 The summary.

FieldTypeDetails
merchantIdrequiredstring
grossVolumeCentsrequiredinteger
successfulChargesrequiredinteger
refundCountrequiredinteger
currencyrequiredstring
Exactly 3 characters

Errors

  • 400 The request was invalid.
  • 401 Missing or invalid API key.
  • 500 Unexpected server error.

Errors return { statusCode, error, message }.

curl -X GET 'https://api.dev.payofy.si/v1/reports/merchants/{id}/summary' \
-H "Authorization: Bearer $PAYOFY_SECRET_KEY"

Set PAYOFY_SECRET_KEY in your server environment. Samples never include your key.

Try it
Set a server and test key in Authorize (left).
Example response
{
"merchantId": "string",
"grossVolumeCents": 1250,
"successfulCharges": 1,
"refundCount": 1,
"currency": "USD"
}