Skip to content

Commit 084811b

Browse files
committed
Add image to embedded payment option display data
1 parent f8612c8 commit 084811b

3 files changed

Lines changed: 46 additions & 4 deletions

File tree

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
import android.graphics.drawable.Drawable
12
import com.facebook.react.bridge.Arguments
23
import com.facebook.react.bridge.WritableMap
4+
import com.reactnativestripesdk.getBase64FromBitmap
5+
import com.reactnativestripesdk.getBitmapFromDrawable
36
import com.reactnativestripesdk.utils.mapFromPaymentSheetBillingDetails
47
import com.stripe.android.paymentelement.EmbeddedPaymentElement
8+
import kotlinx.coroutines.withTimeout
59

610
/**
711
* Serialize Stripe's PaymentOptionDisplayData into a WritableMap
@@ -12,4 +16,29 @@ fun EmbeddedPaymentElement.PaymentOptionDisplayData.toWritableMap(): WritableMap
1216
putString("label", label)
1317
putString("paymentMethodType", paymentMethodType)
1418
putMap("billingDetails", mapFromPaymentSheetBillingDetails(billingDetails))
19+
20+
// Direct access to imageLoader and call it synchronously with timeout
21+
val imageBase64 =
22+
try {
23+
val imageLoaderField = this@toWritableMap.javaClass.getDeclaredField("imageLoader")
24+
imageLoaderField.isAccessible = true
25+
@Suppress("UNCHECKED_CAST")
26+
val imageLoader = imageLoaderField.get(this@toWritableMap) as suspend () -> Drawable
27+
28+
// Load synchronously with 2 second timeout
29+
val drawable =
30+
kotlinx.coroutines.runBlocking {
31+
withTimeout(2000L) {
32+
imageLoader()
33+
}
34+
}
35+
36+
getBitmapFromDrawable(drawable)?.let { bitmap ->
37+
getBase64FromBitmap(bitmap)
38+
} ?: ""
39+
} catch (e: Exception) {
40+
// If imageLoader fails or times out, return empty string
41+
""
42+
}
43+
putString("image", imageBase64)
1544
}

example/src/screens/EmbeddedPaymentElementScreen.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { Alert, View, Text, Modal } from 'react-native';
2+
import { Alert, View, Text, Modal, Image } from 'react-native';
33
import { SafeAreaView } from 'react-native-safe-area-context';
44
import Button from '../components/Button';
55
import PaymentScreen from '../components/PaymentScreen';
@@ -63,9 +63,18 @@ function PaymentElementView({ intentConfig, elementConfig }: any) {
6363
{embeddedPaymentElementView}
6464

6565
<View style={{ paddingVertical: 16 }}>
66-
<Text style={{ fontSize: 16, fontWeight: '600' }}>
67-
{paymentOption?.label ?? 'No option'}
68-
</Text>
66+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
67+
{paymentOption?.image && (
68+
<Image
69+
source={{ uri: `data:image/png;base64,${paymentOption.image}` }}
70+
style={{ width: 32, height: 20 }}
71+
resizeMode="contain"
72+
/>
73+
)}
74+
<Text style={{ fontSize: 16, fontWeight: '600' }}>
75+
{paymentOption?.label ?? 'No option'}
76+
</Text>
77+
</View>
6978
</View>
7079

7180
<Button

src/types/EmbeddedPaymentElement.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ export interface PaymentOptionDisplayData {
5252
* A user-facing label for the payment method, like "Apple Pay" or "•••• 4242" for a card.
5353
*/
5454
label: string;
55+
/**
56+
* A base64 encoded string representing the image for the payment option.
57+
*/
58+
image: string;
5559
/**
5660
* Optional billing details associated with the payment method, such as name, email, or address.
5761
*/

0 commit comments

Comments
 (0)