Quickstart
Lidya is a payment gateway for high-risk merchants. Accept Turkish lira card payments and receive the settlement in USDT next business day.
This page walks you from a fresh API key to your first successful charge in under five minutes.
What you need
- A merchant account approved by underwriting (apply at lidya.money/apply)
- A live or test API key — they look like
sk_live_xxxxorsk_test_xxxx - Your server can make outbound HTTPS requests to
api.lidya.money
Test keys are sandboxed against Balupay's test environment. They never move real money — use them while wiring up your integration.
1 · Create a charge
A charge is a request to collect money from a customer. The response contains a paymentPageUrl — redirect your customer there and Lidya handles the rest.
curl -X POST https://api.lidya.money/v1/charges \
-H "X-API-Key: sk_test_xxxx" \
-H "X-Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"amount": 12550,
"currency": "TRY",
"paymentMethod": "bank_transfer",
"merchantReference": "order-2026-000045",
"customer": {
"name": "Customer Name",
"email": "customer@example.com"
}
}'amount is in minor units — 12550 means ₺125.50.
2 · Redirect the customer
The response contains a paymentPageUrl. Redirect the customer there:
const charge = await fetch("https://api.lidya.money/v1/charges", {
method: "POST",
headers: {
"X-API-Key": process.env.LIDYA_API_KEY!,
"X-Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
amount: 12550,
currency: "TRY",
paymentMethod: "bank_transfer",
merchantReference: order.reference,
}),
}).then((r) => r.json());
return Response.redirect(charge.paymentPageUrl, 303);3 · Receive the webhook
When the customer completes payment, Lidya sends a signed webhook to your configured URL. Verify the Lidya-Signature HMAC, then mark the order paid:
import { createHmac, timingSafeEqual } from "node:crypto";
export async function POST(req: Request) {
const raw = await req.text();
const signature = req.headers.get("Lidya-Signature")!;
const timestamp = req.headers.get("Lidya-Timestamp")!;
const expected = createHmac("sha256", process.env.LIDYA_WEBHOOK_SECRET!)
.update(`${timestamp}.`)
.update(raw)
.digest("hex");
if (!timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
return new Response("invalid signature", { status: 401 });
}
const event = JSON.parse(raw);
if (event.eventType === "charge.succeeded") {
await markOrderPaid(event.payment.merchantReference);
}
return new Response("ok", { status: 200 });
}See Webhooks for the full event taxonomy and retry behaviour.
4 · Receive your USDT
Once a charge succeeds, the net amount (gross minus the per-merchant card fee) lands in your pending balance. Each business day at 03:00 UTC we batch the day's pending into a USDT crypto payout to your default wallet.
curl https://api.lidya.money/v1/balance -H "X-API-Key: sk_test_xxxx"That's the full integration. From here you'll want:
- Quickstart — Node.js — the working Express server, end to end
- Authentication — key rotation, scopes, IP allowlists
- Idempotency — safely retrying writes
- Errors — every error code Lidya can return, and what to do about it
- Postman collection — import every endpoint with
{{baseUrl}}/{{apiKey}}variables pre-wired