Issuance

Start an issuance

Every issuance run requires an intent. Use the Ver.iD Node.js SDK to create the intent on your server, redirect the customer, finalize the callback, and verify the result.

The SDK discovers and calls the OAuth issuer's intent endpoint when you create the intent.

Copy the issuer URI and client identifier from the active issuance's Configuration tab. Use the key from an OAuth secret attached to the issuance as the client secret.

yarn add @ver-id/node-client

Create the client

import { VeridIssuanceClient } from '@ver-id/node-client';

const issuanceClient = new VeridIssuanceClient({
  issuerUri: '<ISSUER_URI>',
  clientId: '<ISSUANCE_CLIENT_ID>',
  redirectUri: 'https://example.com/issuance/callback',
});

const clientAuth = {
  client_secret: process.env.VERID_CLIENT_SECRET!,
};

The redirect URI must be registered on the issuance. Keep VERID_CLIENT_SECRET on the server.

Create an intent with a mapping

Use a mapping payload when an active issuance mapping is attached to the flow. Its keys must exactly match the claims configured in that mapping.

const { codeChallenge, state } =
  await issuanceClient.generateCodeChallenge();

const { intent_id: intentId } =
  await issuanceClient.createIssuanceIntent(
    {
      payload: {
        mapping: {
          firstName: 'Jane',
          membershipNumber: 'M-12345',
        },
      },
    },
    codeChallenge,
    clientAuth,
  );

Use raw attribute data

When the issuance has no mapping, replace payload.mapping with a data array. Copy the attribute UUIDs from the issuance's Configuration tab.

payload: {
  data: [
    {
      attributeUuid: '<ATTRIBUTE_UUID>',
      value: 'Jane',
    },
  ],
}

Provide either mapping or data. Do not send both, and provide every value required by the configured credential.

Redirect the customer

Use the intent identifier with the same PKCE values:

const { issuanceUrl } =
  await issuanceClient.generateIssuanceUrl({
    state,
    codeChallenge,
    intentId,
  });

res.redirect(issuanceUrl);

The intent can also include these optional settings next to payload:

SettingEffect
challengeAssociates an optional challenge UUID with this run.
brandUuidUses an active brand attached to the issuance.
requireExplicitConsentOverrides the consent setting for this run.

Finalize the callback

Exchange the authorization code on your server and verify the returned JWT:

import { assertIssuanceV1JwtPayload } from '@ver-id/node-client';

const issuanceResponse = await issuanceClient.finalize({
  callbackParams: callbackUrl,
  clientAuth,
});

const issuanceToken = await issuanceClient.decode(
  issuanceResponse,
  assertIssuanceV1JwtPayload,
);

callbackUrl must be the complete redirect URL, including its code and state query parameters.

The SDK stores the PKCE verifier under the generated state. Keep that cache available between the start request and callback. Use shared storage when your application runs on more than one server.

See the complete @ver-id/node-client issuance guide for cache options and response types.

On this page