Quickstart

Accept your first payment in 10 minutes. We will install the Node SDK, create a session on your server, open the hosted checkout, and verify a webhook.

Already have an account? Grab a TEST key from Dashboard → Developers → API Keys.

1. Install the server SDK

bash
npm install @minnha/node

2. Create a session

Add a route on your backend (Next.js, Express, NestJS — anything):

ts
// app/api/checkout/route.ts
import { Minnha } from "@minnha/node";

const minnha = new Minnha(process.env.MINNHA_API_KEY!); // mp_test_...

export async function POST() {
  const session = await minnha.sessions.create({
    amount: 199.50,
    currency: "SAR",
    description: "Order #123",
    customerEmail: "customer@example.com",
    customerPhone: "+966512345678",
    successUrl: "https://yourapp.com/orders/123/success",
    cancelUrl:  "https://yourapp.com/orders/123/cancel",
    metadata: { orderId: "ord_123" },
  });

  return Response.json({ sessionToken: session.sessionToken });
}

3. Open the checkout on the client

tsx
// React example — npm install @minnha/pay-react
import { MinnhaCheckoutButton } from "@minnha/pay-react";

<MinnhaCheckoutButton
  createSession={async () => (await fetch("/api/checkout", { method: "POST" })).json()}
  checkoutOptions={{ mode: "popup", locale: "ar" }}
  onSuccess={({ transactionId }) => router.push(`/orders/${transactionId}`)}
>
  Pay 199.50 SAR
</MinnhaCheckoutButton>
Don't use React? Use the framework-agnostic @minnha/pay-js, or for mobile see the iOS / Android / RN guides.

4. Test with a card

On the hosted checkout, use any of:

Card numberResult
4111 1111 1111 1111SUCCESS
4000 0000 0000 0002FAILED
4000 0027 6000 31843-D Secure required

Use any future expiry, any 3-digit CVV, and any name.

5. Receive the webhook

Register a webhook endpoint from Dashboard → Developers → Webhooks. Then verify the signature on your server:

ts
import { Minnha, MinnhaSignatureError } from "@minnha/node";

app.post("/webhooks/minnha", express.raw({ type: "application/json" }), (req, res) => {
  try {
    const event = Minnha.Webhooks.parse(
      req.body,
      req.header("x-minnha-signature")!,
      process.env.MINNHA_WEBHOOK_SECRET!
    );
    if (event.event === "payment.success") {
      // mark order paid
    }
    res.status(200).end();
  } catch (err) {
    if (err instanceof MinnhaSignatureError) return res.status(400).send("bad signature");
    throw err;
  }
});