Skip to content

Commit a858aa6

Browse files
Merge branch 'master' into porter/mandate-text
2 parents 7e202a3 + c9f83c7 commit a858aa6

5 files changed

Lines changed: 191 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# CHANGELOG
22

3+
## 0.50.3 - 2025-08-07
4+
5+
**Fixed**
6+
- Fixed Android crash when using `RowSelectionBehavior.ImmediateAction` with `FormSheetAction.Confirm` in EmbeddedPaymentElement.
7+
38
## 0.50.2 - 2025-08-06
49

510
**Changes**

android/src/androidTest/java/com/reactnativestripesdk/PaymentSheetFragmentTest.kt

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,8 @@ class PaymentSheetFragmentTest {
4444
}
4545

4646
@Test
47-
fun buildGooglePayConfig_defaultsToCorrectValues() {
47+
fun buildGooglePayConfig_returnsNullForEmptyBundle() {
4848
val config = PaymentSheetFragment.buildGooglePayConfig(Bundle.EMPTY)
49-
Assert.assertEquals(
50-
config,
51-
PaymentSheet.GooglePayConfiguration(
52-
environment = PaymentSheet.GooglePayConfiguration.Environment.Production,
53-
countryCode = "",
54-
currencyCode = "",
55-
buttonType = PaymentSheet.GooglePayConfiguration.ButtonType.Pay,
56-
),
57-
)
49+
Assert.assertNull(config)
5850
}
5951
}

android/src/main/java/com/reactnativestripesdk/PaymentSheetFragment.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ class PaymentSheetFragment :
550550
)
551551

