[READY] Feature: Alfredpay Fiat Accounts#1088
[READY] Feature: Alfredpay Fiat Accounts#1088Sharqiewicz wants to merge 52 commits intoadd-alfredpay-supportfrom
Conversation
✅ Deploy Preview for vortex-sandbox ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for vortexfi ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
…t Method is selected
There was a problem hiding this comment.
Pull request overview
This PR adds Alfredpay-specific fiat account management and expands fiat token support (USD/MXN/COP), wiring the selected fiat account into the ramp execution flow and updating UI flows (Summary/KYC) accordingly.
Changes:
- Extend shared token + payment method definitions to include MXN/COP and Alfredpay fiat account types/endpoints.
- Add a new frontend fiat-account registration + selection UX (XState machine, hooks, API service, SummaryStep integration).
- Refactor Alfredpay KYC UI into composable screens and introduce new UI primitives (AlertBanner, Checkbox, MaskedAccountNumber, Select, etc.) plus styling/translation updates.
Reviewed changes
Copilot reviewed 82 out of 95 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/shared/src/tokens/types/base.ts | Adds MXN/COP to FiatToken enum. |
| packages/shared/src/tokens/freeTokens/config.ts | Updates USD decimals; adds free-token configs for MXN/COP. |
| packages/shared/src/services/alfredpay/types.ts | Adds fiat account types + isAlfredpayToken helper. |
| packages/shared/src/helpers/payment-method-mapper.ts | Adds shared mapFiatToDestination mapping for fiat tokens. |
| packages/shared/src/endpoints/payment-methods.endpoints.ts | Adds SPEI/WIRE payment methods. |
| packages/shared/src/endpoints/alfredpay.endpoints.ts | Adds Alfredpay fiat accounts + requirements endpoint request/response types. |
| apps/frontend/src/types/phases.ts | Adds selectedFiatAccountId to RampExecutionInput. |
| apps/frontend/src/translations/pt.json | Updates existing strings; adds Alfredpay fiat-account strings in PT. |
| apps/frontend/src/translations/en.json | Updates existing strings; adds Alfredpay fiat-account strings in EN. |
| apps/frontend/src/stories/providers/MockProviders.tsx | Wraps Storybook stories with a TanStack Router provider. |
| apps/frontend/src/stories/MaskedAccountNumber.stories.tsx | Adds Storybook coverage for MaskedAccountNumber. |
| apps/frontend/src/stories/AlertBanner.stories.tsx | Adds Storybook coverage for AlertBanner. |
| apps/frontend/src/stores/quote/useQuoteStore.ts | Removes local mapFiatToDestination in favor of shared helper import. |
| apps/frontend/src/stores/quote/useQuoteFormStore.ts | Adds default amounts for USD/MXN/COP. |
| apps/frontend/src/services/api/alfredpay.service.ts | Adds API methods for fiat accounts CRUD + requirements + listing. |
| apps/frontend/src/sections/business/WhyVortexApi/index.tsx | Updates video asset path. |
| apps/frontend/src/pages/widget/index.tsx | Adds FiatAccountMachineContext.Provider + conditional fiat account registration routing. |
| apps/frontend/src/pages/success/index.tsx | Adds MXN/COP success arrival-text mapping. |
| apps/frontend/src/pages/alfredpay/FiatAccountRegistration/index.tsx | Introduces the Alfredpay fiat account registration page/controller component. |
| apps/frontend/src/pages/alfredpay/FiatAccountRegistration/RemoveAccountControls.tsx | Adds hold-to-remove UX for deleting a fiat account. |
| apps/frontend/src/pages/alfredpay/FiatAccountRegistration/RegisteredAccountsList.tsx | Adds list view for registered accounts, skeleton, and KYC gating. |
| apps/frontend/src/pages/alfredpay/FiatAccountRegistration/RegisterFiatAccountScreen.tsx | Adds dynamic RHF+Zod registration form and submission logic. |
| apps/frontend/src/pages/alfredpay/FiatAccountRegistration/KycRequiredBanner.tsx | Adds banner prompting KYC completion before adding accounts. |
| apps/frontend/src/pages/alfredpay/FiatAccountRegistration/CardHeader.tsx | Adds reusable card header for account cards. |
| apps/frontend/src/pages/alfredpay/FiatAccountRegistration/AccountTypePickerScreen.tsx | Adds payment-method picker UI for account type. |
| apps/frontend/src/pages/alfredpay/FiatAccountRegistration/AccountCardSkeleton.tsx | Adds skeleton loader for the account card deck. |
| apps/frontend/src/pages/alfredpay/FiatAccountRegistration/AccountCardDeck.tsx | Adds animated stacked card deck for account selection/removal. |
| apps/frontend/src/machines/ramp.machine.ts | Carries selectedFiatAccountId into executionInput on proceed-to-registration. |
| apps/frontend/src/machines/fiatAccount.machine.ts | Adds new XState v5 machine for fiat account selection/registration navigation. |
| apps/frontend/src/machines/alfredpayKyc.machine.ts | Adjusts Alfredpay KYC machine to add a VerificationDone step. |
| apps/frontend/src/machines/actors/validateKyc.actor.ts | Uses isAlfredpayToken to decide when KYC is needed. |
| apps/frontend/src/machines/actors/register.actor.ts | Sends fiatAccountId for Alfredpay registrations via selectedFiatAccountId. |
| apps/frontend/src/hooks/useStepper.ts | Marks stepper steps as error when Alfredpay KYC subflow is in failure state. |
| apps/frontend/src/hooks/useStepBackNavigation.ts | Adds “back” handling for the fiat account registration subflow. |
| apps/frontend/src/hooks/useRampUrlParams.ts | Uses shared mapFiatToDestination (removes local copy). |
| apps/frontend/src/hooks/useOnchainTokenBalances.ts | Minor comment/punctuation tweak. |
| apps/frontend/src/hooks/useGetAssetIcon.tsx | Adds icon mapping for COP/MXN/USD; updates EUR asset import. |
| apps/frontend/src/hooks/alfredpay/useFiatAccounts.ts | Adds React Query hooks for listing/adding/deleting fiat accounts. |
| apps/frontend/src/contexts/FiatAccountMachineContext.tsx | Adds actor context wiring for the fiat account machine. |
| apps/frontend/src/constants/fiatAccountMethods.ts | Defines country/method configs and mapping helpers for fiat account methods. |
| apps/frontend/src/constants/fiatAccountForms.ts | Defines dynamic form field schemas per payment method. |
| apps/frontend/src/constants/cache.ts | Adds fiatAccounts cache key. |
| apps/frontend/src/config/tokenAvailability.ts | Adds MXN/COP token availability flags. |
| apps/frontend/src/components/widget-steps/SummaryStep/index.tsx | Adds FiatAccountSelector and replaces inline warnings with AlertBanner. |
| apps/frontend/src/components/widget-steps/SummaryStep/TransactionTokensDisplay.tsx | Adds Alfredpay homepage link resolution. |
| apps/frontend/src/components/widget-steps/SummaryStep/FiatAccountSelector.tsx | Adds dropdown selector to choose/manage registered fiat accounts. |
| apps/frontend/src/components/widget-steps/DetailsStep/index.tsx | Updates StepFooter usage after StepFooter API change. |
| apps/frontend/src/components/widget-steps/AveniaLivenessStep/index.tsx | Updates StepFooter usage after StepFooter API change. |
| apps/frontend/src/components/widget-steps/AuthOTPStep/index.tsx | Removes local quote plumbing; relies on store-backed QuoteSummary. |
| apps/frontend/src/components/widget-steps/AuthEmailStep/index.tsx | Removes local quote plumbing; relies on store-backed QuoteSummary. |
| apps/frontend/src/components/ui/select.tsx | Adds a Select component wrapper around Radix primitives. |
| apps/frontend/src/components/ui/DropdownSelector.tsx | Adds custom dropdown selector component (used for fiat account selection). |
| apps/frontend/src/components/StepFooter/index.tsx | Refactors StepFooter to read quote from store and add hideQuoteSummary. |
| apps/frontend/src/components/Spinner/index.tsx | Updates spinner “dark” theme border class. |
| apps/frontend/src/components/RampSubmitButton/RampSubmitButton.tsx | Requires selected fiat account for Alfredpay in KycComplete; passes account id into machine event. |
| apps/frontend/src/components/QuoteSummary/index.tsx | Refactors QuoteSummary to read quote from store and render null when absent. |
| apps/frontend/src/components/MaskedAccountNumber/index.tsx | Adds masked/revealable account number display component. |
| apps/frontend/src/components/ContactForm/ContactInfo.tsx | Minor Tailwind class ordering tweak. |
| apps/frontend/src/components/Checkbox/index.tsx | Adds reusable checkbox primitive. |
| apps/frontend/src/components/Avenia/DocumentUpload/index.tsx | Updates StepFooter usage after StepFooter API change. |
| apps/frontend/src/components/Avenia/AveniaVerificationForm/index.tsx | Updates StepFooter usage after StepFooter API change. |
| apps/frontend/src/components/Avenia/AveniaKYCForm.tsx | Removes local quote plumbing; relies on store-backed QuoteSummary. |
| apps/frontend/src/components/Avenia/AveniaKYBForm.tsx | Removes local quote plumbing; relies on store-backed QuoteSummary. |
| apps/frontend/src/components/Avenia/AveniaKYBFlow/AveniaKYBVerifyStep.tsx | Updates StepFooter usage after StepFooter API change. |
| apps/frontend/src/components/AnimatedRemoveFiatAccountLabel/index.tsx | Adds animated label component used in account removal controls. |
| apps/frontend/src/components/Alfredpay/PollingScreen.tsx | Adds Alfredpay KYC polling screen component. |
| apps/frontend/src/components/Alfredpay/OpeningLinkScreen.tsx | Adds Alfredpay “opening link” screen component. |
| apps/frontend/src/components/Alfredpay/LoadingScreen.tsx | Adds Alfredpay loading screen component. |
| apps/frontend/src/components/Alfredpay/LinkReadyScreen.tsx | Adds Alfredpay “link ready” screen component. |
| apps/frontend/src/components/Alfredpay/FillingScreen.tsx | Adds Alfredpay “complete in new window” screen component. |
| apps/frontend/src/components/Alfredpay/FailureScreen.tsx | Adds Alfredpay failure screen component. |
| apps/frontend/src/components/Alfredpay/FailureKycScreen.tsx | Adds Alfredpay KYC failure screen component. |
| apps/frontend/src/components/Alfredpay/DoneScreen.tsx | Adds Alfredpay done/verified screen component. |
| apps/frontend/src/components/Alfredpay/CustomerDefinitionScreen.tsx | Adds customer type selection/confirmation screen component. |
| apps/frontend/src/components/Alfredpay/AlfredpayKycFlow.tsx | Refactors flow to use new screen components and callbacks. |
| apps/frontend/src/components/AlertBanner/index.tsx | Adds reusable alert banner component. |
| apps/frontend/src/assets/exclamation_mark_error.svg | Adds error illustration asset. |
| apps/frontend/src/assets/document_verified.svg | Adds “verified” illustration asset. |
| apps/frontend/src/assets/document_ready.svg | Adds “document ready” illustration asset. |
| apps/frontend/src/assets/coins/placeholder.svg | Updates placeholder coin SVG asset. |
| apps/frontend/src/assets/coins/USD.png | Adds USD icon asset. |
| apps/frontend/src/assets/business-handshake.svg | Adds business handshake illustration asset. |
| apps/frontend/src/assets/coins/EUR.svg | Removes old EUR svg asset (replaced by EU.png in code). |
| apps/frontend/package.json | Adds radix-ui dependency. |
| apps/frontend/App.css | Adds success button variant and various button/modal style tweaks. |
| apps/api/src/api/services/sep10/sep10.service.ts | Extends token mapping to include MXN/COP (mapped to USDC). |
| apps/api/src/api/services/phases/handlers/final-settlement-subsidy.ts | Removes unused import. |
| apps/api/src/api/controllers/auth.controller.ts | Modifies token verification endpoint (currently hardcoded). |
| CLAUDE.md | Updates repo guidelines (Bun usage, XState v5 patterns, token exhaustiveness notes). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return { user_id: "4f1cf68e-831a-4314-b156-0d5c0fa93d67", valid: true }; | ||
|
|
There was a problem hiding this comment.
verifyToken returns a hardcoded { user_id, valid } object before any validation logic and without sending an HTTP response via res.json(...). This effectively bypasses auth verification (and may leave requests hanging depending on the framework wiring). Remove the early return and restore proper token verification + response handling.
| return { user_id: "4f1cf68e-831a-4314-b156-0d5c0fa93d67", valid: true }; |
| [FiatToken.USD]: { | ||
| disabledReasonTranslationKey: "pages.swap.error.USD_tokenUnavailable", | ||
| enabled: true | ||
| }, | ||
| [FiatToken.MXN]: { | ||
| disabledReasonTranslationKey: "pages.swap.error.MXN_tokenUnavailable", | ||
| enabled: false | ||
| }, | ||
| [FiatToken.COP]: { | ||
| disabledReasonTranslationKey: "pages.swap.error.COP_tokenUnavailable", | ||
| enabled: false | ||
| } |
There was a problem hiding this comment.
MXN/COP are introduced as part of this Alfredpay fiat accounts feature, but they are marked enabled: false here. This conflicts with the PR description (“enabling users… when transacting in USD, MXN and COP”) and will keep them unavailable in the UI. Either enable them or clarify/gate the rollout elsewhere and update the PR description accordingly.
| "noNewslettersNoSpam": "No newsletters, no spam- just your honest thoughts.", | ||
| "submit": "Submit", |
There was a problem hiding this comment.
These strings replaced an em dash with a hyphen but missed spacing ("spam- just"). This reads like a typo; use either an em dash (—) or add spaces around the hyphen for proper punctuation.
| "cnpjUserDoesntExist": "Please contact our support team at support@vortexfinance.co to get onboarded as a business user.", | ||
| "kycInvalid": "Your KYC level is invalid. Please contact support.", | ||
| "maintenance": "Temporary maintenance in progress — please check back later." | ||
| "maintenance": "Temporary maintenance in progress- please check back later." |
There was a problem hiding this comment.
This string replaced an em dash with a hyphen but missed spacing ("progress- please"). This reads like a typo; use either an em dash (—) or add spaces around the hyphen for proper punctuation.
| "error": "Erro ao salvar seu e-mail. Por favor, tente novamente.", | ||
| "loading": "Carregando...", | ||
| "noNewslettersNoSpam": "Sem newsletters, sem spam — apenas suas opiniões sinceras.", | ||
| "noNewslettersNoSpam": "Sem newsletters, sem spam- apenas suas opiniões sinceras.", |
There was a problem hiding this comment.
This string replaced an em dash with a hyphen but missed spacing ("spam- apenas"). This reads like a punctuation typo; use either an em dash (—) or add a space after the hyphen.
| const ALFREDPAY_FIAT_TOKEN_SET = new Set<FiatToken>([FiatToken.USD, FiatToken.MXN, FiatToken.COP]); | ||
|
|
||
| export const isAlfredpayToken = (token: FiatToken): boolean => ALFREDPAY_FIAT_TOKEN_SET.has(token); |
There was a problem hiding this comment.
isAlfredpayToken includes FiatToken.COP, but the frontend Alfredpay country/method config currently only covers USD (US) and MXN (MX). This can cause COP flows to require Alfredpay KYC / fiat-account selection without having a supported country/method mapping. Either add full COP support (country config + payment method mapping + UI) or remove COP from the Alfredpay token set until it’s supported end-to-end.
| export const ALFREDPAY_COUNTRY_METHODS: CountryFiatAccountConfig[] = [ | ||
| { | ||
| country: "US", | ||
| countryName: "United States", | ||
| currency: "USD", | ||
| offramp: ["ACH", "WIRE"], | ||
| onramp: ["ACH", "WIRE"] | ||
| }, | ||
| { | ||
| country: "MX", | ||
| countryName: "Mexico", | ||
| currency: "MXN", | ||
| offramp: ["SPEI"], | ||
| onramp: ["SPEI"] | ||
| } | ||
| ]; |
There was a problem hiding this comment.
FiatToken.COP is treated as an Alfredpay token elsewhere (e.g. isAlfredpayToken), but there is no corresponding country config here, so ALFREDPAY_FIAT_TOKEN_TO_COUNTRY will never map COP to a country. That means the fiat account selector/registration flow can’t work for COP. Add a Colombia entry (and supported methods) or remove COP from the Alfredpay token set until it’s fully supported end-to-end.
| export const mapFiatToDestination = (fiatToken: FiatToken): DestinationType => { | ||
| const destinationMap: Record<FiatToken, DestinationType> = { | ||
| ARS: EPaymentMethod.CBU, | ||
| BRL: EPaymentMethod.PIX, | ||
| COP: EPaymentMethod.SPEI, | ||
| EUR: EPaymentMethod.SEPA, | ||
| MXN: EPaymentMethod.SPEI, | ||
| USD: EPaymentMethod.ACH |
There was a problem hiding this comment.
mapFiatToDestination maps COP to SPEI, which is a Mexico payment rail. Given COP isn’t configured in ALFREDPAY_COUNTRY_METHODS, this mapping is likely incorrect and will route COP quotes to the wrong destination type. Please confirm the correct payment method for COP and update this mapping (or avoid mapping COP until supported).
| <> | ||
| {"•" | ||
| .repeat(accountNumber.length - 4) | ||
| .split("") | ||
| .map((_, i) => ( | ||
| <span className="inline-block w-[1ch] text-center" key={i}> | ||
| • | ||
| </span> | ||
| ))} |
There was a problem hiding this comment.
"•".repeat(accountNumber.length - 4) will throw a RangeError if accountNumber is shorter than 4 characters. Since AlfredpayFiatAccountFields.accountNumber is just a string (no length guarantees at the type level), this can crash the UI for unexpected provider data. Guard the repeat count with Math.max(0, accountNumber.length - 4) (and consider a sensible fallback display for very short values).
| import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react"; | ||
| import { Select as SelectPrimitive } from "radix-ui"; | ||
| import * as React from "react"; | ||
|
|
||
| import { cn } from "../../helpers/cn"; | ||
|
|
||
| function Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>) { | ||
| return <SelectPrimitive.Root data-slot="select" {...props} />; | ||
| } |
There was a problem hiding this comment.
The Select primitive is imported as a single named export (Select as SelectPrimitive) but then used as a namespace (SelectPrimitive.Root, SelectPrimitive.Trigger, etc.). Unless the library explicitly exports an object with these members, this will be undefined at runtime. Use a namespace import that matches Radix Select’s API surface (and ensure the dependency matches the import path).
What this PR does
This PR extends the Vortex app with full fiat account management support for the Alfredpay payment provider, enabling users to register and select fiat accounts when transacting in USD, MXN (Mexican Peso) and COP (Colombian Peso).
Key changes
New currencies & token support
FiatTokenvalues inpackages/shared, including token config, token mapping, and anisAlfredpayTokenhelperuseGetAssetIconto handle the new currenciesFiat Account Registration flow (new page)
pages/alfredpay/FiatAccountRegistration/, including:AccountTypePickerScreen,RegisterFiatAccountScreen,RegisteredAccountsList,AccountCardDeck,AccountCardSkeleton,CardHeader,KycRequiredBanner,RemoveAccountControlsfiatAccount.machine.ts) with associated hooks (useFiatAccounts) and service (alfredpay.service.ts)FiatAccountMachineContextprovides machine state to the UISummary Step integration
FiatAccountSelectorcomponent surfaces registered fiat accounts in the paymentSummaryStepselectedFiatAccountIdwired intoRampExecutionInputKYC flow refactor
AlfredpayKycFlowdecomposed into discrete screen components:CustomerDefinitionScreen,DoneScreen,FailureKycScreen,FailureScreen,FillingScreen,LinkReadyScreen,LoadingScreen,OpeningLinkScreen,PollingScreenNew reusable components
Checkbox— general-purpose checkbox primitiveAlertBanner— contextual alert display (with Storybook story)MaskedAccountNumber— masked display of account numbers (with Storybook story)AnimatedRemoveFiatAccountLabel— animated label for account removalUI & styling
btn-vortex-successbutton variant (green)cursor: pointer !important)btn-vortex-primaryandbtn-vortex-dangerTranslations
en.jsonandpt.jsonfor all Alfredpay screensMinor backend fixes
auth.controller.ts: removed stale hardcoded mock returnsep10.service.ts: added MXN and COP to the token mapping (marked as not used for SEP10)isEvmTokenimport fromfinal-settlement-subsidy.tsDocs / tooling
CLAUDE.mdupdated with XState v5 patterns, token exhaustiveness requirements, and "no over-engineering" guidelinesAlertBannerandMaskedAccountNumberradix-uiadded as a frontend dependency