npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

verifiabl

v0.15.0

Published

Official Verifiabl Node.js SDK for issuing payslip QR codes, formatting PII, AES-256-GCM encryption helpers, and typed issuer API calls.

Readme

verifiabl

Official Node.js SDK for issuing Verifiabl payslip QR codes.

Add a scannable QR code to each payslip you issue. You register the non-PII payslip data with Verifiabl and encrypt the employee's personal details on your own infrastructure, so they live only inside the QR code on the document and never reach Verifiabl.

Verifiabl is for accredited payroll providers. You receive sandbox credentials at onboarding. Full documentation is at docs.verifiabl.io.

Installation

npm install verifiabl

Requires Node.js 20+. The example below renders an SVG badge, which needs no extra dependencies. To render a PNG instead (slower, and it pulls in a native renderer), also install:

npm install @resvg/resvg-js

Getting started

This is the self-managed flow: register the payslip, encrypt the personal details locally, and generate the QR code yourself. You need four values from onboarding: your OAuth client ID and secret, your encryption key, and your key version.

import { VerifiablClient, formatPii, encryptPii, createBarcodeSvg } from "verifiabl";

const client = new VerifiablClient({
  environment: "sandbox",
  auth: {
    clientId: process.env.VERIFIABL_CLIENT_ID!,
    clientSecret: process.env.VERIFIABL_CLIENT_SECRET!,
  },
});

// Your 32-byte key and key version, from onboarding. Load the key from a secrets manager.
const key = Buffer.from(process.env.VERIFIABL_ENCRYPTION_KEY_BASE64!, "base64");
const keyVersion = process.env.VERIFIABL_KEY_VERSION!; // e.g. "0f8fad5b-...e.1"

// 1. Format and encrypt the employee's details locally.
const pii = formatPii({
  employeeName: "Jane A. Doe",
  position: "Senior Developer",
  department: "Engineering",
  employerAbn: "12345678901",
  bsb: "062-000",
  accountNumber: "12345678",
  accountName: "Jane A Doe",
});
const { encryptedPii, encryptionMetadata } = encryptPii(pii, key, keyVersion);

// 2. Register the non-PII data. Verifiabl returns a Verifiabl reference.
const { verifiablReference } = await client.registerNonPii({
  schema: "au.payslip.v1",
  issuedAt: new Date().toISOString(),
  // Canonical au.payslip.v1: money is integer cents, and net must reconcile as
  // net = gross - salarySacrifice - paygw - deductions + reimbursements.
  payslipNonPii: {
    periodStart: "2026-05-01",
    periodEnd: "2026-05-31",
    paymentDate: "2026-06-04",
    currency: "AUD",
    grossCents: 900_000,
    paygwCents: 225_000,
    netCents: 675_000,
    ytdGrossCents: 5_400_000,
    ytdPaygwCents: 1_350_000,
  },
  encryptionMetadata,
});

// 3. Render the QR code and embed the SVG in your payslip PDF.
const { svg } = createBarcodeSvg(
  { verifiablReference, encryptedPii },
  { environment: "sandbox" },
);

Prefer createBarcodeSvg when you can: SVG scales to any size without losing quality. Use createBarcodePng when you need a raster PNG (it needs the @resvg/resvg-js renderer). Verifiabl can also build the QR code for you instead of generating it locally. See the docs for both.

Rendering many codes

Generate codes in a loop. Each call is independent, so a single payslip and a large pay run are both fast:

for (const { verifiablReference, encryptedPii } of records) {
  const { png } = await createBarcodePng({ verifiablReference, encryptedPii }, {}, 720);
  // embed png in this record's PDF
}

PNGs default to truecolour. Pass { palette: true } for smaller files when you embed many codes in a PDF.

Batch registration

For pay runs, register up to 1000 records in one request with registerNonPiiBatch. The provider generates each Verifiabl reference up-front with generateVerifiablReference and includes it on each record, so the whole batch can go in one round trip. Results come back in the same order as the input records (results[i] is the outcome of records[i]); one bad record never fails the whole batch.

import { encryptPii, formatPii, generateVerifiablReference } from "verifiabl";

const issuedAt = new Date().toISOString();
const prepared = payslips.map((payslip) => {
  const verifiablReference = generateVerifiablReference();
  const { encryptedPii, encryptionMetadata } = encryptPii(
    formatPii(payslip.pii),
    key,
    keyVersion,
  );
  // Keep `encryptedPii` alongside the reference locally: you need both to render the barcode.
  return { verifiablReference, encryptedPii, encryptionMetadata, payslip };
});

const { results } = await client.registerNonPiiBatch({
  records: prepared.map(({ verifiablReference, encryptionMetadata, payslip }) => ({
    verifiablReference,
    schema: "au.payslip.v1",
    issuedAt,
    payslipNonPii: payslip.nonPii,
    encryptionMetadata,
  })),
});

for (const result of results) {
  if (result.status === "error") {
    console.error(result.verifiablReference, result.code, result.detail);
  }
}

Environments

Set environment to production (default) or sandbox. Pass the same value to the client and the barcode renderer, so the scan URL printed on the document matches where the record was registered.

Errors

Failed requests throw VerifiablApiError with a stable code and a requestId to quote to support. Auth failures throw VerifiablAuthError.

import { VerifiablApiError } from "verifiabl";

try {
  await client.registerNonPii(request);
} catch (err) {
  if (err instanceof VerifiablApiError && err.code === "VALIDATION_FAILED") {
    console.log(err.requestId);
  }
}

Security

Employee PII is encrypted on your infrastructure and never reaches Verifiabl. Keep your encryption key and OAuth secret in a secrets manager. See the security model for the full detail.

Documentation

Full API reference, the alternative API flow, barcode placement rules, and the security model are at docs.verifiabl.io.

License

MIT