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

@molecule/api-kyc-stripe-identity

v1.0.1

Published

Stripe Identity KYC bond for molecule.dev — document + selfie verification, normalized status, signed webhooks.

Readme

@molecule/api-kyc-stripe-identity

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Stripe Identity KYC bond for molecule.dev.

Implements the {@link KycProvider} contract from @molecule/api-kyc using Stripe Identity's REST API. Verification sessions are document + selfie (document), id-number (id_number), or hosted address checks (provider-dependent). Webhooks are verified against STRIPE_IDENTITY_WEBHOOK_SECRET.

Setup

  1. Create a Stripe account and enable Stripe Identity.
  2. Set STRIPE_SECRET_KEY and STRIPE_IDENTITY_WEBHOOK_SECRET in the API environment (or pass secretKey / webhookSecret to {@link createProvider}).
  3. Configure a webhook endpoint subscribed to identity.verification_session.verified, identity.verification_session.requires_input, and identity.verification_session.canceled.
  4. Bond at startup: setProvider(provider).

Quick Start

import { setProvider } from '@molecule/api-kyc'
import { provider } from '@molecule/api-kyc-stripe-identity'

setProvider(provider)

Type

provider

Installation

npm install @molecule/api-kyc-stripe-identity @molecule/api-bond @molecule/api-kyc @molecule/api-secrets

API

Interfaces

CreateKycSessionOptions

Caller-supplied parameters when creating a verification session.

interface CreateKycSessionOptions {
  /**
   * Caller's stable identifier for the end user. Stored as provider metadata
   * so webhook events and status lookups can be correlated.
   */
  userId: string
  /** Type of identity check to request. */
  type: KycVerificationType
  /**
   * URL to send the user to after they complete or abandon the
   * provider-hosted flow. Some providers also expose a hosted URL — see
   * {@link KycSession.url}.
   */
  returnUrl?: string
  /**
   * Free-form key/value pairs forwarded to the provider as session metadata.
   * Useful for correlating with caller-side records (case id, app id, etc.).
   * Values are coerced to strings by the provider.
   */
  metadata?: Record<string, string>
}

KycProvider

KYC provider contract.

Each method is stack-neutral; bonds for different providers (Stripe Identity, Persona, Onfido, Sumsub) expose the same shape. Providers throw on errors with sanitized messages — never leaking API keys, webhook secrets, or verbatim provider error bodies that may echo credentials.

interface KycProvider {
  /**
   * Creates a new verification session at the provider.
   *
   * @param options - Session parameters (user, type, return URL, metadata).
   * @returns The created session, including a hosted URL where applicable.
   */
  createVerificationSession(options: CreateKycSessionOptions): Promise<KycSession>
  /**
   * Fetches the current status of a verification session.
   *
   * @param sessionId - Provider-specific session id from
   *   {@link KycSession.sessionId}.
   * @returns The normalized session status.
   */
  getVerificationStatus(sessionId: string): Promise<KycSessionStatus>
  /**
   * Cancels a verification session. Idempotent — canceling an already-canceled
   * session SHOULD return the same status without throwing.
   *
   * @param sessionId - Provider-specific session id from
   *   {@link KycSession.sessionId}.
   * @returns The session status after cancellation.
   */
  cancelVerificationSession(sessionId: string): Promise<KycSessionStatus>
  /**
   * Verifies the signature of an inbound webhook and returns the normalized
   * event. Throws if the signature is invalid or the payload cannot be parsed.
   *
   * @param headers - Inbound request headers (verbatim — bonds extract the
   *   right signature header).
   * @param body - Raw request body bytes (do NOT pass a parsed JSON object —
   *   most providers sign the exact byte sequence).
   * @returns The normalized webhook event.
   */
  processWebhook(headers: KycWebhookHeaders, body: string | Buffer): Promise<KycWebhookEvent>
}

KycSession

A verification session created with a KYC provider.

Sessions are the unit of state — once created they progress through statuses ({@link KycStatus}) until terminal (verified or canceled).

interface KycSession {
  /** Provider-specific session identifier. Opaque to callers. */
  sessionId: string
  /**
   * Provider-hosted URL to redirect the user to. Some providers (e.g. those
   * using a client-side SDK with a single-use token) MAY return `null` —
   * callers must then use the SDK directly.
   */
  url: string | null
  /**
   * Optional epoch-millis expiry of the hosted session. After this time the
   * session URL stops working and the caller must create a new session.
   */
  expiresAt?: number
}

KycSessionStatus

Result of {@link KycProvider.getVerificationStatus}.

interface KycSessionStatus {
  /** Provider-specific session identifier. */
  sessionId: string
  /** Normalized status across providers. */
  status: KycStatus
  /**
   * Verification type at create time. Useful for callers that do not store
   * the type alongside the session id.
   */
  type?: KycVerificationType
  /**
   * Provider-specific reason code when status is `requires_input` or
   * `canceled`. Opaque string — meant for logging / display, not branching.
   */
  lastErrorCode?: string
  /** Provider-specific human-readable error reason. */
  lastErrorReason?: string
}

KycWebhookEvent

A normalized webhook event. Returned by {@link KycProvider.processWebhook} after the signature has been verified.

interface KycWebhookEvent {
  /** The normalized event type. */
  type: KycWebhookEventType
  /** Provider-specific session identifier the event applies to. */
  sessionId: string
  /** Caller-supplied user id stored in session metadata. */
  userId?: string
  /** Verification type at create time. */
  verificationType?: KycVerificationType
  /** Caller-supplied metadata stored on the session. */
  metadata?: Record<string, string>
  /** Provider-specific reason code for failure events. */
  lastErrorCode?: string
  /** Provider-specific human-readable failure reason. */
  lastErrorReason?: string
  /** Raw provider event object — kept for round-tripping / debugging. */
  raw?: Record<string, unknown>
}

StripeIdentityProviderOptions

Configuration options for {@link createProvider}.

Every field defaults to environment variables so handlers can call createProvider() with no arguments. Tests inject overrides (especially {@link StripeIdentityProviderOptions.fetch} and {@link StripeIdentityProviderOptions.apiBaseUrl}).

interface StripeIdentityProviderOptions {
  /**
   * Stripe secret API key. Defaults to `process.env.STRIPE_SECRET_KEY`.
   */
  secretKey?: string
  /**
   * Stripe Identity webhook signing secret. Defaults to
   * `process.env.STRIPE_IDENTITY_WEBHOOK_SECRET`.
   */
  webhookSecret?: string
  /**
   * Override the Stripe API base URL. Defaults to `https://api.stripe.com`.
   * Useful for tests pointing at a fake Stripe server.
   */
  apiBaseUrl?: string
  /** Request timeout in milliseconds. Defaults to `15_000`. */
  timeoutMs?: number
  /**
   * Override the Stripe API version sent on every request. Defaults to
   * Stripe's pinned `2024-06-20`.
   */
  apiVersion?: string
  /**
   * Maximum allowed clock-drift between the bond's host and Stripe when
   * verifying webhook signatures, in seconds. Defaults to `300` (5 minutes),
   * matching Stripe's recommendation.
   */
  webhookToleranceSeconds?: number
  /**
   * Replace the global fetch implementation. Tests inject a stub here;
   * production callers should leave it unset.
   */
  fetch?: typeof fetch
}

Types

KycStatus

Normalized verification status, common across all KYC bonds.

  • pending — the session has been created but the user has not started.
  • requires_input — provider has rejected or paused; the user must take another action (resubmit document, retry selfie, etc.).
  • processing — provider is currently reviewing submitted material.
  • verified — verification succeeded.
  • canceled — the session was canceled (by caller, user, or provider).
type KycStatus = 'pending' | 'requires_input' | 'processing' | 'verified' | 'canceled'

KycVerificationType

Type of identity check requested for a verification session.

  • document — government-issued photo ID + selfie liveness check.
  • id_number — verifies a government-issued number (e.g. SSN) without a document.
  • address — verifies the user's residential address.

Provider support varies; bonds MAY throw when asked for a type they do not support.

type KycVerificationType = 'document' | 'id_number' | 'address'

KycWebhookEventType

Discriminated event type emitted by {@link KycProvider.processWebhook}.

Bonds normalize provider-specific event names into one of these three variants. Provider-specific raw payload is preserved in {@link KycWebhookEvent.raw} so callers needing extra detail can opt in.

type KycWebhookEventType =
  'verification.verified' | 'verification.requires_input' | 'verification.canceled'

KycWebhookHeaders

Headers required for {@link KycProvider.processWebhook}. Lower-cased keys.

Different providers use different header names for the signature; bonds are responsible for picking the right one(s) from this map. Callers should pass the request's headers verbatim.

type KycWebhookHeaders = Record<string, string | string[] | undefined>

Functions

createProvider(options)

Creates a Stripe Identity provider.

function createProvider(options?: StripeIdentityProviderOptions): KycProvider
  • options — Optional configuration. Falls back to STRIPE_SECRET_KEY / STRIPE_IDENTITY_WEBHOOK_SECRET env vars when secretKey / webhookSecret are omitted.

Returns: A {@link KycProvider} implementation.

verifyStripeSignature(payload, signatureHeader, secret, toleranceSeconds, now)

Verifies a Stripe webhook signature. Equivalent to Stripe.webhooks.constructEvent minus the SDK dependency.

function verifyStripeSignature(
  payload: string | Buffer<ArrayBufferLike>,
  signatureHeader: string | undefined,
  secret: string,
  toleranceSeconds: number,
  now?: number,
): void
  • payload — The raw request body.
  • signatureHeader — The stripe-signature header value.
  • secret — The webhook signing secret.
  • toleranceSeconds — Allowed clock-drift between hosts.
  • now — Current epoch millis (injectable for tests).

Constants

kycStripeIdentitySecretDefinitions

Secret definitions required by the Stripe Identity KYC bond.

const kycStripeIdentitySecretDefinitions: SecretDefinition[]

provider

The Stripe Identity provider. Lazily initialized on first use so that environment variables are read at call time rather than import time.

const provider: KycProvider

Core Interface

Implements @molecule/api-kyc interface.

Bond Wiring

Setup function to register this provider with the core interface:

import { setProvider } from '@molecule/api-kyc'
import { provider } from '@molecule/api-kyc-stripe-identity'

export function setupKycStripeIdentity(): void {
  setProvider(provider)
}

Injection Notes

Requirements

Peer dependencies:

  • @molecule/api-bond ^1.0.1
  • @molecule/api-kyc ^1.0.1
  • @molecule/api-secrets ^1.0.1

Environment Variables

  • STRIPE_SECRET_KEY (required) — Stripe secret key
    • Setup: Stripe Dashboard → Developers → API keys; use the sk_test_ key in test mode, sk_live_ in production.
    • Get it here: https://dashboard.stripe.com/apikeys
    • Example: sk_test_...
  • STRIPE_IDENTITY_WEBHOOK_SECRET (required) — Stripe Identity webhook signing secret

Runtime Dependencies

  • @molecule/api-bond
  • @molecule/api-kyc
  • @molecule/api-secrets

E2E Tests

Integration checklist — drive the real UI (live preview, no mocks), adapt each item to this app's actual screens/flows, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip:

  • [ ] Starting a verification from the UI creates a real session: createVerificationSession is called, the app persists the returned KycSession.sessionId on the user's record with stored status pending, and the user is handed to the provider-hosted session.url — NOT a home-grown document-capture screen, and NOT marked verified at creation.
  • [ ] COUNTERPARTY (the identity check runs out-of-band on the external vendor and can't be completed for real in-sandbox): verify the decision against the app's OWN stored KYC state — deliver a verification.verified (or verification.requires_input / verification.canceled) event to the webhook endpoint, or poll getVerificationStatus, and confirm the user's stored status flips pendingverified / requires_input / canceled and the UI shows it. Observe the transition, never guess it.
  • [ ] KYC-gated features are enforced SERVER-SIDE: while the stored status is not verified, the restricted action is REJECTED by the server (not merely a hidden button); once verified, the same user is allowed. Flipping the stored status changes access after a full reload.
  • [ ] processWebhook rejects a forged decision — a bad/missing signature THROWS and becomes a 4xx with NO state change (the user stays unverified); only a signature-verified event may flip stored status.
  • [ ] A user CANNOT self-verify: no endpoint accepts a client-sent "verified" flag or lets a caller PATCH their own status, and landing back on returnUrl alone changes nothing — the only path to verified is a signature-verified webhook or a server-side getVerificationStatus check.
  • [ ] SECURITY / PRIVACY — identity documents and PII stay server-side: the user is redirected to the provider-hosted flow (the app never receives or stores raw ID images), one user can't read another's session/status/PII by guessing its id, and neither the documents nor the webhook secret are logged in the clear.