Skip to content

[Ready] Fix Alfredpay KYB flow and other miscellaneous changes for dashboard.#1271

Open
gianfra-t wants to merge 9 commits into
stagingfrom
fix-alfred-kyb-flo
Open

[Ready] Fix Alfredpay KYB flow and other miscellaneous changes for dashboard.#1271
gianfra-t wants to merge 9 commits into
stagingfrom
fix-alfred-kyb-flo

Conversation

@gianfra-t

Copy link
Copy Markdown
Contributor

No description provided.

gianfra-t and others added 3 commits July 16, 2026 12:31
…s Alfredpay requires

The KYB corridor had no contract coverage at all: every KYB fixture in the repo was
asserted only against mocks we wrote from types we also wrote, so nothing had ever met
the provider. Running the real sequence against the sandbox found that Alfredpay's KYB
requirements had expanded without us noticing — sendKybSubmission rejects our payload
with 110002 "Invalid field(s)", naming nine compliance questionnaire fields plus a
fourth company document. No company KYB can be finalized today.

Alfredpay self-describes the per-country set at GET …/penny/kybRequirements?country=
(MEX and MX both resolve). Its required list matches the 110002 rejection exactly. The
questionnaire is sent flat and stored nested under `questionnaire`; the shareholder
registry uploads as fileType `shareholderRegistry` (undocumented — found by probing,
the other spellings 422). `pep` is required for CO/US/AR but not MX.

- AlfredpayKybQuestionnaire on SubmitKybInformationRequest, and SHAREHOLDER_REGISTRY on
  AlfredpayKybFileType. The questionnaire fields are optional only because the KYB form
  does not collect them yet; making them required would force either invented compliance
  answers or a form demanding inputs it lacks. The gap is documented and the live flow
  test is what covers it — the compiler will not.
- alfredpayKybBusinessDetailsResponseSchema pins submissionId + relatedPersons[]
  .idRelatedPerson, the pair the document uploads key off.
- Live details read against a fully populated sandbox company, and an opt-in
  (ALFREDPAY_CONTRACT_RUN_KYB_FLOW=1) end-to-end flow: every call is accepted and every
  shape holds. The submission is then FAILED by sandbox verification within ~30s because
  the uploads are blank placeholder images, which is the correct outcome for fake
  documents — noted in the test so nobody chases it.
- Security spec: the requirement set, the conditional branches, the pep corridor delta,
  and the known UI gap.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@netlify

netlify Bot commented Jul 16, 2026

Copy link
Copy Markdown

Deploy Preview for vrtx-dashboard canceled.

Name Link
🔨 Latest commit e9a09e1
🔍 Latest deploy log https://app.netlify.com/projects/vrtx-dashboard/deploys/6a5a9e2fefe179000841a06b

@netlify

netlify Bot commented Jul 16, 2026

Copy link
Copy Markdown

Deploy Preview for vortex-sandbox ready!

Name Link
🔨 Latest commit e9a09e1
🔍 Latest deploy log https://app.netlify.com/projects/vortex-sandbox/deploys/6a5a9e2f41815d00072e4f24
😎 Deploy Preview https://deploy-preview-1271--vortex-sandbox.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@gianfra-t gianfra-t changed the title [WIP] Fix Alfredpay KYB flow and other miscellaneous fixes. [WIP] Fix Alfredpay KYB flow and other miscellaneous changes for dashboard. Jul 16, 2026
@netlify

netlify Bot commented Jul 16, 2026

Copy link
Copy Markdown

Deploy Preview for vortexfi ready!

Name Link
🔨 Latest commit e9a09e1
🔍 Latest deploy log https://app.netlify.com/projects/vortexfi/deploys/6a5a9e2f3a3b6000084659be
😎 Deploy Preview https://deploy-preview-1271--vortexfi.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

gianfra-t and others added 4 commits July 16, 2026 17:54
… provider requires

Alfredpay's KYB requirement set had grown past what the form asked for, so no company
KYB could be finalized through the widget or dashboard: sendKybSubmission rejected every
submission with 110002 naming nine questionnaire fields and the shareholder registry.
Nothing caught it because every KYB fixture was a mock written from types we also wrote.

