← All Posts
Integrations

Using Paychainly with Next.js: Server Actions and API Routes Integration

May 21, 2026· 2 min read

Project Setup

// .env.local
PAYCHAINLY_API_KEY=pk_live_...
PAYCHAINLY_WEBHOOK_SECRET=whsec_...
PAYCHAINLY_API_URL=https://api.paychainly.com

Server Action: Create Payment Link

// app/actions/payment.ts
'use server';

export async function createPaymentLink(formData: FormData) {
  const amount = parseFloat(formData.get('amount') as string);

  const res = await fetch(`${process.env.PAYCHAINLY_API_URL}/api/v1/payment-links`, {
    method: 'POST',
    headers: {
      'x-api-key': process.env.PAYCHAINLY_API_KEY!,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ amount, description: 'Payment from Next.js' }),
  });

  const { data } = await res.json();
  redirect(data.payUrl);
}

API Route: Webhook Handler

// app/api/webhooks/paychainly/route.ts
import crypto from 'crypto';
import { NextRequest, NextResponse } from 'next/server';

export async function POST(req: NextRequest) {
  const rawBody = await req.text();
  const sig = req.headers.get('x-paychainly-signature') ?? '';

  const expected = 'sha256=' + crypto
    .createHmac('sha256', process.env.PAYCHAINLY_WEBHOOK_SECRET!)
    .update(rawBody)
    .digest('hex');

  if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig))) {
    return NextResponse.json({ error: 'Invalid signature' }, { status: 401 });
  }

  const event = JSON.parse(rawBody);
  // Process: credit user, update order, send email...

  return NextResponse.json({ received: true });
}

Checkout Form Component

// app/checkout/page.tsx
import { createPaymentLink } from '@/app/actions/payment';

export default function CheckoutPage() {
  return (
    <form action={createPaymentLink}>
      <input name="amount" type="number" step="0.01" placeholder="Amount in USDT" />
      <button type="submit">Pay with USDT</button>
    </form>
  );
}

Edge Runtime Compatibility

The webhook route can run on the Edge Runtime since it only uses the Web Crypto API (no Node.js buffers). Change runtime to 'edge' for lower latency globally.

← Back to Blog
Next.jsserver actionsAPI routesReactcrypto payments