Digital Lending business KYC onboarding form

/ 7 min read

Digital Lending Platform: KYC & Onboarding System

Project Metadata

Overview of the project context, scope, and tech choices.

completed
Internal Project

Overview

Role
Full Stack Developer
Client
Confidential (Banking Sector)
Type
Enterprise Web Application
Industry
Financial Technology (FinTech)
Platform
Web
Duration
-

Description

A digital lending application for banking tender requirements, featuring a modular KYC onboarding system for business applicants with company verification, document validation, and external service integration.

Key Features

  • • Business KYC Onboarding
  • • Company Information Validation
  • • Document Verification
  • • External Verification Integration
  • • Multi-step Application Flow
  • • Modular Backend Services

Tech Stack

Next.js
React
Material UI
Java
Spring Boot
PostgreSQL

Unlike personal projects where I had full autonomy over every decision, this was my first real experience working in a genuine enterprise context, with strict business constraints, non-negotiable security standards, and a cross-functional team that had to collaborate effectively under real delivery pressure.

Digital Lending business KYC onboarding form

The platform was developed to fulfill requirements for a banking tender, where the digital lending system had to comply with regulations set by financial authorities. Every technical decision, from how company information is collected to how supporting documents are verified, had to be grounded in compliance, not just convenience.

The Complexity of Business KYC

In a business lending context, KYC is not simply about collecting an individual’s identity information. The process needs to establish a clear and verifiable picture of the company applying for financing, including its legal identity, registered address, business information, management structure, ownership, and supporting documentation.

That means the onboarding flow needs to ensure that:

  1. Company information matches its official registration documents
  2. Business and registration data are complete and internally consistent
  3. Directors and beneficial owners can be identified and verified
  4. Supporting documents are valid and can be validated against the submitted information
  5. The overall application can be reviewed and audited before submission

The challenge was therefore not only to build a comprehensive form, but to make a process with many validation rules feel structured and understandable to the applicant.

Designing the Multi-step Onboarding Flow

The onboarding experience was organized into five logical stages:

Step 1: Company Profile
→ Legal identity, registered address, and company contact
Step 2: Business Details
→ Business operations and financial information
Step 3: Directors & Owners
→ Management structure and ownership information
Step 4: Documents
→ Supporting documents and verification
Step 5: Review & Submit
→ Final review, confirmation, and submission

Each stage has a specific purpose and exposes only the information required for that part of the application. The progress indicator gives applicants a clear overview of where they are in the process, while keeping the current step visually focused.

The first stage, Company Profile, focuses on the company’s legal identity and registered information. It includes the legal company name, business entity type, registration number, tax identification number, establishment date, primary industry, registered address, and company contact details.

Building the Company Profile Step

The first onboarding step was designed around three main areas: legal identity, registered address, and company contact information.

Rather than presenting all fields as one continuous form, the information was grouped into clearly defined sections. This made the form easier to scan and helped separate different types of information without adding unnecessary complexity to the interface.

The legal identity section captures the core information required to identify the business, while the registered address section handles the company’s official location. Company email and phone information are collected separately as the primary communication channels throughout the application process.

This structure also creates a consistent pattern that can be reused across the remaining onboarding steps.

Frontend: Building a Reusable Component System

One of the most impactful technical contributions I made on this project was establishing a reusable component system for the onboarding flow.

The different onboarding stages share many of the same interaction patterns, so common UI elements were standardized instead of being implemented independently for every screen. This included form fields, select controls, validation states, section headers, step containers, and navigation controls.

The component approach helped maintain consistency across the onboarding experience while making it easier to introduce new fields or adjust existing requirements as the project evolved.

For example, a standardized form field could consistently handle:

  • Labels and required states for mandatory information
  • Input and select controls with consistent styling and behavior
  • Validation messages for invalid or incomplete data
  • Helper text for contextual guidance
  • Focus and error states for interaction feedback
  • Responsive layouts across different screen sizes

