Skip to content

Commit 9bda2f5

Browse files
committed
Use webview
1 parent 6fa9bbd commit 9bda2f5

File tree

4 files changed

+149
-21
lines changed

4 files changed

+149
-21
lines changed

paymentsheet/src/main/java/com/stripe/android/paymentelement/confirmation/link/LinkConfirmationDefinition.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.stripe.android.paymentelement.confirmation.link
22

33
import androidx.activity.result.ActivityResultCaller
44
import com.stripe.android.common.exception.stripeErrorMessage
5+
import com.stripe.android.core.strings.resolvableString
56
import com.stripe.android.link.LinkAccountUpdate
67
import com.stripe.android.link.LinkActivityResult
78
import com.stripe.android.link.LinkPaymentLauncher
@@ -68,6 +69,11 @@ internal class LinkConfirmationDefinition @Inject constructor(
6869
deferredIntentConfirmationType: DeferredIntentConfirmationType?,
6970
result: LinkActivityResult
7071
): ConfirmationDefinition.Result {
72+
return ConfirmationDefinition.Result.Failed(
73+
cause = Throwable("Link is not supported yet"),
74+
message = "Link is not supported yet".resolvableString,
75+
type = ConfirmationHandler.Result.Failed.ErrorType.Payment,
76+
)
7177
if (
7278
result !is LinkActivityResult.Canceled ||
7379
result.reason != LinkActivityResult.Canceled.Reason.BackPressed

paymentsheet/src/main/java/com/stripe/android/shoppay/ShopPayActivity.kt

Lines changed: 138 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,16 @@ package com.stripe.android.shoppay
22

33
import android.content.Context
44
import android.content.Intent
5+
import android.net.Uri
6+
import android.os.Build
57
import android.os.Bundle
8+
import android.view.ViewGroup
9+
import android.webkit.WebResourceRequest
10+
import android.webkit.WebView
11+
import android.webkit.WebViewClient
612
import androidx.activity.ComponentActivity
713
import androidx.activity.compose.setContent
14+
import androidx.annotation.RequiresApi
815
import androidx.compose.foundation.layout.Box
916
import androidx.compose.foundation.layout.Column
1017
import androidx.compose.foundation.layout.fillMaxSize
@@ -19,6 +26,7 @@ import androidx.compose.ui.Alignment
1926
import androidx.compose.ui.Modifier
2027
import androidx.compose.ui.res.painterResource
2128
import androidx.compose.ui.unit.dp
29+
import androidx.compose.ui.viewinterop.AndroidView
2230
import androidx.core.os.BundleCompat
2331
import androidx.core.os.bundleOf
2432
import com.stripe.android.common.ui.BottomSheetScaffold
@@ -60,6 +68,8 @@ internal class ShopPayActivity : ComponentActivity() {
6068
}
6169
) {
6270
BottomSheetScaffold(
71+
// modifier = Modifier
72+
// .fillMaxSize(),
6373
topBar = {
6474
Box(
6575
modifier = Modifier
@@ -80,31 +90,59 @@ internal class ShopPayActivity : ComponentActivity() {
8090
}
8191
},
8292
content = {
83-
Column(
84-
modifier = Modifier
85-
.fillMaxSize()
86-
) {
87-
Button(
88-
onClick = {
89-
dismissWithResult(ShopPayActivityResult.Completed("pm_1234"))
90-
}
91-
) {
92-
Text("Complete")
93-
}
94-
95-
Button(
96-
onClick = {
97-
dismissWithResult(ShopPayActivityResult.Failed(Throwable("Failed")))
98-
}
99-
) {
100-
Text("Fail")
101-
}
102-
}
93+
ComposeWebView()
94+
// Column(
95+
// modifier = Modifier
96+
// .fillMaxSize()
97+
// ) {
98+
// Button(
99+
// onClick = {
100+
// dismissWithResult(ShopPayActivityResult.Completed("pm_1234"))
101+
// }
102+
// ) {
103+
// Text("Complete")
104+
// }
105+
//
106+
// Button(
107+
// onClick = {
108+
// dismissWithResult(ShopPayActivityResult.Failed(Throwable("Failed")))
109+
// }
110+
// ) {
111+
// Text("Fail")
112+
// }
113+
// }
103114
}
104115
)
105116
}
106117
}
107118

119+
@Composable
120+
private fun ComposeWebView() {
121+
// Declare a string that contains a url
122+
val mUrl = "https://www.google.com"
123+
124+
// Adding a WebView inside AndroidView
125+
// with layout as full screen
126+
AndroidView(
127+
modifier = Modifier
128+
.fillMaxSize(),
129+
factory = {
130+
WebView(it).apply {
131+
layoutParams = ViewGroup.LayoutParams(
132+
ViewGroup.LayoutParams.MATCH_PARENT,
133+
ViewGroup.LayoutParams.MATCH_PARENT
134+
)
135+
settings.javaScriptEnabled = true
136+
}
137+
}, update = {
138+
it.webViewClient = CustomWebViewClient { id, addressLine1 ->
139+
dismissWithResult(ShopPayActivityResult.Completed(id, addressLine1))
140+
}
141+
it.loadDataWithBaseURL(null, RAW_HTML, "text/html", "UTF-8", null)
142+
// it.loadUrl(mUrl)
143+
})
144+
}
145+
108146
private fun dismissWithResult(result: ShopPayActivityResult) {
109147
val bundle = bundleOf(
110148
ShopPayActivityContract.EXTRA_RESULT to result
@@ -113,6 +151,44 @@ internal class ShopPayActivity : ComponentActivity() {
113151
finish()
114152
}
115153

154+
private class CustomWebViewClient(
155+
private val onComplete: (String, String) -> Unit
156+
): WebViewClient() {
157+
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
158+
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
159+
return handleUrl(request.url.toString())
160+
}
161+
162+
// For API below 21
163+
@Suppress("OverridingDeprecatedMember")
164+
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
165+
return handleUrl(url)
166+
}
167+
168+
private fun handleUrl(url: String): Boolean {
169+
170+
// Check if it's our stripe URL scheme
171+
if (url.startsWith("stripe://")) {
172+
// Parse the URL
173+
val uri = Uri.parse(url)
174+
val paymentMethodId = uri.getQueryParameter("paymentMethodId")
175+
?: throw IllegalStateException("No paymentMethodId")
176+
val addressLine1 = uri.getQueryParameter("address.line1")
177+
?: throw IllegalStateException("No address")
178+
179+
// Process the payment
180+
// processPayment(paymentMethodId, addressLine1)
181+
onComplete(paymentMethodId, addressLine1)
182+
183+
// Return true to indicate we handled the URL
184+
return true
185+
}
186+
187+
// For all other URLs, let the WebView handle it normally
188+
return false
189+
}
190+
}
191+
116192
companion object {
117193
internal const val EXTRA_ARGS = "shop_pay_args"
118194
internal const val RESULT_COMPLETE = 63636
@@ -126,3 +202,45 @@ internal class ShopPayActivity : ComponentActivity() {
126202
}
127203
}
128204
}
205+
206+
private const val RAW_HTML = """
207+
<!DOCTYPE html>
208+
<html lang="en">
209+
<head>
210+
<meta charset="UTF-8">
211+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
212+
<title>Shop Pay</title>
213+
<style>
214+
body {
215+
font-family: Arial, sans-serif;
216+
max-width: 600px;
217+
margin: 0 auto;
218+
padding: 20px;
219+
text-align: center;
220+
}
221+
h1 {
222+
color: #5A31F4;
223+
margin-bottom: 30px;
224+
}
225+
.checkout-button {
226+
background-color: #5A31F4;
227+
color: white;
228+
border: none;
229+
padding: 12px 24px;
230+
font-size: 16px;
231+
border-radius: 4px;
232+
cursor: pointer;
233+
transition: background-color 0.3s;
234+
}
235+
.checkout-button:hover {
236+
background-color: #4526C3;
237+
}
238+
</style>
239+
</head>
240+
<body>
241+
<h1>Welcome to Shop Pay</h1>
242+
<button class="checkout-button" onclick="window.location.href = 'stripe://action?paymentMethodId=pm_123456758&address.line1=123%20main';">Checkout</button>
243+
</body>
244+
</html>
245+
246+
"""

paymentsheet/src/main/java/com/stripe/android/shoppay/ShopPayActivityResult.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ internal sealed interface ShopPayActivityResult : Parcelable {
77
@Parcelize
88
data class Completed(
99
val shopPaymentMethodId: String,
10+
val addressLine1: String? = null
1011
) : ShopPayActivityResult
1112

1213
@Parcelize

paymentsheet/src/main/java/com/stripe/android/shoppay/ShopPayLauncher.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.stripe.android.shoppay
22

3+
import android.util.Log
34
import androidx.activity.result.ActivityResultCaller
45
import androidx.activity.result.ActivityResultLauncher
56
import androidx.activity.result.ActivityResultRegistry
@@ -43,7 +44,9 @@ internal class ShopPayLauncher @Inject internal constructor(
4344
) {
4445
when (shopPayActivityResult) {
4546
ShopPayActivityResult.Canceled -> Unit
46-
is ShopPayActivityResult.Completed -> Unit
47+
is ShopPayActivityResult.Completed -> {
48+
Log.d("ShopPayLauncher", "$shopPayActivityResult")
49+
}
4750
is ShopPayActivityResult.Failed -> Unit
4851
}
4952
nextStep(shopPayActivityResult)

0 commit comments

Comments
 (0)