Identity verification

Three providers, one onboarding flow. The most common technical-buyer question is "who actually holds the KYC data?" — this page answers it.

The matrix

| Check | Provider | Triggered when | What they see | |---|---|---|---| | Business KYB | Banking partner | Workspace creation → submitKybAction() | Legal name, EIN, formation date, beneficial owners, control persons | | KYC of beneficial owners | Banking partner (bundled) | Same form as KYB | Each owner: name, DOB, SSN last 4, address, ownership % | | Cardholder verification (business cards) | Issuing partner | POST /api/cardholders | Accepts bank-verified control persons OR re-verifies via issuing partner KYC | | Standalone consumer KYC | Persona | /onboarding/personalcreateInquiry() | Government ID + selfie + liveness + watchlist check | | OFAC / sanctions | Banking partner + Persona at onboarding; we re-screen nightly | Continuous | Match against OFAC SDN, EU consolidated, UN sanctions | | Travel Rule (crypto >$3k) | Issuing partner | Per intl-payment / offramp >$3k | Originator + beneficiary info exchange per FATF Recommendation 16 |

Why three providers, not one

Our banking partner verifies businesses but requires a business entity — it can't verify a consumer who doesn't have one.

Our issuing partner verifies cardholders but expects either bank-style business context OR an external KYC token (we use Persona's).

Persona verifies individuals standalone — ID + selfie + liveness — which is the only path that fits Phase D (consumer self-custody card with no business attached).

Soren Pay's role

We orchestrate. We never store:

  • Raw government IDs (Persona holds these)
  • SSNs / DOBs of beneficial owners (our banking partner holds these in their KYB tool)
  • Card PANs (our issuing partner's PCI-scope iframe)

We do store:

  • The provider case ID (kyb_records.provider_case_id, kyc_records.provider_inquiry_id)
  • The decision outcome (kyb_status, personal_accounts.status)
  • The hashed reference to fetch from the provider's tool

Data retention

| Data | Storage | Retention | |---|---|---| | KYB documents | Banking partner's tool | 5 yr after account closure (banking partner policy) | | KYC documents | Persona's tool | 5 yr (Persona policy) | | KYB decision + provider_case_id | Soren Pay Postgres | 7 yr (BSA) | | Ledger entries | Soren Pay Postgres | 7 yr (BSA) | | Auth logs | Soren Pay Postgres | 2 yr (operational) | | Card PANs | Never stored | N/A |

Subject access requests / data deletion

GDPR / CCPA: email privacy@sorenpay.com with the user's email or workspace id. We'll fetch from each provider on request.

Note: regulatory records (ledger, KYB decisions) cannot be deleted within the retention window per BSA. We can delete UI-layer cached PII but not the regulated records.

OFAC re-screening

Background cron (nightly): we re-screen every active workspace + personal account against the latest OFAC SDN diff. Hits → workspace/account freezes

  • alert to compliance@sorenpay.com.

Travel Rule

For crypto transfers > $3,000 USD equivalent (off-ramp or international payment), our issuing partner exchanges originator + beneficiary information per FATF guidance. Transparent to your API call — you don't pass anything extra.

Audit trail

Every state transition (KYB pending → approved, KYC submitted → declined, OFAC hit → frozen) is logged in auth_audit_chain with a SHA-256 hash chained to the previous entry. Tampering breaks the chain.

Related