This became especially valuable in an enterprise project where requirements could change during development and UI consistency had to be maintained across multiple screens.

Managing Multi-step Form State

A multi-step business onboarding form introduces several state-management challenges. Data entered in one stage needs to remain available when the applicant moves between stages, while validation rules can differ depending on the information being collected.

For example, the company profile stage contains different data types across legal identity, registered address, and company contact sections. Later stages introduce additional information about business operations, financial conditions, ownership, and supporting documents.

I used Formik for form state management together with Yup for schema-based validation. This provided a centralized way to define validation rules while allowing each onboarding stage to maintain its own requirements.

A simplified example of the validation approach for the company profile step could look like:

const companyProfileSchema = Yup.object({
legalName: Yup.string()
.trim()
.max(150, 'Legal company name is too long')
.required('Legal company name is required'),
businessEntity: Yup.string().required('Business entity type is required'),
registrationNumber: Yup.string()
.trim()
.max(50, 'Registration number is too long')
.required('Registration number is required'),
taxId: Yup.string()
.transform((value) => value?.replace(/\D/g, ''))
.test(
'tax-id-length',
'Tax identification number must contain 15 or 16 digits',
(value) => !value || value.length === 15 || value.length === 16,
)
.required('Tax identification number is required'),
establishmentDate: Yup.date()
.typeError('Invalid establishment date')
.required('Establishment date is required'),
industry: Yup.string().required('Primary industry is required'),
registeredAddress: Yup.string()
.trim()
.max(255, 'Registered address is too long')
.required('Registered address is required'),
province: Yup.string().required('Province is required'),
city: Yup.string().required('City or regency is required'),
district: Yup.string().nullable(),
postalCode: Yup.string()
.matches(/^\d{5}$/, 'Postal code must contain 5 digits')
.required('Postal code is required'),
companyEmail: Yup.string()
.trim()
.email('Invalid company email')
.required('Company email is required'),
companyPhone: Yup.string()
.trim()
.matches(/^\+?[0-9\s()-]{8,20}$/, 'Invalid company phone number')
.required('Company phone number is required'),
});

Cross-step state was managed at the parent level so that previously entered information remained available when users navigated between stages. This prevented data loss and allowed each step to focus on its own validation responsibilities.

Integrating External Verification Services

Another technically challenging area was integrating the onboarding platform with external verification services.

The onboarding flow was connected to downstream services responsible for validating submitted company information and verifying supporting documents. This meant the frontend could not simply assume that every request would complete successfully or return a predictable response.

External services introduced differences in response formats, processing times, and failure conditions. To keep these concerns isolated from the user interface, the backend service layer handled the integration and normalized the results before exposing them to the frontend.

The integration layer was responsible for several concerns:

  • Response normalization to provide a consistent internal representation of external responses
  • Timeout and retry handling for transient service failures
  • Error mapping to translate technical service errors into meaningful application states
  • Asynchronous processing for verification operations that required additional processing time

This separation allowed the frontend to remain focused on the onboarding experience while the backend handled the complexity of communicating with external services.

Working Agile in an Enterprise Environment

This was the first project I worked on with a real Agile process: two-week sprints, daily standups, sprint reviews with stakeholders, and regular retrospectives.

The experience taught something that no tutorial can: a feature that’s “done” in sprint one can have its requirements change in sprint three due to QA feedback, tender requirements, or shifting client expectations. The ability to modify an implementation without breaking what surrounds it depends heavily on how modular the code was written from the start.

Working within a banking environment also changed how I approached seemingly small implementation decisions. Consistency, traceability, validation, and maintainability were not secondary concerns. They were part of the product requirements themselves.

This project reinforced my view that clean architecture is not simply a preference, but a prerequisite for software that needs to evolve and remain maintainable under real-world constraints.

Client details and specific implementation details are confidential per NDA agreement.