One verification. Selected services.
Implement unified CDD onboarding and the Banking customer controls in your Flutter app, using the existing admin settings.
This is an app implementation guide, not a change to every public API integration. The example backend owns /api/v1/mobile; keep company credentials there. Existing public API KYC contracts remain available. The dedicated upstream mobile-onboarding flow is explicit opt-in and is not part of the general published OpenAPI catalogue.
Read the implementation checklist ↗ · Browse the current Flutter and C# source
Choose services at registration
Crypto cards remain included. Offer Banking and Exchange only when enabled for the installation. Card-only customers keep the established flow. Selecting Banking or Exchange uses one CDD verification, including proof of address, and the server submits only the selected services plus Crypto cards. Identity approval and provider approval are separate states.
Resume the saved application
Keep the CDD applicant, questionnaire and service selection on the server. Resume missing questions or provider progress instead of sending the customer back to the old proof-of-address upload. Reuse the CDD identity and address evidence, preserve the Banking questionnaire and future card-use answers, and display queued or uncertain submissions as in progress. Do not invite duplicate submissions. Exchange submission is disabled in staging when the provider has no staging environment.
Invites, tiers and onboarding payment
Read the current onboarding requirements. Support requesting an invite, showing pending approval, redeeming the issued code and continuing after admin approval. Read tier and Stripe checkout requirements from the server. A checkout redirect is not payment confirmation: reload authoritative state and retain explicit payment-terms acceptance.
Use the existing admin legal settings
Configure the app backend with the tenant’s DashboardBrandingUrl, DashboardBrandingDomain and DashboardCompanyId. The returned entry must be active, default and owned by that company. The UI and acceptance checks use the same resolved documents. Terms and Privacy have separate controls. Each opens in a dialog and requires reaching the bottom before review confirmation; review does not itself accept the agreement. Document failures and version changes keep acceptance blocked. The existing-customer agreement gate has its own navigator so dialogs work above the app router.
Payee checks and payment confirmation
Show the full returned name-check result and returned account name when provided. Keep acknowledgement distinct from a match and follow the server’s validation. Display quoted fees and total debit before approval, with trusted-payee wording. Email OTP remains the configured method for email approval flows; align the engine and email template so the delivered message contains the same transaction facts. Preserve existing device/passkey approval methods where configured.
Fees, safeguarding and complaints
Help & Legal provides the assigned Banking fee schedule, legal documents, safeguarding information and complaints. Fees come from the customer’s assigned tier, with transaction quotes authoritative for each payment. A submitted complaint creates its support record and forwarding job together. Administrators can inspect and retry delivery. Production dispatches through the configured email service; staging holds forwarding for review. Queued is not delivered.
Record and review the evidence
The example repository includes scripts/evidence/evidence.py, a requirement catalogue and a reusable Codex scenario. Use the brand profile, synthetic staging accounts and the actual release revision. Record happy and unhappy paths, import message/device records where needed, and produce an index with timestamps and SHA-256 hashes. The index shows missing cases and does not claim approval. Confirm retention periods, marketing disclosures, delivered OTPs, payee-result variants and complaint delivery. Email OTP alone is not proof of a separate stronger-authentication requirement. Explicitly record excluded or deferred cases.
Backend routes used by the app
These routes are hosted by your app backend, not by the public Hoppa API. The authenticated backend resolves customer and company ownership.
GET /api/v1/mobile/config— installation capabilities and legal settings.GET /api/v1/mobile/onboarding/cdd/preferences— saved service selection.GET /api/v1/mobile/onboarding/cdd— saved application and provider status.POST /api/v1/mobile/onboarding/cdd/session— start or resume CDD.PUT /api/v1/mobile/onboarding/cdd/answers— save the questionnaire.POST /api/v1/mobile/onboarding/cdd/submit— submit selected services.GET /api/v1/mobile/onboarding/requirements— invitation, tier and payment requirements.GET /api/v1/mobile/agreements/equals/status— current document acceptance.POST /api/v1/mobile/complaints— record a complaint and queue forwarding.
Deploy the compatible engine API and worker before enabling the new app release. Keep server-owned credentials, provider settings and database connections outside app commits. Builds and automated checks do not substitute for programme review or recorded evidence.