Skip to content
GitLab
Projects Groups Topics Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Register
  • Sign in
  • A Ahad Mobile
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributor statistics
    • Graph
    • Compare revisions
  • Issues 0
    • Issues 0
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Terraform modules
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • holatech
  • Ahad Mobile
  • Merge requests
  • !108

fix(fiat-payout): take beneficiary first and last name from the typed holder name

  • Review changes

  • Download
  • Patches
  • Plain diff
Merged Khanh Pham requested to merge fix/fiat-payout-beneficiary-name into develop Oct 08, 2026
  • Overview 0
  • Commits 3
  • Pipelines 1
  • Changes 12

Why

The Airwallex PERSONAL beneficiary was created with account_name set to the holder name the user typed, but first_name/last_name taken from KYC. If the user typed a different holder name, Airwallex got a beneficiary whose first and last name contradicted its account name.

What

  • BE:
    • splitHolderName derives the first and last name from the typed holder name: the last word is the last name, and the rest is the first name.
    • KYC is still loaded. It gates on an approved KYC and supplies the address and country.
    • CreateBankBeneficiaryDto.accountName now needs at least two words, and the last word must contain a letter. Otherwise it returns 400 accountName must include a first and last name.
    • The split runs before the provider call, outside the try that maps errors to PAYOUT_UNAVAILABLE.
  • FE:
    • The add-bank screen enforces the same rule, with the same regex as the BE and an i18n error message. The holder field is still prefilled with the KYC name and can be edited.
    • The Checking/Savings pills are now a proper radio group: radiogroup container, radio + accessibilityState.checked.
  • No migration, no new column, and no change to the API shape beyond the stricter validation.

Tests

  • BE: yarn jest src/modules/fiat-payout passes (223 tests). yarn build and eslint are clean.
  • FE: pnpm jest src/components/withdraw src/utils passes (112 tests). tsc and eslint are clean.
  • Every new assertion is mutation-checked, including the edge cases "Ada Lovelace ." (rejected) and "Ada . Lovelace" (accepted) on both sides.

Opus review gate: PASS after 2 rounds. Round 1 raised 1 should-fix (an unanchored two-word regex let a junk last name such as "-" through), which is fixed.

Parked, not fixed here:

  • A generational suffix becomes the last name, for example "John Smith Jr." gives last name Jr.. Whether to special-case it is a product decision.
  • VerifiedName.firstName/lastName/fullName are no longer read in production, but loadVerifiedName still raises KYC_NAME_MISSING. Clean this up later.
  • The doc comment on hasFirstAndLastName (fe/src/utils/bank-account-name.ts:11) overstates what it checks on its own.

Also related: staging now charges a payout fee of FIAT_PAYOUT_FEE_USD=3.00 (Airwallex charges $3 per transfer). This is env only, with no code change.

🤖 Generated with Claude Code

Assignee
Assign to
Reviewers
Request review from
Time tracking
Source branch: fix/fiat-payout-beneficiary-name