From 7eb26e102189026970b4271f92143bcc34073159 Mon Sep 17 00:00:00 2001 From: Fabien Date: Mon, 9 Feb 2026 19:33:59 +0100 Subject: [PATCH] Generate deeplinks instead of calling Cashtab directly Cashtab will still be called via a redirection if no app handles the link first. This makes this code compatible with both mobile and desktop with no special case. Works together with https://github.com/PayButton/paybutton-server/pull/1106. --- react/lib/components/Widget/Widget.tsx | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/react/lib/components/Widget/Widget.tsx b/react/lib/components/Widget/Widget.tsx index a6cdc156..eea5557f 100644 --- a/react/lib/components/Widget/Widget.tsx +++ b/react/lib/components/Widget/Widget.tsx @@ -946,9 +946,32 @@ export const Widget: React.FunctionComponent = props => { } }, [totalReceived, currency, goalAmount, price, hasPrice, contributionOffset]) + const convertBip21ToDeeplink = (bip21Url: string): string => { + // Parse BIP21 URL: ecash:address?amount=100&opreturnraw=xxx + const [addressPart, queryPart] = bip21Url.split('?') + const params = new URLSearchParams() + params.set('address', addressPart) + + if (queryPart) { + const queryParams = new URLSearchParams(queryPart) + // Add all query parameters from the BIP21 string + queryParams.forEach((value, key) => { + params.set(key, value) + }) + } + + // Add b=1 to the deeplink URL to indicate that the payment app should move + // back to the browser after the payment is complete. + params.set('b', '1') + + // Return absolute URL for the deeplink + return `https://paybutton.org/app?${params.toString()}` + } + const handleButtonClick = async () => { if (thisAddressType === 'XEC') { - await openCashtabPayment(url) + const deeplinkUrl = convertBip21ToDeeplink(url) + await openCashtabPayment(url, deeplinkUrl) } else { window.location.href = url }