@@ -67,111 +67,109 @@ const API_FIELD_TO_FORM_FIELD: Record<string, string> = {
6767} ;
6868
6969/**
70- * Maps Impact API error messages (from validationErrors[].message ) to short,
70+ * Maps Impact API error code paths (from validationErrors[].errorPath ) to short,
7171 * readable frontend error codes used in the ICU select props.
7272 *
73- * The Impact API returns human-readable English messages (e.g. "Invalid Routing Code").
74- * The GraphQL layer passes these through unchanged. The keys below match those messages
73+ * The Impact API returns a stable dot-delimited error path (e.g.
74+ * "withdrawal.settings.error.routingcode") alongside the human-readable message.
75+ * The GraphQL layer exposes this as `errorPath`. The keys below match those paths
7576 * to short frontend codes used in the ICU `{errorCode, select, ...}` props.
76- *
77- * If a message doesn't match any key here, it passes through as-is to the ICU select's
78- * `other` branch, which displays it directly via `{errorCode}`.
7977 */
80- const API_MESSAGE_TO_FRONTEND : Record < string , string > = {
78+ const API_ERROR_PATH_TO_FRONTEND : Record < string , string > = {
8179 // Beneficiary account name
82- "Beneficiary name is empty " : "empty" ,
83- "Contains invalid characters" : "invalidCharacters" ,
84- "Name is purely numeric" : "numeric ",
85- "Name exceeds 70 characters " : "tooLong " ,
86- "CNY currency account with non-English characters " : "nonEnglish " ,
87- "Beneficiary name does not match tax document " : "nameMismatch " ,
88- "Business beneficiary name does not match tax document " :
80+ "withdrawal.settings.error.empty_beneficiaryname " : "empty" ,
81+ "withdrawal.settings.error.invalid_character_beneficiaryname" :
82+ "invalidCharacters ",
83+ "withdrawal.settings.error.numeric_beneficiaryname " : "numeric " ,
84+ "withdrawal_settings.error.beneficiaryname.size " : "tooLong " ,
85+ "withdrawal.settings.error.non_english_beneficiaryname " : "nonEnglish " ,
86+ "withdrawal_settings.error.business_beneficiaryname_match " :
8987 "businessNameMismatch" ,
90- "Payee name does not match tax document" : "payeeMismatch" ,
91- "Business payee name does not match tax document" : "businessPayeeMismatch" ,
88+ "withdrawal_settings.error.beneficiaryname_match" : "nameMismatch" ,
89+ "withdrawal_settings.error.business_checkpayeename_match" :
90+ "businessPayeeMismatch" ,
91+ "withdrawal_settings.error.checkpayeename_match" : "payeeMismatch" ,
9292
9393 // Bank account number
94- "Account number is empty" : "empty" ,
95- "Account number invalid & country is UK " : "invalidUk" ,
96- "Account number invalid & country is not UK " : "invalid" ,
94+ "withdrawal.settings.error.accountnumber. empty" : "empty" ,
95+ "withdrawal.settings.error.accountnumber.uk " : "invalidUk" ,
96+ "withdrawal.settings.error.bankaccount. invalid" : "invalid" ,
9797
9898 // IBAN
99- "IBAN is empty " : "ibanEmpty" ,
100- "IBAN contains non- alphanumeric chars " : "ibanAlphanumeric" ,
101- "IBAN fails obfuscation or IBAN validation " : "ibanInvalid" ,
102- 'UK GBP account but IBAN doesn\'t start with "GB"' : "ibanCountryMismatch" ,
99+ "withdrawal.settings.error.iban " : "ibanEmpty" ,
100+ "withdrawal.settings.error.iban. alphanumeric" : "ibanAlphanumeric" ,
101+ "withdrawal.settings.error.iban.invalid " : "ibanInvalid" ,
102+ "withdrawal.settings.error.iban.uk.country.mismatch" : "ibanCountryMismatch" ,
103103
104104 // Routing code
105- "Empty or invalid routing code & country is Australia " : "invalidBsb" ,
106- "Empty or invalid routing code & country is UK " : "invalidSortCode" ,
107- "Empty routing code (other countries) " : "empty" ,
108- "Invalid routing code (other countries) " : "invalid" ,
105+ "withdrawal.settings.error.bsbNumber " : "invalidBsb" ,
106+ "withdrawal.settings.error.sortcode " : "invalidSortCode" ,
107+ "withdrawal.settings.error.routingNumber " : "empty" ,
108+ "withdrawal.settings.error.routingcode " : "invalid" ,
109109
110110 // SWIFT / BIC
111- "SWIFT/BIC code is empty " : "empty" ,
112- "SWIFT/BIC contains non- alphanumeric chars " : "alphanumeric" ,
113- "SWIFT/BIC fails obfuscation or BIC validation " : "invalid" ,
111+ "withdrawal.settings.error.bic " : "empty" ,
112+ "withdrawal.settings.error.bic. alphanumeric" : "alphanumeric" ,
113+ "withdrawal.settings.error.bic.invalid " : "invalid" ,
114114
115115 // Bank account type
116- "Account type is null " : "empty" ,
116+ "global.error.invalid.accounttype " : "empty" ,
117117
118118 // Bank name
119- "Bank name is empty " : "empty" ,
119+ "withdrawal.settings.error.bankName " : "empty" ,
120120
121121 // Tax payer ID
122- "Tax payer ID is empty (generic)" : "empty" ,
123- "Tax payer ID is empty (Argentina)" : "emptyAr" ,
124- "Tax payer ID is empty (South Korea)" : "emptyKr" ,
125- "Tax payer ID not alphanumeric (generic)" : "alphanumeric" ,
126- "Tax payer ID not alphanumeric (Argentina)" : "alphanumericAr" ,
127- "Tax payer ID not alphanumeric (South Korea)" : "alphanumericKr" ,
128- "Argentina ID not 11 chars, or South Korea individual ID not 13 / business ID not 10 chars" :
129- "invalid" ,
130- "Argentina-specific invalid length" : "invalidAr" ,
131- "South Korea-specific invalid length" : "invalidKr" ,
132- "KZT currency and tax payer ID not 12 chars" : "invalidKzt" ,
133- "Classification is CNPJ and tax payer ID length < 14" : "cnpjTooShort" ,
134- "Classification is CPF and tax payer ID length < 11" : "cpfTooShort" ,
122+ "withdrawal.settings.error.taxPayerId" : "empty" ,
123+ "withdrawal.settings.error.taxPayerId.ar" : "emptyAr" ,
124+ "withdrawal.settings.error.taxPayerId.kr" : "emptyKr" ,
125+ "withdrawal.settings.error.taxPayerId.alphanumeric" : "alphanumeric" ,
126+ "withdrawal.settings.error.taxPayerId.alphanumeric.ar" : "alphanumericAr" ,
127+ "withdrawal.settings.error.taxPayerId.alphanumeric.kr" : "alphanumericKr" ,
128+ "withdrawal.settings.error.taxPayerId.invalid" : "invalid" ,
129+ "withdrawal.settings.error.taxPayerId.invalid.ar" : "invalidAr" ,
130+ "withdrawal.settings.error.taxPayerId.invalid.kr" : "invalidKr" ,
131+ "withdrawal.settings.error.taxPayerId.invalid.kzt" : "invalidKzt" ,
132+ "withdrawal.settings.error.taxPayerId.cnpj" : "cnpjTooShort" ,
133+ "withdrawal.settings.error.taxPayerId.cpf" : "cpfTooShort" ,
135134
136135 // Patronymic name
137- "Individual classification & patronymic name is empty " : "empty" ,
138- "Patronymic name is not alphanumeric" : "alphanumeric" ,
136+ "withdrawal.settings.error.patronymicName " : "empty" ,
137+ "withdrawal.settings.error.patronymicName. alphanumeric" : "alphanumeric" ,
139138
140139 // VO code
141- "VO code is empty " : "empty" ,
142- "VO code is not alphanumeric" : "alphanumeric" ,
140+ "withdrawal.settings.error.voCode " : "empty" ,
141+ "withdrawal.settings.error.voCode. alphanumeric" : "alphanumeric" ,
143142
144143 // Agency code
145- "Agency code is empty " : "empty" ,
146- "Agency code is not alphanumeric" : "alphanumeric" ,
147- "Agency code length < 5 " : "tooShort" ,
144+ "withdrawal.settings.error.agencyCode " : "empty" ,
145+ "withdrawal.settings.error.agencyCode. alphanumeric" : "alphanumeric" ,
146+ "withdrawal.settings.error.agencyCode. length" : "tooShort" ,
148147
149148 // Bank address fields
150- "Bank address is empty " : "empty" ,
151- "Bank city is empty " : "empty" ,
152- "Bank province/state is empty " : "empty" ,
153- "Bank postal code is empty " : "empty" ,
149+ "withdrawal.settings.error.bankAddress " : "empty" ,
150+ "withdrawal.settings.error.bankCity " : "empty" ,
151+ "withdrawal.settings.error.bankProvinceState " : "empty" ,
152+ "withdrawal.settings.error.bankPostalCode " : "empty" ,
154153
155154 // Branch code / name
156- "Branch code invalid " : "invalid" ,
157- "Branch name is empty " : "empty" ,
155+ "withdrawal.settings.error.branchCode " : "invalid" ,
156+ "withdrawal.settings.error.branchName " : "empty" ,
158157
159158 // Classification code
160- "Classification code is empty (non-KZT) " : "empty" ,
161- "Empty or not exactly 2 chars (KZT currency) " : "invalidKzt" ,
159+ "withdrawal.settings.error.classificationCode.invalid " : "empty" ,
160+ "withdrawal.settings.error.classificationCode.invalid.kzt " : "invalidKzt" ,
162161
163162 // PayPal
164- "PayPal email is empty " : "empty" ,
165- "Currency not eligible for PayPal " : "unsupportedCurrency" ,
166- "Email format is invalid" : "invalidEmail" ,
167- "PayPal OAuth state is not SUCCESS " : "verificationIncomplete" ,
163+ "payment.error. email" : "empty" ,
164+ "payment.error.paypal_not_supported " : "unsupportedCurrency" ,
165+ "payment.error.email. invalid" : "invalidEmail" ,
166+ "payment.error.paypal_verification_incomplete " : "verificationIncomplete" ,
168167
169168 // Payment schedule
170- "Balance threshold schedule with zero threshold" : "empty" ,
171- "PayPal threshold not in allowed list, or bank threshold is invalid" :
172- "invalid" ,
173- "Fixed-day schedule without a specific day" : "empty" ,
174- "Fixed-day schedule with day not in [1, 15]" : "invalid" ,
169+ "payment.error.no_threshold" : "empty" ,
170+ "payment.error.invalid_threshold" : "invalid" ,
171+ "payment.error.no_dayOfMonth" : "empty" ,
172+ "payment.error.invalid_dayOfMonth" : "invalid" ,
175173} ;
176174
177175export type BankingInfoFormData = {
@@ -226,7 +224,11 @@ export function getFormInputs({ bitset, formMap }) {
226224type SetImpactPublisherWithdrawalSettingsResult = {
227225 setImpactPublisherWithdrawalSettings : {
228226 success : boolean ;
229- validationErrors : { field : string ; message : string } [ ] ;
227+ validationErrors : {
228+ field : string ;
229+ message : string ;
230+ errorPath : string ;
231+ } [ ] ;
230232 } ;
231233} ;
232234type SetImpactPublisherWithdrawalSettingsInput = {
@@ -245,7 +247,11 @@ type UpdateImpactPublisherWithdrawalSettingsInput =
245247type UpdateImpactPublisherWithdrawalSettingsResult = {
246248 updateImpactPublisherWithdrawalSettings : {
247249 success : boolean ;
248- validationErrors : { field : string ; message : string } [ ] ;
250+ validationErrors : {
251+ field : string ;
252+ message : string ;
253+ errorPath : string ;
254+ } [ ] ;
249255 } ;
250256} ;
251257
@@ -260,6 +266,7 @@ const SAVE_WITHDRAWAL_SETTINGS = gql`
260266 validationErrors {
261267 field
262268 message
269+ errorPath
263270 }
264271 }
265272 }
@@ -276,6 +283,7 @@ const UPDATE_WITHDRAWAL_SETTINGS = gql`
276283 validationErrors {
277284 field
278285 message
286+ errorPath
279287 }
280288 }
281289 }
@@ -518,7 +526,7 @@ export function useBankingInfoForm(
518526 const formField =
519527 API_FIELD_TO_FORM_FIELD [ error . field ] || error . field ;
520528 const errorCode =
521- API_MESSAGE_TO_FRONTEND [ error . message ] || error . message ;
529+ API_ERROR_PATH_TO_FRONTEND [ error . errorPath ] || error . errorPath ;
522530 return {
523531 ...agg ,
524532 [ formField ] : {
0 commit comments