#baytler_code
1 messages ยท Page 1 of 1 (latest)
๐ Welcome to your new thread!
โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.
โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.
๐ This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1382795364926619779
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
Hi ๐
SO you are using deep linking in Stripe Checkout but the success URL is not returning what you expect? Can you clarify what exactly you expect to occur?
Hi! Yeah I am actually using universal linking, not deep linking. I tried both but universal is actually better because it's seamless without any user interaction.
Okay and you are redirecting your users to a Checkout Session in a mobile browser (not a Web View)?
Yes
Funny enough I actually just published my app in the app store and it's live.... so this is a production issue now LOL
It works on the simulator which is the weirdest part, but not on a physical device.
Okay and what is the problem exactly? Are users not redirected at all? Is the query parameter being stripped out?
when the user has a successful transaction (they pay for the subscription) it redirects to the url but it doesnt open the app,
we send a successUrl and a cancelUrl,
when the user clicks the back arrow it uses the cancelUrl to just go back and it opens the app right away,
when the user has a succesful transaction it redirects to the successUrl and just stays on that url in the browser app instead of going to the app right away
Do you have an example Checkout Session ID I could review?
im trying to find it
looking under the transactions in stripe but no luck
cs_live_b1Znvwzh7513ir9LDnI9oNn7VZ7cvU9PDVQ6lonzT4LhO6GEORRpXyN59r
i found this in my firebase logs
Okay thanks, taking a look
thx ๐
Okay, I see the exact same strings are provided in the creation request: https://dashboard.stripe.com/logs/req_uHJUPDGVsgziwh and we store them exactly as that in our back-end.
yeah those look right, do you have another approach for having the user be directly navigated back to the app right after a succesful payment?
without them being directed to another link where they have to click 'return to app' or something like that
Universal links should work. Let me see if we have more documentation on this
Okay right, I think we recently release this documentation: https://docs.stripe.com/mobile/digital-goods/checkout
Are you following the scheme we describe here?
taking a look
so i think im doing all of this exactly how the documentation shows... here is the AASA example:
{
"applinks": {
"apps": [],
"details": [
{
"appIDs": [ "A28BC3DEF9.com.example.MyApp1",
"A28BC3DEF9.com.example.MyApp1-Debug" ],
"components": [
{
"/": "/checkout_redirect*",
"comment": "Matches any URL whose path starts with /checkout_redirect"
}
]
}
]
}
}
but here is mine:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "877K5V9WGM.com.jointapp.joint",
"paths": ["/dashboard", "/lists", "/finances", "/settings/subscription", "/settings/delete-account"]
}
]
}
}
and remember, the universal links works for the return url, just not the success url
Unfortunately I'm not familiar enough with Apple's AASA syntax to be certain your format would behave the same way. But I do realize that, if the cancel_url works, the same string for the success_url should work
const baseUrl = 'https://joint-app.com/settings/subscription';
const successUrl = ${baseUrl}?checkout_status=success;
const cancelUrl = ${baseUrl}?checkout_status=cancel;
console.log(Using successUrl: ${successUrl});
console.log(Using cancelUrl: ${cancelUrl});
so it grabs the base url from the AASA and then depending if stripe has success or return, it appends that basically
Right and those are static strings by the time you create the checkout session
when testing on a ios simulator it redirects fine, but when trying on my actual device i just get sent to the redirect url and a little download appears but its just an empty document file
hello ?
Hi hi! Iโm going to be taking over for my colleague here. Please give me a minute to read back and understand things.
Okay sounds good!
Ok, so using this:
const baseUrl = 'https://joint-app.com/settings/subscription';
const successUrl = ${baseUrl}?checkout_status=success;
const cancelUrl = ${baseUrl}?checkout_status=cancel;
console.log(Using successUrl: ${successUrl});
console.log(Using cancelUrl: ${cancelUrl});
...the cancelUrl takes the user to the correct place in your app, but the successUrl results in them just downloading 'something', is that correct?
yeah exactly. they stay in the browser and once the checkout is completed (finished processing), it redirects them to a white screen in the browser with some weird empty download, instead of back into the app using universal links
const handleDeepLink = async (event: { url: string }) => {
console.log("Deep link event received (custom or universal):", event.url);
const { url } = event;
try {
const incomingUrl = new URL(url); // Parse the URL
const pathname = incomingUrl.pathname; // e.g., /settings/subscription
const checkoutStatus = incomingUrl.searchParams.get('checkout_status'); // e.g., 'success' or 'cancel'
// Check if the link is for the subscription screen and has a checkout status
if (pathname.includes('/settings/subscription')) {
if (checkoutStatus === 'success') {
console.log("Checkout success detected from Universal Link. Refreshing subscription status.");
Alert.alert("Payment Successful", "Your payment was successful. You're now subscribed to Joint Premium!");
await fetchSubscriptionStatus(); // Refresh subscription status
} else if (checkoutStatus === 'cancel') {
console.log("Checkout canceled detected from Universal Link.");
Alert.alert("Payment Canceled", "Your payment process was canceled.");
}
}
Have you tried using separate paths? Like /subscription_success and /subscription_failure ?
not a bad idea, i could try that. but it does catch into the else if for === cancel
what's really crazy to me is it works on my simulator... just not on my real phone.
That is bizarre for sure. This seems more like an Apple issue than a Stripe issue, since it feels like it relates exclusively to (your use of) Universal Links, so you might want to search around to see if anyone else has had a similar problem but in a different scenario.
I can't find anyone else doing it because Stripe just announced this like a month ago haha
the knowledge base article on stripe is really new, right?
I wasn't clear. I mean, this isn't about Stripe, it's about Universal Links, so search for issues with 'reusing URLs' in Universal Links, and leave the 'Stripe' part out of it.
but it kind of is because the success url that stripe returns is different and my app needs to handle that. how do i see exactly what stripe is returning after a successful payment?
would it be this?
What makes you think the cause is Stripe and not iOS/Apple?
Ruling it out ๐
Based on what?
Because the return url from stripe works, but that never changes. it's always a cancel appended to it
Based on what?
based on the logs
From what?
Or rather, which logs?
I ask because if you're not seeing in your app logs, that tells me that it's most likely that iOS is never redirecting that particular URL, which is why you never see it in your app logs.
i have a feeling Stripe is sending back a success url with additional data that I'm not catching in my backend function. for example, a checkout session ID appended or something that could be causing an issue.
console.log("Deep link event received (custom or universal):", event.url);
Are you ever seeing that event with the success value?
ok let me show you
one second
LOG Deep link event received (custom or universal): https://joint-app.com/settings/subscription?checkout_status=success
LOG Checkout success detected from Universal Link. Refreshing subscription status.
await fetchSubscriptionStatus(); // Refresh subscription status
That's the only difference in the conditional, which implies pretty hard that it's the issue.
i just did it on my simulator but i dont feel comfortable sharing the screen recording because at checkout, i had to put a coupon code to make it $0 and also enter my real credit card in for it to process
but it worked
i do the exact same thing on my real phone but it goes to that white screen
instead of back into the app using universal link
it just doesnt make sense
and this is what it looks like when i click the cancel/return button on stripes checkout page:
LOG Deep link event received (custom or universal): https://joint-app.com/settings/subscription?checkout_status=cancel
LOG Checkout canceled detected from Universal Link.
Awesome. So it sounds to me like there is a difference between how the simulator and your phone behave with regards to Universal Links/Deep Links.
Which again points to this being a Universal Links/Deep Links issue, rather than a Stripe one.
Your best bet will be to deploy a testmode version of your app to a physical device, and check the logs / crash logs to see what's happening.
You're welcome! Without seeing the exact failure, it's ~impossible to dig into what might be causing this.
I'm curious who wrote that kb article at stripe to see how they ended up doing it lol