Next.js + Tegro.Money checkout

A prompt for Cursor / Claude Code / Copilot Chat. It builds a complete checkout flow: product page → redirect to Tegro → success/fail pages → webhook handler.

Prompt

Add a Tegro.Money checkout to my Next.js (App Router, TypeScript) app:

1) app/products/[id]/page.tsx — a product page with a "Buy for [price] ₽" button.
   On click — a server action createCheckout(productId) that calls POST /api/checkout.

2) app/api/checkout/route.ts — the server endpoint:
   POST https://tegro.money/api/createOrder/ with the body:
   {
     shop_id: process.env.TEGRO_SHOP_ID,
     nonce: crypto.randomUUID(),
     currency: "RUB",
     amount: 500,                         // look this up in the DB by productId
     order_id: crypto.randomUUID(),        // store it in the DB to reconcile in the webhook
     description: "Product name",
     success_url: process.env.SITE_URL + "/checkout/success",
     fail_url: process.env.SITE_URL + "/checkout/fail",
     notify_url: process.env.SITE_URL + "/api/tegro-notify"
   }
   THE KEY PART: the signature.
   - bodyString = JSON.stringify(body)
   - sign = crypto.createHmac("sha256", process.env.TEGRO_API_KEY).update(bodyString).digest("hex")
   - fetch with header Authorization: "Bearer " + sign, body: bodyString (do NOT JSON.stringify(body) again!)
   Response: {type:"success", data:{url}} — return NextResponse.redirect(data.url).
   On type:"error" — return NextResponse.json({error: data.desc}, {status: 400}).

3) app/checkout/success/page.tsx + app/checkout/fail/page.tsx — simple static pages.

4) app/api/tegro-notify/route.ts — the webhook from Tegro:
   - Tegro sends a form-urlencoded POST.
   - Read the body via await request.formData()
   - Verify the signature per the docs at /docs/en/payments/notify/.
   - Find your order by order_id and update its status in the DB.
   - Return plain-text "OK" with status 200.

5) .env.example — add TEGRO_SHOP_ID, TEGRO_API_KEY, SITE_URL.

6) README with the steps:
   - Sign up at tegro.money/begin/register/
   - Create a shop, copy shop_id and api_key
   - Enable the shop's test mode during development
   - Set SITE_URL to your public URL (for local dev — ngrok)
   - When going live — turn off test mode

Use whatever database model the project already has (Prisma / Drizzle / etc — check the code).
If there's no DB — add a simple in-memory Map for the demo.

Don't use the legacy pages router. App Router only.

Before you run it

  • Get your keys in your merchant cabinet.
  • To test the webhook locally you need a public URL — use ngrok.
  • In the shop settings, set notify_url = https://<ngrok>/api/tegro-notify.
  • Enable the shop's test mode — payments go through with no charge.

Related