/* * Copyright (c) 2023 Adyen N.V. * * This file is open source and available under the MIT license. See the LICENSE file for more info. */ package com.adyenreactnativesdk.component.googlepay import com.adyen.checkout.components.core.CheckoutConfiguration import com.adyen.checkout.components.core.ComponentAvailableCallback import com.adyen.checkout.components.core.PaymentMethod import com.adyen.checkout.components.core.PaymentMethodsApiResponse import com.adyen.checkout.googlepay.GooglePayComponent import com.adyenreactnativesdk.component.base.BaseActionModule import com.adyenreactnativesdk.component.base.KnownException import com.adyenreactnativesdk.component.base.ModuleException import com.adyenreactnativesdk.configuration.CheckoutConfigurationFactory import com.adyenreactnativesdk.util.ReactNativeJson import com.adyenreactnativesdk.util.messaging.MessageBus import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.ReactMethod import com.facebook.react.bridge.ReadableMap class GooglePayModule( context: ReactApplicationContext?, messageBus: MessageBus, ) : BaseActionModule(context, messageBus) { override fun getName(): String = COMPONENT_NAME override fun getConstants(): MutableMap = mutableMapOf("supportedEvents" to supportedEvents()) @ReactMethod fun addListener(eventName: String?) { // No JS events expected } @ReactMethod fun removeListeners(count: Int?) { // No JS events expected } @ReactMethod fun open( paymentMethodsData: ReadableMap, configuration: ReadableMap, ) { val checkoutConfiguration: CheckoutConfiguration val paymentMethodsResponse: PaymentMethodsApiResponse try { paymentMethodsResponse = getPaymentMethodsApiResponse(paymentMethodsData) checkoutConfiguration = CheckoutConfigurationFactory.get(configuration) } catch (e: java.lang.Exception) { return sendError(e) } val googlePayPaymentMethod = getPaymentMethod(paymentMethodsResponse, PAYMENT_METHOD_KEYS) if (googlePayPaymentMethod == null) { sendError(ModuleException.NoPaymentMethods(PAYMENT_METHOD_KEYS)) return } val payPaymentMethod: PaymentMethod = googlePayPaymentMethod currentModule = this GooglePayComponent.run { PROVIDER.isAvailable( appCompatActivity.application, payPaymentMethod, checkoutConfiguration, object : ComponentAvailableCallback { override fun onAvailabilityResult( isAvailable: Boolean, paymentMethod: PaymentMethod, ) { if (!isAvailable) { sendError(GooglePayException.NotSupported()) return } GooglePayFragment.show( appCompatActivity.supportFragmentManager, checkoutConfiguration, paymentMethod, session, ) } }, ) } } @ReactMethod fun handle(actionMap: ReadableMap?) { try { val action = parseActionFromMap(actionMap) GooglePayFragment.handle(appCompatActivity.supportFragmentManager, action) } catch (e: Exception) { sendError(e) } } @ReactMethod override fun hide( success: Boolean, message: ReadableMap?, ) { cleanup() GooglePayFragment.hide(appCompatActivity.supportFragmentManager) } @ReactMethod fun isAvailable( paymentMethods: ReadableMap, configuration: ReadableMap, promise: Promise, ) { val checkoutConfiguration: CheckoutConfiguration val paymentMethod: PaymentMethod try { val jsonObject = ReactNativeJson.convertMapToJson(paymentMethods) paymentMethod = PaymentMethod.SERIALIZER.deserialize(jsonObject) checkoutConfiguration = CheckoutConfigurationFactory.get(configuration) } catch (e: java.lang.Exception) { return promise.reject(e) } val callback: ComponentAvailableCallback = object : ComponentAvailableCallback { override fun onAvailabilityResult( isAvailable: Boolean, paymentMethod: PaymentMethod, ) { promise.resolve(isAvailable) } } GooglePayComponent.PROVIDER.isAvailable( appCompatActivity.application, paymentMethod, checkoutConfiguration, callback, ) } companion object { private const val COMPONENT_NAME = "AdyenGooglePay" internal const val GOOGLEPAY_REQUEST_CODE = 1001 private val PAYMENT_METHOD_KEYS = setOf("paywithgoogle", "googlepay") } } sealed class GooglePayException( code: String, message: String, cause: Throwable? = null, ) : KnownException(code = code, errorMessage = message, cause) { class NotSupported : GooglePayException( code = "notSupported", message = "GooglePay unavailable", ) }