552552
internal fun buildGooglePayConfig(params: Bundle?): PaymentSheet.GooglePayConfiguration? {
553-
if (params == null) {
553+
if (params == null || params.isEmpty) {
554554
return null
555555
}
556556

jest/mock.js

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
/* eslint-disable no-undef */
22

3+
const React = require('react');
4+
35
const mockFunctions = {
46
initStripe: jest.fn(async () => ({})),
57
createPaymentMethod: jest.fn(async () => ({
@@ -172,11 +174,191 @@ const mockHooks = {
172174
...mockFunctions.collectFinancialConnectionsAccounts(),
173175
})),
174176
})),
177+
useEmbeddedPaymentElement: jest.fn((intentConfig, configuration) => ({
178+
embeddedPaymentElementView: React.createElement('View', {
179+
testID: 'embedded-payment-element-view',
180+
style: { width: '100%', height: 200 },
181+
}),
182+
paymentOption: {
183+
label: 'Card ending in 4242',
184+
paymentMethodType: 'card',
185+
billingDetails: {
186+
name: 'John Doe',
187+
email: 'john.doe@example.com',
188+
address: {
189+
country: 'US',
190+
postalCode: '12345',
191+
line1: '123 Main St',
192+
city: 'Anytown',
193+
state: 'CA',
194+
},
195+
},
196+
},
197+
confirm: jest.fn(async () => ({
198+
status: 'completed',
199+
})),
200+
update: jest.fn(async () => ({ status: 'completed', error: null })),
201+
clearPaymentOption: jest.fn(() => {}),
202+
loadingError: null,
203+
})),
204+
};
205+
206+
// Stripe constants and enums for testing - matches runtime exports
207+
const StripeConstants = {
208+
// PlatformPay enums
209+
PlatformPay: {
210+
PaymentType: {
211+
Immediate: 'Immediate',
212+
Deferred: 'Deferred',
213+
Recurring: 'Recurring',
214+
},
215+
BillingAddressFormat: {
216+
Full: 'FULL',
217+
Min: 'MIN',
218+
},
219+
ContactField: {
220+
EmailAddress: 'emailAddress',
221+
Name: 'name',
222+
PhoneNumber: 'phoneNumber',
223+
PhoneticName: 'phoneticName',
224+
PostalAddress: 'postalAddress',
225+
},
226+
},
227+
228+
// Error enums
229+
PlatformPayError: {
230+
Canceled: 'Canceled',
231+
Failed: 'Failed',
232+
Unknown: 'Unknown',
233+
},
234+
235+
// PaymentSheet enums
236+
PaymentSheet: {
237+
CollectionMode: {
238+
AUTOMATIC: 'automatic',
239+
NEVER: 'never',
240+
ALWAYS: 'always',
241+
},
242+
AddressCollectionMode: {
243+
AUTOMATIC: 'automatic',
244+
NEVER: 'never',
245+
FULL: 'full',
246+
},
247+
CardBrandCategory: {
248+
Visa: 'visa',
249+
Mastercard: 'mastercard',
250+
Amex: 'amex',
251+
Discover: 'discover',
252+
},
253+
CardBrandAcceptanceFilter: {
254+
All: 'all',
255+
Allowed: 'allowed',
256+
Disallowed: 'disallowed',
257+
},
258+
CustomPaymentMethodResultStatus: {
259+
Completed: 'completed',
260+
Canceled: 'canceled',
261+
Failed: 'failed',
262+
},
263+
},
264+
};
265+
266+
// EmbeddedPaymentElement constants and enums for testing
267+
const EmbeddedPaymentElementMocks = {
268+
// Result status constants (from EmbeddedPaymentElementResult)
269+
EmbeddedPaymentElementStatus: {
270+
COMPLETED: 'completed',
271+
CANCELED: 'canceled',
272+
FAILED: 'failed',
273+
},
274+
275+
// Form sheet action types (from EmbeddedFormSheetAction)
276+
EmbeddedFormSheetActionType: {
277+
CONFIRM: 'confirm',
278+
CONTINUE: 'continue',
279+
},
280+
281+
// Row selection behavior types (from EmbeddedRowSelectionBehavior)
282+
EmbeddedRowSelectionBehaviorType: {
283+
DEFAULT: 'default',
284+
IMMEDIATE_ACTION: 'immediateAction',
285+
},
286+
287+
// Row display styles for Embedded Payment Element (from PaymentSheet.RowStyle)
288+
RowStyle: {
289+
FlatWithRadio: 'flatWithRadio',
290+
FloatingButton: 'floatingButton',
291+
FlatWithCheckmark: 'flatWithCheckmark',
292+
FlatWithDisclosure: 'flatWithDisclosure',
293+
},
294+
295+
// Mock payment method types commonly used with EmbeddedPaymentElement
296+
PaymentMethodTypes: {
297+
CARD: 'card',
298+
APPLE_PAY: 'apple_pay',
299+
GOOGLE_PAY: 'google_pay',
300+
LINK: 'link',
301+
KLARNA: 'klarna',
302+
AFTERPAY: 'afterpay_clearpay',
303+
US_BANK_ACCOUNT: 'us_bank_account',
304+
SEPA_DEBIT: 'sepa_debit',
305+
},
306+
307+
// Mock test helpers for different payment option states
308+
mockPaymentOptions: {
309+
card: {
310+
label: 'Card ending in 4242',
311+
paymentMethodType: 'card',
312+
billingDetails: {
313+
name: 'John Doe',
314+
email: 'john.doe@example.com',
315+
address: {
316+
country: 'US',
317+
postalCode: '12345',
318+
line1: '123 Main St',
319+
city: 'Anytown',
320+
state: 'CA',
321+
},
322+
},
323+
},
324+
applePay: {
325+
label: 'Apple Pay',
326+
paymentMethodType: 'apple_pay',
327+
billingDetails: {
328+
name: 'John Doe',
329+
},
330+
},
331+
googlePay: {
332+
label: 'Google Pay',
333+
paymentMethodType: 'google_pay',
334+
billingDetails: {
335+
name: 'John Doe',
336+
},
337+
},
338+
link: {
339+
label: 'Link',
340+
paymentMethodType: 'link',
341+
billingDetails: {
342+
email: 'john.doe@example.com',
343+
},
344+
},
345+
null: null,
346+
},
347+
348+
// Mock results for different scenarios
349+
mockResults: {
350+
completed: { status: 'completed' },
351+
canceled: { status: 'canceled' },
352+
failed: { status: 'failed', error: new Error('Payment failed') },
353+
networkError: { status: 'failed', error: new Error('Network error') },
354+
},
175355
};
176356

177357
module.exports = {
178358
...mockFunctions,
179359
...mockHooks,
360+
...StripeConstants,
361+
...EmbeddedPaymentElementMocks,
180362
StripeContainer: () => 'StripeContainer',
181363
StripeProvider: () => 'StripeProvider',
182364
CardField: () => 'CardField',

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@stripe/stripe-react-native",
3-
"version": "0.50.2",
3+
"version": "0.50.3",
44
"author": "Stripe",
55
"description": "Stripe SDK for React Native",
66
"main": "lib/commonjs/index",

0 commit comments

Comments
 (0)