# Supplier onboarding with due diligence and risk scoring

Canonical: https://useformwork.com/use-cases/supplier-onboarding

Updated: 2026-10-09

A supplier onboarding form for due diligence that collects company, insurance and bank details, scores risk, routes approval and hands off to finance.

Supplier onboarding often runs on a questionnaire, a chain of emails with certificates attached, and bank details retyped from a PDF. A supplier onboarding form in FormWork keeps the supplier's answers, documents, risk score, approvals and bank-detail check on one entry with its own history. The supplier fills it in; procurement, compliance and finance work it.

This is a configuration pattern with fictional organisations, not a case study. FormWork records the checks your team makes. It doesn't verify bank accounts, check company registers or screen for sanctions.

## Build the supplier onboarding form

Use five pages, and turn on **Let people save and continue later** in [form settings](/docs/forms/form-settings), because suppliers often stop to find a certificate.

1. **Company.** Legal name, company type, company number (shown only for limited companies and LLPs), **Country** of registration, **Address**, VAT number and trading start date, plus the name and **Email** of the person filling it in. "What will you supply?" is a **Dropdown** with options from a Supply categories [data table](/docs/data-tables/options-source) that holds each category's risk points and minimum public liability cover.
2. **Contacts.** A [repeating group](/docs/forms/form-structure) with name, role (accounts and remittance, orders, compliance), email and phone. **Min items** 1, **Max items** 6.
3. **Insurance and certificates.** Public liability cover as a **Number**, its expiry as a **Date** directly on the page, and the certificate as a **File upload** limited to `.pdf` and `image/*`. Other certificates, such as ISO 9001, go in a repeating group with an expiry date and an upload each.
4. **Compliance.** **Yes or no** questions on personal data, subcontractors, a turnover of £36 million or more, and conflicts of interest. [Conditional logic](/docs/logic/conditional-logic) shows follow-up questions only after a yes.
5. **Bank details and declaration.** Account name with sort code and account number, or IBAN and BIC for an account outside the UK, and a bank letter. Finish with a declaration that **Must be on** and a **Signature**.

Check formats with **Must match a pattern (regular expression)** [validation](/docs/logic/validation-rules), such as `^[0-9]{6}$` for a sort code. Patterns are case-sensitive, so say "capital letters, no spaces" in the IBAN's error message.

## Score supplier risk from the answers

Work the score out in an automation and keep it in a **Risk score** [team field](/docs/entries/team-fields), which respondents can't see or change. Avoid a **Hidden value** field on the form for this: the respondent's browser receives the form's answers, hidden ones included.

| Factor | Points |
| --- | --- |
| The category's risk points, from the data table | 1 to 5 |
| Processes personal data for you | 3 |
| Public liability cover below the category's minimum | 3 |
| Uses subcontractors | 2 |
| Registered outside the UK | 2 |
| Trading for less than two years | 2 |

In the **Calculate** step, give each reference a fallback such as `|default:0`, so a skipped question doesn't leave the score empty. See [calculated values](/docs/logic/calculations). Points are read from the data table when the automation runs, so changing them affects later scores only.

## Set up compliance review and approval stages

Set up the [process](/product/process) on the form's **Process** tab. Entries start in Compliance review when submitted.

| Stage | Kind | Owner and due time | Moves on with |
| --- | --- | --- | --- |
| Compliance review | Open | The Procurement group, due in 3 days | **Send for approval**; **Ask the supplier** and **Decline**, each with a required comment |
| Enhanced checks | Open | The Compliance group, due in 5 days | **Send for senior approval**, **Ask the supplier**, **Decline** |
| Waiting on supplier | Waiting | Keep the current owner, due in 7 days | **Supplier replied**, back to Compliance review |
| Waiting for approval | Waiting, needs approval | No owner; **Any one** of the Procurement leads group approves | Approved to Finance set-up, rejected to Declined |
| Senior approval | Waiting, needs approval | No owner; **Everyone**: the heads of procurement and compliance | Approved to Finance set-up, rejected to Declined |
| Finance set-up | Open | The Finance group, due in 2 days | **Bank details verified**, used by **People in a group**: Finance |
| Approved supplier, Declined | Closed | None | |

Under **Choose what approvers can see**, tick the company, category and insurance answers, and leave bank details unticked so they stay out of approval emails. See [approvals](/docs/process/approvals).

In Finance set-up, someone in finance phones the supplier on a number found independently, not one from the form, to confirm the account. Give **Bank details verified** a confirmation question and a required comment, and record who checked and when in team fields.

An entry is in one stage at a time, so finance can't check bank details while compliance reviews. **Supplier replied** returns the entry to the Procurement group, not the person who asked. Due times count calendar days, not working days, and nobody is emailed about an assignment or an overdue entry unless an automation does it. See [owners and due dates](/docs/process/owners-due-dates).

## Automate routing, reminders and the finance hand-off

Five [automations](/product/automations) do the routine work. See [triggers](/docs/automations/triggers) and [steps](/docs/automations/steps).

| Automation | Trigger | Steps |
| --- | --- | --- |
| Score and route | **Stage changes**, from any stage to Compliance review | **Calculate** the score, **Update entry or row** to save it, then **If** it **Is at least** 10, **Move to stage** Enhanced checks |
| Ask the supplier | **Stage changes** to Waiting on supplier | **Send email** to the supplier with the move's **Comment**, replies going to your procurement inbox |
| Chase approvals | **In a stage too long**: Waiting for approval or Senior approval, for 2 days | **Remind approvers** |
| Send to finance | **Stage changes** to Approved supplier | **Send to webhook** with your finance system's key as **A secret**, **Retry twice**, and an email to finance under **If it fails** |
| Insurance renewal | **Before or after a date answer**: 30 days before the cover expiry | **If** the stage **Is** Approved supplier, **Send email** to the supplier asking for the new certificate |

Score and route runs on every arrival in Compliance review, so it scores again after a supplier replies. Upload documents a supplier emails you through **Edit answers**; the [history](/docs/entries/revisions) records the change.

The date trigger only offers dates placed directly on a page, not inside a group. For the repeating certificates, record the earliest expiry in a team field date, which the trigger also offers.

**Send to webhook** never sends to private or local network addresses, so a finance system only reachable inside your network needs an endpoint it can reach. A stage move doesn't prove the hand-off worked: check [automation runs](/docs/automations/runs) and turn on **Email admins when an automation run fails**.

## Handle bank details and sensitive data carefully

What FormWork does, as described in [security and access](/security) and the [privacy policy](/privacy): data is encrypted in transit, logic and validation run on the server, uploads have no permanent public links, approval and status links are stored only as hashes, and secrets for webhook headers are stored encrypted. FormWork doesn't mask answers or encrypt them field by field.

What stays with you:

- **Everyone in the account can see every entry**, bank details included. Groups decide who owns and approves work, not who can see it. If only finance should see bank details, ask for them after approval in a separate form in a finance-only account, or through your finance system.
- **Emails.** **Email your team** includes every answer by default; turn off **Include all the answers** and rely on **Open entry**. Consider turning off **Include a copy of their answers** in the supplier's confirmation.
- **Saved links and exports.** Anyone with a "save and continue later" link can see and change the answers, so keep **Link lifetime (days)** short. Exports put bank details in a spreadsheet.
- **Retention.** Decide how long to keep declined suppliers. Deleting an entry deletes its files and can't be undone.
- **Later changes.** Treat a request to change bank details as a new check with the same call-back, never an email alone.

## Keep suppliers informed

Turn on [respondent status](/docs/process/respondent-status) so the supplier's confirmation has a **See progress** button. Label both review stages "Being checked", so a move to Enhanced checks doesn't show as an update, then use "Waiting for information from you", "Being approved", "Setting up your account", "Approved" and "Closed".

## Test these cases before you publish

- A UK limited company, a sole trader, and a supplier outside the UK with an IBAN.
- A score of exactly 10, and a supplier who skips every optional question.
- A sort code with dashes, and a lowercase IBAN.
- A corrected answer that changes the score after **Ask the supplier**.
- A rejection in Senior approval after one approval.
- A webhook that times out, and a cover expiry date changed after approval.

## Change it safely

Publish changes as a [new form version](/product/versioned-forms). Entries keep the questions they were answered with, while the process and automations follow the latest published version, and the publish review asks where entries in a removed stage should go.

## What success looks like

Every approved supplier has complete answers and documents, a risk score, a recorded approval, a named person who verified the bank details, and a finance hand-off that succeeded in the runs. Set your own targets for how long onboarding should take.

Start with the [quick start](/docs/getting-started/quick-start), see how [client onboarding](/use-cases/client-onboarding) differs, compare [pricing](/pricing), or [talk through your process](/#contact).