Skip to content

Payments ​

A payment (pay_...) is the central resource of the Paytami API. It's created once and its status advances as the customer completes the payment flow — see the status catalog.

The Payment object ​

json
{
  "id": "pay_8f2c1a9d4e6b7c0a1d2e3f40",
  "status": "created",
  "currency": "GTQ",
  "amount": "15000",
  "paytami_fee": "435",
  "net_amount": "14565",
  "description": "Tuition — August 2026",
  "checkout_url": "https://app.paytami.com/api/v1/checkout/pay_8f2c1a9d4e6b7c0a1d2e3f40",
  "created_at": "2026-08-28T15:04:00.000Z"
}
FieldTypeDescription
idstringPublic identifier, pay_ prefix. Stable over time.
statusstringSee the status catalog.
currencystringGTQ or USD.
amountstringGross charge amount, integer in the minor unit (cents), never a number.
paytami_feestringPaytami's fee on this charge, same unit as amount.
net_amountstringWhat your merchant receives: amount - paytami_fee.
descriptionstring | undefinedOnly present if sent when creating the payment.
checkout_urlstringPayment page, always on Paytami's domain.
created_atstringISO 8601, UTC.

TIP

checkout_url always lives on Paytami's own domain — it's part of the platform's stable contract.

POST /v1/payments ​

Creates a charge.

Authentication: required (Authorization: Bearer sk_...). Headers: Idempotency-Key required — see Idempotency.

Request body ​

FieldTypeRequiredDescription
amountstringYesInteger in the minor unit, as a string (e.g. "15000" = Q150.00).
currencystringYesGTQ or USD.
method_typestringYescard or bank_transfer.
success_urlstringYesWhere the customer returns to if the payment completes.
cancel_urlstringYesWhere the customer returns to if they cancel or it fails.
descriptionstringNoUp to 500 characters. Shown to the customer at checkout.
customer.emailstringNoEnd customer's email.
customer.namestringNoEnd customer's name.

Example ​

bash
curl https://app.paytami.com/api/v1/payments \
  -X POST \
  -H "Authorization: Bearer sk_test_..." \
  -H "Idempotency-Key: 6e4b6f0a-a5f0-4b9a-9b8b-1a2b3c4d5e6f" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "15000",
    "currency": "GTQ",
    "method_type": "card",
    "success_url": "https://your-site.com/thanks",
    "cancel_url": "https://your-site.com/cart"
  }'
js
const res = await fetch('https://app.paytami.com/api/v1/payments', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.PAYTAMI_SECRET_KEY}`,
    'Idempotency-Key': crypto.randomUUID(),
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    amount: '15000',
    currency: 'GTQ',
    method_type: 'card',
    success_url: 'https://your-site.com/thanks',
    cancel_url: 'https://your-site.com/cart'
  })
})
const payment = await res.json()

Response: 201 Created with the Payment object.

Possible errors: 401 unauthorized, 400 idempotency_key_required, 409 idempotency_key_reused, 400 validation_error, 400 currency_not_supported, 400 method_not_supported, 400 amount_below_minimum, 400 amount_above_maximum.

GET /v1/payments/{id} ​

Looks up a charge by its public id.

Authentication: required. Only returns payments belonging to the authenticated merchant — an id from another merchant returns 404, same as a nonexistent one, so it never leaks which identifiers exist.

bash
curl https://app.paytami.com/api/v1/payments/pay_8f2c1a9d4e6b7c0a1d2e3f40 \
  -H "Authorization: Bearer sk_test_..."

Response: 200 OK with the Payment object. Possible errors: 401 unauthorized, 404 unknown_payment.

GET /v1/payments ​

Lists the authenticated merchant's charges, most recent first.

Authentication: required.

Query parameters ​

ParameterTypeDescription
limitnumberBetween 1 and 100. Defaults to 25.
starting_afterstringA payment id; returns the page after it.
statusstringFilters by an exact state.
bash
curl "https://app.paytami.com/api/v1/payments?limit=10&status=captured" \
  -H "Authorization: Bearer sk_test_..."

Response ​

json
{
  "data": [ { "id": "pay_...", "status": "captured", "...": "..." } ],
  "has_more": true
}

For the next page, pass the id of the last item in data as starting_after.

Cursor pagination: the list is ordered by creation date descending; using starting_after instead of a numeric offset prevents a new payment from shifting the page while you paginate.

Official Paytami Documentation