Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce suspend fun for Stripe Android SDK - part1 #3557

Merged
merged 7 commits into from
Apr 6, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions stripe/api/stripe.api
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,8 @@ public final class com/stripe/android/Stripe {
public static synthetic fun handleNextActionForSetupIntent$default (Lcom/stripe/android/Stripe;Landroid/app/Activity;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)V
public static synthetic fun handleNextActionForSetupIntent$default (Lcom/stripe/android/Stripe;Landroidx/fragment/app/Fragment;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)V
public final fun isAuthenticateSourceResult (ILandroid/content/Intent;)Z
public final fun isForPaymentIntentResult (ILandroid/content/Intent;)Z
public final fun isForSetupIntentResult (ILandroid/content/Intent;)Z
public final fun onAuthenticateSourceResult (Landroid/content/Intent;Lcom/stripe/android/ApiResultCallback;)V
public final fun onPaymentResult (ILandroid/content/Intent;Lcom/stripe/android/ApiResultCallback;)Z
public final fun onSetupResult (ILandroid/content/Intent;Lcom/stripe/android/ApiResultCallback;)Z
Expand Down Expand Up @@ -909,6 +911,40 @@ public final class com/stripe/android/StripeIntentResult$Outcome$Companion {
public static final field UNKNOWN I
}

public final class com/stripe/android/StripeSuspendKt {
public static final fun confirmPaymentIntentSuspend (Lcom/stripe/android/Stripe;Lcom/stripe/android/model/ConfirmPaymentIntentParams;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun confirmPaymentIntentSuspend$default (Lcom/stripe/android/Stripe;Lcom/stripe/android/model/ConfirmPaymentIntentParams;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public static final fun confirmSetupIntentSuspend (Lcom/stripe/android/Stripe;Lcom/stripe/android/model/ConfirmSetupIntentParams;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun confirmSetupIntentSuspend$default (Lcom/stripe/android/Stripe;Lcom/stripe/android/model/ConfirmSetupIntentParams;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public static final fun createAccountToken (Lcom/stripe/android/Stripe;Lcom/stripe/android/model/AccountParams;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun createAccountToken$default (Lcom/stripe/android/Stripe;Lcom/stripe/android/model/AccountParams;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public static final fun createBankAccountToken (Lcom/stripe/android/Stripe;Lcom/stripe/android/model/BankAccountTokenParams;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun createBankAccountToken$default (Lcom/stripe/android/Stripe;Lcom/stripe/android/model/BankAccountTokenParams;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public static final fun createCardToken (Lcom/stripe/android/Stripe;Lcom/stripe/android/model/CardParams;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun createCardToken$default (Lcom/stripe/android/Stripe;Lcom/stripe/android/model/CardParams;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public static final fun createCvcUpdateToken (Lcom/stripe/android/Stripe;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun createCvcUpdateToken$default (Lcom/stripe/android/Stripe;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public static final fun createFile (Lcom/stripe/android/Stripe;Lcom/stripe/android/model/StripeFileParams;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun createFile$default (Lcom/stripe/android/Stripe;Lcom/stripe/android/model/StripeFileParams;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public static final fun createPaymentMethod (Lcom/stripe/android/Stripe;Lcom/stripe/android/model/PaymentMethodCreateParams;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun createPaymentMethod$default (Lcom/stripe/android/Stripe;Lcom/stripe/android/model/PaymentMethodCreateParams;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public static final fun createPersonToken (Lcom/stripe/android/Stripe;Lcom/stripe/android/model/PersonTokenParams;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun createPersonToken$default (Lcom/stripe/android/Stripe;Lcom/stripe/android/model/PersonTokenParams;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public static final fun createPiiToken (Lcom/stripe/android/Stripe;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun createPiiToken$default (Lcom/stripe/android/Stripe;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public static final fun createSource (Lcom/stripe/android/Stripe;Lcom/stripe/android/model/SourceParams;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun createSource$default (Lcom/stripe/android/Stripe;Lcom/stripe/android/model/SourceParams;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public static final fun getAuthenticateSourceResult (Lcom/stripe/android/Stripe;ILandroid/content/Intent;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final fun getPaymentIntentResult (Lcom/stripe/android/Stripe;ILandroid/content/Intent;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final fun getSetupIntentResult (Lcom/stripe/android/Stripe;ILandroid/content/Intent;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final fun retrievePaymentIntent (Lcom/stripe/android/Stripe;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun retrievePaymentIntent$default (Lcom/stripe/android/Stripe;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public static final fun retrieveSetupIntent (Lcom/stripe/android/Stripe;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun retrieveSetupIntent$default (Lcom/stripe/android/Stripe;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public static final fun retrieveSource (Lcom/stripe/android/Stripe;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun retrieveSource$default (Lcom/stripe/android/Stripe;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
}

public final class com/stripe/android/StripeTextUtils {
public static final field INSTANCE Lcom/stripe/android/StripeTextUtils;
public static final fun removeSpacesAndHyphens (Ljava/lang/String;)Ljava/lang/String;
Expand Down
70 changes: 70 additions & 0 deletions stripe/src/main/java/com/stripe/android/PaymentController.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.stripe.android

import android.content.Intent
import com.stripe.android.exception.APIConnectionException
import com.stripe.android.exception.APIException
import com.stripe.android.exception.AuthenticationException
import com.stripe.android.exception.InvalidRequestException
import com.stripe.android.model.ConfirmPaymentIntentParams
import com.stripe.android.model.ConfirmStripeIntentParams
import com.stripe.android.model.Source
Expand Down Expand Up @@ -64,6 +68,28 @@ internal interface PaymentController {
callback: ApiResultCallback<PaymentIntentResult>
)

/**
* Get the PaymentIntent's client_secret from {@param data} and use to retrieve
* the PaymentIntent object with updated status.
*
* @param data the result Intent
* @return the [PaymentIntentResult] object
*
* @throws AuthenticationException failure to properly authenticate yourself (check your key)
* @throws InvalidRequestException your request has invalid parameters
* @throws APIConnectionException failure to connect to Stripe's API
* @throws APIException any other type of problem (for instance, a temporary issue with Stripe's servers)
* @throws IllegalArgumentException if the PaymentIntent response's JsonParser returns null
*/
@Throws(
AuthenticationException::class,
InvalidRequestException::class,
APIConnectionException::class,
APIException::class,
IllegalArgumentException::class
)
suspend fun getPaymentIntentResult(data: Intent): PaymentIntentResult
ccen-stripe marked this conversation as resolved.
Show resolved Hide resolved

/**
* If setup authentication triggered an exception, get the exception object and pass to
* [ApiResultCallback.onError].
Expand All @@ -78,11 +104,55 @@ internal interface PaymentController {
callback: ApiResultCallback<SetupIntentResult>
)

/**
* Get the SetupIntent's client_secret from {@param data} and use to retrieve
* the SetupIntent object with updated status.
*
* @param data the result Intent
* @return the [SetupIntentResult] object
*
* @throws AuthenticationException failure to properly authenticate yourself (check your key)
* @throws InvalidRequestException your request has invalid parameters
* @throws APIConnectionException failure to connect to Stripe's API
* @throws APIException any other type of problem (for instance, a temporary issue with Stripe's servers)
* @throws IllegalArgumentException if the SetupIntent response's JsonParser returns null
*/
@Throws(
AuthenticationException::class,
InvalidRequestException::class,
APIConnectionException::class,
APIException::class,
IllegalArgumentException::class
)
suspend fun getSetupIntentResult(data: Intent): SetupIntentResult

fun handleSourceResult(
data: Intent,
callback: ApiResultCallback<Source>
)

/**
* Get the Source's client_secret from {@param data} and use to retrieve
* the Source object with updated status.
*
* @param data the result Intent
* @return the [Source] object
*
* @throws AuthenticationException failure to properly authenticate yourself (check your key)
* @throws InvalidRequestException your request has invalid parameters
* @throws APIConnectionException failure to connect to Stripe's API
* @throws APIException any other type of problem (for instance, a temporary issue with Stripe's servers)
* @throws IllegalArgumentException if the Source response's JsonParser returns null
*/
@Throws(
AuthenticationException::class,
InvalidRequestException::class,
APIConnectionException::class,
APIException::class,
IllegalArgumentException::class
)
suspend fun getSource(data: Intent): Source

/**
* Determine which authentication mechanism should be used, or bypass authentication
* if it is not needed.
Expand Down
50 changes: 41 additions & 9 deletions stripe/src/main/java/com/stripe/android/Stripe.kt
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ import kotlin.coroutines.CoroutineContext
*
*/
class Stripe internal constructor(
private val stripeRepository: StripeRepository,
private val paymentController: PaymentController,
internal val stripeRepository: StripeRepository,
internal val paymentController: PaymentController,
ccen-stripe marked this conversation as resolved.
Show resolved Hide resolved
publishableKey: String,
private val stripeAccountId: String? = null,
internal val stripeAccountId: String? = null,
private val workContext: CoroutineContext = Dispatchers.IO
) {
private val publishableKey: String = ApiKeyValidator().requireValid(publishableKey)
internal val publishableKey: String = ApiKeyValidator().requireValid(publishableKey)

/**
* Constructor with publishable key and Stripe Connect account id.
Expand Down Expand Up @@ -322,6 +322,20 @@ class Stripe internal constructor(
)
}

/**
* Check if the requestCode and intent is for [PaymentIntentResult].
* The Intent should the retrieved from result from `Activity#onActivityResult(int, int, Intent)}}`
* by activity started with [confirmPayment] or [handleNextActionForPayment].
*
* @return whether the requestCode and intent is for [PaymentIntentResult].
*/
fun isForPaymentIntentResult(
requestCode: Int,
data: Intent?
): Boolean {
return data != null && paymentController.shouldHandlePaymentResult(requestCode, data)
}
ccen-stripe marked this conversation as resolved.
Show resolved Hide resolved

/**
* Should be called via `Activity#onActivityResult(int, int, Intent)}}` to handle the
* result of a PaymentIntent automatic confirmation (see [confirmPayment]) or
Expand All @@ -333,8 +347,8 @@ class Stripe internal constructor(
data: Intent?,
callback: ApiResultCallback<PaymentIntentResult>
): Boolean {
return if (data != null && paymentController.shouldHandlePaymentResult(requestCode, data)) {
paymentController.handlePaymentResult(data, callback)
return if (isForPaymentIntentResult(requestCode, data)) {
paymentController.handlePaymentResult(data!!, callback)
true
} else {
false
Expand Down Expand Up @@ -597,6 +611,20 @@ class Stripe internal constructor(
)
}

/**
* Check if the requestCode and intent is for [SetupIntentResult].
* The Intent should the retrieved from result from `Activity#onActivityResult(int, int, Intent)}}`
* by activity started with [confirmSetupIntent].
*
* @return whether the requestCode and intent is for [SetupIntentResult].
*/
fun isForSetupIntentResult(
requestCode: Int,
data: Intent?
): Boolean {
return data != null && paymentController.shouldHandleSetupResult(requestCode, data)
}

/**
* Should be called via `Activity#onActivityResult(int, int, Intent)}}` to handle the
* result of a SetupIntent confirmation (see [confirmSetupIntent]).
Expand All @@ -607,8 +635,8 @@ class Stripe internal constructor(
data: Intent?,
callback: ApiResultCallback<SetupIntentResult>
): Boolean {
return if (data != null && paymentController.shouldHandleSetupResult(requestCode, data)) {
paymentController.handleSetupResult(data, callback)
return if (isForSetupIntentResult(requestCode, data)) {
paymentController.handleSetupResult(data!!, callback)
true
} else {
false
Expand Down Expand Up @@ -850,7 +878,11 @@ class Stripe internal constructor(
}

/**
* Should be called in `onActivityResult()` to determine if the result is for Source authentication
* Check if the requestCode and intent is for [Source] authentication.
* The Intent should the retrieved from result from `Activity#onActivityResult(int, int, Intent)}}`
* by activity started with [authenticateSource].
*
* @return whether the requestCode and intent is for [Source] authentication
*/
fun isAuthenticateSourceResult(
requestCode: Int,
Expand Down
Loading