Built for the people who actually earn.

Card machines were designed for shops. QR Pay JJJ is designed for the way South Africans work — in taxis, on street corners, in living rooms, on WhatsApp.

Become a merchant

Instant settlement

Money lands in your wallet the moment your customer confirms.

Zero card fees

During beta, keep every rand. No hidden card-machine cuts.

Fraud-safe

Only signed-in wallet holders can send. No chargebacks, no bounced cards.

Works everywhere

Any smartphone, any bank, any suburb. If they have a camera, they can pay.

See your day

Every payment logged. Filter sent vs received. Export coming soon.

Verified profile

Show a service type — driver, tutor, vendor — so customers know who they're paying.

Developers

Accept QR Pay on your online store

Drop a button on your Shopify, WooCommerce, or custom store. We handle checkout, notify you via webhook when the customer pays, and settle straight into your wallet.

1. Get an API key

Sign in, open Merchant → API keys, and copy the key. Treat it like a password.

2. Create a checkout server-side

curl -X POST https://qr-pay-jjj.lovable.app/api/public/v1/checkouts \
  -H "Authorization: Bearer qp_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount_cents": 24900,
    "reference": "order_1234",
    "note": "Cappuccino x2",
    "success_url": "https://your-store.com/thanks",
    "cancel_url": "https://your-store.com/cart"
  }'

# → { "id": "chk_…", "url": "https://.../checkout/chk_…", "status": "pending", "expires_at": "..." }

3. Drop the pay button

<script src="https://qr-pay-jjj.lovable.app/qrpay.js" async></script>

<button data-qrpay data-checkout="chk_..." data-success-redirect="/thanks">
  Pay with QR Pay
</button>

Opens a popup checkout, dispatches qrpay:paid and qrpay:cancelled events, and redirects on success.

4. Verify the webhook

We POST checkout.paid, checkout.expired, and checkout.cancelled to your endpoint with an X-QRPay-Signature: t=<ts>,v1=<hmac> header. HMAC-SHA256 of ts + "." + rawBody using your signing secret.

import crypto from "node:crypto";

app.post("/webhooks/qrpay", express.raw({type: "application/json"}), (req, res) => {
  const [t, v1] = req.header("X-QRPay-Signature").split(",");
  const ts = t.split("=")[1];
  const sig = v1.split("=")[1];
  const expected = crypto
    .createHmac("sha256", process.env.QRPAY_WEBHOOK_SECRET)
    .update(ts + "." + req.body.toString())
    .digest("hex");
  if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
    return res.status(401).end();
  }
  const event = JSON.parse(req.body.toString());
  if (event.event === "checkout.paid") fulfil(event.checkout.reference);
  res.status(200).end();
});

Set up in under 2 minutes

Create your account, generate your QR, start accepting payments today.

Get started