Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

**Features**
- [#1956](https://github.com/stripe/stripe-react-native/pull/1956) Added support for the Billie payment method
- Added `image` to `EmbeddedPaymentElement.PaymentOptionDisplayData`

**Changes**
- Klarna: Made `billingDetails.email` and `billingDetails.address.country` optional when creating Klarna payment methods. See Stripe docs: [Migrate Klarna from Sources – Field mapping reference](https://docs.stripe.com/payments/klarna/migrate) ("Not required when using the Payment Element. It’s collected automatically.").
Expand Down Expand Up @@ -68,7 +69,7 @@
## 0.47.0 - 2025-05-21

**Features**
- Added `customerEphemeralKeySecret` and `customerSessionClientSecret` to EmbeddedPaymentElement
- Added `customerEphemeralKeySecret` and `customerSessionClientSecret` to EmbeddedPaymentElement

## 0.46.0 - 2025-05-08

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,40 @@
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.WritableMap
import com.reactnativestripesdk.getBase64FromBitmap
import com.reactnativestripesdk.getBitmapFromDrawable
import com.reactnativestripesdk.utils.mapFromPaymentSheetBillingDetails
import com.stripe.android.paymentelement.EmbeddedPaymentElement
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeout

/**
* Serialize Stripe's PaymentOptionDisplayData into a WritableMap
* that can be sent over the RN bridge.
*/
fun EmbeddedPaymentElement.PaymentOptionDisplayData.toWritableMap(): WritableMap =
suspend fun EmbeddedPaymentElement.PaymentOptionDisplayData.toWritableMap(): WritableMap =
Arguments.createMap().apply {
putString("label", label)
putString("paymentMethodType", paymentMethodType)
putMap("billingDetails", mapFromPaymentSheetBillingDetails(billingDetails))

// Load image off the main thread with a timeout
val imageBase64 =
try {
withContext(Dispatchers.Default) {
val drawable =
withTimeout(5_000L) {
withContext(Dispatchers.IO) {
imageLoader()
}
}
getBitmapFromDrawable(drawable)?.let { bitmap ->
getBase64FromBitmap(bitmap)
} ?: ""
}
} catch (e: Exception) {
// If imageLoader fails or times out, return empty string
""
}
putString("image", imageBase64)
}
17 changes: 13 additions & 4 deletions example/src/screens/EmbeddedPaymentElementScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Alert, View, Text, Modal } from 'react-native';
import { Alert, View, Text, Modal, Image } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import Button from '../components/Button';
import PaymentScreen from '../components/PaymentScreen';
Expand Down Expand Up @@ -63,9 +63,18 @@ function PaymentElementView({ intentConfig, elementConfig }: any) {
{embeddedPaymentElementView}

<View style={{ paddingVertical: 16 }}>
<Text style={{ fontSize: 16, fontWeight: '600' }}>
{paymentOption?.label ?? 'No option'}
</Text>
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
{paymentOption?.image && (
<Image
source={{ uri: `data:image/png;base64,${paymentOption.image}` }}
style={{ width: 32, height: 20 }}
resizeMode="contain"
/>
)}
<Text style={{ fontSize: 16, fontWeight: '600' }}>
{paymentOption?.label ?? 'No option'}
</Text>
</View>
</View>

<Button
Expand Down
4 changes: 4 additions & 0 deletions src/types/EmbeddedPaymentElement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ export interface PaymentOptionDisplayData {
* A user-facing label for the payment method, like "Apple Pay" or "•••• 4242" for a card.
*/
label: string;
/**
* A base64 encoded string representing the image for the payment option.
*/
image: string;
/**
* Optional billing details associated with the payment method, such as name, email, or address.
*/
Expand Down
Loading