Skip to content
Comms.ID
Esc
↑↓navigate↵open⌘Jpreview
On this page

Check a financier against APRA's list on a server

Check a financier against APRA’s list on a server

What you build: a server function that takes the ABN a business gives you for its financier and checks it against the list of registered financial corporations that APRA publishes. It answers “registered” (with the category), “exempted” (listed as exempted from registration, which is not registered), “not on the list” or “the list did not answer”. A miss says only that the ABN is not on APRA’s page; it is not proof of anything else.

Before you start: a development app, then a production app

  1. npx comms-id init makes a development key in .env.local and prints its public key. In the Companion App, register it as a development app, enable APRA list of registered financial corporations for it, and put the app id in .env.local as COMMS_ID_CLIENT_ID. This key reaches only the TEST service (https://api-test.comms.id): the same API, errors and authentication as LIVE, with synthetic replies.
  2. When it works in TEST, npx comms-id key --worker <your worker> makes the production key straight into your server’s COMMS_ID_PRIVATE_JWK secret and prints the public key; register it as a production app with the product enabled. Going live changes only the environment and the key: nothing in the code below.

A .env.local never holds a production key, and a browser never holds any key.

The check

pnpm add @comms-id/apra-list-registered-financial-corporations

check-financier.ts:

// Check a financier's ABN against APRA's published list on your server. An exempted corporation
// is never reported as registered, a miss says only "not on the list", and an outage is never a miss.
import {
  type ApraListRegisteredFinancialCorporationsClient,
  outcomeOf,
} from "@comms-id/apra-list-registered-financial-corporations";

const ABN = /^\d{11}$/;
const SPACES = /\s+/g;

export type FinancierCheck =
  | {
      readonly listed: "registered" | "exempted";
      readonly name: string;
      readonly category: string;
      readonly sourceDate: string;
      readonly attribution: string;
    }
  | { readonly listed: false; readonly reason: "invalid" | "not-listed" | "unavailable"; readonly message: string };

export const checkFinancier = async (
  input: string,
  apra: ApraListRegisteredFinancialCorporationsClient
): Promise<FinancierCheck> => {
  const abn = input.replace(SPACES, "");
  if (!ABN.test(abn)) {
    return { listed: false, reason: "invalid", message: "An ABN has 11 digits." };
  }
  try {
    const reply = await apra.lookup({ abn });
    const fact = reply.facts[0];
    if (reply.outcome === "no-match" || fact === undefined) {
      // Not on APRA's published page. That says nothing else about the business.
      return { listed: false, reason: "not-listed", message: reply.meaning ?? "Not on APRA's published list." };
    }
    return {
      listed: fact.data.status,
      name: fact.data.name,
      category: fact.data.categoryLabel,
      sourceDate: fact.sourceDate,
      attribution: fact.attribution,
    };
  } catch (error) {
    if (outcomeOf(error) === "source-unavailable") {
      return { listed: false, reason: "unavailable", message: "The list did not answer; try again later." };
    }
    throw error;
  }
};

Call it with a server client:

import { createApraListRegisteredFinancialCorporationsClient } from "@comms-id/apra-list-registered-financial-corporations/server";

const apra = createApraListRegisteredFinancialCorporationsClient({
  clientId: process.env.COMMS_ID_CLIENT_ID ?? "",
  privateJwk: JSON.parse(process.env.COMMS_ID_PRIVATE_JWK ?? "{}"),
  environment: "test", // Going live: "live", with the production key.
});
const result = await checkFinancier("45 114 248 458", apra);

Keep sourceDate and attribution with the result you store: they say which edition of APRA’s page answered, and the licence requires the attribution.

TEST first

In TEST, 45114248458 is a registered corporation in category D, 10000000032 an exempted one, 10000000000 is not on the list, 10000000064 is an outage and 10000000096 the fair-use limit. All TEST replies are fictional and say so in their attribution.

In a browser

The same lookup is a finished field: @comms-id/apra-list-registered-financial-corporations-react for React, or the <comms-id-apra-list-registered-financial-corporations> element from cdn.comms.id, both through your own relay route (see the Charity guide for the relay and its signer). The field shows an exempted corporation as exempted, never as registered.

LIVE

Use environment: "live" and the production key. Reference: APRA list API. The attribution in each LIVE reply (APRA, CC BY 4.0) is part of the licence: do not hide it.

Was this page helpful?