Telr
Setup guide for the telr payments provider. The shared API (initiate_payment,
verify_payment, refund_payment, webhooks, hooks, saved methods) is documented in
Payments.
The telr provider supports one-time payments through Telr’s Hosted Payment
Page (initiate_payment, verify_payment) and webhooks (Telr’s transaction
advice), in the Gulf and other currencies your store accepts (AED, SAR, KWD,
BHD, OMR, JOD, QAR, EGP, USD, …). GET /payments/providers reports no
optional capability.
| Feature | Status |
|---|---|
| One-time payments (Hosted Payment Page), verify | Supported |
refund_payment |
Not supported (NOT_SUPPORTED, 501): refunds need Telr’s Remote API, enabled per store; refund in the Telr admin and the transaction advice records it |
| Subscriptions, disputes, billing portal | Not supported (NOT_SUPPORTED, 501) |
Saved payment methods, charge_off_session |
Not supported (NOT_SUPPORTED, 501) |
It needs no extra install: it calls https://secure.telr.com/gateway/order.json
directly over HTTP, following Telr’s integration docs as of September 2026.
Why plain HTTP (no Telr SDK). Telr publishes no Python SDK.
1. Get credentials. In the Telr Merchant Administration System (MAS), note the store id and create an authentication key for the Hosted Payment Page.
2. Set the transaction advice. In MAS, Payment Page (or Security) ->
Transaction advice, set the URL to
https://your-domain.com/payments/webhook/telr
(/payments/webhook/<instance> for another instance name) and set a
secret key, which signs each advice’s tran_check.
3. Configure the instance and secrets. In kirak.json:
"telr": { "type": "telr", "store_id": "15996", "environment": "test", "success_url": "https://your-domain.com/payment/return"}store_id is the numeric store id. environment is test (the default,
which marks orders test) or live. success_url is required and must be
absolute: Telr returns the buyer to it after paying, declining or
cancelling. Anything else is a CONFIGURATION_ERROR at startup. In the
environment:
KIRAK_PAYMENT_TELR_AUTH_KEY=<the authentication key>KIRAK_PAYMENT_TELR_ADVICE_SECRET=<the transaction advice secret key>For an instance with another name the variables are
KIRAK_PAYMENT_<INSTANCE>_AUTH_KEY and KIRAK_PAYMENT_<INSTANCE>_ADVICE_SECRET.
Both are required.
4. Use it:
result = await kirak.payments.initiate_payment({ "provider": "telr", "user_id": "42", "amount": 1500, "currency": "KWD", # fils: KWD 1.500 "name": "Pro Plan", "type": "one_time",})reference = result["data"]["reference"] # the cart id, kirak-<32 hex># redirect the buyer to result["data"]["url"] at once (the order is short lived)
# On the return page: completes the row if the order was paidawait kirak.payments.verify_payment({"provider": "telr", "payment_id": reference})Payments. initiate_payment stores a random cart id (kirak-<32 hex>)
on the PENDING row before calling order.json (method: "create",
amount x quantity as a major-unit decimal string, description = name,
the return URLs), then keeps Telr’s order ref on the row and returns the
payment page url. An error answer marks the row FAILED (TELR_ERROR,
400); a timeout, 5xx or 429 leaves it PENDING.
The order is always read with order.json method: "check" before the row
changes: a Paid order with the row’s cart id, currency and an amount of at
least amount x quantity, whose transaction is authorised (A or H),
completes the row once; an Expired or Cancelled order fails it. Telr
retries a transaction advice only 3 times, 5 seconds apart, so
verify_payment (payment_id = the cart id) is the main completion path:
call it when the buyer returns. It reports no event: the first authorised
sale advice of that transaction still reports payment_completed once, so
fulfil on the event and use verify_payment’s status only for the return
page. If no advice arrives (all three attempts failed), there is no event.
Transaction advice. Each advice (a form POST) must carry a tran_check
equal to the SHA1 hex of <secret>:<tran_store>:<tran_type>:<tran_class>: <tran_test>:<tran_ref>:<tran_prevref>:<tran_firstref>:<tran_currency>: <tran_amount>:<tran_cartid>:<tran_desc>:<tran_status>:<tran_authcode>: <tran_authmessage> (missing fields empty) and name this instance’s store;
a missing check is MISSING_WEBHOOK_SIGNATURE, a wrong one
INVALID_WEBHOOK_SIGNATURE (400). An authorised sale advice runs the same
check (payment_completed, with amount and currency, when it completes
the row); an order the check does not show paid yet fails the advice (500)
so Telr sends it again, while a paid order that does not match is
acknowledged (order.not_paid). An authorised refund advice of the transaction that completed the
row is recorded (keyed by its tran_ref, with a running total;
refund_completed). Advices are deduplicated on tran_type + tran_ref.
Currencies. Telr amounts are major-unit decimal strings with ISO 4217
decimals; KWD, BHD, OMR and JOD have three (1500 fils = "1.500").
Known limits.
refund_paymentis not supported; refunds made in the Telr admin are recorded from their advice.- The order status codes (
3Paid,-1Expired,-2Cancelled) follow Telr’s Hosted Payment Page documentation and are on the sandbox checklist. - Subscriptions (repeat billing), saved cards and off-session charges are not supported.
Webhook events
Section titled “Webhook events”after_webhook receives these provider-neutral event names (see
Webhook Hooks):
Telr reports payment_completed (an authorised sale transaction advice whose check completes the row, event_type transaction_advice; a declined one reports none, with advice.declined, and a paid order that does not match none, with order.not_paid; one not paid yet fails the advice so Telr retries), payment_failed (an expired or cancelled order, order.ended) and refund_completed (an authorised refund advice, refund.recorded); verify_payment reports no event, but a payment it completed is reported by the first sale advice of its transaction.