// Array with meta tag data $metaData = array( "" => array( "title" => "Online Payment System | Connecting Payment Systems and Banks Without Fees.", "description" => "Tegro.money offers advantageous tariff plans for online acquiring with a variety of payment acceptance methods. Register and start accepting payments today!", "keywords" => "tegro, online cash register, internet acquiring, payment acceptance, fund withdrawal, acquiring, card payment, online payment, online payment through internet, tegro.money" ), "referral-program" => array( "title" => "Referral Program | Online Payment System - Tegro.Money", "description" => "Invite acquaintances and friends – earn a percentage of their turnover. A unique opportunity for additional income from invited users.", "keywords" => "tegro, online cash register, internet acquiring, partnership, referral" ), "security" => array( "title" => "Security | Online Payment System - Tegro.Money", "description" => "We use PCI DSS security standard, SSL protocol, Verified by Visa and MasterCard SecureCode security systems.", "keywords" => "" ), "pricing" => array( "title" => "Tariffs | Online Payment System - Tegro.Money", "description" => "Payments for your customers will become simpler and more accessible, and more profitable for you.", "keywords" => "" ), "coupons" => array( "title" => "Discounts and Coupons | Online Payment System - Tegro.Money", "description" => "Payments for your customers will become simpler and more accessible, and more profitable for you.", "keywords" => "" ), "advantages" => array( "title" => "Our Advantages | Online Payment System - Tegro.Money", "description" => "Utilize all the features of Tegro.money service.", "keywords" => "" ), "policy" => array( "title" => "Personal Data Processing Policy | Tegro.Money", "description" => "Tegro.Money prioritizes compliance with and protection of its clients' interests.", "keywords" => "" ), "offer" => array( "title" => "Public Offer for Agreement on Use of Tegro.Money Service", "description" => "Agreement on Use of Tegro.Money Service", "keywords" => "" ), "contacts" => array( "title" => "Contacts | About Tegro.Money Company", "description" => "We are a modern IT company that provides services for electronic payments on the internet and beyond.", "keywords" => "" ), "docs/en/" => array( "title" => "Documentation and API | Tegro.Money", "description" => "Tegro.money API allows you to accept payments, process refunds, check transaction statuses, and much more. To use the API, you'll need to have a store in our system.", "keywords" => "" ) ); // Get the current page's name $current_page = basename($_SERVER['REQUEST_URI'], ""); // Check if there's data for the current page in the $metaData array if (array_key_exists($current_page, $metaData)) { $title = $metaData[$current_page]["title"]; $description = $metaData[$current_page]["description"]; $keywords = $metaData[$current_page]["keywords"]; } else { // If data is absent, set default values $title = "Online Payment System"; $description = "Tegro.money offers advantageous tariff plans for online acquiring with a variety of payment acceptance methods."; $keywords = "tegro, online cash register, internet acquiring, payment acceptance, fund withdrawal, acquiring, card payment, online payment, online payment through internet, tegro.money"; } ?>

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