GET .../penny/kybRequirements?country= self-describes the set, and it is the source of
truth here. The questionnaire goes on a new screen between the company form and the
uploads (FillingKybQuestionnaire), is sent flat alongside the company fields, and is
stored by Alfredpay nested under `questionnaire`. Two conditionals mirror the provider's:
transmitsCustomerFunds reveals the compliance-screening pair, isRegulatedBusiness reveals
the business licence and AML policy documents. `pep` is required for CO/US/AR but not MX
— the only field that differs by corridor, so the form always asks it.

The wire type keeps the questionnaire required and the machine splits the form data so
back-navigation restores what was entered. submitKybInformation validates the
questionnaire and its conditionals server-side, so a client that omits them is rejected
with 400 rather than reaching Alfredpay.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s KYB

Company KYB failed for real users at the representative's ID upload with a bare
`{"errorCode":111301,"errorMessage":"UNKNOWN_ERROR"}` that names no field. The cause is
the filename: Alfredpay's relate-person endpoint answers any non-ASCII byte in the
multipart filename with a 502, and macOS separates the time from AM/PM with U+202F — so
`Screenshot ... at 12.23.56 PM.png` is rejected while the same name retyped with an
ordinary space is accepted. Accented names ("Identificación oficial.png") fail the same
way. Verified against the sandbox on the customer and related person from the production
log: the failing call succeeds with a blank.png, and every size, mime type and ASCII name
tested passes. The company-document endpoint next door accepts these names, which is why
only this one step broke.

Alfredpay stores every upload under a generated {uuid}.{ext}, so the submitted name is
discarded on arrival and rewriting it loses nothing. Applied to all three uploads.

The sanitizer copies the bytes into a new File, which is load-bearing: under Bun,
new File([file], name), new Blob([file]) and FormData.append(field, file, name) all alias
or ignore their way back to the original name. The first attempt used append's filename
argument and passed against the live sandbox while doing nothing; the test asserts the
name that reaches the wire, which is what caught it.

The contract test never saw this because it sent "blank.png" — faithful to every part of
the flow except the one thing a real user controls. It now drives the flow with the
production filename.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…splays

The link text was updated to support@vortexfinance.co but the href still opened
support@vortex.co, so clicking it mailed the old address.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gianfra-t gianfra-t changed the title [WIP] Fix Alfredpay KYB flow and other miscellaneous changes for dashboard. [Ready] Fix Alfredpay KYB flow and other miscellaneous changes for dashboard. Jul 17, 2026
@ebma
ebma requested a review from Copilot July 17, 2026 14:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Alfredpay KYB flow end-to-end (shared types/schemas, API validation, XState machine, widget + dashboard UI, and tests/spec) to match Alfredpay’s provider-defined requirements, fix related-person upload targeting, and harden file uploads against provider failures caused by non-ASCII multipart filenames.

Changes:

  • Align KYB submission payload with Alfredpay’s kybRequirements contract by adding the compliance questionnaire fields and additional required/conditional KYB documents.
  • Fix KYB representative document uploads by selecting idRelatedPerson for the current submissionId (avoids stale-business related-person IDs).
  • Sanitize upload filenames to ASCII before sending multipart requests to Alfredpay, with unit/contract/e2e test coverage and security-spec updates.

Reviewed changes

