Created
November 4, 2017 18:32
-
-
Save mataanin/35f6a97b938f50a936b8feb74f72dc70 to your computer and use it in GitHub Desktop.
Pay With Google snipplet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.app.Activity | |
import android.content.Context | |
import com.google.android.gms.common.api.ApiException | |
import com.google.android.gms.wallet.IsReadyToPayRequest | |
import com.google.android.gms.wallet.PaymentsClient | |
import com.google.android.gms.wallet.Wallet | |
import com.google.android.gms.wallet.WalletConstants | |
import rx.Emitter | |
import rx.Observable | |
/** | |
* 'Pay with Google' works as a layer on top of Android Pay. | |
* User is able to add cards to Android Pay. | |
* If a user doesn't have a card in Android Pay, Pay with Google checks if a user doesn't have any cards | |
* stored in Play Store, Youtube, Chrome, etc. If she does, user can use such card with Instacart. | |
* If a used doesn't have a card anywhere, Pay with Google may still be available on her phone. | |
*/ | |
class PayWithGoogleReadyUseCase(private val isProductionServer: Boolean) { | |
companion object { | |
// with the following parameters isReadyToPay call checks if the user has a card on file in Android Pay | |
private val CARD_READY_METHODS = intArrayOf() | |
// with the following parameters isReadyToPay call checks if Pay with Google works on this phone | |
private val GOOGLE_PAY_AVAILABLE = intArrayOf( | |
WalletConstants.PAYMENT_METHOD_TOKENIZED_CARD, | |
WalletConstants.PAYMENT_METHOD_CARD) | |
} | |
/** | |
* @isAvailable - does Pay with Google works on this phone? | |
* @isCardReady - does the user have a credit card on file in Android Pay app? | |
*/ | |
data class PayWithGoogleStatus( | |
val isAvailable: Boolean, | |
val isCardReady: Boolean) | |
fun createPaymentsClient(context: Context): PaymentsClient { | |
val env = if (isProductionServer) WalletConstants.ENVIRONMENT_PRODUCTION else WalletConstants.ENVIRONMENT_TEST | |
val builder = Wallet.WalletOptions.Builder() | |
.setEnvironment(env) | |
.build() | |
return Wallet.getPaymentsClient(context, builder) | |
} | |
private fun readinessStream(activity: Activity, methods: IntArray): Observable<Boolean> { | |
return Observable | |
.create<Boolean>({ emitter -> | |
val paymentsClient = createPaymentsClient(activity) | |
val request = IsReadyToPayRequest.newBuilder() | |
.apply { methods.forEach { method -> addAllowedPaymentMethod(method) } } | |
.build() | |
val task = paymentsClient.isReadyToPay(request) | |
task.addOnCompleteListener { task -> | |
try { | |
emitter.onNext(task.getResult(ApiException::class.java)) | |
} catch (exception: Throwable) { | |
emitter.onError(exception) | |
} | |
emitter.onCompleted() | |
} | |
}, Emitter.BackpressureMode.BUFFER) | |
} | |
fun statusStream(activity: Activity): Observable<PayWithGoogleStatus> = | |
readinessStream(activity, CARD_READY_METHODS) | |
/* | |
* Using switch map instead of combineLatest or zip to ensure that subscriptions are | |
* created synchronously, one after another | |
*/ | |
.switchMap { isCardReady -> | |
readinessStream(activity, GOOGLE_PAY_AVAILABLE) | |
.map { isAvailable -> PayWithGoogleStatus(isAvailable, isCardReady) } | |
} | |
.onErrorReturn { error -> PayWithGoogleStatus(false, false) } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment