LidyaDocs

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_xxxx or sk_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 units12550 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: