@vpdev2/vc-sdk
v3.3.0
Published
React SDK for VeroCompliance due diligence workflows with configurable API endpoints and comprehensive step coverage
Maintainers
Readme
VeroCompliance SDK
A comprehensive React SDK for VeroCompliance due diligence workflows with configurable API endpoints, dynamic form generation, and complete workflow step coverage.
Features
- ✅ Configurable API Endpoints - Support for both Host Controller and Application Service patterns
- ✅ Complete Workflow Coverage - All 9 workflow step types supported
- ✅ Dynamic Applicant Form - 23 configurable form fields for applicant creation
- 🎨 Backend-Driven Theming - Multi-tenant theme customization with 6 presets, custom logo, colors, and CSS (NEW v1.2.0)
- ✅ React Hooks - Clean API with hooks for each workflow step
- ✅ Pre-built Components - Ready-to-use UI components with Tailwind CSS
- ✅ Dynamic Form Validation - Automatic zod schema generation from API rules
- ✅ Identity Provider Integration - Sumsub, Onfido, and SardinAI support
- ✅ TypeScript - Full type safety with types generated from C# DTOs
- ✅ Session Token Auth - Server-side token creation with optional
externalRefIdscoping guard - ✅ Dark Mode - Built-in dark mode support
Installation
npm install @vpdev2/verocompliance
# or
yarn add @vpdev2/verocompliance
# or
pnpm add @vpdev2/verocomplianceQuick Start
Step 1 — Server: create a session token
Create a short-lived session token on your backend. The API key and secret never leave your server.
// ── Server-side (Next.js API route, Express, etc.) ──
import { VeroComplianceSession } from '@vpdev2/verocompliance';
export async function POST() {
const { accessToken, expiresInSeconds } = await VeroComplianceSession.createToken({
baseUrl: 'https://api.example.com',
clientId: 'your-client-id', // or tenantId: 1
apiKey: process.env.VEROCOMPLIANCE_API_KEY!,
secretKey: process.env.VEROCOMPLIANCE_SECRET_KEY!,
externalRefId: 'USER-12345', // optional — scopes the token to this user
});
return Response.json({ accessToken, expiresInSeconds });
}| Parameter | Type | Required | Description |
|---|---|---|---|
| baseUrl | string | Yes | VeroCompliance API base URL |
| apiKey | string | Yes | Your tenant API key |
| secretKey | string | Yes | Your tenant secret key |
| tenantId | number | One of | Numeric tenant ID (provide this or clientId) |
| clientId | string | One of | String client ID (provide this or tenantId) |
| externalRefId | string | No | When set, the returned token is scoped: all API calls made with it can only create or access applicants matching this externalRefId. Tokens created without it remain unrestricted (backward-compatible). |
Step 2 — Client: initialize the SDK
Pass the token to the frontend SDK via getAccessToken:
import { VeroComplianceProvider } from '@vpdev2/verocompliance';
function App() {
return (
<VeroComplianceProvider
config={{
getAccessToken: () => fetchSessionToken(), // returns the accessToken string
clientId: 'your-client-id',
baseUrl: 'https://api.example.com',
endpoints: { pattern: 'host-controller' },
applicantForm: {
externalRefId: 'USER-12345',
},
// Optional: Configure identity providers (e.g., SardinAI)
identityProviders: {
sardinai: process.env.SARDINAI_CLIENT_ID ? {
clientId: process.env.SARDINAI_CLIENT_ID,
environment: 'sandbox', // or 'production'
region: 'us', // 'us', 'eu', 'ca', or 'au'
enableBiometrics: true,
enablePortScanning: false,
} : undefined,
},
}}
>
<YourApp />
</VeroComplianceProvider>
);
}Tip: You can also pass
apiKeydirectly instead ofgetAccessTokenfor quick testing, but session tokens are recommended for production since they keep your secret key on the server.
Step 3 — Use the workflow component
import { KycWorkflow } from '@vpdev2/verocompliance';
function KYCPage() {
return (
<KycWorkflow
applicantId={applicantId}
onComplete={(result) => console.log('Complete:', result)}
onError={(error) => console.error('Error:', error)}
onAppropriatenessOutcome={(outcome) => console.log('Appropriateness:', outcome)}
/>
);
}Appropriateness test outcome
When the workflow contains a MiFID appropriateness test, the optional onAppropriatenessOutcome
callback (available on both VeroCompliance and KycWorkflow) reports the canonical outcome:
{
testId: number;
completionMode: 'PassRequired' | 'CompletionRequired';
result: 'Passed' | 'FailedExhausted' | 'FailedContinued';
attempts: number;
passed: boolean;
warningAcknowledged: boolean; // true only for FailedContinued
acknowledgedAt?: string; // ISO-8601
startedAt?: string;
completedAt: string;
}The test's completion mode is configured server-side per test. With PassRequired (the default)
the investor must pass to continue; with CompletionRequired an investor who fails is clearly
warned that they may lack sufficient knowledge/experience, may retake within the configured
limits, and may continue after explicitly acknowledging the warning (FailedContinued).
Step 4 — Or build custom UI with hooks
import { useKycWorkflow, useQuestionnaire } from '@vpdev2/verocompliance';
function CustomKYC() {
const { progress, currentStep, moveToNext } = useKycWorkflow(applicantId);
const questionnaire = useQuestionnaire(applicantId);
// Build your custom UI...
}Workflow steps
KycWorkflow renders the step VeroCompliance says is current (currentStep.action):
| Step type | Step | What the applicant sees |
|---|---|---|
| 0 | IdentitySdk | The configured identity provider (Sumsub, Onfido or SardinAI) |
| 1 | RiskScoring | The risk criteria that ask the applicant for input |
| 2 | Questionaries | The questionnaire selected for the applicant |
| 3 | AdditionalData | The Additional Data questions configured in VeroCompliance, or the built-in investor-type question (below) |
| 4 | AppropriatenessTest | The appropriateness test, with its timer and retry limits |
| 5 | UploadDocument | The documents to upload |
| 6 | ManualReview | The review status while an administrator decides |
| 7 | Overview | An overview the applicant confirms before continuing |
| 8 | InvestorCategorization | Investor-type radios sent with SetInvestorCategorization. VeroCompliance does not send this step type |
Step names in the stepper
Each step is named by the first of these that has a value:
- an Additional Data step's definition title;
- the step's
displayNamefrom VeroCompliance; - its
name, unless that is only the step type (IdentitySdk,Overview,ManualReview), which VeroCompliance sends for a step with no content of its own; - the SDK's name for the step type, from the
stepNamestranslations (stepNames.identityfor the identity step). SDK Configuration → Translations overrides them per language.
Identity step: the review page
Unless SDK Configuration disables it, the identity step opens on a review page, and the provider starts when the applicant confirms. First the built-in fields they changed there are saved:
- only the changed ones go, and a field left empty keeps its saved value;
- they're sent with
ApplicantRegistrationRequestfor the applicant under way, with the current workflow's key andwebSdk: false, so no second OnApplicantCreated webhook is sent; - this is done before
IdentityRequest, because VeroCompliance picks the provider by the applicant's country and hands the provider their details.
If VeroCompliance refuses the change with a 400, the page shows its message (for example ApplicantFlow.Immutable
once an identity check has its result) and the provider doesn't start. Any other failure shows a generic error.
Additional Data step
The step calls GetAdditionalData when it opens, and shows a spinner until it answers.
With a definition. When the applicant's current Additional Data step has a definition in VeroCompliance,
the result carries it as definition. The step then shows its title and description, and each question as a
group of radio cards: the question's label, its description, and each option's label and description. Required
questions are marked with * and must be answered before the step submits. An answer the applicant saved before
is preselected while it is still one of the question's options. The step sends one item per answered question
to SetAdditionalData, in the definition's order:
{ applicantId, items: [{ paramName: question.key, value: option.value }, /* … */] }If VeroCompliance refuses the answers with a 400 (ApplicantFlow.InvalidAdditionalData), the step shows the
server's message. Any other failure shows a generic error.
The stepper names the step after the definition's title, which VeroCompliance also sends as title on the flow
step.
Without a definition. When definition is null, missing or has no questions, or GetAdditionalData
fails, the step shows the built-in investor-type question (Individual, Sophisticated, High net worth) and sends
{ paramName: 'investor_type', value }, exactly as SDK versions before definitions did.
Text. Every title, label and description may be plain text or a $t:key marker. Markers resolve through the
SDK's translations, bundled and tenant overrides alike, as backend text does elsewhere in the SDK, and fall back
to the raw key when there is no translation. The text is always rendered as plain text, never as HTML.
Documentation
Core Features
- 🎨 Theming System - Multi-tenant theme customization (NEW v1.2.0)
- Dynamic Form Configuration - Configure visible fields in applicant creation form
- Workflow Key Management - Configure and handle workflow keys and transitions
- External Reference ID - Required field for system integration
- Step Visibility - Configure which workflow steps appear in the UI
- Appropriateness Test - Quiz system with timer and retry logic
- Identity Expiration Handling - Managing expired identity verification sessions
- KYC Status Display - Rich status UI for completed/rejected/pending states
- SardinAI Integration - Sardine's device script, run with the settings VeroCompliance sends
Backend Integration
- 🔧 Backend Theme Integration - Database schema, API endpoints, DTOs (NEW v1.2.0)
- 🎨 Panel Theme UI - Complete Panel UI implementation guide (NEW v1.2.0)
Migration & Changes
- Migration Guide - Migrate from custom form to dynamic configuration (v1.0.0 → v1.1.0)
- Changelog - Version history and changes
License
MIT
