// This needs to be in the same package as StripeSdkModule to access protected methods. package com.reactnativestripesdk import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.ReactApplicationContext import com.stripe.android.customersheet.CustomerAdapter import com.stripe.android.model.PaymentMethod import kotlinx.coroutines.CompletableDeferred class ReactNativeCustomerAdapter( val context: ReactApplicationContext, private val adapter: CustomerAdapter, private val overridesFetchPaymentMethods: Boolean, private val overridesAttachPaymentMethod: Boolean, private val overridesDetachPaymentMethod: Boolean, private val overridesSetSelectedPaymentOption: Boolean, private val overridesFetchSelectedPaymentOption: Boolean, private val overridesSetupIntentClientSecretForCustomerAttach: Boolean, ) : CustomerAdapter by adapter { private val stripeSdkModule = context.getNativeModule(StripeSdkModule::class.java) internal var fetchPaymentMethodsCallback: CompletableDeferred>? = null internal var attachPaymentMethodCallback: CompletableDeferred? = null internal var detachPaymentMethodCallback: CompletableDeferred? = null internal var setSelectedPaymentOptionCallback: CompletableDeferred? = null internal var fetchSelectedPaymentOptionCallback: CompletableDeferred? = null internal var setupIntentClientSecretForCustomerAttachCallback: CompletableDeferred? = null override suspend fun retrievePaymentMethods(): CustomerAdapter.Result> { if (overridesFetchPaymentMethods) { CompletableDeferred>().also { fetchPaymentMethodsCallback = it stripeSdkModule?.eventEmitter?.emitOnCustomerAdapterFetchPaymentMethodsCallback() val resultFromJavascript = it.await() return CustomerAdapter.Result.success(resultFromJavascript) } } return adapter.retrievePaymentMethods() } override suspend fun attachPaymentMethod(paymentMethodId: String): CustomerAdapter.Result { if (overridesAttachPaymentMethod) { CompletableDeferred().also { attachPaymentMethodCallback = it val params = Arguments.createMap().also { it.putString("paymentMethodId", paymentMethodId) } stripeSdkModule?.eventEmitter?.emitOnCustomerAdapterAttachPaymentMethodCallback(params) val resultFromJavascript = it.await() return CustomerAdapter.Result.success(resultFromJavascript) } } return adapter.attachPaymentMethod(paymentMethodId) } override suspend fun detachPaymentMethod(paymentMethodId: String): CustomerAdapter.Result { if (overridesDetachPaymentMethod) { CompletableDeferred().also { detachPaymentMethodCallback = it val params = Arguments.createMap().also { it.putString("paymentMethodId", paymentMethodId) } stripeSdkModule?.eventEmitter?.emitOnCustomerAdapterDetachPaymentMethodCallback(params) val resultFromJavascript = it.await() return CustomerAdapter.Result.success(resultFromJavascript) } } return adapter.detachPaymentMethod(paymentMethodId) } override suspend fun setSelectedPaymentOption(paymentOption: CustomerAdapter.PaymentOption?): CustomerAdapter.Result { if (overridesSetSelectedPaymentOption) { CompletableDeferred().also { setSelectedPaymentOptionCallback = it val params = Arguments.createMap().also { it.putString("paymentOption", paymentOption?.id) } stripeSdkModule?.eventEmitter?.emitOnCustomerAdapterSetSelectedPaymentOptionCallback(params) val resultFromJavascript = it.await() return CustomerAdapter.Result.success(resultFromJavascript) } } return adapter.setSelectedPaymentOption(paymentOption) } override suspend fun retrieveSelectedPaymentOption(): CustomerAdapter.Result { if (overridesFetchSelectedPaymentOption) { CompletableDeferred().also { fetchSelectedPaymentOptionCallback = it stripeSdkModule?.eventEmitter?.emitOnCustomerAdapterFetchSelectedPaymentOptionCallback() val resultFromJavascript = it.await() return CustomerAdapter.Result.success( if (resultFromJavascript != null) { CustomerAdapter.PaymentOption.fromId(resultFromJavascript) } else { null }, ) } } return adapter.retrieveSelectedPaymentOption() } override suspend fun setupIntentClientSecretForCustomerAttach(): CustomerAdapter.Result { if (overridesSetupIntentClientSecretForCustomerAttach) { CompletableDeferred().also { setupIntentClientSecretForCustomerAttachCallback = it stripeSdkModule?.eventEmitter?.emitOnCustomerAdapterSetupIntentClientSecretForCustomerAttachCallback() val resultFromJavascript = it.await() return CustomerAdapter.Result.success(resultFromJavascript) } } return adapter.setupIntentClientSecretForCustomerAttach() } }