Copilot reviewed 33 out of 33 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/shared/src/services/alfredpay/types.ts Extends KYB file types and introduces questionnaire typing to match provider requirements.
packages/shared/src/services/alfredpay/schemas.ts Adds zod schema for KYB business details response including submissionId + idRelatedPerson.
packages/shared/src/services/alfredpay/alfredpayApiService.ts Sanitizes multipart filenames by rebuilding uploads with ASCII-safe names.
packages/shared/src/services/alfredpay/alfredpayApiService.test.ts Adds tests asserting the filename that actually reaches fetch is ASCII-sanitized.
packages/kyc/src/index.ts Re-exports new KYB questionnaire schema/types and mapping helpers.
packages/kyc/src/alfredpay/types.ts Splits KYB data into form vs questionnaire; adds new required/conditional document fields.
packages/kyc/src/alfredpay/schemas.ts Adds KYB questionnaire schema and mapping helpers for two-step KYB collection.
packages/kyc/src/alfredpay/schemas.test.ts Adds tests for questionnaire requiredIf logic and mapping behavior.
packages/kyc/src/alfredpay/machine.ts Adds questionnaire step, merges payload at submit, uploads new docs, filters related persons by submissionId.
packages/kyc/src/alfredpay/machine.test.ts Expands unit coverage and adds “recording API” tests for payload merge + uploaded document set.
docs/security-spec/05-integrations/alfredpay.md Updates Alfredpay KYB invariants and requirements, including filename sanitization and submissionId-related-person selection.
apps/frontend/src/translations/pt.json Adds KYB questionnaire + document labels in Portuguese.
apps/frontend/src/translations/en.json Adds KYB questionnaire + document labels in English.
apps/frontend/src/components/Alfredpay/KybQuestionnaireScreen.tsx New widget questionnaire step UI wired to kybQuestionnaireSchema/mapping.
apps/frontend/src/components/Alfredpay/KybFormScreen.tsx Adds repPep field and repopulation support when navigating back.
apps/frontend/src/components/Alfredpay/KybBusinessDocsScreen.tsx Adds shareholder registry + conditional regulated-business docs.
apps/frontend/src/components/Alfredpay/AlfredpayKycFlow.tsx Wires the new questionnaire step into the widget KYB flow.
apps/dashboard/src/components/transfer/TransferForm.tsx Simplifies FundingMethods usage (removes network label prop).
apps/dashboard/src/components/transfer/FundingMethods.tsx Gates funding UI to “connect wallet only” and removes crypto-tab functionality.
apps/dashboard/src/components/recipients/RecipientsTable.tsx Adjusts focus-visible class ordering on recipient row.
apps/dashboard/src/components/onboarding/alfredpay/KybQuestionnaireScreen.tsx New dashboard questionnaire step UI using shared schema/mapping.
apps/dashboard/src/components/onboarding/alfredpay/KybFormScreen.tsx Adds repPep and supports repopulating form values when navigating back.
apps/dashboard/src/components/onboarding/alfredpay/KybDocumentUploadScreen.tsx Adds shareholder registry + conditional regulated-business docs and updates required file counts.
apps/dashboard/src/components/onboarding/alfredpay/AlfredpayKycFlow.tsx Wires dashboard questionnaire step into onboarding flow.
apps/dashboard/e2e/transfer-mxn-journey.spec.ts Skips transfer journeys while FundingMethods submit is gated off.
apps/dashboard/e2e/support/mockBackend.ts Tracks KYB upload fileType values and returns submissionId in KYB details mock.
apps/dashboard/e2e/onboarding-alfredpay-mxn-kyb.spec.ts Updates e2e to fill questionnaire and assert correct upload types/counts.
apps/dashboard/e2e/funding-gate.spec.ts Adds e2e asserting the funding UI gate (no crypto tab / no submit button).
apps/api/src/tests/contracts/alfredpay.contract.test.ts Adds live KYB details contract and an opt-in end-to-end KYB sandbox flow.
apps/api/src/tests/alfredpay-kyb-pending.integration.test.ts Updates fixtures for questionnaire fields and adds validator tests + submissionId assertion.
apps/api/src/api/routes/v1/alfredpay.route.ts Adds validateKybSubmission middleware to KYB submit route.
apps/api/src/api/middlewares/validators.ts Implements validateKybSubmission enforcing questionnaire + conditional rules pre-provider.
apps/api/src/api/controllers/alfredpay.controller.ts Includes submissionId in minimized KYB details response for clients.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +98 to +99
expectedMonthlyTransactions: z.number("Enter a number").int("Enter a whole number").min(0),
expectedMonthlyVolumeUsd: z.number("Enter a number").min(0),
Comment on lines +60 to +62
* Alfredpay's relate-person upload rejects any non-ASCII byte in the multipart filename with a
* bare 500 `{"errorCode":111301,"errorMessage":"UNKNOWN_ERROR"}`. Verified against the sandbox:
* `ñandú.png` and `acentuación.png` fail while `with space.png`, `parens(1).png` and
Comment on lines +215 to +216
<button className="btn btn-vortex-accent w-full" onClick={onBack} type="button">
{t("components.alfredpayKycFlow.cancel")}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants