mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-23 04:28:35 +00:00
Separate PayPal flags into one-time and recurring.
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
package org.thoughtcrime.securesms.components.settings.app.subscription
|
package org.thoughtcrime.securesms.components.settings.app.subscription
|
||||||
|
|
||||||
|
import org.signal.donations.PaymentSourceType
|
||||||
|
import org.thoughtcrime.securesms.components.settings.app.subscription.donate.DonateToSignalType
|
||||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags
|
import org.thoughtcrime.securesms.util.FeatureFlags
|
||||||
import org.thoughtcrime.securesms.util.LocaleFeatureFlags
|
import org.thoughtcrime.securesms.util.LocaleFeatureFlags
|
||||||
@@ -21,18 +23,34 @@ object InAppDonations {
|
|||||||
return isCreditCardAvailable() || isPayPalAvailable() || isGooglePayAvailable()
|
return isCreditCardAvailable() || isPayPalAvailable() || isGooglePayAvailable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isPaymentSourceAvailable(paymentSourceType: PaymentSourceType, donateToSignalType: DonateToSignalType): Boolean {
|
||||||
|
return when (paymentSourceType) {
|
||||||
|
PaymentSourceType.PayPal -> isPayPalAvailableForDonateToSignalType(donateToSignalType)
|
||||||
|
PaymentSourceType.Stripe.CreditCard -> isCreditCardAvailable()
|
||||||
|
PaymentSourceType.Stripe.GooglePay -> isGooglePayAvailable()
|
||||||
|
PaymentSourceType.Unknown -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isPayPalAvailableForDonateToSignalType(donateToSignalType: DonateToSignalType): Boolean {
|
||||||
|
return when (donateToSignalType) {
|
||||||
|
DonateToSignalType.ONE_TIME, DonateToSignalType.GIFT -> FeatureFlags.paypalOneTimeDonations()
|
||||||
|
DonateToSignalType.MONTHLY -> FeatureFlags.paypalRecurringDonations()
|
||||||
|
} && !LocaleFeatureFlags.isPayPalDisabled()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the user is in a region that supports credit cards, based off local phone number.
|
* Whether the user is in a region that supports credit cards, based off local phone number.
|
||||||
*/
|
*/
|
||||||
fun isCreditCardAvailable(): Boolean {
|
private fun isCreditCardAvailable(): Boolean {
|
||||||
return FeatureFlags.creditCardPayments() && !LocaleFeatureFlags.isCreditCardDisabled()
|
return FeatureFlags.creditCardPayments() && !LocaleFeatureFlags.isCreditCardDisabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the user is in a region that supports PayPal, based off local phone number.
|
* Whether the user is in a region that supports PayPal, based off local phone number.
|
||||||
*/
|
*/
|
||||||
fun isPayPalAvailable(): Boolean {
|
private fun isPayPalAvailable(): Boolean {
|
||||||
return FeatureFlags.paypalDonations() && !LocaleFeatureFlags.isPayPalDisabled()
|
return (FeatureFlags.paypalOneTimeDonations() || FeatureFlags.paypalRecurringDonations()) && !LocaleFeatureFlags.isPayPalDisabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -86,10 +86,14 @@ class DonationCheckoutDelegate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleGatewaySelectionResponse(gatewayResponse: GatewayResponse) {
|
private fun handleGatewaySelectionResponse(gatewayResponse: GatewayResponse) {
|
||||||
when (gatewayResponse.gateway) {
|
if (InAppDonations.isPaymentSourceAvailable(gatewayResponse.gateway.toPaymentSourceType(), gatewayResponse.request.donateToSignalType)) {
|
||||||
GatewayResponse.Gateway.GOOGLE_PAY -> launchGooglePay(gatewayResponse)
|
when (gatewayResponse.gateway) {
|
||||||
GatewayResponse.Gateway.PAYPAL -> launchPayPal(gatewayResponse)
|
GatewayResponse.Gateway.GOOGLE_PAY -> launchGooglePay(gatewayResponse)
|
||||||
GatewayResponse.Gateway.CREDIT_CARD -> launchCreditCard(gatewayResponse)
|
GatewayResponse.Gateway.PAYPAL -> launchPayPal(gatewayResponse)
|
||||||
|
GatewayResponse.Gateway.CREDIT_CARD -> launchCreditCard(gatewayResponse)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error("Unsupported combination! ${gatewayResponse.gateway} ${gatewayResponse.request.donateToSignalType}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,11 +135,7 @@ class DonationCheckoutDelegate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun launchPayPal(gatewayResponse: GatewayResponse) {
|
private fun launchPayPal(gatewayResponse: GatewayResponse) {
|
||||||
if (InAppDonations.isPayPalAvailable()) {
|
callback.navigateToPayPalPaymentInProgress(gatewayResponse.request)
|
||||||
callback.navigateToPayPalPaymentInProgress(gatewayResponse.request)
|
|
||||||
} else {
|
|
||||||
error("PayPal is not currently enabled.")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun launchGooglePay(gatewayResponse: GatewayResponse) {
|
private fun launchGooglePay(gatewayResponse: GatewayResponse) {
|
||||||
@@ -148,11 +148,7 @@ class DonationCheckoutDelegate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun launchCreditCard(gatewayResponse: GatewayResponse) {
|
private fun launchCreditCard(gatewayResponse: GatewayResponse) {
|
||||||
if (InAppDonations.isCreditCardAvailable()) {
|
callback.navigateToCreditCardForm(gatewayResponse.request)
|
||||||
callback.navigateToCreditCardForm(gatewayResponse.request)
|
|
||||||
} else {
|
|
||||||
error("Credit cards are not currently enabled.")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerGooglePayCallback() {
|
private fun registerGooglePayCallback() {
|
||||||
|
|||||||
@@ -2,12 +2,21 @@ package org.thoughtcrime.securesms.components.settings.app.subscription.donate.g
|
|||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
|
import org.signal.donations.PaymentSourceType
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class GatewayResponse(val gateway: Gateway, val request: GatewayRequest) : Parcelable {
|
data class GatewayResponse(val gateway: Gateway, val request: GatewayRequest) : Parcelable {
|
||||||
enum class Gateway {
|
enum class Gateway {
|
||||||
GOOGLE_PAY,
|
GOOGLE_PAY,
|
||||||
PAYPAL,
|
PAYPAL,
|
||||||
CREDIT_CARD
|
CREDIT_CARD;
|
||||||
|
|
||||||
|
fun toPaymentSourceType(): PaymentSourceType {
|
||||||
|
return when (this) {
|
||||||
|
GOOGLE_PAY -> PaymentSourceType.Stripe.GooglePay
|
||||||
|
PAYPAL -> PaymentSourceType.PayPal
|
||||||
|
CREDIT_CARD -> PaymentSourceType.Stripe.CreditCard
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsIcon
|
|||||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsText
|
import org.thoughtcrime.securesms.components.settings.DSLSettingsText
|
||||||
import org.thoughtcrime.securesms.components.settings.NO_TINT
|
import org.thoughtcrime.securesms.components.settings.NO_TINT
|
||||||
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentComponent
|
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentComponent
|
||||||
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppDonations
|
|
||||||
import org.thoughtcrime.securesms.components.settings.app.subscription.donate.DonateToSignalType
|
import org.thoughtcrime.securesms.components.settings.app.subscription.donate.DonateToSignalType
|
||||||
import org.thoughtcrime.securesms.components.settings.app.subscription.models.GooglePayButton
|
import org.thoughtcrime.securesms.components.settings.app.subscription.models.GooglePayButton
|
||||||
import org.thoughtcrime.securesms.components.settings.app.subscription.models.PayPalButton
|
import org.thoughtcrime.securesms.components.settings.app.subscription.models.PayPalButton
|
||||||
@@ -82,7 +81,7 @@ class GatewaySelectorBottomSheet : DSLSettingsBottomSheetFragment() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InAppDonations.isPayPalAvailable()) {
|
if (state.isPayPalAvailable) {
|
||||||
space(8.dp)
|
space(8.dp)
|
||||||
|
|
||||||
customPref(
|
customPref(
|
||||||
@@ -97,7 +96,7 @@ class GatewaySelectorBottomSheet : DSLSettingsBottomSheetFragment() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InAppDonations.isCreditCardAvailable()) {
|
if (state.isCreditCardAvailable) {
|
||||||
space(8.dp)
|
space(8.dp)
|
||||||
|
|
||||||
primaryButton(
|
primaryButton(
|
||||||
|
|||||||
@@ -4,5 +4,7 @@ import org.thoughtcrime.securesms.badges.models.Badge
|
|||||||
|
|
||||||
data class GatewaySelectorState(
|
data class GatewaySelectorState(
|
||||||
val badge: Badge,
|
val badge: Badge,
|
||||||
val isGooglePayAvailable: Boolean = false
|
val isGooglePayAvailable: Boolean = false,
|
||||||
|
val isPayPalAvailable: Boolean = false,
|
||||||
|
val isCreditCardAvailable: Boolean = false
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import androidx.lifecycle.ViewModelProvider
|
|||||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||||
|
import org.signal.donations.PaymentSourceType
|
||||||
|
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppDonations
|
||||||
import org.thoughtcrime.securesms.components.settings.app.subscription.StripeRepository
|
import org.thoughtcrime.securesms.components.settings.app.subscription.StripeRepository
|
||||||
import org.thoughtcrime.securesms.util.rx.RxStore
|
import org.thoughtcrime.securesms.util.rx.RxStore
|
||||||
|
|
||||||
@@ -13,7 +15,14 @@ class GatewaySelectorViewModel(
|
|||||||
private val repository: StripeRepository
|
private val repository: StripeRepository
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
private val store = RxStore(GatewaySelectorState(args.request.badge))
|
private val store = RxStore(
|
||||||
|
GatewaySelectorState(
|
||||||
|
badge = args.request.badge,
|
||||||
|
isGooglePayAvailable = InAppDonations.isPaymentSourceAvailable(PaymentSourceType.Stripe.GooglePay, args.request.donateToSignalType),
|
||||||
|
isCreditCardAvailable = InAppDonations.isPaymentSourceAvailable(PaymentSourceType.Stripe.CreditCard, args.request.donateToSignalType),
|
||||||
|
isPayPalAvailable = InAppDonations.isPaymentSourceAvailable(PaymentSourceType.PayPal, args.request.donateToSignalType)
|
||||||
|
)
|
||||||
|
)
|
||||||
private val disposables = CompositeDisposable()
|
private val disposables = CompositeDisposable()
|
||||||
|
|
||||||
val state = store.stateFlowable
|
val state = store.stateFlowable
|
||||||
|
|||||||
@@ -106,7 +106,8 @@ public final class FeatureFlags {
|
|||||||
public static final String PAYPAL_DISABLED_REGIONS = "global.donations.paypalDisabledRegions";
|
public static final String PAYPAL_DISABLED_REGIONS = "global.donations.paypalDisabledRegions";
|
||||||
private static final String CDS_HARD_LIMIT = "android.cds.hardLimit";
|
private static final String CDS_HARD_LIMIT = "android.cds.hardLimit";
|
||||||
private static final String CHAT_FILTERS = "android.chat.filters";
|
private static final String CHAT_FILTERS = "android.chat.filters";
|
||||||
private static final String PAYPAL_DONATIONS = "android.donations.paypal";
|
private static final String PAYPAL_ONE_TIME_DONATIONS = "android.oneTimePayPalDonations";
|
||||||
|
private static final String PAYPAL_RECURRING_DONATIONS = "android.recurringPayPalDonations";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We will only store remote values for flags in this set. If you want a flag to be controllable
|
* We will only store remote values for flags in this set. If you want a flag to be controllable
|
||||||
@@ -166,7 +167,8 @@ public final class FeatureFlags {
|
|||||||
KEEP_MUTED_CHATS_ARCHIVED,
|
KEEP_MUTED_CHATS_ARCHIVED,
|
||||||
CDS_HARD_LIMIT,
|
CDS_HARD_LIMIT,
|
||||||
CHAT_FILTERS,
|
CHAT_FILTERS,
|
||||||
PAYPAL_DONATIONS
|
PAYPAL_ONE_TIME_DONATIONS,
|
||||||
|
PAYPAL_RECURRING_DONATIONS
|
||||||
);
|
);
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -590,10 +592,17 @@ public final class FeatureFlags {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not we should allow PayPal payments for donations
|
* Whether or not we should allow PayPal payments for one-time donations
|
||||||
*/
|
*/
|
||||||
public static boolean paypalDonations() {
|
public static boolean paypalOneTimeDonations() {
|
||||||
return getBoolean(PAYPAL_DONATIONS, Environment.IS_STAGING);
|
return getBoolean(PAYPAL_ONE_TIME_DONATIONS, Environment.IS_STAGING);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not we should allow PayPal payments for recurring donations
|
||||||
|
*/
|
||||||
|
public static boolean paypalRecurringDonations() {
|
||||||
|
return getBoolean(PAYPAL_RECURRING_DONATIONS, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Only for rendering debug info. */
|
/** Only for rendering debug info. */
|
||||||
|
|||||||
Reference in New Issue
Block a user