Stripe Express Checkout Element Integration

Created on 26 September 2024, 11 months ago

API documentation: https://docs.stripe.com/elements/express-checkout-element

Requirements: To be determined

โœจ Feature request
Status

Active

Version

1.0

Component

Code

Created by

๐Ÿ‡บ๐Ÿ‡ฆUkraine marchuk.vitaliy Rivne, UA

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @marchuk.vitaliy
  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine marchuk.vitaliy Rivne, UA
  • ๐Ÿ‡จ๐Ÿ‡ฆCanada redsky

    We've applied this as a patch and tested, it work great. We're deploying it to a production site tomorrow. Not sure if you want to call that "Reviewed and tested by the community or not".

    Thanks!

  • niharika.s โ†’ changed the visibility of the branch 3477028-stripe-express-checkout to hidden.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Anybody Porta Westfalica

    Whao, super nice to see this, really looking forward to the express functionality, this will be huge! Thank you!

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Anybody Porta Westfalica

    anybody โ†’ changed the visibility of the branch 3477028-stripe-express-checkout to active.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Anybody Porta Westfalica

    anybody โ†’ changed the visibility of the branch 8.x-1.x to hidden.

  • Pipeline finished with Success
    9 months ago
    Total: 268s
    #352318
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Anybody Porta Westfalica

    Any further plans here @vmarchuk I think this is a super important feature. It's assigned to you currently, so nobody else will work on it so far.

  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine marchuk.vitaliy Rivne, UA
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States rszrama

    Does this patch currently reset things properly when someone exits the Express Checkout Element and goes through normal checkout to pay via the Payment Element? We're getting reports from production usage that someone exiting one path and going to the other causes data loss.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Anybody Porta Westfalica

    Any feedback or plan to share @vmarchuk?

  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine marchuk.vitaliy Rivne, UA

    @anybody
    We're currently working on this and want to launch it soon.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Anybody Porta Westfalica

    @vmarchuk thanks for the feedback, that's great news! ๐ŸŽ‰ Let us and @rszrama know when it's ready for review by the community.

  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine marchuk.vitaliy Rivne, UA
  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine marchuk.vitaliy Rivne, UA
  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine marchuk.vitaliy Rivne, UA
  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine marchuk.vitaliy Rivne, UA
  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine marchuk.vitaliy Rivne, UA

    Added a patch for compatibility with version 1.3.

  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine marchuk.vitaliy Rivne, UA
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States rszrama
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Anybody Porta Westfalica

    @vmarchuk, @rszrama is there work going on in the background on this issue or any further plan or should we simply review & test it and send feedback as-is?

    Thank you! :)

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States TomTech

    @anybody,

    This is already being used on production sites.

    We are in final testing before committing. (We generally try to test in different use cases/scenarios before committing, especially a larger feature add like this.)

    Found some minor issues during recent testing that @vmarchuk has since addressed.

    If you have any issues/feedback, please provide! (Note that, depending on the issue, we will likely still commit and tag a release, then follow up in a future commit/release.)

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Anybody Porta Westfalica

    Cool, thank you @tomtech! Then we'll also try it now! That sounds amazing, very much looking forward to the official release!

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Anybody Porta Westfalica

    Latest MR as patch attached.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Anybody Porta Westfalica

    Clearer versioned patches attached.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Anybody Porta Westfalica

    Hi, we just tried the Stripe Express Checkout Element and these are our observations:

    The wrappers are correctly placed on the cart page:
    <div id="payment-errors"></div><div id="stripe-express-checkout-element" data-drupal-selector="edit-stripe-express-checkout-element"></div>

    The JavaScript initializes the Express Checkout within the element:

    <div id="stripe-express-checkout-element" data-drupal-selector="edit-stripe-express-checkout-element" data-once="stripe-processed" class="StripeElement">
        <div class="__PrivateStripeElement" style="margin: -4px 0px !important; padding: 0px !important; border: medium !important; display: block !important; background: transparent !important; position: relative !important; opacity: 1 !important; transition: height 0.35s !important;">
            <iframe name="__privateStripeFrame3093" frameborder="0" allowtransparency="true" scrolling="no" role="presentation" src="https://js.stripe.com/v3/elements-inner-express-checkout-with-shared-39bb4efb86b60c9971566f493d873828.html#__shared_params__[version]=v3&amp;wait=false&amp;rtl=false&amp;publicOptions[paymentMethods][applePay]=never&amp;publicOptions[paymentMethods][googlePay]=never&amp;publicOptions[paymentMethods][amazonPay]=never&amp;elementsInitSource=stripe.elements&amp;componentName=expressCheckout&amp;keyMode=live&amp;apiKey=pxx&amp;referrer=https%3A%2F%2Fwww.example.com%2Fcart%3FWDEBUG&amp;controllerId=__privateStripeController3091" title="Sicherer Rahmen fรผr schnelle Bezahlvorgรคnge" style="border: 0px !important; margin: -4px; padding: 0px !important; width: calc(100% + 8px); min-width: 100% !important; overflow: hidden !important; display: block !important; user-select: none !important; transform: translate(0px) !important; color-scheme: light only !important; height: 80px; transition: height 0.35s, opacity 0.4s 0.1s;"></iframe>
        </div>
    </div>
    

    But the iframe is empty (white) and shows no payment methods.

    So either I'm doing something wrong or miss something. Maybe it needs additional documentation for the setup?

    Because of https://docs.stripe.com/elements/express-checkout-element#supported-brow... I tried it in Firefox and Chrome as logged-in user.

    Maybe other users will run into similar issues in the future, so I hope my comment helps.

  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine marchuk.vitaliy Rivne, UA

    @anybody
    You can try to test it here https://express-checkout-ttkizeq-gugct5y3vw43w.us-2.platformsh.site/ (this is our demo environment). If you see buttons, it means something is wrong with your environment settings.
    There are many reasons why buttons may not be showing: Stripe configurations, browser, no wallet for the account, etc.
    See a screenshot of what I see here: https://express-checkout-ttkizeq-gugct5y3vw43w.us-2.platformsh.site/

  • Status changed to Needs review 3 months ago
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Anybody Porta Westfalica

    @vmarchuk the testing environment is currently broken, could you revive it?
    TypeError: Drupal\Core\Entity\Sql\DefaultTableMapping::Drupal\Core\Entity\Sql\{closure}(): Argument #1 ($definition) must be of type Drupal\Core\Field\FieldStorageDefinitionInterface, __PHP_Incomplete_Class given in Drupal\Core\Entity\Sql\DefaultTableMapping::Drupal\Core\Entity\Sql\{closure}() (line 175 of core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php).

    So we could proceed the comparison. Would it be possible to share a screenshot of your Drupal Stripe payment gateway settings? (admin/commerce/config/payment-gateways/manage/stripe_payment_element)

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Anybody Porta Westfalica
  • Pipeline finished with Failed
    3 months ago
    Total: 593s
    #496861
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Grevil

    @vmarchuk the testing environment is currently broken, could you revive it?

    Already told Jonathan about that via Slack, he is already at it / forwarded it.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Grevil

    Note, that !MR 129 is against 2.0.x, seems like that is a mirror of 2.x?

  • ๐Ÿ‡ฎ๐Ÿ‡ฑIsrael jsacksick

    The environment is fixed.

  • Pipeline finished with Failed
    3 months ago
    Total: 8632s
    #496865
  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine marchuk.vitaliy Rivne, UA

    Would it be possible to share a screenshot of your Drupal Stripe payment gateway settings? (admin/commerce/config/payment-gateways/manage/stripe_payment_element)

    See the attached screenshot.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Anybody Porta Westfalica

    Thank you so much @jsacksick and @vmarchuk! We're on it!

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Grevil

    Added a few comments on the MR. Furthermore, when pressing e.g. the amazonPay checkout button, I get the following error in console:

    Uncaught (in promise) IntegrationError: The amount 1986 is less than the total amount of the line items provided.

    And the Amazon popup just loads infinitely.

    I do not get this error when e.g. using the express checkout buttons from commerce_paypal.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Grevil

    Ok, the problem is the VAT that is part of the line items, even if it should be already included in the price of the products:

    I'll have a closer look at this tommorow.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Anybody Porta Westfalica

    @grevil: I think the logical mistake is, that only product line items should be included in the JSON generally and never adjustments. I didn't look into the code, but hopefully it's easy to find the reason how VAT comes in here.

  • Pipeline finished with Success
    3 months ago
    Total: 302s
    #497851
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Grevil

    Ok, I found the issue. Adjustments were added as "extra_line_items", leading to this error.

    Although this code seems intentional, I could not yet find the reason it was coded this way. @vmarchuk could you give feedback, on why the adjustments were added as line items? It might be needed for "onShippingRateChange()" and "onShippingAddressChange()" but not passed to the js eventually? Or we need to revert https://git.drupalcode.org/project/commerce_stripe/-/merge_requests/129/... again and just add a check?

  • Pipeline finished with Success
    3 months ago
    Total: 287s
    #497984
  • Pipeline finished with Canceled
    3 months ago
    Total: 698s
    #498070
  • Pipeline finished with Canceled
    3 months ago
    Total: 124s
    #498083
  • Pipeline finished with Success
    3 months ago
    Total: 291s
    #498084
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Grevil

    Ignore #40 โœจ Stripe Express Checkout Element Integration Active we now skip the adjustment if it is of type "tax" and already included in the line item price. Meaning, the original implementation of "commerce_stripe_get_express_checkout_order_line_items" by @vmarchuk is restored again (with the mentioned check included).

    But I am still unsure if is the correct approach, to pass the tax as a line item. But according to the Stripe AI assistan it is:

    Certainly! Here's how you can add tax to a line item using Stripe.js without automatic tax calculation:
    
    example.js
    const stripe = Stripe('your_publishable_key');
    
    const lineItems = [
      {
        price_data: {
          currency: 'usd',
          unit_amount: 2000,
          product_data: {
            name: 'T-shirt',
          },
        },
        quantity: 1,
      },
      {
        price_data: {
          currency: 'usd',
          unit_amount: 200,
          product_data: {
            name: 'Sales Tax',
          },
        },
        quantity: 1,
      }
    ];
    
    stripe.checkout.sessions.create({
      mode: 'payment',
      line_items: lineItems,
      success_url: 'https://example.com/success',
      cancel_url: 'https://example.com/cancel',
    }).then(function(session) {
      // Handle the session
    });
    In this example:
    
    We define two line items in the lineItems array:
    
    The T-shirt priced at $20.00 (2000 cents)
    The sales tax as a separate line item, priced at $2.00 (200 cents)
    We don't use the automatic_tax parameter, as we're manually adding the tax as a separate line item.
    

    But on docs provided as resources by the AI I couldn't find this approach. But yea seems good enough.

  • Pipeline finished with Success
    3 months ago
    Total: 277s
    #498180
  • Pipeline finished with Success
    3 months ago
    Total: 355s
    #498204
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Grevil

    Alright, this is pretty far now.

    Regarding the payment methods:

    Klarna
    Works great and as expected.

    AmazonPay
    Works great and as expected.

    GooglePay
    Works great and as expected.

    ApplePay
    Not tested. I do not have Safari.

    Link
    Could not test link, since I couldn't log into my account for some reason

    PayPal
    After confirming the payment I get an error and get sent to the "checkout/{order_id}/order_information" page with the error:

    Payment failed at the payment server. Please review your information and try again.

    There are still a couple of console errors and I feel like a few parts of code should use existing commerce services instead of "reinventing the wheel" (e.g. the shipping address validation). But generally speaking, this is fairly close!
    We will test it in a live environment tommorow and give further feedback.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Grevil

    Sorry, back to "Needs work" regarding PayPal.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Anybody Porta Westfalica

    Great work for a great feature based on the work done by @vmarchuk! Thanks for the various important finding and fixes!

    @vmarchuk will you or your team have a look soon so we don't lose focus here? Would be wonderful to have this feature released soon IMHO!

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States TomTech

    We are working to land this ASAP.

    Appreciate the testing and feedback!

    PayPal and Link are NOT supported at this time, as we have not landed Payment Method Types for them. (This needs to land with PaymentElement in order for Express Checkout to be able to support it.)

    (If you are able to enable either of these, then that is something that needs to be addressed in this MR.)

    After we land the Payment Method Types, we can then enable them in Express Checkout. (PayPal has a proposed MR that is under consideration. Link needs additional work, as it it not only needs a PaymentMethodType, but also some js/UX changes for support. Specifically, Link works with a very simple PaymentMethodType for new payments, but does not work for saved payment methods.)

  • Pipeline finished with Success
    3 months ago
    Total: 267s
    #498725
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Grevil

    @tomtech thanks for the feedback! And great to hear, that you guys are on it! Really appreciate the work of your team (and especially by @vmarchuk for working on this issue!).

    I disabled support for link and PayPal. We will test it live now and come back to you guys again!

    Static patch of the current MR attached.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Grevil

    New patch. Old patch had a bug I introduced, sorry for that.

  • Pipeline finished with Success
    3 months ago
    Total: 344s
    #498811
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Grevil

    Alright! Seems to work as expected! We just had 2 test purchases inside a live environment using amazonPay and googlePay. Both worked as expected (Klarna was tested before inside a sandbox environment, which also worked great).

    Setting this to "Needs review" for the Centarro people to take a final look at the changes!

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Grevil

    Hey @tomtech, just wanted to ask how soon we can expect to get this reviewed / merged?

    Also, I couldn't find an issue regarding the missing PayPal / Link PaymentMethodTypes, so I created one here: ๐Ÿ› Implement PayPal and Link "PaymentMethodType"s Active . Not sure if you guys plan to implement that yourself? Otherwise, we could also chime in to help implement the PayPal integration, as the "commerce_paypal" Express Checkout Buttons are currently no option for us (see ๐Ÿ› Anonymous user can't finish checkout using PayPal Express Checkout, when shipping rates exist Active ).

    Thanks for the feedback! ๐Ÿ™‚๐Ÿ‘

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Grevil

    Ignore #49. Updated the former related issue, just a heads-up.

    Still very eager to get this merged! ๐Ÿคฉ

  • ๐Ÿ‡ฎ๐Ÿ‡ฑIsrael jsacksick

    @grevil: Could you address the phpcs & CSPELL issues? Those are pretty simple to address so this can all be green. Tom would still be the one signing off on this as I wasn't really involved, but would be great to have a green MR.

  • Pipeline finished with Success
    about 1 month ago
    Total: 290s
    #539127
  • Pipeline finished with Success
    about 1 month ago
    Total: 305s
    #539138
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Grevil

    Done! Everything is green now!

  • ๐Ÿ‡ฎ๐Ÿ‡ฑIsrael jsacksick

    Reviewed the code quickly and left a few feedbacks. We don't necessarily need to address everything, but was curious to why we're duplicating the logic for handling the guest checkout registration as this should already be handled by core.

    We're also duplicating logic from the ShippingOrderManager (for determining whether shipping is required), not sure why we are not using the method defined by the shipping order manager directly?

    And the biggest NO to me here is making commerce_stripe dependent on commerce_shipping. We should go with conditional dependency injection when/if needed, but we shouldn't require commerce_shipping just to install commerce_stripe.

    I see for example the code largely inspired from Commerce Paypal (for the express checkout buttons builder), but Commerce PayPal does NOT depend on shipping.

  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine marchuk.vitaliy Rivne, UA
  • Status changed to Needs work about 1 month ago
  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine marchuk.vitaliy Rivne, UA

    @jsacksick Added some fixes, but not all, as per your comment. Please check my comment regarding anonymous checkout. I also need to check if the applyRate() method can be used.

  • ๐Ÿ‡ฎ๐Ÿ‡ฑIsrael jsacksick

    Regarding the subscriber; if we have no other option fine. I'm just wondering if we should add a setting for this behavior? Was creating an account part of the requirements?

    Also, regarding applyRate(), does it work without? I don't see where the rate is applied otherwise? All we do is setting a shipping method?
    I also merged 2.x changes to fix the test failures.

  • ๐Ÿ‡ฎ๐Ÿ‡ฑIsrael jsacksick

    Updated the target branch to be 2.x (and not 2.0.x).

  • ๐Ÿ‡ฎ๐Ÿ‡ฑIsrael jsacksick

    @grevil: Could you elaborate on what needs to be adjusted? Not too familiar with the other issue linked... Also the links from your comment #58 aren't working for me (I'm getting a "Couldn't fetch the linked file" error).

  • ๐Ÿ‡ฎ๐Ÿ‡ฑIsrael jsacksick

    @vmarchuk: Reviewing the code once again, and regarding your feedback:

    @jsacksick
    When an anonymous user is on the cart page (not going deep into the checkout process), we don't have a "checkout_flow" value, so we can't check if we can use the "guest_new_account"/"guest_order_assign" settings. I don't want to duplicate the logic, but otherwise, we need to "force" site owners to use "guest_new_account"/"guest_order_assign" settings. Maybe we should add an "Allow anonymous checkout" setting to the payment gateway that will only be available when "guest_new_account"/"guest_order_assign" is checked (we can specify this in the field description). But this will affect the entire checkout process.
    Another option is to leave everything as is and just document it (as you said).

    The duplicated code runs on CheckoutEvents::COMPLETION, is Stripe firing that event manually? Maybe from StripePaymentElement::placeOrder()?
    Then maybe we should resolve a checkout flow? Though that makes it hard for merchants to figure out the right checkout flow to configure for the guest account behavior...

    @tomtech: thoughts?

    Also pasting here the feedbacks from Tom regarding the JS file:

    We got rid of jQuery in the paymentintent js file. We are regressing by re-introducing it in this new js file.
    closest() is a native call since ~2015.
    Same for forEach() (as a replacement for jQuery each())
    $.ajax is replaceable by either Drupal.ajax or just js native fetch().

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States TomTech

    I've pushed a commit to fix an inconsistency in the config schema. A few more commits to follow to address a couple other issues.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Grevil

    @jsacksick concerning #59 โœจ Stripe Express Checkout Element Integration Active :

    We need to add "paypal" to the "$supported_payment_method_types" array in "src/Plugin/Commerce/PaymentGateway/StripePaymentElement.php" line 286 (https://git.drupalcode.org/project/commerce_stripe/-/merge_requests/129/...) and remove the explicit removal of "paypal" as a "expressCheckoutOption" in line 117 of "src/ExpressCheckoutButtonsBuilder.php" (https://git.drupalcode.org/project/commerce_stripe/-/merge_requests/129/...).

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States TomTech

    3 new commits added.

    Commit 51 is primarily to cleanup and modernize the javascript.

    Main items of note:
    1. Removes jQuery dependency (e.g. replaced jQuery Ajax with fetch)
    2. Removes dead code (e.g. there was an "off"/removeEventListener for an event that was never added.)

    The commit also passes the isShippable setting, so that we can properly handle non-shippable orders.

    Commit 52 is mainly some additional fixes needed for non-shippable orders.

    Commit 53 removes redundant guest checkout order assignment/account creation logic.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States TomTech

    eslint configuration updated to properly test classes with fields.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States TomTech

    merged in the latest 2.x and resolved merge conflicts.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States TomTech

    Going to merge with the latest changes, unless there is something critical someone wants to call out.

    @grevil, we'll handle enabling PayPal in the other issue after this is merged in.

Production build 0.71.5 2024