Skip to content

Commit 1e7c8de

Browse files
authored
Merge pull request #692 from code-payments/fix/dismiss-gpay-sheet-on-timeout
chore(onramp): dismiss Google Pay sheet on payment sheet timeout
2 parents 8dc9e5f + 67c36a6 commit 1e7c8de

5 files changed

Lines changed: 51 additions & 3 deletions

File tree

apps/flipcash/core/src/main/res/values/strings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,9 @@
572572
<string name="error_title_onrampTimeout">Payment Timed Out</string>
573573
<string name="error_description_onrampTimeout">The payment session took too long to respond. Please try again.</string>
574574

575+
<string name="error_title_onrampPaymentSheetTimeout">Purchase Timed Out</string>
576+
<string name="error_description_onrampPaymentSheetTimeout">Purchases must be authorized within 60 seconds</string>
577+
575578
<string name="error_title_onrampTransactionSendFailed">Something Went Wrong</string>
576579
<string name="error_description_onrampTransactionSendFailed">We are working with the Coinbase team to resolve the issue. Your card will be refunded in the meantime. Please try again later</string>
577580

apps/flipcash/shared/onramp/coinbase/src/main/kotlin/com/flipcash/app/onramp/CoinbaseOnRampHandler.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,5 +140,12 @@ private fun showOnRampFailure(resources: Resources, error: CoinbaseOnRampWebErro
140140
message = resources.getString(R.string.error_description_onrampInternal),
141141
)
142142
}
143+
144+
is CoinbaseOnRampWebError.PaymentSheetTimeout -> {
145+
BottomBarManager.showInfo(
146+
title = resources.getString(R.string.error_title_onrampPaymentSheetTimeout),
147+
message = resources.getString(R.string.error_description_onrampPaymentSheetTimeout),
148+
)
149+
}
143150
}
144151
}

apps/flipcash/shared/onramp/coinbase/src/main/kotlin/com/flipcash/app/onramp/CoinbaseOnRampWebview.kt

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.flipcash.app.onramp
22

33
import android.annotation.SuppressLint
4+
import android.app.Activity
5+
import android.content.Intent
46
import android.webkit.CookieManager
57
import android.webkit.JavascriptInterface
68
import android.webkit.WebChromeClient
@@ -77,10 +79,12 @@ private fun WebView.configureForCoinbaseOnRamp(
7779

7880
var initialTimeoutRunnable: Runnable? = null
7981
var interEventTimeoutRunnable: Runnable? = null
82+
var paymentSheetTimeoutRunnable: Runnable? = null
8083

8184
fun cancelAllTimeouts() {
8285
initialTimeoutRunnable?.let { removeCallbacks(it) }
8386
interEventTimeoutRunnable?.let { removeCallbacks(it) }
87+
paymentSheetTimeoutRunnable?.let { removeCallbacks(it) }
8488
}
8589

8690
val timeoutAction = Runnable {
@@ -125,8 +129,30 @@ private fun WebView.configureForCoinbaseOnRamp(
125129
post { cancelAllTimeouts(); scheduleInterEventTimeout() }
126130
}
127131

132+
val paymentSheetTimeoutAction = Runnable {
133+
if (terminalEventReceived.compareAndSet(false, true)) {
134+
trace(tag = "CoinbaseOnRamp", message = "Payment sheet timeout fired (60s)")
135+
cancelAllTimeouts()
136+
// The Google Pay sheet is a GMS Activity sitting on top of ours
137+
// in the task stack. Relaunching our Activity with CLEAR_TOP
138+
// finishes everything above it, dismissing the sheet.
139+
(context as? Activity)?.let { activity ->
140+
val intent = Intent(activity, activity::class.java).apply {
141+
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
142+
}
143+
activity.startActivity(intent)
144+
}
145+
onPaymentFailure(CoinbaseOnRampWebError.PaymentSheetTimeout())
146+
}
147+
}
148+
128149
val pauseWatchdog: () -> Unit = {
129-
post { cancelAllTimeouts() }
150+
post {
151+
cancelAllTimeouts()
152+
val runnable = Runnable { paymentSheetTimeoutAction.run() }
153+
paymentSheetTimeoutRunnable = runnable
154+
postDelayed(runnable, PAYMENT_SHEET_TIMEOUT_MS)
155+
}
130156
}
131157

132158
settings.javaScriptEnabled = true
@@ -213,8 +239,13 @@ private fun WebView.configureForCoinbaseOnRamp(
213239
CookieManager.getInstance().setAcceptThirdPartyCookies(this, true)
214240
}
215241

216-
return { cancelAllTimeouts() }
242+
return {
243+
cancelAllTimeouts()
244+
(parent as? android.view.ViewGroup)?.removeView(this@configureForCoinbaseOnRamp)
245+
destroy()
246+
}
217247
}
218248

219249
private const val INITIAL_TIMEOUT_MS = 30_000L
220-
private const val INTER_EVENT_TIMEOUT_MS = 22_000L
250+
private const val INTER_EVENT_TIMEOUT_MS = 22_000L
251+
private const val PAYMENT_SHEET_TIMEOUT_MS = 60_000L

apps/flipcash/shared/onramp/coinbase/src/main/kotlin/com/flipcash/app/onramp/internal/CoinbaseOnRampEventHandler.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ sealed class CoinbaseOnRampWebError(val data: String? = null): Throwable() {
278278
class Internal(data: String? = null) : CoinbaseOnRampWebError(data), NotifiableError
279279
class GooglePayButtonNotFound(data: String? = null) : CoinbaseOnRampWebError(data), NotifiableError
280280
class WebViewTimeout(data: String? = null) : CoinbaseOnRampWebError(data), NotifiableError
281+
class PaymentSheetTimeout(data: String? = null) : CoinbaseOnRampWebError(data)
281282

282283
companion object {
283284
fun fromErrorCode(errorCode: String, data: String? = null): CoinbaseOnRampWebError {

apps/flipcash/shared/onramp/coinbase/src/test/kotlin/com/flipcash/app/onramp/internal/CoinbaseOnRampEventHandlerTest.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,4 +241,10 @@ class CoinbaseOnRampWebErrorTest {
241241
assertIs<NotifiableError>(error)
242242
assertIs<Throwable>(error)
243243
}
244+
245+
@Test
246+
fun paymentSheetTimeoutIsNotNotifiable() {
247+
val error = CoinbaseOnRampWebError.PaymentSheetTimeout()
248+
assertFalse(error is NotifiableError)
249+
}
244250
}

0 commit comments

Comments
 (0)