Native collection developer guide

How native tax documentation collection is designed to work, in detail. Use it to evaluate fit and plan an integration.

🚧

In development

Native Mobile Tax Documentation Collection is in development. If you're interested in using it, reach out to your Taxbit contact.

Read the sections that apply to you, in any order. The samples are in Swift. React Native takes the same names as props.

Add the questionnaire

The questionnaire is one native screen. Add it where your users complete their tax form:

TaxbitQuestionnaire(
    questionnaire: "W-FORM",
    onSuccess: { _ in markTaxFormDone() },
    onError: { error, _ in showRetry(error) }
)
<TaxbitQuestionnaire
  questionnaire="W-FORM"
  onSuccess={() => markTaxFormDone()}
  onError={(error) => showRetry(error)}
/>

What the user is filling in, and what you already know about them, go directly on the questionnaire. Settings that are the same for every user of your app go in config.

OptionWhat it does
questionnaireWhich form to collect. See Choosing the form.
dataAnswers you already have. See Pre-fill what you know.
configSettings shared by every user: question settings, language, paging, which parts to show, theme and components.
dryRunRun the whole questionnaire without storing anything. Useful while you build.

When things happen

CallbackWhen it runs
onProgressThe screen changed. It gets the screen's title, its position and the percentage complete.
onSubmitThe user finished and the answers are ready, before anything is stored. The questionnaire waits for it, and if it fails, nothing is stored.
onSuccessTaxbit has stored the form.
onErrorA request failed, or your onSubmit failed.
onSettledThe session is over, whichever way it ended.

Each callback also gets the answers so far.

Choosing the form

For W-forms, use "W-FORM". You don't need to know ahead of time which form a person owes. Taxbit asks a few short questions first, such as whether they're a US person and whether they're an individual or a business, then takes them to the right form: W-9, W-8BEN, W-8BEN-E or W-8IMY.

If you collect…questionnaire
Any W-form. You don't need to know which one. (Recommended)W-FORM
Only W-9s (US persons)W-9
Only W-8s (non-US persons)W-8
Only W-8BEN (non-US individuals)W-8BEN
Only W-8BEN-E (non-US entities)W-8BEN-E
Only W-8IMY (intermediaries)W-8IMY
A self-certificationSELF-CERT
A DPS declarationDPS

Name a specific form only if every user needs the same one. Taxbit then skips the questions that form already answers.

W-9 and W-8BEN come first. The other W-8 forms and DPS are in development. See Development status.

Question settings

These turn optional parts of the form on, and set how some questions are asked. They go in config.

SettingWhat it does
fatcaAsk the FATCA questions.
treatyClaimsAsk the treaty-claim questions. Needs typesOfIncome.
typesOfIncomeThe kinds of income the treaty claims cover.
eDeliveryConsentAsk for consent to electronic delivery when the user signs a W-form.
dateFormatThe order a date's parts are asked in: mdy, dmy or ymd.
minimumAgeThe youngest age a date of birth can give.
languageThe user's preferred language. Every label and message arrives in it.
TaxbitQuestionnaire(
    questionnaire: "W-FORM",
    config: QuestionnaireConfig(
        fatca: true,
        treatyClaims: true,
        typesOfIncome: ["INTEREST", "DIVIDENDS"],
        language: "fr"
    )
)

Match your brand

Pass a theme in config to set colors and shapes. Anything you leave out uses the default. Spacing and type follow the platform.

let brandTheme = QuestionnaireTheme(
    accent: .brandOrange,            // primary button
    accentForeground: .black,        // text on the primary button
    selection: .black,               // selected option, checkboxes
    focus: .brandOrange,             // focused field outline
    fieldBackground: .gray.opacity(0.1),
    fieldCornerRadius: 16,
    buttonCornerRadius: 28,
    showsOptionIndicator: false      // option cards without radio circles
)

