The problem
Issue #1959, open since May 2025: when an app passes shippingDetails to confirmPayment, the name and address reach Stripe, but carrier and phone do not. In a React Native bridge, the native side only reads the fields it maps explicitly; everything else is ignored without an error. Both native mappers built the shipping parameters from name and address only, and on the TypeScript side ShippingDetails was simply BillingDetails, which has no carrier or trackingNumber at all.
The proposed fix
The pull request maps the three fields on both platforms and widens the type:
return ConfirmPaymentIntentParams.Shipping(
name = getValOr(shippingDetails, "name") ?: "",
address = address,
carrier = getValOr(shippingDetails, "carrier"),
phone = getValOr(shippingDetails, "phone"),
trackingNumber = getValOr(shippingDetails, "trackingNumber"),
)export type ShippingDetails = BillingDetails & {
carrier?: string;
trackingNumber?: string;
};A maintainer had approved it, then asked for the build to be fixed before merging, and a day later noted that "the same tasks continue to fail".
What I found in review
The failing check was not about this change
The repository runs API Extractor, which generates a report of the public TypeScript surface; CI fails when the committed report differs from the regenerated one. I read the failed job log. The only remaining difference was one removed // (undocumented) comment above style?: StyleProp<ViewStyle> in the platform pay button props, around line 3568 of the report. The new ShippingDetails entry already matched. That kind of drift comes from main, not from the pull request, so rebasing and regenerating the report (yarn api-extractor run --local) should clear it.
The type is still wider than the native objects
BillingDetails includes email. Stripe's shipping object has no email, and neither do ConfirmPaymentIntentParams.Shipping on Android nor STPPaymentIntentShippingDetailsParams on iOS. So an app can pass shippingDetails.email, see no error, and lose it. That is the same class of bug the pull request fixes, one field over.
export type ShippingDetails = Omit<BillingDetails, 'email'> & {
carrier?: string;
trackingNumber?: string;
};With Omit, an object literal containing email becomes a compile error. I marked it as arguably out of scope.
What happened next
Takeaways
- When CI fails on a generated report, read the diff in the log before changing code. Here the change was correct and the report was stale.
- Across a native bridge, the TypeScript type is the only guard. If it is wider than what the native side reads, data disappears silently.
- Small, specific help ("the remaining difference is this one line, regenerate it this way") is often what moves a stuck contribution.