package com.reactnativestripesdk.pushprovisioning import android.app.Activity import android.app.Activity.RESULT_OK import android.content.Intent import android.content.pm.PackageManager import android.nfc.NfcAdapter import android.util.Log import com.facebook.react.bridge.BaseActivityEventListener import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.ReadableMap import com.reactnativestripesdk.utils.createError import com.reactnativestripesdk.utils.mapError import com.stripe.android.pushProvisioning.PushProvisioningActivity import com.stripe.android.pushProvisioning.PushProvisioningActivityStarter object PushProvisioningProxy { private const val TAG = "StripePushProvisioning" private var description = "Added by Stripe" private var tokenRequiringTokenization: ReadableMap? = null fun getApiVersion(): String = try { Class.forName("com.stripe.android.pushProvisioning.PushProvisioningActivity") PushProvisioningActivity.API_VERSION } catch (e: Exception) { Log.e(TAG, "PushProvisioning dependency not found") "" } fun isNFCEnabled(context: ReactApplicationContext): Boolean = if (context.packageManager.hasSystemFeature(PackageManager.FEATURE_NFC)) { val adapter = NfcAdapter.getDefaultAdapter(context) adapter?.isEnabled ?: false } else { false } fun invoke( context: ReactApplicationContext, view: AddToWalletButtonView, cardDescription: String, ephemeralKey: String, token: ReadableMap?, ) { try { Class.forName("com.stripe.android.pushProvisioning.PushProvisioningActivityStarter") description = cardDescription tokenRequiringTokenization = token createActivityEventListener(context, view) context.currentActivity?.let { DefaultPushProvisioningProxy() .beginPushProvisioning(it, description, EphemeralKeyProvider(ephemeralKey)) } ?: run { view.dispatchEvent( createError("Failed", "Activity doesn't exist yet. You can safely retry."), ) } } catch (e: Exception) { Log.e(TAG, "There was a problem using Stripe Android PushProvisioning: " + e.message) } } fun isCardInWallet( activity: Activity, cardLastFour: String, callback: TokenCheckHandler, ) { TapAndPayProxy.findExistingToken(activity, cardLastFour, callback) } private fun createActivityEventListener( context: ReactApplicationContext, view: AddToWalletButtonView, ) { val listener = object : BaseActivityEventListener() { override fun onActivityResult( activity: Activity, requestCode: Int, resultCode: Int, data: Intent?, ) { super.onActivityResult(activity, requestCode, resultCode, data) if (requestCode == TapAndPayProxy.REQUEST_CODE_TOKENIZE) { view.dispatchEvent( if (resultCode == RESULT_OK) { null } else { mapError("Failed", "Failed to verify identity.", null, null, null, null) }, ) } else if (requestCode == PushProvisioningActivityStarter.REQUEST_CODE) { if (resultCode == PushProvisioningActivity.RESULT_OK) { tokenRequiringTokenization?.let { tokenRequiringTokenization -> val tokenReferenceId = tokenRequiringTokenization.getString("id") if (tokenReferenceId.isNullOrBlank()) { view.dispatchEvent( mapError( "Failed", "Token object passed to `` is missing the `id` field.", null, null, null, null, ), ) } else { TapAndPayProxy.tokenize( activity, tokenReferenceId, tokenRequiringTokenization, description, ) } } ?: run { view.dispatchEvent(null) } } else if (resultCode == PushProvisioningActivity.RESULT_ERROR) { data?.let { val error: PushProvisioningActivityStarter.Error = PushProvisioningActivityStarter.Error.fromIntent(data) view.dispatchEvent( mapError(error.code.toString(), error.message, null, null, null, null), ) } } } } } context.addActivityEventListener(listener) } } class DefaultPushProvisioningProxy { fun beginPushProvisioning( activity: Activity, description: String, provider: EphemeralKeyProvider, ) { PushProvisioningActivityStarter( activity, PushProvisioningActivityStarter.Args(description, provider, false), ).startForResult() } }