TaxbitQuestionnaire(
    questionnaire: "W-FORM",
    config: QuestionnaireConfig(theme: brandTheme)
)
Theme optionWhat it controls
accent, accentForegroundThe primary button and its text
selectionThe selected option and checkbox fill
focusThe outline around the field being edited
fieldBackground, fieldBorder, fieldCornerRadiusText boxes, dropdowns and option cards
cardBackgroundThe box behind certification statements
buttonCornerRadiusButton shape
showsOptionIndicatorWhether options show a radio circle
text, secondaryText, errorBody text, supporting text and error messages

Choose how it pages

granularity sets how many questions appear on each screen:

granularityWhat the user sees
step (default)One step per screen, for example all contact details together
unitOne question per screen. Related fields, like the parts of an address, stay together.
phaseOne screen per part of the form: classification, then details, then signing
allEverything on one scrolling screen, then a second screen to review and sign
TaxbitQuestionnaire(
    questionnaire: "W-FORM",
    config: QuestionnaireConfig(granularity: .unit)
)

The questions and rules are the same at every granularity. Only the paging changes.

Pre-fill what you know

If you already have some of the person's information, pass it in data. The questionnaire opens with those fields filled in, on the first screen that still needs something from the user:

TaxbitQuestionnaire(
    questionnaire: "W-9",
    data: [
        "account_holder.name": "Robert Smith",
        "account_holder.address.country": "US"
    ]
)

Pre-filled answers are checked just like typed ones, and the user can still change them unless you lock them.

Ask only some questions

Sometimes you only need part of a form. Three options in config cover the common cases:

OptionWhat it doesAccepts
skipLeaves these questions out. Their answers come from data.classification, name, address, tin, dbaName
lockShows these answers read-only.name, address, tin
collectAsks only these.residencies, certification

A skipped question also drops its row from the review screen. skip wins over collect.

Two common cases:

  • Review and sign. You already have the person's W-9 details. Lock them and ask only for the signature:

    TaxbitQuestionnaire(
        questionnaire: "W-9",
        data: knownDetails,
        config: QuestionnaireConfig(
            lock: [.name, .address, .tin],
            collect: [.certification]
        )
    )
  • Residencies only. You only need tax residencies for a self-certification: collect: [.residencies].

If a skipped or locked answer is missing or invalid, the questionnaire asks the user for it anyway, as an editable field, so the form can still be completed. Set skipInvalid: true to keep it hidden instead. The form then can't be completed until your app fixes that answer, so the questionnaire hands the answers back without storing anything.

📘

Show what people sign

If a user is certifying a form, show them the information they're certifying, even if they can't change it. Use lock rather than skip for anything on the signed form.

Use your own components

If the theme and paging aren't enough, replace any field with your own component through components in config. Name the field by its key, for example account_holder.name. Your component gets the same field data the questionnaire uses (see Under the hood): the label, the options, any errors, and a way to set the answer. Taxbit still decides the questions, and you decide how they look.

You can also replace the screen around the questions: the title, the progress indicator and the Next and Back buttons.

TaxbitQuestionnaire(
    questionnaire: "W-9",
    config: QuestionnaireConfig(
        components: ["account_holder.name": MyNameField.self]
    )
)

Authentication

Every request to Taxbit needs a short-lived token for the user filling in the form. In production, your server creates that token, never your app. How your app passes the token to the questionnaire is being finalized.

Requests can go to Taxbit's US or EU region, or through your own proxy, the same as with the Taxbit React SDK.

❗️

Keep your secret on your server

Your Taxbit client secret never goes into your app. Your app only receives the short-lived token from your server.

Development status

Nothing is published yet. Every item below refers to the prototype or to planned work.

Working in the prototypeIn developmentPlanned
W-9 on iOS, from start to finishW-8BEN-E and W-8IMYAndroid (Kotlin)
W-8BEN on iOSFATCA and treaty questions on iOSHow it's delivered on each platform
W-forms and self-certification on the webDPSHow teams get access, including sandbox and production
Themes and pagingReact Native
Pre-filling, skipping and locking answersFinal names for the Swift options
Replacing individual fields (iOS and web)
Translated text

Interested?

If native collection sounds like a fit, reach out to your Taxbit contact. We'd love to hear which platforms, forms and customizations matter most to you.