Create Payment
To start a payment, call POST /v1/payments. This call creates a payment request (amount, terminal, returnUrl); the request is cardless, so the card is not part of it. The response returns a handoffUrl you redirect the buyer’s browser to, and a paymentRef bound to it. The card is carried, in the next step, from the buyer’s browser to the handoff page; see Card Handoff.
POST /v1/paymentsAuthorization: Bearer ptk_live_…Content-Type: application/jsonRequest body
Section titled “Request body”{ "amount": 125050, "partnerTxCode": "ORD-2026-8841", "terminalId": "trm_3Kd9x", "installment": 1, "description": "Order #8841", "returnUrl": "https://yourstore.example/payment/result"}| Field | Required | Description |
|---|---|---|
amount | Yes | Amount to charge, integer in minor units (kuruş) (1,250.50 TRY → 125050). See Amounts and Currency. |
partnerTxCode | Yes | A unique transaction code generated on your side. Used as an idempotency key (see below). |
terminalId | Yes | The terminal the payment is routed to. Must belong to you and be active; otherwise terminal_not_allowed is returned. Today Paytalya provisions terminals for you and you use the terminalId you were given (self-service terminal creation from your own panel is planned for a future release). |
installment | No | Number of installments; 1 for a single charge (default). |
description | No | Transaction description. |
returnUrl | Yes | The address the buyer is redirected to via 303 after the 3D return. Paytalya validates this address (open-redirect protection). |
Response
Section titled “Response”201 Created: the response contains no card or bank 3D form data; it returns a paymentRef and a handoffUrl:
{ "paymentCode": "pay_7Hq2bL", "status": "initiated", "paymentRef": "pr_3Kd9xQ1w2E", "handoffUrl": "https://pay.paytalya.example/checkout"}| Field | Description |
|---|---|
paymentCode | The payment’s permanent identifier; used in query and refund calls. |
status | The initial status is always initiated. See Payment Lifecycle. |
paymentRef | A single-use payment reference; carried with the card in the handoff POST. It is distinct from paymentCode and is not used in query/refund calls. |
handoffUrl | The handoff page address the buyer’s browser/WebView is redirected to, with the card + paymentRef. |
Redirect the buyer to the handoff
Section titled “Redirect the buyer to the handoff”You redirect the buyer’s browser/WebView to the handoffUrl from the response, carrying the card you collected on your own checkout plus the paymentRef. You do not build the bank’s 3D form; the handoff page produces the auto-submit form. Detail (web form-POST and mobile WebView): Card Handoff.
Window (TTL)
Section titled “Window (TTL)”The payment’s window to complete 3D is 30 minutes. If the buyer does not complete it within this window, the payment moves to expired.
Idempotency: partnerTxCode
Section titled “Idempotency: partnerTxCode”partnerTxCode must be unique on your side. If an active or successful payment already exists with the same code, the request is rejected with duplicate_partner_tx_code. This prevents duplicate charges in cases like network retries or double clicks.
You can query a previously created payment by the same partnerTxCode via GET /v1/payments?partnerTxCode=….
Possible errors
Section titled “Possible errors”| Code | Reason |
|---|---|
duplicate_partner_tx_code | An active/successful payment already exists with the same partnerTxCode. |
terminal_not_allowed | The terminal does not belong to you or is inactive. |
amount_limit_exceeded | The amount is outside the min/max limits. |
installment_not_allowed | The card is not eligible for installments or the terminal has no installment permission. |
Full list: Error Codes.