From e754c92a1804e517957490e4dcc3f206d25308e8 Mon Sep 17 00:00:00 2001 From: Peng Ying Date: Tue, 28 Apr 2026 16:06:30 -0700 Subject: [PATCH] fix(grid-visualizer): emit documented minimum beneficiary fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The generated curl examples included `birthDate` and `nationality` on every beneficiary (both are optional per docs) and omitted `address` even for countries where docs say it's required. Aligns the output with the minimum-required-fields table in the External Accounts docs: - All countries: emit only beneficiaryType + fullName as the universal minimum (drop birthDate / nationality — both are optional, "providing additional information... can reduce false positive compliance checks"). - US (USD), Europe (EUR), UK (GBP): include a country-appropriate beneficiary.address (line1, city, postalCode, country, optional state). - Mexico (MXN), Brazil (BRL), Philippines (PHP): explicit beneficiaryAddressRequired: false — docs call out that address is not required for these. - Other account types: left undefined so the generated payload still emits the universal minimum, since the docs only document the minimum-fields table for the six countries above. Adds BeneficiaryAddressExample type + two optional fields on AccountTypeSpec (beneficiaryAddressRequired, beneficiaryAddressExample). The code-generator's buildAccountInfoBody is updated to include the address block conditionally. Ref: https://grid.lightspark.com/payouts-and-b2b/depositing-funds/external-accounts#individual-beneficiaries Co-Authored-By: Claude Opus 4.7 (1M context) --- .../grid-visualizer/src/data/account-types.ts | 41 +++++++++++++++++++ .../grid-visualizer/src/lib/code-generator.ts | 13 ++++-- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/components/grid-visualizer/src/data/account-types.ts b/components/grid-visualizer/src/data/account-types.ts index ac692b91..3d094b02 100644 --- a/components/grid-visualizer/src/data/account-types.ts +++ b/components/grid-visualizer/src/data/account-types.ts @@ -4,10 +4,26 @@ export interface AccountFieldSpec { description?: string; } +export interface BeneficiaryAddressExample { + line1: string; + city: string; + state?: string; + postalCode: string; + country: string; +} + export interface AccountTypeSpec { accountType: string; fields: AccountFieldSpec[]; beneficiaryRequired: boolean; + // Whether the beneficiary needs a postal address. Per docs + // (https://grid.lightspark.com/payouts-and-b2b/depositing-funds/external-accounts): + // - US (USD), UK (GBP), Europe (EUR): address required + // - Mexico (MXN), Brazil (BRL), Philippines (PHP): explicitly not required + // - Other countries: not in the documented minimum-fields table; left + // undefined here so the generated payload matches the docs minimum. + beneficiaryAddressRequired?: boolean; + beneficiaryAddressExample?: BeneficiaryAddressExample; } export const accountTypeSpecs: Record = { @@ -18,6 +34,14 @@ export const accountTypeSpecs: Record = { { name: 'routingNumber', example: '021000021' }, ], beneficiaryRequired: true, + beneficiaryAddressRequired: true, + beneficiaryAddressExample: { + line1: '123 Main Street', + city: 'San Francisco', + state: 'CA', + postalCode: '94105', + country: 'US', + }, }, EUR_ACCOUNT: { accountType: 'EUR_ACCOUNT', @@ -26,6 +50,13 @@ export const accountTypeSpecs: Record = { { name: 'swiftCode', example: 'DEUTDEFF', description: 'Optional' }, ], beneficiaryRequired: true, + beneficiaryAddressRequired: true, + beneficiaryAddressExample: { + line1: 'Friedrichstraße 43', + city: 'Berlin', + postalCode: '10117', + country: 'DE', + }, }, GBP_ACCOUNT: { accountType: 'GBP_ACCOUNT', @@ -34,6 +65,13 @@ export const accountTypeSpecs: Record = { { name: 'accountNumber', example: '12345678' }, ], beneficiaryRequired: true, + beneficiaryAddressRequired: true, + beneficiaryAddressExample: { + line1: '10 Downing Street', + city: 'London', + postalCode: 'SW1A 2AA', + country: 'GB', + }, }, BRL_ACCOUNT: { accountType: 'BRL_ACCOUNT', @@ -43,6 +81,7 @@ export const accountTypeSpecs: Record = { { name: 'taxId', example: '12345678901' }, ], beneficiaryRequired: true, + beneficiaryAddressRequired: false, }, MXN_ACCOUNT: { accountType: 'MXN_ACCOUNT', @@ -50,6 +89,7 @@ export const accountTypeSpecs: Record = { { name: 'clabeNumber', example: '123456789012345678' }, ], beneficiaryRequired: true, + beneficiaryAddressRequired: false, }, INR_ACCOUNT: { accountType: 'INR_ACCOUNT', @@ -90,6 +130,7 @@ export const accountTypeSpecs: Record = { { name: 'accountNumber', example: '001234567890' }, ], beneficiaryRequired: true, + beneficiaryAddressRequired: false, }, SGD_ACCOUNT: { accountType: 'SGD_ACCOUNT', diff --git a/components/grid-visualizer/src/lib/code-generator.ts b/components/grid-visualizer/src/lib/code-generator.ts index 85146a0c..a00c9484 100644 --- a/components/grid-visualizer/src/lib/code-generator.ts +++ b/components/grid-visualizer/src/lib/code-generator.ts @@ -48,14 +48,19 @@ function buildAccountInfoBody(sel: CurrencySelection): Record { info[field.name] = field.example; } - // Beneficiary goes inside accountInfo per API spec + // Beneficiary goes inside accountInfo. We emit only the documented minimum + // for individual beneficiaries — `beneficiaryType` and `fullName` always, + // plus `address` for the countries that require it (US, UK, EU). Per docs, + // `birthDate` and `nationality` are optional but recommended. if (spec.beneficiaryRequired) { - info.beneficiary = { + const beneficiary: Record = { beneficiaryType: 'INDIVIDUAL', fullName: sel.examplePerson.fullName, - birthDate: '1985-06-20', - nationality: sel.examplePerson.nationality, }; + if (spec.beneficiaryAddressRequired && spec.beneficiaryAddressExample) { + beneficiary.address = spec.beneficiaryAddressExample; + } + info.beneficiary = beneficiary; } return info;