Skip to content

Fix Android Alipay handoff from payment webview#8755

Merged
atavism merged 3 commits into
mainfrom
atavism/android-alipay
May 14, 2026
Merged

Fix Android Alipay handoff from payment webview#8755
atavism merged 3 commits into
mainfrom
atavism/android-alipay

Conversation

@atavism

@atavism atavism commented May 13, 2026

Copy link
Copy Markdown
Contributor

Updates the payment webview to use mobile content mode on Android and launch external app schemes/intents like Alipay, so Shepherd checkout can open the Alipay app instead of getting stuck in the desktop QR flow.

Copilot AI review requested due to automatic review settings May 13, 2026 21:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the payment webview flow so Android checkout pages can hand off Alipay-style app links/intents to external apps instead of remaining stuck in a webview QR flow.

Changes:

  • Switches AppWebView content mode for mobile platforms and intercepts external app URL schemes.
  • Adds URL utility helpers plus tests for detecting webview-external schemes.
  • Adds Android method-channel support and manifest visibility entries for launching Alipay/intents.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
lib/core/widgets/app_webview.dart Intercepts external app URLs from webview navigation/window creation and launches them externally.
lib/core/utils/url_utils.dart Adds external-webview scheme detection and launch helpers.
test/core/utils/url_utils_test.dart Adds unit tests for external scheme detection.
android/app/src/main/kotlin/org/getlantern/lantern/handler/MethodHandler.kt Adds native Android handling for external URL and intent launches.
android/app/src/main/AndroidManifest.xml Adds package visibility queries for Alipay schemes/package.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/core/utils/url_utils.dart Outdated
Comment on lines +42 to +44
static bool shouldOpenExternallyFromWebView(Uri uri) {
final scheme = uri.scheme.toLowerCase();
return scheme.isNotEmpty && !_webviewHandledSchemes.contains(scheme);
Comment on lines +1285 to +1286
val fallbackUrl = intent.getStringExtra("browser_fallback_url")
!fallbackUrl.isNullOrBlank() && launchExternalUrl(fallbackUrl)
@myleshorton

Copy link
Copy Markdown
Contributor

Took a look — clean, well-scoped fix. A few thoughts (none are blockers):

What's good:

  • Two-callback interception (onCreateWindow + shouldOverrideUrlLoading) is correct — window.open(alipays://…) popups and direct navigations both get caught, not redundant.
  • intent.component = null; intent.selector = null after Intent.parseUri is the right defensive move against a malicious page forging a target component via the intent: URI.
  • CATEGORY_BROWSABLE + FLAG_ACTIVITY_NEW_TASK is the canonical pattern when starting from an app (non-activity) context.
  • browser_fallback_url recovery matches Chrome's standard, which is what Alipay's web flow actually emits.
  • <queries> entries are required on API 30+ for package-visibility — easy to forget, glad it's here.
  • could_not_open_url i18n key exists in en.po et al, so the snackbar will resolve.

Things to consider:

  1. Allowlist is fail-open by design. Anything outside {about, blob, chrome, data, file, http, https, javascript} gets handed to Android intent dispatch — so beyond alipays/intent/market, this also captures tel, sms, mailto, whatsapp, wechat, etc. Probably fine (and CATEGORY_BROWSABLE filters out non-browsable intents), but worth being conscious that the surface widened beyond just Alipay.

  2. The preferredContentMode flip is buried. This is arguably the most critical part of the fix — without switching to MOBILE content mode, Shepherd serves the desktop QR-code flow and the intent-launching code never gets a chance to fire. I'd consider calling this out more prominently in the PR description so a future bisecter doesn't revert this PR for the intent-launching change and silently lose the content-mode flip too.

  3. Two intercept sites stay in sync manually. _consumeExternalAppUrlIfNeeded is called from both onCreateWindow and shouldOverrideUrlLoading — if anyone adds scheme-specific logic later, easy to update one and not the other. Minor.

  4. iOS path is the existing url_launcher fallback. Probably fine since iOS routes alipays:// natively to the app, but worth a quick smoke test if iOS is in scope.

  5. browser_fallback_url recursion has no depth guard, but per spec the fallback must be http/https, so it resolves in one hop. Not a real concern, just noting.

LGTM.

@myleshorton

Copy link
Copy Markdown
Contributor

Some comments from claude incoming but overall lgtm!

@atavism

atavism commented May 14, 2026

Copy link
Copy Markdown
Contributor Author

Thanks, @myleshorton! I fixed the fail-open scheme concern by narrowing external dispatch to a payment-specific allowlist

@atavism atavism merged commit 41ae88c into main May 14, 2026
8 checks passed
@atavism atavism deleted the atavism/android-alipay branch May 14, 2026 13:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants