Add proper endpoint for setting iDEAL default payment method.

This commit is contained in:
Alex Hart
2023-10-23 13:13:13 -04:00
committed by GitHub
parent 10eec025d2
commit a4df433d80
9 changed files with 47 additions and 44 deletions

View File

@@ -202,23 +202,19 @@ class StripeRepository(activity: Activity) : StripeApi.PaymentIntentFetcher, Str
* that we are successful and proceed as normal. If the payment didn't actually succeed, then we
* expect an error later in the chain to inform us of this.
*/
fun getStatusAndPaymentMethodId(stripeIntentAccessor: StripeIntentAccessor, paymentSourceType: PaymentSourceType): Single<StatusAndPaymentMethodId> {
fun getStatusAndPaymentMethodId(stripeIntentAccessor: StripeIntentAccessor): Single<StatusAndPaymentMethodId> {
return Single.fromCallable {
when (stripeIntentAccessor.objectType) {
StripeIntentAccessor.ObjectType.NONE -> StatusAndPaymentMethodId(StripeIntentStatus.SUCCEEDED, null)
StripeIntentAccessor.ObjectType.NONE -> StatusAndPaymentMethodId(stripeIntentAccessor.intentId, StripeIntentStatus.SUCCEEDED, null)
StripeIntentAccessor.ObjectType.PAYMENT_INTENT -> stripeApi.getPaymentIntent(stripeIntentAccessor).let {
if (it.status == null) {
Log.d(TAG, "Returned payment intent had a null status.", true)
}
StatusAndPaymentMethodId(it.status ?: StripeIntentStatus.SUCCEEDED, it.paymentMethod)
StatusAndPaymentMethodId(stripeIntentAccessor.intentId, it.status ?: StripeIntentStatus.SUCCEEDED, it.paymentMethod)
}
StripeIntentAccessor.ObjectType.SETUP_INTENT -> stripeApi.getSetupIntent(stripeIntentAccessor).let {
if (paymentSourceType == PaymentSourceType.Stripe.IDEAL) {
StatusAndPaymentMethodId(it.status, it.requireGeneratedSepaDebit())
} else {
StatusAndPaymentMethodId(it.status, it.paymentMethod)
}
StatusAndPaymentMethodId(stripeIntentAccessor.intentId, it.status, it.paymentMethod)
}
}
}
@@ -226,6 +222,7 @@ class StripeRepository(activity: Activity) : StripeApi.PaymentIntentFetcher, Str
fun setDefaultPaymentMethod(
paymentMethodId: String,
setupIntentId: String,
paymentSourceType: PaymentSourceType
): Completable {
return Single.fromCallable {
@@ -235,9 +232,15 @@ class StripeRepository(activity: Activity) : StripeApi.PaymentIntentFetcher, Str
Log.d(TAG, "Setting default payment method via Signal service...")
// TODO [sepa] -- iDEAL has its own call
Single.fromCallable {
ApplicationDependencies
.getDonationsService()
.setDefaultStripePaymentMethod(it.subscriberId, paymentMethodId)
if (paymentSourceType == PaymentSourceType.Stripe.IDEAL) {
ApplicationDependencies
.getDonationsService()
.setDefaultIdealPaymentMethod(it.subscriberId, setupIntentId)
} else {
ApplicationDependencies
.getDonationsService()
.setDefaultStripePaymentMethod(it.subscriberId, paymentMethodId)
}
}
}.flatMap(ServiceResponse<EmptyResponse>::flattenResult).ignoreElement().doOnComplete {
Log.d(TAG, "Set default payment method via Signal service!")
@@ -267,6 +270,7 @@ class StripeRepository(activity: Activity) : StripeApi.PaymentIntentFetcher, Str
}
data class StatusAndPaymentMethodId(
val intentId: String,
val status: StripeIntentStatus,
val paymentMethod: String?
)

View File

@@ -11,6 +11,7 @@ import android.content.Intent
import android.net.Uri
import android.widget.Toast
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.signal.donations.StripeApi
import org.thoughtcrime.securesms.R
/**
@@ -21,7 +22,7 @@ object ExternalNavigationHelper {
fun maybeLaunchExternalNavigationIntent(context: Context, webRequestUri: Uri?, launchIntent: (Intent) -> Unit): Boolean {
val url = webRequestUri ?: return false
if (url.scheme?.startsWith("http") == true) {
if (url.scheme?.startsWith("http") == true || url.scheme == StripeApi.RETURN_URL_SCHEME) {
return false
}

View File

@@ -165,14 +165,13 @@ class StripePaymentInProgressViewModel(
paymentSourceProvider.paymentSourceType.code
)
)
.flatMap { secure3DSResult -> stripeRepository.getStatusAndPaymentMethodId(secure3DSResult, paymentSourceProvider.paymentSourceType) }
.map { (_, paymentMethod) -> paymentMethod ?: secure3DSAction.paymentMethodId!! }
.flatMap { secure3DSResult -> stripeRepository.getStatusAndPaymentMethodId(secure3DSResult) }
}
.flatMapCompletable { stripeRepository.setDefaultPaymentMethod(it, paymentSourceProvider.paymentSourceType) }
.flatMapCompletable { stripeRepository.setDefaultPaymentMethod(it.paymentMethod!!, it.intentId, paymentSourceProvider.paymentSourceType) }
.onErrorResumeNext {
when {
it is DonationError -> Completable.error(it)
it is DonationProcessorError -> Completable.error(it.toDonationError(DonationErrorSource.MONTHLY, paymentSourceProvider.paymentSourceType))
when (it) {
is DonationError -> Completable.error(it)
is DonationProcessorError -> Completable.error(it.toDonationError(DonationErrorSource.MONTHLY, paymentSourceProvider.paymentSourceType))
else -> Completable.error(DonationError.getPaymentSetupError(DonationErrorSource.MONTHLY, it, paymentSourceProvider.paymentSourceType))
}
}
@@ -225,7 +224,7 @@ class StripePaymentInProgressViewModel(
)
)
}
.flatMap { stripeRepository.getStatusAndPaymentMethodId(it, paymentSourceProvider.paymentSourceType) }
.flatMap { stripeRepository.getStatusAndPaymentMethodId(it) }
.flatMapCompletable {
oneTimeDonationRepository.waitForOneTimeRedemption(
gatewayRequest = request,

View File

@@ -303,7 +303,7 @@ public class DonationReceiptRedemptionJob extends BaseJob {
}
private boolean isForSubscription() {
return Objects.equals(getParameters().getQueue(), SUBSCRIPTION_QUEUE);
return Objects.requireNonNull(getParameters().getQueue()).startsWith(SUBSCRIPTION_QUEUE);
}
private boolean isForOneTimeDonation() {

View File

@@ -139,8 +139,13 @@ class ExternalLaunchDonationJob private constructor(
val subscriber = SignalStore.donationsValues().requireSubscriber()
Log.i(TAG, "Setting default payment method...", true)
val setPaymentMethodResponse = ApplicationDependencies.getDonationsService()
.setDefaultStripePaymentMethod(subscriber.subscriberId, stripeSetupIntent.paymentMethod!!)
val setPaymentMethodResponse = if (stripe3DSData.paymentSourceType == PaymentSourceType.Stripe.IDEAL) {
ApplicationDependencies.getDonationsService()
.setDefaultIdealPaymentMethod(subscriber.subscriberId, stripeSetupIntent.id)
} else {
ApplicationDependencies.getDonationsService()
.setDefaultStripePaymentMethod(subscriber.subscriberId, stripeSetupIntent.paymentMethod!!)
}
getResultOrThrow(setPaymentMethodResponse)