Files
sxchnge/docs/identity-verification.md
T

6.9 KiB
Raw Blame History

Customer identity verification

Task SXCHNGE #48, following sign-up Facts intake. Platform implementation: Sendico #2885.

Customer flow

Sign-up still creates a basic account and submits its initial name/email/customer reference as immutable facts. Email verification and login remain independent of identity proof collection. After the first authenticated login in an app session, an unverified customer is offered verification and can choose Keep basic limits. An unavailable optional identity dependency does not prevent login. Accounts → Identity verification, Limits, and the existing identity navigation let the customer return later.

The customer supplies their full legal name, date of birth (YYYY-MM-DD), country of residence, an ID document photo and a selfie holding that same document. The backend supplies the authenticated customer's email and reference. The client cannot choose a platform subject, organization, source principal, review status or limits profile. JPEG/PNG photos must decode, be at least 600×600, at most 40 megapixels and no larger than 10 MiB each. Sendico also enforces its existing configured evidence cap, MIME/extension rules and submission rate limits.

Unsent fields and photos stay in memory, survive retryable errors and are cleared on successful submission, discard or page disposal. Previews leave Flutter's image cache on exit/replacement. Profile edits or photo replacements create a new request key; unchanged retries retain their key. Draft loss requires an explicit discard choice. No sensitive extras enter browser history or analytics.

A successful submission means pending staff review. Corrections permit a new submission; rejection retains basic access and the existing support route. A recorded approval with an unfinished limits assignment is shown as Limits upgrade pending, rather than verified. Refresh fetches the real reviewed state and the authoritative limits. Production uses no simulated KYC review controls or illustrative limit amounts. Demo mode remains separately simulated.

Boundaries and contracts

The authenticated local routes are GET/POST /accounts/identity and GET /accounts/limits, under the configured API mount. Multipart POST fields are profile (JSON), document, selfie, and idempotencyKey. A customer ID is always resolved from the full authenticated session. Pending-login tokens do not provide account access. Browser and native requests both carry the access token; browser refresh cookies remain an auth concern.

The existing signup_facts binding resolves each local customer to one independent Sendico subject. A conditional unique (namespace, subjectRef) index prevents binding the same provider subject to two customers. Empty registration claims are excluded. Existing duplicates cause bootstrap to fail and require controlled reconciliation; the application never guesses a replacement subject. Credential rotation must retain the configured source account.

The Sendico adapter exclusively uses public HTTP:

  • GET/POST /identity_facts/{organization}/proofs/{subject};
  • GET /identity_facts/{organization}/proofs/{subject}/limits.

Adapter DTOs and mappers remain separate from local models and local HTTP DTOs. There are no Sendico database, gRPC, bus or sibling-module imports in SXCHNGE. Provider organization/source settings remain in the adapter configuration. Uploads have a bounded 60-second upstream timeout and redirects are rejected. Upstream error bodies and photo bytes are never logged. Rate-limit responses retain typed recovery. Registration's existing non-idempotent reconciliation rules are unchanged.

Visible policy entries retain exact decimal strings, currency, group labels and per-operation minimum/maximum, day and month slots. Usage is not invented for per-operation slots. The backend owns the effective policy and remaining capacity. The existing wallet remains a simulated service; this contribution connects identity and visible limits, not real money movement. Future money adapters must use the platform-owned customer account resource and authoritative Limits reservation path, not a browser-selected policy or displayed balance.

Review and rollout

Staff work in the existing Sendico backoffice → KYC → Identity proof review. The platform stores private proofs, immutable profile assertions, review history and the reviewed limits assignment. See the platform's docs/customer-identity-proofs.md for authorization, retry and retention details.

Deploy Sendico Product/provider, Backoffice, Limits and backoffice frontend changes together before enabling the new SXCHNGE frontend/backend adapters. Existing api.sendico settings are reused. The integration account needs organization read/update access. The platform's existing evidence/storage, cleanup, discovery and limits configuration must be provisioned. Its ACCOUNT default for SXCHNGE must be the existing unverified profile, and the existing verified profile and personal-account visible view must be active. No new runtime configuration parameters or live submissions are introduced by this work.

Merge SXCHNGE sign-up Facts PR #47 before this task's branch. Deploy the Sendico identity-proofs PR before using this flow. The platform change reuses the Limits assignment contract being developed in Sendico #2884; its PR documents the shared scope and merge order. No merge or deployment is automatic.

UX, measurement and validation

Existing KYC journey events measure preparation, selection, accepted submission, status reads, retries, abandonment and latency. Profile contents, filenames, photo bytes and credentials are excluded. Submission success is an intake outcome, not proof of approval. Pending asynchronous staff review is not counted as customer abandonment. A resumed route starts a new client attempt; immutable submission IDs deduplicate backend business outcomes.

Authoritative completion is the staff decision plus the Limits assignment receipt for that submission. Backend IDs correlate these records without becoming metric labels. Existing identity request counters/histograms distinguish accepted, invalid, denied, conflict, rate-limited and unavailable operations and include actual authorization/I/O duration. Client analytics still defaults to the existing in-memory sink; retained cross-device analytics depends on deployment.

Review covers optional onboarding, later account navigation, editable profile, readable ID/selfie guidance, disabled actions, error/session recovery, input preservation, correction/rejection/pending/approval, exact monetary presentation, EN/RU at narrow widths and large text, keyboard access and private-image cache eviction. Tests use synthetic data, local HTTP servers and disposable MongoDB. No live ID documents, live email, production review or deployment were exercised. Full validation commands and final PR links are recorded in implementation.md and the task.