takemypay

Creating a payment

One POST creates a payment and returns the checkout page address. The payment method is not part of the request — the customer picks it on the checkout page, which is why adding a new method never requires a release on your side.

POST /api/v1/payments

curl
curl -X POST https://takemypay.net/api/v1/payments \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "external_order_id": "order-123",
    "amount": "1000.00",
    "description": "Order #123",
    "return_url": "https://shop.example.com/ok",
    "fail_url":   "https://shop.example.com/fail"
  }'

Request fields

FieldTypeDescription
external_order_id string, required Your order ID, up to 255 characters. Unique within a project: different projects may reuse the same ID without colliding.
amount string, required Rouble amount as a decimal string, e.g. "1000.00". Greater than zero, at most two decimal places. What the number means depends on the fee mode — see below. A single payment is capped at ₽199,999, applied to the amount the customer is charged and not to crypto (see Maximum amount).
description string Shown to the customer on the checkout page. Up to 2000 characters.
return_url URL Where to send the customer after a successful payment.
fail_url URL Where to send the customer after a failure.

What amount means

In the default mode the merchant pays the fee: amount is what the customer sees and pays, and you receive the remainder.

Switch the mode to "customer pays the fee" and amount becomes your net: the fee is added on top, the customer is charged more, and you receive exactly the number you passed. In that mode reconcile orders against amount_net from the webhook — it equals what you sent here.

Maximum amount

A single payment is capped at ₽199,999. The cap covers SBP and both card rails; crypto is exempt, having no such limit.

It is measured against what the customer is actually charged. In "customer pays the fee" mode you pass your net and the customer is charged more — reconcile against the charged figure, because it is the payment rail that refuses it, not us.

Above the cap the payment is still created: the checkout page disables the fiat methods with a note and crypto remains payable, and the create response looks normal. The one exception is when crypto is unavailable to you — there would be nothing left to pay with, so create answers 422 with amount_above_maximum straight away.

Response

201 Created
{
  "id": "6f1c8f7e-...",
  "checkout_url": "https://takemypay.net/c/8f3a...",
  "status": "pending",
  "expires_at": "2026-05-19T12:30:00Z",
  "warnings": []
}
  • id — the payment ID, the same one that arrives in the webhook.
  • checkout_url — where to send the customer.
  • status — status at creation, always pending.
  • expires_at — the moment after which the payment can no longer be paid.
  • warnings — non-fatal integration problems. One value exists today: webhook_not_configured, meaning the project has no webhook URL, so nobody will be told about a successful payment and no delivery is even attempted. The list is always present and may be empty; ignore codes you do not know — it grows without a version bump.

Idempotency

A repeat POST with the same external_order_id in the same project returns 200 and the existing payment, rather than creating a second one or erroring. The first create answers 201.

So the request is safe to retry after a network timeout — no need to mint a new order ID. Tell 201 and 200 apart if you care whether the payment was created by this particular call.

GET /api/v1/payments/{id}

curl
curl https://takemypay.net/api/v1/payments/PAYMENT_ID \
  -H "Authorization: Bearer YOUR_API_KEY"
200 OK
{
  "id": "6f1c8f7e-...",
  "external_order_id": "order-123",
  "amount": "1000.00",
  "status": "succeeded",
  "expires_at": "2026-05-19T12:30:00Z",
  "paid_at": "2026-05-19T12:01:32Z",
  "is_test": false
}

The primary notification channel is the webhook. This endpoint exists to recover state when a webhook was missed; it is not meant to be polled in place of one.

A project's key only sees that project's payments: asking for someone else's returns 404 rather than 403, so the response never reveals whether the payment exists.

Statuses

pendingprocessingsucceeded / declined / expired.

  • pending — created; the customer has not picked a method yet.
  • processing — payment started, awaiting confirmation from the processor.
  • succeeded — money received; the only status you may fulfil an order on.
  • declined — refused.
  • expired — the window closed and payment is no longer possible.

How long a payment lives

At creation expires_at is set 30 minutes ahead. When the customer picks a method with a different window, expires_at is re-anchored: crypto gets 60 minutes, because the transfer has to clear the network.

Do not hard-code 30 minutes. Read expires_at from the response — it is the only place the deadline is correct for that particular payment.

Projects and keys are managed on the projects page.