woocommerce / woocommerce-blocks

(Deprecated) This plugin has been merged into woocommerce/woocommerce
https://wordpress.org/plugins/woo-gutenberg-products-block/
GNU General Public License v3.0
403 stars 219 forks source link

Allow Gateways to set billing address fields in the checkout, and other changes to better support embeded checkouts. #5424

Closed MichaelBengtsson closed 11 months ago

MichaelBengtsson commented 2 years ago

Is your feature request related to a problem? Please describe.

We are trying to integrate Klarna Checkout with the Checkout Blocks logic and have run into a couple of problems.

Background Embedded (iFrame based) checkouts are very popular in the Nordics and this solution is offered by the majority of the biggest payment providers here. At Krokedil we have for quite some time developed solutions for WooCommerce for these types of integrations (Klarna Checkout, Payson Checkout, Nets Easy, Walley Checkout, Billmate Checkout, Briqpay etc). We are now looking to integrate these with the new WooCommerce Checkout Blocks logic.

The logic behind embedded checkout solutions The basic logic with these types of embedded checkouts is that they replace parts of the WooCommerce checkout page. Mainly the address form fields and the payment methods. Within the embedded checkout the customer enters name and address and selects one of multiple offered payment methods.

The problem Since the embedded checkout replaces the entire billing and shipping address form, we do not have a proper way to hide the standard WooCommerce form fields. Also when the address data is sent via a JS event from the embedded checkout (in frontend) we do not have a proper way to update the standard WooCommerce checkout form address fields.

Describe the solution you'd like

  1. As an absolute minimum, we need to be able to fill in the billing form fields from a payment method that is registered. Right now we can use the setShippingAddress function that is passed to us, to manage the shipping fields. However, we can not fill in any billing fields (including email and phone) if the customer chooses to have separate billing and shipping data.

  2. We would also like to be able to hide the checkout form and the Place order button when the embedded checkout is the selected payment method (since this is information/logic handled by the embedded checkout).

  3. A way to process the order programmatically. For most of our partners they send us a JS/front-end callback when the customer is about to place the order/payment in the iFrame. At this point we would like to be able to submit the order to WooCommerce so that the normal validation flow is respected. Right now in the old shortcode based checkout, we do this by calling your AJAX function directly, in the same way you do normally. The only way we have found to do this now however is to use JavaScript to press the place order button programmatically.

Describe alternatives you've considered

As stated above, as a minimum we need some way for us to fill in the billing fields. Simply setting the billing address to what we need and submitting the form does not work, as this will not generate an order in WooCommerce as of now. If the data that the payment method has in the billingData prop is used to create the order, this might also be an acceptable alternative.

Additional context

None that I can think of.

ralucaStan commented 2 years ago

Hello Team Krokedil, :wave: Thank you for reaching out. We are more than happy to assist you with your WooCommerce Blocks integration.

We have carefully read through your request and we are afraid that our understanding of your current flow and the scope/target audience is not fully understood. Ideally, before you can offer our best advices we need to have a clear understanding of:

Because from what we understood to be your requirements we managed to spot a lot of differences from what our Checkout block currently offers and from others integrations we have had in the past, it's best that we are all aligned with the requirements of your checkout flow.

Starting from there we will of course offer the best advice for the right approach to the integration using the current extensibility tools and/or discuss about new extensibility points.

MichaelBengtsson commented 2 years ago

Hi @ralucaStan ! Thank you for your reply.

I will try to clarify as much as possible, if there are any things you want further clarification on please let me know!

Checkout flow

  1. The customer place items in their cart as normal and proceeds to the checkout page where they are shown and iframe/embedded checkout or are able to select the the payment method for the embedded checkout which will then show the iframe.
  2. The customer enter their address data in the embedded checkout.
  3. The iframe will then trigger a JavaScript event from a library with information that the customer has been identified in the embedded checkout. This event contains some address data like postal code, country etc but could also be the full customer address depending on what the payment provider share at this point.
  4. The Klarna Checkout plugin then take this data, and populates the WooCommerce checkout form and then trigger _updatecheckout so that shipping rates can be calculated correctly.
  5. The customer selects a shipping method.
  6. The customer fills in any remaining form fields outside of the iframe (for example from other plugins that use fields that are not supported by the iframe itself).
  7. The customer then places the order by pressing a button in the iframe, which will trigger an event that the Klarna Checkout plugin listen to. When this event is triggered, it pauses the purchase process and expects a response from the KCO plugin before it proceeds.
  8. When this event fires, we fetch the full address data from the payment providers API, supply this to WooCommerce, and submit the order (in the shortcode flow we do this by triggering the checkout AJAX call that you use onSubmit for the checkout form).
  9. If the order creation went well, the KCO plugin responds with a true message in the JavaScript event (if something went wrong during the order creation process the KCO plugin will respond with a false message in the JavaScript event and Klarna will not finalize the purchase. Instead an error notice will be displayed for the customer).
  10. The payment provider then redirect the customer to a confirmation page, where the order is verified and completed by running payment_complete() on the order in WooCommerce.

The basic idea behind all these steps is so that we can follow the normal WooCommerce order flow as much as possible even for the iframe payment methods that we support. This increases our compatibility with other plugins that might be doing their own thing during the checkout. For example we try to trigger the exact same order creation flow to allow other plugins to hook into the normal validation call using the data that they have stored in the session for the customer, which is why we don't for example use the API for creating orders.

Components that we use

The things that we still use from the normal checkout form is:

Who we want to target

We will want to support people that use both this type of payment method, as well as a standard payment method.

We do have some demo pages set up for this that you can check if you want as well if you want to check things more in detail yourself, and if you want a closer discussion we are very open to have a meeting or closer contact where we can show more things in depth if that is needed as well.

Some examples for different iframe payment methods:

Klarna Checkout

Payson Checkout

mikejolley commented 2 years ago

@senadir this is the use-case we discussed which could be serviced by a "checkout anywhere" approach. In this case, it would replace the address blocks, and possibly the payment step, but utilise the shipping, order review, and place order blocks. All communication would be done via data-stores and API.

github-actions[bot] commented 2 years ago

This issue has been marked as stale because it has not seen any activity within the past 60 days. Our team uses this tool to help surface issues for review. If you are the author of the issue there's no need to comment as it will be looked at.

Internal: After 10 days with no activity this issue will be automatically be closed.
senadir commented 2 years ago

This seems to fit what we call an express payment method (like Apple Pay, Google Pay), however, I have a hard time imagining this flow as a regular payment method, as by the time a user reach to the payment step, he would have already filled all other fields.

Is it possible that you register an express payment method, that opens a modal and a shopper can select address for it to be prefilled, and can select Klarna as a checkout option in the end of the form?

While we do provide functions to fetch fields values and fill them (via wp.data.dispatch('wc/store/cart') functions), I believe that hiding core steps and replacing them with your own will result in a poor experience in this instance. We do support such thing (to a certain level) but only for fully controlled checkout instances where only a single payment method is supported, it's hard to support several payment methods and other plugins if you're rebuilding core steps.

I'd love to discuss the possibility of using an express payment more, I think another aspect we need to discuss is the placing order phase and why can't you use the core Place Order button? There's also the possibility that you hit POST /wp-json/wc/store/v1/checkout yourself but this won't support custom fields yet.

Is using a fully embeded checkout a business requirement, or was it there to replace the old and poor checkout experience, we belive using the new checkout experience should make those solutions only needed for niche use cases.

github-actions[bot] commented 2 years ago

This issue has been marked as stale because it has not seen any activity within the past 60 days. Our team uses this tool to help surface issues for review. If you are the author of the issue there's no need to comment as it will be looked at.

Internal: After 10 days with no activity this issue will be automatically be closed.
github-actions[bot] commented 2 years ago

This issue has been marked as stale because it has not seen any activity within the past 60 days. Our team uses this tool to help surface issues for review. If you are the author of the issue there's no need to comment as it will be looked at.

Internal: After 10 days with no activity this issue will be automatically be closed.
ralucaStan commented 2 years ago

@MichaelBengtsson how do you feel about closing this issue. Based on our last interaction it seemed that you are exploring other approaches.

MichaelBengtsson commented 2 years ago

@ralucaStan Yes i believe that is what we need to do by the looks of it. So we can go ahead and close the issue.

Thank you for your time and suggestions!

j-falk commented 1 year ago

I wanted to re-open the discussion here around embedded checkouts, not sure if it would be best suited to open a new issue but I'll try it this way.

As you asked @senadir, having it as a embedded checkout is a business requirement in these cases and is not specifically tied to WooCommerce as a platform specifically. See eg Nets easy and their api documentation, https://developers.nets.eu/nets-easy/en-EU/docs/, they allow different platforms such as WooCommerce (we at Krokedil have eg built and are maintaining their WooCommerce plugin) to use their checkout experience.

As you mentioned @mikejolley it would be wonderful if we could replace the address blocks and the payment step, while utilise the shipping and order review inner blocks?

Because we are now in a scenario where we might get the possibility to build another plugin with a embedded checkout for another payment provider (which is actually using using web components instead of an iframe approach). Our suggestion to the Payment provider have then been that we would build this as a block-first approach.

However when trying to take that approach a couple of high-level questions pop-up in my head:

madjedo commented 1 year ago

Has there been any progress or updates in getting Klarna Payments/Checkout integrated with the new checkout block?

This has been plannd for well over a year now....

j-falk commented 1 year ago

@madjedo We will be out with blocks compatibility for Klarna Payments within the next month, but Klarna Checkout support is further away, partly due to issues raised in in this issue :slightly_smiling_face:

pierorocca commented 1 year ago

Hi Johan, I don't have access to the private slack discussing Klarna Checkout I do want to understand where I can help and where I can provide guidance.

Embedded (iFrame based) checkouts are very popular in the Nordics and this solution is offered by the majority of the biggest payment providers here.

I'm not sure if an iFrame approach is still being pursued, I would caution that popularity may not translate into the best compatibility and interoperability. What I've learned in my 6 months in the ecosystem is that straying from the framework can cause unintended consequences especially incompatibilities with the vast 3rd party ecosystem that merchants rely on to customize and enhance their stores. That could severely limit Klarna's desirability, especially with site builders, and compatibility with current and future core and 3P functionality.

I think I saw somewhere that you all may be looking at an inner block approach rather than an iFrame. If so, that's likely the best path forward. I came across a fantastic article on Blocks anatomy that may be informative as to why Blocks. https://css-tricks.com/a-deep-introduction-to-wordpress-block-themes/

pierorocca commented 1 year ago

Another approach that significantly increases scope is to create your own Checkout replacement extension. The challenge with that is then you're required to build and sustain your own 3P ecosystem to ensure compatibility. e.g. Flux integrated with Klarna Payment Gateway.

pierorocca commented 1 year ago

@j-falk Lastly we're also looking to make improvements to the core Checkout blocks page, especially the address component. Are there areas of the core checkout that if were enhanced, would reduce the scope of your build?

j-falk commented 1 year ago

Sorry for late follow up here.

@madjedo Klarna Payments for WooCommerce got support for checkout blocks in the 3.0.0 release that was released last week. Please let us know if you encounter any issues 🙌

@pierorocca we have full understanding of the issues of an embedded external checkout since we have built many such plugins and actively manage support for them 😄 . But I understand the arguments, so I will try to give examples of examples where a more flexible cart block would be needed instead.

1) Set address information for a remembered shopper or lookup addresses in external systems. Some payment methods allow users to be remembered so that eg their billing information etc is automatically picked up if the visit the same or another store that uses the same payment method. It could also be that as a merchant you allow customers to get and set their address based on their personal identity number / SSN or company identity number which is connected to an external service. Some payment providers also tries to figure out the shoppers addresses in a multistep approach, eg asking for e-mail and postal number first, SSN number is the first step did not get a match and then show all address fields if nothing was found.

2) Read-only billing/shipping addresses - If you are running a B2B shop it could be that you only allow synced users from eg an ERP system to place orders and therefore don't want to allow WooCommerce users to change billing and/or shipping addresses. Therefore you would like to make the billing and shipping addresses read-only fields. Maybe you also want to display the information a bit more condensed instead of as full input fields to save space.

3) Only allow express payment methods - to simplify the checkout process as a merchant you might want to only allow express payments. You would then want to show the information that you have in the right column in the checkout block (cart information, totals etc) and have a "Place order with Apple Pay" button in the bottom.

4) Start the checkout with shipping options based on postal code - for some merchants the delivery is so key that you want to allow the shopper to start the checkout with first asking for the postal code and then letting the shopper choose a shipping method before you continue with more details about the actual billing/shipping address.

5) Multistep checkout - as a merchant you might want to break out the checkout process in more separate steps and not show all info at the same time, eg 1) Login 2) Shipping 3) Addresses 4) Payment / Place order

So these are all examples that would require a more flexible checkout,

I understand that you might not want to allow all these things directly from the block editor, maybe some of them could be different checkout patterns that a merchant could choose from(?), but I do think that it should be possible to find solutions to these scenarios through code and extending the checkout block in various ways. 😄

ralucaStan commented 1 year ago

Thank you so much @j-falk for the great news! We will include the plugin in our compatibility list tomorrow.

We should sync about the second part of your message and discuss it more in detail.

opr commented 11 months ago

Hi @j-falk and @MichaelBengtsson and @madjedo we are closing this issue and will continue further discussion over on our discussions board: https://github.com/woocommerce/woocommerce-blocks/discussions/11179