Skip to content

Commit 5febdbd

Browse files
authored
fix(payouts): handle failures in payout flow decoder (#1241)
1 parent 16734b1 commit 5febdbd

File tree

1 file changed

+82
-77
lines changed

1 file changed

+82
-77
lines changed

src/Types/PaymentMethodCollectTypes.res

Lines changed: 82 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -344,57 +344,62 @@ let sortByCustomOrder = (arr: array<'a>, getKey: 'a => string, customOrder: arra
344344
})
345345
}
346346

347-
let decodePayoutDynamicFields = (json: JSON.t, defaultDynamicPmdFields): option<
348-
payoutDynamicFields,
349-
> =>
347+
let decodePayoutDynamicFields = (json: JSON.t, defaultDynamicPmdFields): payoutDynamicFields =>
350348
json
351349
->JSON.Decode.object
352-
->Option.map(obj => {
353-
let (address, pmd) =
354-
obj
355-
->Js.Dict.entries
356-
->Array.reduce(([], []), ((addressFields, payoutMethodDataFields), (key, value)) => {
357-
switch JSON.Decode.object(value) {
358-
| Some(fieldObj) => {
359-
let getString = key => fieldObj->Dict.get(key)->Option.flatMap(JSON.Decode.string)
360-
let fieldType = getFieldOptions(fieldObj)
361-
switch (getString("required_field"), getString("display_name"), getString("value")) {
362-
| (Some(pmdMap), Some(displayName), value) =>
363-
switch decodeFieldType(key, fieldType) {
364-
| Some(BillingAddress(fieldType)) =>
365-
let addressField: dynamicFieldForAddress = {
366-
pmdMap,
367-
displayName,
368-
fieldType,
369-
value,
370-
}
371-
([addressField, ...addressFields], payoutMethodDataFields)
372-
| Some(PayoutMethodData(fieldType)) =>
373-
let payoutMethodDataField = {
374-
pmdMap,
375-
displayName,
376-
fieldType,
377-
value,
350+
->Option.mapOr(
351+
// Fallback for null/invalid JSON - always return valid defaults
352+
{
353+
address: None,
354+
payoutMethodData: defaultDynamicPmdFields,
355+
},
356+
obj => {
357+
let (address, pmd) =
358+
obj
359+
->Js.Dict.entries
360+
->Array.reduce(([], []), ((addressFields, payoutMethodDataFields), (key, value)) => {
361+
switch JSON.Decode.object(value) {
362+
| Some(fieldObj) => {
363+
let getString = key => fieldObj->Dict.get(key)->Option.flatMap(JSON.Decode.string)
364+
let fieldType = getFieldOptions(fieldObj)
365+
switch (getString("required_field"), getString("display_name"), getString("value")) {
366+
| (Some(pmdMap), Some(displayName), value) =>
367+
switch decodeFieldType(key, fieldType) {
368+
| Some(BillingAddress(fieldType)) =>
369+
let addressField: dynamicFieldForAddress = {
370+
pmdMap,
371+
displayName,
372+
fieldType,
373+
value,
374+
}
375+
([addressField, ...addressFields], payoutMethodDataFields)
376+
| Some(PayoutMethodData(fieldType)) =>
377+
let payoutMethodDataField = {
378+
pmdMap,
379+
displayName,
380+
fieldType,
381+
value,
382+
}
383+
(addressFields, [payoutMethodDataField, ...payoutMethodDataFields])
384+
| None => (addressFields, payoutMethodDataFields)
378385
}
379-
(addressFields, [payoutMethodDataField, ...payoutMethodDataFields])
380-
| None => (addressFields, payoutMethodDataFields)
386+
| _ => (addressFields, payoutMethodDataFields)
381387
}
382-
| _ => (addressFields, payoutMethodDataFields)
383388
}
389+
| None => (addressFields, payoutMethodDataFields)
384390
}
385-
| None => (addressFields, payoutMethodDataFields)
386-
}
387-
})
388-
389-
{
390-
address: address->Array.length > 0
391-
? Some(sortByCustomOrder(address, item => item.pmdMap, customAddressOrder))
392-
: None,
393-
payoutMethodData: pmd->Array.length > 0
394-
? sortByCustomOrder(pmd, item => item.pmdMap, customPmdOrder)
395-
: defaultDynamicPmdFields,
396-
}
397-
})
391+
})
392+
393+
{
394+
address: address->Array.length > 0
395+
? Some(sortByCustomOrder(address, item => item.pmdMap, customAddressOrder))
396+
: None,
397+
payoutMethodData: pmd->Array.length > 0
398+
? sortByCustomOrder(pmd, item => item.pmdMap, customPmdOrder)
399+
: defaultDynamicPmdFields,
400+
}
401+
},
402+
)
398403

399404
let decodePaymentMethodTypeWithRequiredFields = (
400405
json: JSON.t,
@@ -408,12 +413,12 @@ let decodePaymentMethodTypeWithRequiredFields = (
408413
->Dict.get("payment_method_types_info")
409414
->Option.flatMap(JSON.Decode.array)
410415
->Option.map(pmtInfoArr =>
411-
pmtInfoArr->Array.reduce(
412-
([], []),
413-
((pmta, pmtr), pmtInfo) =>
416+
pmtInfoArr
417+
->Belt.Array.keepMap(
418+
pmtInfo =>
414419
pmtInfo
415420
->JSON.Decode.object
416-
->Option.map(
421+
->Option.flatMap(
417422
obj => {
418423
let paymentMethodType =
419424
obj->Dict.get("payment_method_type")->Option.flatMap(JSON.Decode.string)
@@ -431,47 +436,47 @@ let decodePaymentMethodTypeWithRequiredFields = (
431436
->decodeWallet
432437
->Option.map(wallet => Wallet(wallet))
433438
| _ => None
434-
}
435-
->Option.map(
439+
}->Option.map(
436440
pmt => {
437441
let payoutDynamicFields =
438442
obj
439443
->Dict.get("required_fields")
440-
->Option.flatMap(
444+
->Option.map(
441445
json => json->decodePayoutDynamicFields(defaultDynamicPmdFields(~pmt)),
442446
)
443447
->Option.getOr({
444448
address: None,
445449
payoutMethodData: defaultDynamicPmdFields(~pmt),
446450
})
447-
switch pmt {
448-
| Card(card) => {
449-
pmta->Array.push(Card(card))
450-
let pmtwr: paymentMethodTypeWithDynamicFields = Card(
451-
card,
452-
payoutDynamicFields,
453-
)
454-
pmtr->Array.push(pmtwr)
455-
(pmta, pmtr)
456-
}
457-
| BankTransfer(transfer) => {
458-
pmta->Array.push(BankTransfer(transfer))
459-
pmtr->Array.push(BankTransfer(transfer, payoutDynamicFields))
460-
(pmta, pmtr)
461-
}
462-
| Wallet(wallet) => {
463-
let pmt: paymentMethodType = Wallet(wallet)
464-
pmta->Array.push(pmt)
465-
pmtr->Array.push(Wallet(wallet, payoutDynamicFields))
466-
(pmta, pmtr)
467-
}
468-
}
451+
(pmt, payoutDynamicFields)
469452
},
470453
)
471-
->Option.getOr(([], []))
472454
},
473-
)
474-
->Option.getOr(([], [])),
455+
),
456+
)
457+
->Array.reduce(
458+
([], []),
459+
((pmta, pmtr), (pmt, payoutDynamicFields)) => {
460+
switch pmt {
461+
| Card(card) => {
462+
pmta->Array.push(Card(card))
463+
let pmtwr: paymentMethodTypeWithDynamicFields = Card(card, payoutDynamicFields)
464+
pmtr->Array.push(pmtwr)
465+
(pmta, pmtr)
466+
}
467+
| BankTransfer(transfer) => {
468+
pmta->Array.push(BankTransfer(transfer))
469+
pmtr->Array.push(BankTransfer(transfer, payoutDynamicFields))
470+
(pmta, pmtr)
471+
}
472+
| Wallet(wallet) => {
473+
let pmt: paymentMethodType = Wallet(wallet)
474+
pmta->Array.push(pmt)
475+
pmtr->Array.push(Wallet(wallet, payoutDynamicFields))
476+
(pmta, pmtr)
477+
}
478+
}
479+
},
475480
)
476481
)
477482
})

0 commit comments

Comments
 (0)