Node.js SDK
Official Node.js SDK for Scan & Pay — accept PayTo PayID payments via QR code from any Node.js environment (Express, NestJS, Next.js, etc.). Includes React components for the frontend.
Install
npm install @scanandpay/nodeRequires Node.js 18.0.0 or higher.
Quickstart (Backend)
import { ScanAndPay } from '@scanandpay/node';
const client = new ScanAndPay(
process.env.SCANANDPAY_MERCHANT_ID!,
process.env.SCANANDPAY_API_SECRET!,
process.env.SCANANDPAY_WEBHOOK_SECRET, // optional
);
// 1. Create a session at checkout. Amount is float dollars.
const session = await client.createSession({
amount: 19.90, // $19.90
platformOrderId: 'order_456',
payId: 'merchant@example.com.au',
merchantName: 'Acme Coffee',
});
// 2. Verify and consume webhooks (Express example).
import { WebhookSignatureError } from '@scanandpay/node';
app.post('/webhooks/scanandpay', async (req, res) => {
try {
const signature = req.headers['x-scanpay-signature'] as string;
const event = client.webhooks.verify(signature, req.body);
if (event.status === 'confirmed') {
// Mark order paid using event.order_id, event.tx_id, ...
}
res.json({ received: true });
} catch (err) {
if (err instanceof WebhookSignatureError) {
return res.status(401).send('Webhook verification failed');
}
throw err;
}
});Quickstart (React)
The Node.js SDK includes a React component for rendering the QR checkout widget on your frontend.
import { ScanAndPayCheckout } from '@scanandpay/node/react';
function CheckoutPage({ session }) {
return (
<ScanAndPayCheckout
session={session}
pollUrl="/api/scanandpay/status"
onSuccess={(sessionId) => { window.location.href = '/thank-you'; }}
theme="light"
/>
);
}Amount format
amount is always float dollars (e.g. 19.90 for $19.90). This matches the Scan & Pay API directly — no multiplication or division needed.
await client.createSession({ amount: 19.90, ... }); // ✓ $19.90
await client.createSession({ amount: 0.50, ... }); // ✓ $0.50
await client.createSession({ amount: 1000.00, ... }); // ✓ $1,000.00
await client.createSession({ amount: -1, ... }); // ✗ ValidationError
await client.createSession({ amount: 0, ... }); // ✗ ValidationErrorFor display, use session.amount directly:
const display = session.amount.toFixed(2); // "19.90"Error handling
All thrown errors extend ScanAndPayError.
| Class | When |
|---|---|
| ValidationError | Bad input rejected before any HTTP call. |
| AuthenticationError | API rejected API Secret (rotate your keys). |
| ApiError | Non-2xx response from the API. |
| NetworkError | Transport failure after exhausting retries. |
| WebhookSignatureError | Webhook signature or timestamp check failed. |