Skip to content

Instantly share code, notes, and snippets.

@mataanin
Created November 4, 2017 18:32
Show Gist options
  • Save mataanin/35f6a97b938f50a936b8feb74f72dc70 to your computer and use it in GitHub Desktop.
Save mataanin/35f6a97b938f50a936b8feb74f72dc70 to your computer and use it in GitHub Desktop.
Pay With Google snipplet
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