Components
customtininput
A TIN (Tax Identification Number) input that verifies the number against the RDB/RRA registry and auto-populates downstream fields from the response.
A TIN (Tax Identification Number) input that verifies the number against the RDB/RRA registry and auto-populates downstream fields from the company record.
Read Form Rules before using this component — keys, labels, required fields, expressions, visibility, and validation all follow shared conventions.
When to use
- Capturing a company TIN for business registration, procurement, or tax-related services
- Any field where the TIN must be validated against the RDB/RRA registry and company details should auto-fill
When NOT to use
Instead of customtininput, use… | For… |
|---|---|
customidinput | Individual (citizen) NID, Foreigner ID, Child ID, or NIN verification |
input | Plain reference numbers with no external registry verification |
Props
| Prop | Type | Required? | Description |
|---|---|---|---|
label | string | required | Visible label. Must be unique across the form. |
required | boolean | required | Always false. The expression controls the runtime value. |
defaultRequired | boolean | required | true for required fields, false for optional ones. |
url | string | required | Integration endpoint path. Always /integration/v1/fetch/sync. |
endpointCode | string | required | Integration endpoint code. Always "FTINDETAILS" for production forms. |
useBaseUrl | boolean | required | Always true — prepends the API gateway base URL. |
populates | array | optional | { valueKey, targetKey } pairs mapping API response keys to form field keys. |
usePrefetch | boolean | optional | When true, auto-fetches the TIN from the logged-in user's business profile on load. Only for logged-in business users. |
tinLength | number | optional | Overrides the default 9-digit TIN length validation. |
placeholder | string | optional | Ghost text shown inside the field. |
hint | string | optional | Help text rendered below the field. |
readonly | boolean | optional | Renders the field non-editable. |
hideField | boolean | optional | Hides the field and excludes its value. Toggle via expressions["props.hideField"]. |
API response keys (populates.valueKey)
Common keys returned by the FTINDETAILS endpoint:
valueKey | Description |
|---|---|
SupplierName | Company name |
SupplierTin | Company TIN |
EmailAddress | Company email address |
PhoneNumber | Company phone number |
Validation messages
| Key | When it fires |
|---|---|
required | Field is empty on submit |
invalidTIN | TIN was entered but no company record was found |
invalidInput | Input does not match the expected 9-digit TIN format |
Examples
Minimal
{
"key": "TIN_NUMBER",
"type": "customtininput",
"props": {
"label": "TIN Number",
"placeholder": "Enter TIN Number",
"required": false,
"defaultRequired": true,
"url": "/integration/v1/fetch/sync",
"useBaseUrl": true,
"endpointCode": "FTINDETAILS"
},
"expressions": {
"props.required": "!(field?.props?.hideField || field?.hide) && field?.props?.defaultRequired"
},
"validation": {
"messages": {
"required": "Please fill in this field",
"invalidTIN": "No details found for this TIN",
"invalidInput": "TIN number must be 9 digits"
}
}
}With field population
{
"key": "COMPANY_TIN",
"type": "customtininput",
"props": {
"label": "Company TIN",
"placeholder": "Enter company TIN",
"required": false,
"defaultRequired": true,
"url": "/integration/v1/fetch/sync",
"useBaseUrl": true,
"endpointCode": "FTINDETAILS",
"populates": [
{ "valueKey": "SupplierName", "targetKey": "COMPANY_NAME" },
{ "valueKey": "SupplierTin", "targetKey": "COMPANY_TIN_CODE" },
{ "valueKey": "EmailAddress", "targetKey": "COMPANY_EMAIL" },
{ "valueKey": "PhoneNumber", "targetKey": "COMPANY_PHONE" }
]
},
"expressions": {
"props.required": "!(field?.props?.hideField || field?.hide) && field?.props?.defaultRequired"
},
"validation": {
"messages": {
"required": "Company TIN is required",
"invalidTIN": "No company found for this TIN",
"invalidInput": "TIN number must be 9 digits"
}
}
}With prefetch (logged-in business user)
{
"key": "GUARANTORS_COMPANY_TIN",
"type": "customtininput",
"props": {
"label": "Guarantor Company TIN",
"placeholder": "Enter TIN",
"required": false,
"defaultRequired": true,
"url": "/integration/v1/fetch/sync",
"useBaseUrl": true,
"endpointCode": "FTINDETAILS",
"usePrefetch": true,
"populates": [{ "valueKey": "SupplierName", "targetKey": "GUARANTORS_COMPANY_NAME" }]
},
"expressions": {
"props.required": "!(field?.props?.hideField || field?.hide) && field?.props?.defaultRequired"
},
"validation": {
"messages": {
"required": "Please fill in this field",
"invalidTIN": "No details found for supplier",
"invalidInput": "TIN number must be 9 digits"
}
}
}Common mistakes
- Setting
required: truedirectly — userequired: false+defaultRequired: true+ the expression. See Required fields. - Omitting
url— the component throws at runtime. Always set to/integration/v1/fetch/sync. - Omitting
endpointCode— the component throws at runtime. Always required. - Omitting all three validation messages — users see no feedback when verification fails. Include
required,invalidTIN, andinvalidInput. - Setting
usePrefetch: truefor citizen applicants — the prefetch silently finds nothing and leaves the field empty. Only use for logged-in business users. - Using
customtininputfor individual citizens — usecustomidinputinstead.customtininputis for company TINs only.
Checklist
-
keyisUPPER_SNAKE_CASEand unique across the entire form -
props.labelis present, unique, and correctly cased - Field is nested at the correct depth:
sections > formly-group > block > customtininput -
required: false(nevertrue) -
defaultRequiredis set -
expressions["props.required"]is present with the exact required expression -
urlis/integration/v1/fetch/sync -
endpointCodeis"FTINDETAILS" -
useBaseUrl: true -
validation.messagesincludesrequired,invalidTIN, andinvalidInput -
usePrefetch: trueonly when the applicant is a logged-in business user