Skip to content

Quickstart

Create a customer, issue a pass, and record a purchase with the current SDK contract.

Prerequisites

  • Node.js 18 or newer
  • A WalletHero API token
  • Existing workspace, project, and pass-template UUIDs

Install and initialize

bash
npm install @wallethero/sdk
typescript
import { WalletHero } from "@wallethero/sdk";

const walletHero = new WalletHero({
  apiToken: process.env.WALLETHERO_API_TOKEN!,
});

if (!(await walletHero.ping())) {
  throw new Error("Could not connect to WalletHero");
}

const { data: user } = await walletHero.me();
console.log(`Connected as ${user.email}`);

Create the customer

Identity, consent, loyalty enrollment, and custom fields are stored on the client record, not the pass.

typescript
const workspaceId = "workspace-uuid";
const projectId = "project-uuid";
const templateId = "template-uuid";

const { data: customer } = await walletHero.clients.create(workspaceId, {
  workspace_id: workspaceId,
  first_name: "Jane",
  last_name: "Customer",
  email: "[email protected]",
  marketing_consent: true,
  marketing_consent_text: "I agree to receive loyalty updates.",
  loyalty_program_enabled: true,
  custom_fields: {
    member_number: "M-1042",
    preferred_store: "Downtown",
  },
});

Issue the pass

typescript
const { data: pass } = await walletHero.passes.create({
  workspace_id: workspaceId,
  project_id: projectId,
  pass_template_id: templateId,
  client_id: customer.id,
});

console.log("Pass ID:", pass.id);
console.log("Apple Wallet:", pass.apple_pass_url);
console.log("Google Wallet:", pass.google_pass_url);

You can combine the preceding steps by providing client_identity instead of client_id. The API creates or reuses a matching client in the workspace.

typescript
const { data: pass } = await walletHero.passes.create({
  workspace_id: workspaceId,
  project_id: projectId,
  pass_template_id: templateId,
  client_identity: {
    email: "[email protected]",
    first_name: "Alex",
    marketing_consent: true,
    custom_fields: { member_number: "M-1043" },
  },
});

Record activity

Event convenience methods take positional amount and currency arguments, followed by optional metadata.

typescript
await walletHero.events.recordPurchase(pass.id, 25, "PLN", {
  external_id: "receipt-1842",
  source: "pos",
  metadata: { store: "Downtown" },
});

await walletHero.events.recordCheckIn(pass.id, {
  source: "store-downtown",
});

For normalized transaction analytics and loyalty side effects, use the transactions service:

typescript
await walletHero.transactions.create({
  workspace_id: workspaceId,
  client_id: customer.id,
  external_id: "receipt-1842",
  amount: 25,
  currency: "PLN",
  source: "pos",
  transaction_timestamp: new Date().toISOString(),
});

Update customer fields

Pass display placeholders resolve client-owned custom fields. Update them through ClientsService so field-change events and downstream automation run correctly.

typescript
await walletHero.clients.mergeCustomFields(workspaceId, customer.id, {
  preferred_store: "Airport",
});

await walletHero.passes.sendNotification(
  pass.id,
  "Your preferred store was updated.",
);

Template placeholders

Current pass templates use these placeholder families:

text
${client.first_name}
${client.email}
${custom_fields.member_number}
${wallet.points}
${wallet:bonus.points}
${loyalty.tier}
${loyalty.referral_code}

${wallet.points} targets the default wallet. ${wallet:<code>.points} targets a specific wallet type. The retired ${loyalty.points} placeholder is not supported.

Complete example

typescript
import { WalletHero, WalletHeroError } from "@wallethero/sdk";

async function main() {
  const walletHero = new WalletHero({
    apiToken: process.env.WALLETHERO_API_TOKEN!,
  });

  const workspaceId = process.env.WALLETHERO_WORKSPACE_ID!;
  const projectId = process.env.WALLETHERO_PROJECT_ID!;
  const templateId = process.env.WALLETHERO_TEMPLATE_ID!;

  const { data: customer } = await walletHero.clients.create(workspaceId, {
    workspace_id: workspaceId,
    email: "[email protected]",
    first_name: "Jane",
    loyalty_program_enabled: true,
  });

  const { data: pass } = await walletHero.passes.create({
    workspace_id: workspaceId,
    project_id: projectId,
    pass_template_id: templateId,
    client_id: customer.id,
  });

  await walletHero.events.recordPurchase(pass.id, 25, "PLN", {
    external_id: "receipt-1842",
  });

  console.log(pass.apple_pass_url, pass.google_pass_url);
}

main().catch((error) => {
  if (error instanceof WalletHeroError) {
    console.error(error.status, error.code, error.message);
  } else {
    console.error(error);
  }
  process.exitCode = 1;
});

Next steps

WalletHero Documentation