API reference
Generated from the canonical OpenAPI document (API version 1.0.0). Download paytaka-v1.yaml
Payments
Create a hosted Payment
POST/v1/payments
Creates a PENDING, automatically-verifiable hosted Payment and returns its `checkout_url`. Only a UX-level check runs at creation (an enabled, Bridge-ready receiving method and enough Service Credit for the next fee) — the real fee reservation happens when the customer reaches checkout.
- Authentication
- Secret key (Authorization: Bearer)
- Required scope
payments:write- Idempotency-Key
- recommended — see Idempotency
Parameters
| Field | Type | Description |
|---|---|---|
| Idempotency-Key (header) | string | A merchant-generated key. The same key + an identical request body returns the original result without creating a duplicate Payment. The same key with a different body is a 409 idempotency_conflict. Retained 24 hours. |
Request body CreatePaymentRequest
| Field | Type | Description |
|---|---|---|
| amount* | string | Decimal string in BDT major units, e.g. "500.00". Never a JSON number. |
| description | string | |
| merchant_reference | string | Human/business reference — distinct from external_id. |
| external_id | string | Your own correlation identifier. Unique per business (per livemode) when set. |
| return_url | string | Where hosted checkout offers to return the customer after a terminal state. An absolute https URL or a native-app deep link scheme (myapp://..., com.example.app://...). javascript:/data:/file:/intent: are always rejected. Never authoritative proof of payment — always confirm status via this API or a webhook. |
| metadata | Metadata | Bounded, string-only, developer-supplied context. Never shown to the customer, never used for financial matching. At most 20 keys; each key at most 64 characters; each value at most 500 characters. |
| allowed_methods | PaymentMethod[] | |
| allowed_channels | CollectionChannel[] | |
| customer_id | string | |
| order_id | string |
Responses
| Field | Type | Description |
|---|---|---|
| id* | string | |
| object* | string | payment |
| livemode* | boolean | |
| status* | PaymentStatus | Only statuses a Developer API consumer can actually observe. REVERSED reflects PayTaka's own financial record only — it does not imply a provider-side fund transfer back to the customer. Additive-evolution policy: new statuses may be added in a later release of API v1, so clients must tolerate an unknown value when reading a response (request filters stay strict). |
| amount* | string | |
| currency* | string | BDT |
| description | string | null | |
| merchant_reference | string | null | |
| external_id | string | null | |
| metadata | Metadata | Bounded, string-only, developer-supplied context. Never shown to the customer, never used for financial matching. At most 20 keys; each key at most 64 characters; each value at most 500 characters. |
| allowed_methods | PaymentMethod[] | |
| allowed_channels | CollectionChannel[] | |
| return_url | string | null | |
| checkout_url | string | null | |
| created_at* | string (date-time) | |
| paid_at | string | null (date-time) | |
| cancelled_at | string | null (date-time) |
201Payment created — Payment400Invalid request — Error — see error codes401Missing, invalid, or revoked API key — Error — see error codes403The key does not have the required scope — Error — see error codes409State/idempotency/external_id conflict — Error — see error codes429Too many requests — Error — see error codes
curl $PAYTAKA_API_URL/v1/payments \
-X POST \
-H "Authorization: Bearer $PAYTAKA_SECRET_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-123-payment" \
-d '{
"amount": "500.00",
"external_id": "order-123",
"return_url": "https://example.com/payment-return"
}'List Payments
GET/v1/payments
Cursor-paginated. `payments:read` scope required.
- Authentication
- Secret key (Authorization: Bearer)
- Required scope
payments:read- Pagination
- cursor (
limit,starting_after) — see Pagination
Parameters
| Field | Type | Description |
|---|---|---|
| status (query) | PaymentStatus | |
| external_id (query) | string | |
| created_from (query) | string (date-time) | |
| created_to (query) | string (date-time) | |
| limit (query) | integer | |
| starting_after (query) | string | A Payment id — returns results immediately after it. |
Responses
| Field | Type | Description |
|---|---|---|
| object* | string | list |
| data* | Payment[] | |
| has_more* | boolean | |
| next_cursor | string | null |
200A page of Payments — PaymentList401Missing, invalid, or revoked API key — Error — see error codes403The key does not have the required scope — Error — see error codes429Too many requests — Error — see error codes
Retrieve a Payment
GET/v1/payments/{id}
- Authentication
- Secret key (Authorization: Bearer)
- Required scope
payments:read
Parameters
| Field | Type | Description |
|---|---|---|
| id (path)* | string |
Responses
| Field | Type | Description |
|---|---|---|
| id* | string | |
| object* | string | payment |
| livemode* | boolean | |
| status* | PaymentStatus | Only statuses a Developer API consumer can actually observe. REVERSED reflects PayTaka's own financial record only — it does not imply a provider-side fund transfer back to the customer. Additive-evolution policy: new statuses may be added in a later release of API v1, so clients must tolerate an unknown value when reading a response (request filters stay strict). |
| amount* | string | |
| currency* | string | BDT |
| description | string | null | |
| merchant_reference | string | null | |
| external_id | string | null | |
| metadata | Metadata | Bounded, string-only, developer-supplied context. Never shown to the customer, never used for financial matching. At most 20 keys; each key at most 64 characters; each value at most 500 characters. |
| allowed_methods | PaymentMethod[] | |
| allowed_channels | CollectionChannel[] | |
| return_url | string | null | |
| checkout_url | string | null | |
| created_at* | string (date-time) | |
| paid_at | string | null (date-time) | |
| cancelled_at | string | null (date-time) |
200The Payment — Payment401Missing, invalid, or revoked API key — Error — see error codes403The key does not have the required scope — Error — see error codes404Not found (including a Payment belonging to a different business) — Error — see error codes429Too many requests — Error — see error codes
Cancel a pending Payment
POST/v1/payments/{id}/cancel
Only valid while the Payment is PENDING. Cancels any active checkout attempt and releases its Service Credit fee reservation atomically. `payments:write` scope required.
- Authentication
- Secret key (Authorization: Bearer)
- Required scope
payments:write
Parameters
| Field | Type | Description |
|---|---|---|
| id (path)* | string |
Responses
| Field | Type | Description |
|---|---|---|
| id* | string | |
| object* | string | payment |
| livemode* | boolean | |
| status* | PaymentStatus | Only statuses a Developer API consumer can actually observe. REVERSED reflects PayTaka's own financial record only — it does not imply a provider-side fund transfer back to the customer. Additive-evolution policy: new statuses may be added in a later release of API v1, so clients must tolerate an unknown value when reading a response (request filters stay strict). |
| amount* | string | |
| currency* | string | BDT |
| description | string | null | |
| merchant_reference | string | null | |
| external_id | string | null | |
| metadata | Metadata | Bounded, string-only, developer-supplied context. Never shown to the customer, never used for financial matching. At most 20 keys; each key at most 64 characters; each value at most 500 characters. |
| allowed_methods | PaymentMethod[] | |
| allowed_channels | CollectionChannel[] | |
| return_url | string | null | |
| checkout_url | string | null | |
| created_at* | string (date-time) | |
| paid_at | string | null (date-time) | |
| cancelled_at | string | null (date-time) |
200The cancelled Payment — Payment401Missing, invalid, or revoked API key — Error — see error codes403The key does not have the required scope — Error — see error codes404Not found (including a Payment belonging to a different business) — Error — see error codes409State/idempotency/external_id conflict — Error — see error codes429Too many requests — Error — see error codes
Test helpers
Simulate a successful payment (TEST SECRET KEYS ONLY)
POST/v1/test_helpers/payments/{id}/succeed
**TEST SECRET KEYS ONLY.** Moves a PENDING `livemode: false` Payment to PAID with no real money, SMS, Bridge, or Service Credit involved, and emits `payment.paid` to Test webhook endpoints. A `pt_live_sk_...` key receives 404, exactly as if this route did not exist. `payments:write` scope required.
TEST SECRET KEYS ONLY — a live key receives 404
- Authentication
- Secret key (Authorization: Bearer)
- Required scope
payments:write
Parameters
| Field | Type | Description |
|---|---|---|
| id (path)* | string |
Responses
| Field | Type | Description |
|---|---|---|
| id* | string | |
| object* | string | payment |
| livemode* | boolean | |
| status* | PaymentStatus | Only statuses a Developer API consumer can actually observe. REVERSED reflects PayTaka's own financial record only — it does not imply a provider-side fund transfer back to the customer. Additive-evolution policy: new statuses may be added in a later release of API v1, so clients must tolerate an unknown value when reading a response (request filters stay strict). |
| amount* | string | |
| currency* | string | BDT |
| description | string | null | |
| merchant_reference | string | null | |
| external_id | string | null | |
| metadata | Metadata | Bounded, string-only, developer-supplied context. Never shown to the customer, never used for financial matching. At most 20 keys; each key at most 64 characters; each value at most 500 characters. |
| allowed_methods | PaymentMethod[] | |
| allowed_channels | CollectionChannel[] | |
| return_url | string | null | |
| checkout_url | string | null | |
| created_at* | string (date-time) | |
| paid_at | string | null (date-time) | |
| cancelled_at | string | null (date-time) |
200The PAID Payment — Payment401Missing, invalid, or revoked API key — Error — see error codes403The key does not have the required scope — Error — see error codes404Not found (including a Payment belonging to a different business) — Error — see error codes409State/idempotency/external_id conflict — Error — see error codes429Too many requests — Error — see error codes
Simulate a cancelled payment (TEST SECRET KEYS ONLY)
POST/v1/test_helpers/payments/{id}/cancel
**TEST SECRET KEYS ONLY.** Moves a PENDING `livemode: false` Payment to CANCELLED and emits `payment.cancelled` to Test webhook endpoints. A `pt_live_sk_...` key receives 404. `payments:write` scope required.
TEST SECRET KEYS ONLY — a live key receives 404
- Authentication
- Secret key (Authorization: Bearer)
- Required scope
payments:write
Parameters
| Field | Type | Description |
|---|---|---|
| id (path)* | string |
Responses
| Field | Type | Description |
|---|---|---|
| id* | string | |
| object* | string | payment |
| livemode* | boolean | |
| status* | PaymentStatus | Only statuses a Developer API consumer can actually observe. REVERSED reflects PayTaka's own financial record only — it does not imply a provider-side fund transfer back to the customer. Additive-evolution policy: new statuses may be added in a later release of API v1, so clients must tolerate an unknown value when reading a response (request filters stay strict). |
| amount* | string | |
| currency* | string | BDT |
| description | string | null | |
| merchant_reference | string | null | |
| external_id | string | null | |
| metadata | Metadata | Bounded, string-only, developer-supplied context. Never shown to the customer, never used for financial matching. At most 20 keys; each key at most 64 characters; each value at most 500 characters. |
| allowed_methods | PaymentMethod[] | |
| allowed_channels | CollectionChannel[] | |
| return_url | string | null | |
| checkout_url | string | null | |
| created_at* | string (date-time) | |
| paid_at | string | null (date-time) | |
| cancelled_at | string | null (date-time) |
200The CANCELLED Payment — Payment401Missing, invalid, or revoked API key — Error — see error codes403The key does not have the required scope — Error — see error codes404Not found (including a Payment belonging to a different business) — Error — see error codes409State/idempotency/external_id conflict — Error — see error codes429Too many requests — Error — see error codes
Schemas
PaymentStatus
Only statuses a Developer API consumer can actually observe. REVERSED reflects PayTaka's own financial record only — it does not imply a provider-side fund transfer back to the customer. Additive-evolution policy: new statuses may be added in a later release of API v1, so clients must tolerate an unknown value when reading a response (request filters stay strict).
One of: PENDINGPAIDCANCELLEDREVERSED
PaymentMethod
Provider codes. New providers may be added, so clients must tolerate an unknown value when reading a response.
One of: BKASHNAGAD
CollectionChannel
How the customer pays. SEND_MONEY = Send Money, PAYMENT = Payment, CASH_IN = Cash In, BANK_TRANSFER = Bank / Card Add Money. Clients must tolerate values added in the future when READING a response.
One of: SEND_MONEYPAYMENTCASH_INBANK_TRANSFER
Metadata
Bounded, string-only, developer-supplied context. Never shown to the customer, never used for financial matching. At most 20 keys; each key at most 64 characters; each value at most 500 characters.
CreatePaymentRequest
| Field | Type | Description |
|---|---|---|
| amount* | string | Decimal string in BDT major units, e.g. "500.00". Never a JSON number. |
| description | string | |
| merchant_reference | string | Human/business reference — distinct from external_id. |
| external_id | string | Your own correlation identifier. Unique per business (per livemode) when set. |
| return_url | string | Where hosted checkout offers to return the customer after a terminal state. An absolute https URL or a native-app deep link scheme (myapp://..., com.example.app://...). javascript:/data:/file:/intent: are always rejected. Never authoritative proof of payment — always confirm status via this API or a webhook. |
| metadata | Metadata | Bounded, string-only, developer-supplied context. Never shown to the customer, never used for financial matching. At most 20 keys; each key at most 64 characters; each value at most 500 characters. |
| allowed_methods | PaymentMethod[] | |
| allowed_channels | CollectionChannel[] | |
| customer_id | string | |
| order_id | string |
Payment
| Field | Type | Description |
|---|---|---|
| id* | string | |
| object* | string | payment |
| livemode* | boolean | |
| status* | PaymentStatus | Only statuses a Developer API consumer can actually observe. REVERSED reflects PayTaka's own financial record only — it does not imply a provider-side fund transfer back to the customer. Additive-evolution policy: new statuses may be added in a later release of API v1, so clients must tolerate an unknown value when reading a response (request filters stay strict). |
| amount* | string | |
| currency* | string | BDT |
| description | string | null | |
| merchant_reference | string | null | |
| external_id | string | null | |
| metadata | Metadata | Bounded, string-only, developer-supplied context. Never shown to the customer, never used for financial matching. At most 20 keys; each key at most 64 characters; each value at most 500 characters. |
| allowed_methods | PaymentMethod[] | |
| allowed_channels | CollectionChannel[] | |
| return_url | string | null | |
| checkout_url | string | null | |
| created_at* | string (date-time) | |
| paid_at | string | null (date-time) | |
| cancelled_at | string | null (date-time) |
PaymentList
| Field | Type | Description |
|---|---|---|
| object* | string | list |
| data* | Payment[] | |
| has_more* | boolean | |
| next_cursor | string | null |
WebhookEventType
Only events for transitions that actually exist. `endpoint.test` is a synthetic, non-financial event sent from the dashboard to Test endpoints.
One of: payment.createdpayment.paidpayment.cancelledpayment.reversedendpoint.test
Event
The stable webhook envelope. `id` is generated once per logical event and reused on every retry — your idempotency key. `data.object` is exactly the Payment returned by `GET /v1/payments/{id}` at the moment of the event; the payload is snapshotted at creation and never regenerated for retries.
| Field | Type | Description |
|---|---|---|
| id* | string | evt_... |
| object* | string | event |
| api_version* | string | v1 |
| type* | WebhookEventType | Only events for transitions that actually exist. `endpoint.test` is a synthetic, non-financial event sent from the dashboard to Test endpoints. |
| livemode* | boolean | |
| created_at* | string (date-time) | |
| data* | object |
WebhookPaymentEvent
A `payment.*` event — `data.object` is a Payment.
| Field | Type | Description |
|---|---|---|
| id* | string | evt_... |
| object* | string | event |
| api_version* | string | v1 |
| type* | string | payment.created · payment.paid · payment.cancelled · payment.reversed |
| livemode* | boolean | |
| created_at* | string (date-time) | |
| data* | object |
Error
Every error response has this shape. `code` is a stable, machine-readable string — clients must treat it as an open string (new codes may be added). Always quote `request_id` to support.
| Field | Type | Description |
|---|---|---|
| error* | object |