diff --git a/stripe/lib/src/stripe.dart b/stripe/lib/src/stripe.dart index d6e4cbee9..75b0be18a 100644 --- a/stripe/lib/src/stripe.dart +++ b/stripe/lib/src/stripe.dart @@ -81,6 +81,17 @@ class Stripe { } } + Future createPaymentMethodFromGooglePay( + Map data) async { + try { + final paymentMethod = + await _platform.createPaymentMethodFromGooglePay(data); + return paymentMethod; + } on StripeError catch (error) { + throw StripeError.generic(message: error.message, code: error.message); + } + } + Future retrievePaymentIntent(String clientSecret) async { try { final paymentMethod = await _platform.retrievePaymentIntent(clientSecret); diff --git a/stripe_android/android/src/main/kotlin/com/facebook/react/bridge/BaseActivityEventListener.java b/stripe_android/android/src/main/kotlin/com/facebook/react/bridge/BaseActivityEventListener.java deleted file mode 100644 index efbc4f2b4..000000000 --- a/stripe_android/android/src/main/kotlin/com/facebook/react/bridge/BaseActivityEventListener.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.facebook.react.bridge; - -import android.content.Intent; - -import io.flutter.plugin.common.PluginRegistry; - -public abstract class BaseActivityEventListener implements ActivityEventListener, PluginRegistry.ActivityResultListener { - @Override - public boolean onActivityResult(int requestCode, int resultCode, Intent data) { - onActivityResult(null, requestCode, resultCode, data); - return true; - } -} diff --git a/stripe_android/android/src/main/kotlin/com/facebook/react/bridge/BaseActivityEventListener.kt b/stripe_android/android/src/main/kotlin/com/facebook/react/bridge/BaseActivityEventListener.kt new file mode 100644 index 000000000..e6cc87391 --- /dev/null +++ b/stripe_android/android/src/main/kotlin/com/facebook/react/bridge/BaseActivityEventListener.kt @@ -0,0 +1,14 @@ +package com.facebook.react.bridge + +import android.content.Intent +import com.stripe.android.Stripe +import io.flutter.plugin.common.PluginRegistry.ActivityResultListener + +abstract class BaseActivityEventListener(private val stripeProvider: () -> Stripe?) : ActivityEventListener, ActivityResultListener { + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent): Boolean { + if (stripeProvider()?.isAuthenticateSourceResult(requestCode, data) == true) { + onActivityResult(null, requestCode, resultCode, data) + } + return true + } +} \ No newline at end of file diff --git a/stripe_android/android/src/main/kotlin/com/flutter/stripe/StripeAndroidPlugin.kt b/stripe_android/android/src/main/kotlin/com/flutter/stripe/StripeAndroidPlugin.kt index 4241ecc36..1ac74ce02 100644 --- a/stripe_android/android/src/main/kotlin/com/flutter/stripe/StripeAndroidPlugin.kt +++ b/stripe_android/android/src/main/kotlin/com/flutter/stripe/StripeAndroidPlugin.kt @@ -4,6 +4,8 @@ import androidx.annotation.NonNull import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReadableMap import com.reactnativestripesdk.StripeSdkModule +import com.stripe.android.model.GooglePayResult +import com.stripe.android.model.PaymentMethodCreateParams import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.embedding.engine.plugins.activity.ActivityAware import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding @@ -11,6 +13,7 @@ import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler import io.flutter.plugin.common.MethodChannel.Result +import org.json.JSONObject /** StripeAndroidPlugin */ class StripeAndroidPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { @@ -63,6 +66,10 @@ class StripeAndroidPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { clientSecret = call.requiredArgument("clientSecret"), promise = Promise(result) ) + "createPaymentMethodFromGooglePay" -> stripeSdk.createPaymentMethodFromGooglePay( + data = call.requiredArgument("data"), + promise = Promise(result) + ) else -> result.notImplemented() } } @@ -94,7 +101,8 @@ private inline fun MethodCall.optionalArgument(key: String): T? { private inline fun MethodCall.requiredArgument(key: String): T { if (T::class.java == ReadableMap::class.java) { - return ReadableMap(argument>(key) ?: error("Required parameter $key not set")) as T + return ReadableMap(argument>(key) + ?: error("Required parameter $key not set")) as T } return argument(key) ?: error("Required parameter $key not set") } diff --git a/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/StripeSdkModule.kt b/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/StripeSdkModule.kt index e6a294799..a3d642492 100644 --- a/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/StripeSdkModule.kt +++ b/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/StripeSdkModule.kt @@ -1,13 +1,16 @@ package com.reactnativestripesdk import android.app.Activity -import android.content.Context import android.content.Intent import android.os.AsyncTask import com.facebook.react.bridge.* import com.stripe.android.* -import com.stripe.android.model.* +import com.stripe.android.model.PaymentMethod +import com.stripe.android.model.PaymentMethodCreateParams +import com.stripe.android.model.StripeIntent +import com.stripe.android.model.Token import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding +import org.json.JSONObject class StripeSdkModule(context: ActivityPluginBinding) : ReactContextBaseJavaModule(context) { override fun getName(): String { @@ -20,7 +23,13 @@ class StripeSdkModule(context: ActivityPluginBinding) : ReactContextBaseJavaModu private var handleCardActionPromise: Promise? = null private var confirmSetupIntentPromise: Promise? = null - private val mActivityEventListener = object : BaseActivityEventListener() { + private val mActivityEventListener = object : BaseActivityEventListener( + stripeProvider = { + if (this::stripe.isInitialized) { + stripe + } else null + } + ) { override fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, data: Intent) { stripe.onSetupResult(requestCode, data, object : ApiResultCallback { override fun onSuccess(result: SetupIntentResult) { @@ -223,4 +232,29 @@ class StripeSdkModule(context: ActivityPluginBinding) : ReactContextBaseJavaModu promise.reject(ConfirmPaymentErrorType.Failed.toString(), error.localizedMessage) } } + + + /// not part of original plugin + + @ReactMethod + fun createPaymentMethodFromGooglePay(data: ReadableMap, promise: Promise) { + val paymentDataJson = JSONObject(data) + + //val shippingInformation = GooglePayResult.fromJson(paymentDataJson).shippingInformation + // TODO do we need it? + val paymentMethodCreateParams = PaymentMethodCreateParams.createFromGooglePay(paymentDataJson) + + stripe.createPaymentMethod( + paymentMethodCreateParams, + callback = object : ApiResultCallback { + override fun onError(e: Exception) { + confirmPromise?.reject("Failed", e.localizedMessage) + } + + override fun onSuccess(result: PaymentMethod) { + val paymentMethodMap: WritableMap = mapFromPaymentMethod(result) + promise.resolve(paymentMethodMap) + } + }) + } } diff --git a/stripe_platform_interface/lib/src/method_channel_stripe.dart b/stripe_platform_interface/lib/src/method_channel_stripe.dart index 5ad665039..06eb088e1 100644 --- a/stripe_platform_interface/lib/src/method_channel_stripe.dart +++ b/stripe_platform_interface/lib/src/method_channel_stripe.dart @@ -59,6 +59,16 @@ class MethodChannelStripe extends StripePlatform { return PaymentMethod.fromJson(result.unfoldToNonNull()); } + @override + Future createPaymentMethodFromGooglePay( + Map data) async { + final result = + await _methodChannel.invokeMethod('createPaymentMethodFromGooglePay', { + 'data': data, + }); + return PaymentMethod.fromJson(result.unfoldToNonNull()); + } + @override Future configure3dSecure(ThreeDSecureConfigurationParams params) { // TODO: implement configure3dSecure diff --git a/stripe_platform_interface/lib/stripe_platform_interface.dart b/stripe_platform_interface/lib/stripe_platform_interface.dart index 8661eaee6..e68741f70 100644 --- a/stripe_platform_interface/lib/stripe_platform_interface.dart +++ b/stripe_platform_interface/lib/stripe_platform_interface.dart @@ -41,6 +41,9 @@ abstract class StripePlatform extends PlatformInterface { Map options = const {}, ]); + Future createPaymentMethodFromGooglePay( + Map data); + Future handleCardAction(String paymentIntentClientSecret); Future confirmPaymentMethod( String paymentIntentClientSecret, PaymentMethodParams data,