New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Focused Launch: Only launch site if checkout is complete #48452
Conversation
Caution: This PR affects files in the Editing Toolkit Plugin on WordPress.com D54439-code has been created so you can easily test it on your sandbox. See this FieldGuide page about developing the Editing Toolkit Plugin for more info: PCYsg-ly5-p2 |
Here is how your PR affects size of JS and CSS bundles shipped to the user's browser: Sections (~179 bytes added 📈 [gzipped])
Sections contain code specific for a given set of routes. Is downloaded and parsed only when a particular route is navigated to. Async-loaded Components (~130 bytes added 📈 [gzipped])
React components that are loaded lazily, when a certain part of UI is displayed for the first time. Legend What is parsed and gzip size?Parsed Size: Uncompressed size of the JS and CSS files. This much code needs to be parsed and stored in memory. Generated by performance advisor bot at iscalypsofastyet.com. |
6c6f0e2
to
b173649
Compare
1bab0d7
to
389da7e
Compare
client/my-sites/checkout/composite-checkout/hooks/use-create-payment-complete-callback.tsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks fine from a checkout perspective. I just left a few minor comments.
client/my-sites/checkout/composite-checkout/composite-checkout.tsx
Outdated
Show resolved
Hide resolved
client/my-sites/checkout/composite-checkout/hooks/use-create-payment-complete-callback.tsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left some comments. Can you please address them? Thank you so much and thank you so much for working on this!
apps/editing-toolkit/editing-toolkit-plugin/editor-site-launch/src/utils.ts
Show resolved
Hide resolved
} ); | ||
|
||
const handlePaymentComplete = useCallback( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to myself: There might be something wrong here preventing a site from being launched after the payment is complete.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔 I was just thinking about this and it might not do what you want in cases where the payment method is a redirect. For example, if you pay via PayPal, you're redirected away from checkout when you click to pay, then redirected directly to the thank-you page when you come back from PayPal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very good point, @sirbrillig 🙏🏼
Handling external payment processing fixed in a495601
Here is a demo: https://cloudup.com/cWO7-K6SAEH
Now I guess we need to add exceptions for eCommerce plan and registered domains where we should use the standard Checkout redirect to thank-you pages for their functionality. Do you know other cases like these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I guess we need to add exceptions for eCommerce plan and registered domains where we should use the standard Checkout redirect to thank-you pages for their functionality. Do you know other cases like these?
Hm... not off the top of my head. You could look through the tests that cover the thank-you url function which in theory document all the possible conditions but while I try to shepherd the thank-you functionality, the actual logic is made by other teams (largely @Automattic/martech).
Regarding this point
I'm getting a success view with "Continue editing" CTA for a second, then I'm getting redirected to the checkout on wordpress.com. When I pay, I land at Calypso home and not in the editor anymore. |
Yup, that was fixed in #49872. It will be gone after a rebase. |
c97095a
to
a9ace01
Compare
Not sure if it's desired behavior, but after checking out a Premium Plan w/ PayPal, I'm redirected to a thank-you upsell page. What do you think @razvanpapadopol? |
The site is launched before payment but I briefly noticed the success dialog with options to Continue editing and go to Home before I was redirected to the checkout. |
It seems to work fine now. The unit test that was failing seem to be unrelated anyway.
I'm not able to reproduce this anymore. Did the purchased plan showed up as "Purchased" at the top of Summary view when this happened? Like this:
Were you on
This is expected 👌🏼 We'll probably remove those buttons and add a little delay to make the experience more smooth or come up with a different solution. Opened #50122 to track this. |
After double-checking the setup (sandboxed site, ETK synced, plan active, and picked up by Launch store) and another round of testing, I couldn't reproduce it anymore so consider this resolved.
After double-checking the setup (sandboxed site, ETK synced, plan active, and picked up by Launch store) and another round of testing, I noticed the
Awesome 🤙 |
- Add isInIframe to context and use it in use-cart hook - Add goToCheckoutAndLaunch method on use-cart hook to be used in Focused Launch - Extract addProductsToCart to a function to prepare further extraction
- Disable and show a pulsating effect on Launch button - Make the modal non-dismissible - Add onboarding-loading mixin and re-use it in onboarding-placeholder mixin in onboarding styles
…inue Editing in order for Jetpack premium blocks to pick up the new plan
* Open a new MessageChannel to listen for checkout success on each modal opening. * add handleCheckoutModalOpened function * Wrap handlePaymentComplete in a useCallback * Use destructuring to cleanly remove callback from data before postMessage
* rename isPaidPlan to hasPaidPlan Prevent paid plan to show up in cart. * if site is on a paid plan, don't pre-select plan from cart * if there is a selected plan in Focused Launch, clear selection if the site is on a paid plan Refresh page after purchase only if a paid product is selected to enable Premium blocks * Use getPaidPlanProductId selector in Summary view
* Handle redirecting back to editor after processing payment externally like with Paypal. * Handle auto-launch when landing in editor by using 'should_launch' param and isLaunchImmediately prop on FocusedLaunchModal
* update useSelect for PLANS_STORE * extract LaunchCart to a type
9fe0757
to
d53f569
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apart from the code comments below, here are few more things to add:
When the user completes the checkout flow without redirection, a route is pushed to display the Success view.
When the user completes the checkout flow with redirection, the ?should_launch
query arg is used to mark the isLaunchImmediately
prop as true, which subsequently display the Success view. (Except eCommerce plan - see PR description.)
The composite-checkout component was also slightly modified with the isFocusedLaunch
prop which prevents the component from showing the thank you page. This is so we can display our own Success view with confettis.
This PR is good to go.
launchSite( siteId ); | ||
if ( selectedDomain || ! isSelectedPlanFree ) { | ||
goToCheckout(); | ||
// Launch the site directly if Free plan and subdomain are selected. | ||
// Otherwise, show checkout as the next step. | ||
if ( ! selectedDomain && ! isSelectedPlanPaid ) { | ||
launchSite( siteId ); | ||
} else { | ||
goToCheckoutAndLaunch(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Context:
- The
launchSite()
function makes an API call to mark the site as launched. - In
goToCheckoutAndLaunch()
, it will also calllaunchSite()
when launch is opened inwp-admin
and when the plan chosen is eCommerce plan. This means that the site is launched first before the redirecting to the checkout page. !isSelectedPlanPaid
is used instead of!isSelectedPlanFree
is because user may be entering the launch flow after they have paid for a plan.
export const openCheckout = ( | ||
siteSlug: string = window?.currentSiteId?.toString() || '', | ||
isEcommerce = false, | ||
onSuccessCallback?: () => void | ||
): void => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Context: siteSlug
& isEcommerce
param is used to construct the redirect url after checkout.
|
||
const goToCheckout = async () => { | ||
await addProductsToCart(); | ||
openCheckout( siteSubdomain?.domain, isEcommercePlan, onSuccess ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Context: onSuccess
and launchSite
is synonymous. Maybe can clean this up in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's just that onSuccess
takes no argument and launchSite
takes siteId
🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes right, almost synonymous.
'launch__focused-modal-overlay--delay-animation-in': shouldDisplaySuccessView, | ||
'launch__focused-modal-overlay--delay-animation-in': isLaunchImmediately, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Context: As to why it has 1 sec delay, easier on the eyes. See: #47808 (comment)
// If there is a purchased plan, remove any selected plan from Launch store | ||
const { unsetPlanProductId } = useDispatch( LAUNCH_STORE ); | ||
React.useEffect( () => { | ||
if ( hasPaidPlan ) { | ||
unsetPlanProductId(); | ||
} | ||
}, [ hasPaidPlan, unsetPlanProductId ] ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Context: unsetPlanProductId()
is called in situations where user may have previously used the launch flow to pick a paid plan, but then goes back customizer to actually purchase a paid plan. At this stage, the site is has a paid plan but it is not launched yet. So when launch modal reopens, we need to unset the selected plan product id. @razvanpapadopol Can you verify if this is one of the situations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, exactly that's the case here. It's also one of the cases mentioned in #49958
React.useEffect( () => { | ||
if ( isLaunchImmediately ) { | ||
// if there was a plan in cart before redirect to payment processing, | ||
// remove it now since we don't need to reload the page when dismissing Success view | ||
unsetPlanProductId(); | ||
launchSite( siteId ); | ||
} | ||
}, [ isLaunchImmediately, unsetPlanProductId, launchSite, siteId ] ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Context: This one happens when user enters the block editor again after checkout redirection (e.g. wp-admin or paypal).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the moment we're using this only in Calypso (iframed editor) for cases of external payment (eg: Paypal). If we'll be doing something like this also from wp-admin we need to control via some query argument also where the user lands from /checkout
if they abandon which right now is on /plans
and should be the editor with launch modal open but not launching immediately.
I've linked this comment to #50122 to track this case in the future.
Demo for the full paid flow: https://cloudup.com/cZCigAVkgu0
WBE diff [WIP]
to be approved and merged before merging this PR:D56875-code[Note] WBE diff also contains several undeployed changes
Changes proposed in this Pull Request
shouldDisplaySuccessView
andenablePersistentSuccessView
[Update] New changes proposed in the context of #48452 (comment)
/checkout/thank-you
page to begin the atomic transfer.Follow up ideas:
Testing instructions
Setup:
yarn start
in Claypsoyarn dev --sync
inapps/editing-toolkit
yarn dev --sync
inapps/wpcom-block-editor
after you make surewpcom-sandbox
is aliased (28543-pb)/start
to test changes and via/new
for regression testingFocused launch
/page/{UNLAUNCHED_SITE_ID_CREATED_WITH_START}.wordpress.com/home
/page/{UNLAUNCHED_SITE_ID_CREATED_WITH_START}.wordpress.com/wp-admin/post-new.php
/checkout
after the site is launchedGutenboarding launch (regression testing)
/page/{UNLAUNCHED_SITE_ID_CREATED_WITH_GUTENBOARDING}.wordpress.com/home
{UNLAUNCHED_SITE_ID_CREATED_WITH_GUTENBOARDING}.wordpress.com/wp-admin/post-new.php
Fixes #48081
Fixes #47798
Fixes #49958