Skip to content

Commit

Permalink
Merge pull request #4 from flutter-stripe/pay_plugin
Browse files Browse the repository at this point in the history
Pay plugin
  • Loading branch information
jonasbark authored Apr 6, 2021
2 parents 200fa7b + 13065c5 commit b7d3962
Show file tree
Hide file tree
Showing 15 changed files with 689 additions and 27 deletions.
6 changes: 6 additions & 0 deletions stripe/example/lib/screens/setup_future_payment_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ class _SetupFuturePaymentScreenState extends State<SetupFuturePaymentScreen> {
}

Future<void> _handlePayPress() async {
// just for testing purposes
final test = await Stripe.instance.confirmPaymentMethod(
'paymentIntentClientSecret',
PaymentMethodParams.cardFromToken(
cardDetails: CardTokenDetails(token: 'examplePaymentMethodToken')));
print(test);
if (_card == null) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import android.app.Activity;
import android.content.Intent;

import androidx.annotation.Nullable;

public interface ActivityEventListener {
public void onActivityResult(Activity a, int requestCode, int resultCode, Intent data);
public boolean onActivityResult(@Nullable Activity a, int requestCode, int resultCode, @Nullable Intent data);
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.facebook.react.bridge

import android.content.Intent
import com.stripe.android.Stripe
import io.flutter.plugin.common.PluginRegistry.ActivityResultListener

abstract class BaseActivityEventListener : ActivityEventListener, ActivityResultListener {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean {
return onActivityResult(null, requestCode, resultCode, data)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -275,12 +275,16 @@ internal fun mapToPaymentMethodCreateParams(cardData: ReadableMap): PaymentMetho
}

internal fun mapToCard(card: ReadableMap): PaymentMethodCreateParams.Card {
return PaymentMethodCreateParams.Card.Builder()
.setCvc(card.getString("cvc"))
.setExpiryMonth(card.getInt("expiryMonth"))
.setExpiryYear(card.getInt("expiryYear"))
.setNumber(card.getString("number").orEmpty())
.build()
if (card.hasKey("token")) {
return PaymentMethodCreateParams.Card.create(card.getString("token"))
} else {
return PaymentMethodCreateParams.Card.Builder()
.setCvc(card.getString("cvc"))
.setExpiryMonth(card.getInt("expiryMonth"))
.setExpiryYear(card.getInt("expiryYear"))
.setNumber(card.getString("number").orEmpty())
.build()
}
}

fun getValOr(map: ReadableMap, key: String, default: String? = ""): String? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ class PaymentMethodCreateParamsFactory(private val clientSecret: String, private
return when (paymentMethodType) {
PaymentMethod.Type.Card -> createCardPaymentConfirmParams()
PaymentMethod.Type.Ideal -> createIDEALPaymentConfirmParams(paymentMethodType)
PaymentMethod.Type.Alipay -> createAlipayPaymentConfirmParams()
PaymentMethod.Type.Bancontact -> createBancontactPaymentConfirmParams()
PaymentMethod.Type.Giropay -> createGiropayPaymentConfirmParams()
PaymentMethod.Type.Eps -> createEPSPaymentConfirmParams()
PaymentMethod.Type.GrabPay -> createGrabPayPaymentConfirmParams()
PaymentMethod.Type.P24 -> createP24PaymentConfirmParams()
else -> {
throw Exception("This paymentMethodType is not supported yet")
}
Expand All @@ -28,6 +34,7 @@ class PaymentMethodCreateParamsFactory(private val clientSecret: String, private
return when (paymentMethodType) {
PaymentMethod.Type.Card -> createCardPaymentSetupParams()
PaymentMethod.Type.Ideal -> createIDEALPaymentSetupParams(paymentMethodType)
PaymentMethod.Type.Bancontact -> createBancontactPaymentSetupParams()
else -> {
throw Exception("This paymentMethodType is not supported yet")
}
Expand Down Expand Up @@ -56,6 +63,25 @@ class PaymentMethodCreateParamsFactory(private val clientSecret: String, private
)
}

@Throws(PaymentMethodCreateParamsException::class)
private fun createP24PaymentConfirmParams(): ConfirmPaymentIntentParams {
val billingDetails = billingDetailsParams?.let { it } ?: run {
throw PaymentMethodCreateParamsException("You must provide billing details")
}
if (urlScheme == null) {
throw PaymentMethodCreateParamsException("You must provide urlScheme")
}

val params = PaymentMethodCreateParams.createP24(billingDetails)

return ConfirmPaymentIntentParams
.createWithPaymentMethodCreateParams(
paymentMethodCreateParams = params,
clientSecret = clientSecret,
returnUrl = mapToReturnURL(urlScheme)
)
}

@Throws(PaymentMethodCreateParamsException::class)
private fun createCardPaymentConfirmParams(): ConfirmPaymentIntentParams {
val cardParams = getMapOrNull(params, "cardDetails")
Expand Down Expand Up @@ -122,6 +148,99 @@ class PaymentMethodCreateParamsFactory(private val clientSecret: String, private
return ConfirmSetupIntentParams
.create(paymentMethodParams, clientSecret)
}

@Throws(PaymentMethodCreateParamsException::class)
private fun createAlipayPaymentConfirmParams(): ConfirmPaymentIntentParams {
return ConfirmPaymentIntentParams.createAlipay(clientSecret)
}

@Throws(PaymentMethodCreateParamsException::class)
private fun createGrabPayPaymentConfirmParams(): ConfirmPaymentIntentParams {
if (urlScheme == null) {
throw PaymentMethodCreateParamsException("You must provide urlScheme")
}
val billingDetails = billingDetailsParams ?: PaymentMethod.BillingDetails()
val params = PaymentMethodCreateParams.createGrabPay(billingDetails)

return ConfirmPaymentIntentParams
.createWithPaymentMethodCreateParams(
paymentMethodCreateParams = params,
clientSecret = clientSecret,
returnUrl = mapToReturnURL(urlScheme)
)
}

@Throws(PaymentMethodCreateParamsException::class)
private fun createBancontactPaymentConfirmParams(): ConfirmPaymentIntentParams {
val billingDetails = billingDetailsParams?.let { it } ?: run {
throw PaymentMethodCreateParamsException("You must provide billing details")
}
if (urlScheme == null) {
throw PaymentMethodCreateParamsException("You must provide urlScheme")
}
val params = PaymentMethodCreateParams.createBancontact(billingDetails)

return ConfirmPaymentIntentParams
.createWithPaymentMethodCreateParams(
paymentMethodCreateParams = params,
clientSecret = clientSecret,
returnUrl = mapToReturnURL(urlScheme)
)
}

@Throws(PaymentMethodCreateParamsException::class)
private fun createBancontactPaymentSetupParams(): ConfirmSetupIntentParams {
val billingDetails = billingDetailsParams?.let { it } ?: run {
throw PaymentMethodCreateParamsException("You must provide billing details")
}
if (urlScheme == null) {
throw PaymentMethodCreateParamsException("You must provide urlScheme")
}
val params = PaymentMethodCreateParams.createBancontact(billingDetails)

return ConfirmSetupIntentParams
.create(
paymentMethodCreateParams = params,
clientSecret = clientSecret,
returnUrl = mapToReturnURL(urlScheme)
)
}

@Throws(PaymentMethodCreateParamsException::class)
private fun createEPSPaymentConfirmParams(): ConfirmPaymentIntentParams {
val billingDetails = billingDetailsParams?.let { it } ?: run {
throw PaymentMethodCreateParamsException("You must provide billing details")
}
if (urlScheme == null) {
throw PaymentMethodCreateParamsException("You must provide urlScheme")
}
val params = PaymentMethodCreateParams.createEps(billingDetails)

return ConfirmPaymentIntentParams
.createWithPaymentMethodCreateParams(
paymentMethodCreateParams = params,
clientSecret = clientSecret,
returnUrl = mapToReturnURL(urlScheme)
)
}

@Throws(PaymentMethodCreateParamsException::class)
private fun createGiropayPaymentConfirmParams(): ConfirmPaymentIntentParams {
val billingDetails = billingDetailsParams?.let { it } ?: run {
throw PaymentMethodCreateParamsException("You must provide billing details")
}
if (urlScheme == null) {
throw PaymentMethodCreateParamsException("You must provide urlScheme")
}
val params = PaymentMethodCreateParams.createGiropay(billingDetails)

return ConfirmPaymentIntentParams
.createWithPaymentMethodCreateParams(
paymentMethodCreateParams = params,
clientSecret = clientSecret,
returnUrl = mapToReturnURL(urlScheme)
)
}
}

class PaymentMethodCreateParamsException(message:String): Exception(message)
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@ class StripeSdkModule(context: ActivityPluginBinding) : ReactContextBaseJavaModu
private var confirmSetupIntentPromise: Promise? = null

private val mActivityEventListener = object : BaseActivityEventListener() {

override fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, data: Intent) {
stripe.onSetupResult(requestCode, data, object : ApiResultCallback<SetupIntentResult> {
override fun onActivityResult(activity: Activity?, requestCode: Int, resultCode: Int, data: Intent?): Boolean {
val onSetupResult = stripe.onSetupResult(requestCode, data, object : ApiResultCallback<SetupIntentResult> {
override fun onSuccess(result: SetupIntentResult) {
val setupIntent = result.intent
when (setupIntent.status) {
Expand All @@ -46,12 +45,14 @@ class StripeSdkModule(context: ActivityPluginBinding) : ReactContextBaseJavaModu
}
})

stripe.onPaymentResult(requestCode, data, object : ApiResultCallback<PaymentIntentResult> {
val onPaymentResult = stripe.onPaymentResult(requestCode, data, object : ApiResultCallback<PaymentIntentResult> {
override fun onSuccess(result: PaymentIntentResult) {
val paymentIntent = result.intent

when (paymentIntent.status) {
StripeIntent.Status.Succeeded -> {
StripeIntent.Status.Succeeded,
StripeIntent.Status.Processing,
StripeIntent.Status.RequiresCapture -> {
confirmPromise?.resolve(mapFromPaymentIntentResult(paymentIntent))
handleCardActionPromise?.resolve(mapFromPaymentIntentResult(paymentIntent))
}
Expand Down Expand Up @@ -81,13 +82,15 @@ class StripeSdkModule(context: ActivityPluginBinding) : ReactContextBaseJavaModu
handleCardActionPromise?.reject(NextPaymentActionErrorType.Failed.toString(), e.toString())
}
})

return onSetupResult || onPaymentResult
}
}

private lateinit var stripe: Stripe

init {
context.addActivityResultListener(mActivityEventListener)
context.addActivityResultListener(mActivityEventListener);
}

private fun configure3dSecure(params: ReadableMap) {
Expand Down
5 changes: 5 additions & 0 deletions stripe_ios/ios/Classes/Mappers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ class Mappers {
}

class func mapToPaymentMethodCardParams(params: NSDictionary) -> STPPaymentMethodCardParams {
if let token = params["token"] {
let methodParams = STPPaymentMethodCardParams()
methodParams.token = RCTConvert.nsString(token)
return methodParams
}
let cardSourceParams = STPCardParams()
cardSourceParams.number = RCTConvert.nsString(params["number"])
cardSourceParams.cvc = RCTConvert.nsString(params["cvc"])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class MethodChannelStripe extends StripePlatform {
final result = await _methodChannel
.invokeMapMethod<String, dynamic>('confirmPaymentMethod', {
'paymentIntentClientSecret': paymentIntentClientSecret,
'data': params.toJson(),
'params': params.toJson(),
'options': options,
});
return PaymentIntent.fromJson(result.unfoldToNonNull());
Expand Down
11 changes: 11 additions & 0 deletions stripe_platform_interface/lib/src/models/card_field_input.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ class ColorKey {
}
}

@freezed
class CardTokenDetails with _$CardTokenDetails {
@JsonSerializable(explicitToJson: true)
const factory CardTokenDetails({
required String token,
}) = _CardTokenDetails;

factory CardTokenDetails.fromJson(Map<String, dynamic> json) =>
_$CardTokenDetailsFromJson(json);
}

@freezed
class CardFieldInputDetails with _$CardFieldInputDetails {
@JsonSerializable(explicitToJson: true)
Expand Down
Loading

0 comments on commit b7d3962

Please sign in to comment.