Skip to content
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

Implement deferred payment intents and split Payment Elements #2935

Merged
merged 44 commits into from
Feb 28, 2024

Conversation

a-danae
Copy link
Contributor

@a-danae a-danae commented Feb 25, 2024

Closes the Epic #2746
(Avoiding the closing keyword here to maintain the Epic open until the changes are shipped)

More information under peNR48-kn-p2

This branch is a feature one. All of the changes included here were already tested in separate PRs before being merged into add/deferred-intent.

Changes proposed in this Pull Request:

  • Implement deferred payment intents for Payment Elements, which are used for the updated checkout experience flow.
  • Split the Payment Elements into separate WooCommerce gateways.

Testing instructions

The changes in this branch were already tested in separate, smaller PRs.


  • Covered with tests (or have a good reason not to test in description ☝️)
  • Added changelog entry in both changelog.txt and readme.txt (or does not apply)
  • Tested on mobile (or does not apply)

Post merge

a-danae and others added 30 commits November 27, 2023 09:41
…classic checkout (#2753)

* Separate adding hooks from the constructor for WC_Stripe_Intent_Controller

* Make wc-stripe-upe-element a class instead of an id

* Render the Payment element in the classic checkout page without creating an intention

* Process payments with deferred intent in the classic checkout

* Fix expected dom element in unit tests

* Update process_payment_with_deferred_intent

* Add base uni test for PE with deferred intent processing

* Move some logic out of create_and_confirm_payment_intent

* Add validation for the payment information array

* Update unit tests for processing payments with a deferred intent

* Improve the error messaging on processing failures

* Remove unneeded test

* Fix typo in doc block

Co-authored-by: Matt Allan <[email protected]>

* Remove resolved TODO comment

* Use the order currency instead of the store currency when creating an intent

Co-authored-by: Matt Allan <[email protected]>

* Remove inline TODO comments that already have issues to address them

* Remove unnecesary order status assignment

* Remove TODO that will be addressed in a separate issue

* Set the selected payment method type as the order's payment method title

* Include shipping information for the payment intent when shipping is needed

* Pass the appearance and fonts parameters to the Elements initialization object

* Validate whether the provided payment method type is valid and allowed in the selected country

* Check whether the dom elements exist before changing their attributes

* Fix console error when checking out as a guest

* Adjust unit tests

---------

Co-authored-by: Matt Allan <[email protected]>
…heckout (#2784)

* Separate adding hooks from the constructor for WC_Stripe_Intent_Controller

* Make wc-stripe-upe-element a class instead of an id

* Render the Payment element in the classic checkout page without creating an intention

* Process payments with deferred intent in the classic checkout

* Fix expected dom element in unit tests

* Update process_payment_with_deferred_intent

* Add base uni test for PE with deferred intent processing

* Move some logic out of create_and_confirm_payment_intent

* Add validation for the payment information array

* Update unit tests for processing payments with a deferred intent

* Improve the error messaging on processing failures

* Remove unneeded test

* Fix typo in doc block

Co-authored-by: Matt Allan <[email protected]>

* Remove resolved TODO comment

* Use the order currency instead of the store currency when creating an intent

Co-authored-by: Matt Allan <[email protected]>

* WIP register split upe with deferred intent for block checkout

* Remove inline TODO comments that already have issues to address them

* Remove unnecesary order status assignment

* Remove TODO that will be addressed in a separate issue

* Set the selected payment method type as the order's payment method title

* Include shipping information for the payment intent when shipping is needed

* Pass the appearance and fonts parameters to the Elements initialization object

* Validate whether the provided payment method type is valid and allowed in the selected country

* Add testing instructions, error handling and use checkout billing details

* Check whether the dom elements exist before changing their attributes

* Fix console error when checking out as a guest

* Adjust unit tests

* Wip 3ds support

* Fix unit test

* Fix incorect intent object template

* add mock payment method to intent

* Remove dummy data with real checkout values

* Update unit test to check for a redirct with the confirm pi args

* Add function block comments to hooks functions

* Add function block comments to payment element functions

* Add payment processor function block comments

* Remove added space

* Remove unnecessary post args from payment create request

* Add support for saving payment methods

* Add support for passing the appearance to Stripe

* Add unit tests for testing instructions

* Fix unit test

* Post billing address information so the create customer request can include complete information

* Remove unused return payment method param

* Update has_cart_or_checkout_on_current_page() to account for checkout and cart block pages

* Only return the intent for confirmation if the payment intent requires further action

* Fix unit test and add test for on-checkout-deferred-intents confirmation

* Fix missing test intent data

* restore payment method in response to check unit tests

* Revert "restore payment method in response to check unit tests"

This reverts commit 0d84092.

* Ensure the checkout block styles are imported in preparation for link

* Add support for Stripe Link

* Include mandate information when the payment intent is for Stripe Link or Sepa

* Update client/blocks/upe/upe-deferred-intent-creation/payment-processor.js

Co-authored-by: Matt Allan <[email protected]>

* Remove the legacy 'fields.js' file

* Move intializeAppearance to utils for both classic and blocks to have access

---------

Co-authored-by: Danae Millan <[email protected]>
Co-authored-by: Danae Millan <[email protected]>
Co-authored-by: Matt Allan <[email protected]>
* Only process the deferred intent confirmation if a charge was returned

* Update SCA unit tests to respond with no charge data

* Fix inline comment

* Fix unit test

* Delete unused payment-method file

* Tighten comment about intent responses without a charge being 3DS
* Introduce new API function for setting up and confirm an intent

* Mount new Stripe PE on Add Payment Method page and remove old UPE handling that is not used

* New create and confirm setup intent API function which adds new intent to a hidden input

* Create and confirm setup intent via AJAX

* With the setup intent, fetch the payment method and create/attach a new WC_Payment_Token to the user

* Fix errors rendering EUR payment methods on the Add payment method that don't support 0 amounts + setup intents

* Fix whitespace

* Use the WC Stripe exception class instead of the base exception class

* Send setup intent status in AJAX response to handle requests that require actions if neededC

* Improve error handling when creating and confirming setup intent

* Make use of WC_Stripe_Exception's localized error messages to show to users

* Update includes/class-wc-stripe-intent-controller.php

Co-authored-by: James Allan <[email protected]>

* Update includes/class-wc-stripe-intent-controller.php

Co-authored-by: James Allan <[email protected]>

---------

Co-authored-by: James Allan <[email protected]>
…that redirect customers off-site to complete payment (#2803)

* Some alternative payment methods require the return URL passed to stripe when creating the intent

* Add support for payment intents that require a redirect to stripe URL as the required action

* Only set the return URL param in the createconfirm intent request when needed

* Add nonce and other validation params to the return URL
* Introduce new API function for setting up and confirm an intent

* Mount new Stripe PE on Add Payment Method page and remove old UPE handling that is not used

* New create and confirm setup intent API function which adds new intent to a hidden input

* Create and confirm setup intent via AJAX

* With the setup intent, fetch the payment method and create/attach a new WC_Payment_Token to the user

* Fix errors rendering EUR payment methods on the Add payment method that don't support 0 amounts + setup intents

* Fix whitespace

* Use the WC Stripe exception class instead of the base exception class

* Send setup intent status in AJAX response to handle requests that require actions if neededC

* Improve error handling when creating and confirming setup intent

* Make use of WC_Stripe_Exception's localized error messages to show to users

* Make sure we trigger the credit card init after the page has loaded so the wc callbacks have been attached

* Add script params necessary for the pay for order page

* Add comments

* Add new payment processor for the order pay page and remove the old one

* Remove the additional actions on the pay for order process payment call

* Enable APMs on the Pay for Order page

* Move upe payment scripts to footer

---------

Co-authored-by: mattallan <[email protected]>
Co-authored-by: Matt Allan <[email protected]>
… types) (#2823)

* Don't add the return URL for boleto, oxxo and card payments

* Attach the client secret to the response from server to be used to confirm voucher payment

* Introduce new handleVoucherCheckout JS function to handle payment for boleto/oxxo

* Refactor the voucher confirmation handling to use URL hashes to support Pay for Order

* Fix JS linting warnings

* Don't confirm the intent immediately when using voucher payment type

* Support different payment intent objects returned when boleto/oxxo is confirmed or not

* Update includes/class-wc-stripe-intent-controller.php

Co-authored-by: James Allan <[email protected]>

* Update includes/class-wc-stripe-intent-controller.php

Co-authored-by: James Allan <[email protected]>

* Throw error if calling createPaymentMethod results in an error

* Update includes/payment-methods/class-wc-stripe-upe-payment-gateway.php

Co-authored-by: James Allan <[email protected]>

---------

Co-authored-by: James Allan <[email protected]>
…uts (#2820)

* Add suport for Stripe APMs to be used on block checkout pages with split UPE

* Add support for processing payments using split UPE on the block checkout

* Use Stipe gateway ID constant rather than hardcoding 'stripe_'

* Use already created instances of the upe payment methods

* Hide Stripe APMs on the WooCommerce > Settings > Payments screen

* Test troubleshooting

* Attempt to fix test

* revert test troubleshooting code

* Ensure the Link payment method is available before returning from get_upe_available_payment_methods()

* Add unit testing troubleshooting code

* add track which function is failing unit test

* Troubleshoot why Stripe Link isnt available

* Introduce new function to deteremine if a UPE methods is available depending on Stripe Account country

* Revert unit test troubleshooting code

* Consolidate logic to handle the redirect url for 3ds, vouchers and bank offsite URLs

* Defend against possible uncallable function
…e classic Checkout (#2827)

* Add suport for Stripe APMs to be used on block checkout pages with split UPE

* Add support for processing payments using split UPE on the block checkout

* Use Stipe gateway ID constant rather than hardcoding 'stripe_'

* Use already created instances of the upe payment methods

* Hide Stripe APMs on the WooCommerce > Settings > Payments screen

* Test troubleshooting

* Attempt to fix test

* revert test troubleshooting code

* Ensure the Link payment method is available before returning from get_upe_available_payment_methods()

* Add unit testing troubleshooting code

* add track which function is failing unit test

* Troubleshoot why Stripe Link isnt available

* Introduce new function to deteremine if a UPE methods is available depending on Stripe Account country

* Revert unit test troubleshooting code

* Remove non-split temporary code added while developing deferred intents

* Update generateCheckoutEventNames() so that it attaches checkout hooks for all of our payment methods

* Sends gatewayId in JS params to fix getSelectedUPEGatewayPaymentMethod()

* Don't add the UPE CC class to the list of WC gateways as it's already added

* Adds necessary payment_fields() function to UPE payment method base class

- This function was copied over from the main UPE gateway class.
- This function calls other methods from the main UPE gateway class and so they've been copied over as well.

* Clean up main constuctor after adding helper functions

* Consolidate logic to handle the redirect url for 3ds, vouchers and bank offsite URLs

* Defend against possible uncallable function

* Remove non-split PE support code and manually set selected UPE Payment Method

* Fix isUsingSavedPaymentMethod util function to work in a split PE environment

* Remove get_upe_enabled_payment_method_ids() as it doesn't make sense in base UPE class

* Fix is_enabled() so that it returns a boolean again

* Don't show Stripe payment methods on checkout that have been disabled in the settings

* Make sure stripe payment elements are unique by using IDs with 'stripe_' before each payment method name

* Remove gateway description from payment fields and display testing instruction if they exist

---------

Co-authored-by: James Allan <[email protected]>
* Define whether to save the selected payment method during checkout

* Store the payment method information in the store

* Fix form validation on checkout when using a saved payment method

* Add deferred intent input to the classic UPE checkout form

* Apply the wc_stripe_generate_create_intent_request filter when creating an intent

* Allow using a saved card for processing a payment in the checkout page

* Include the checks for saved payment methods to the UPE payment processing

* Don't save a payment method if it's disabled in the plugin settings

* Handle retries when the payment intent returns an error

* Pass the correct object to save_intent_to_order on payment intent error

* Update filter name and error message for UPE payment processing

* Remove todo comment

The values for this parameter come from WC, we're not setting it so there's no point in trying to unify this. We could also just check whether it's empty, but a stricter check may be better.

* Fix erroring php unit tests

* Adjust unit tests for saved cards to use the deferred intent flow

* Update order of params in the docblock for get_statement_descriptor

Co-authored-by: James Allan <[email protected]>

* Get the payment method type from the payment_method POST parameter

We were getting it from wc_stripe_selected_upe_payment_type before. After implementing Split PE, there's no longer need to use this customized hidden field.

* Improve handling errors where the payment intent didn't get created

* Throw an error when the payment method is empty when creating an intent

* Update SEPA key in the JS constants for payment method types

* Fix APMs not working in the block checkout

* Update the POST parameter in tests for setting the payment method type

* Add POST paramater to unit tests for the selected payment method

---------

Co-authored-by: James Allan <[email protected]>
Co-authored-by: mattallan <[email protected]>
* Add support for Boleto and Oxxo on the block checkout

* Handle error responses for APMs on the block checkout

* Remove option to save payment methods which aren't reusable

* Update code to determine whether the save payment is allowed

* Use the getBlocksConfiguration rather than StripeServerData when on the blocks_checkout

* No longer load classic checkout scripts on the block checkout page

* Revert "No longer load classic checkout scripts on the block checkout page"

This reverts commit 514c25b.

* Make sure isCheckout includes block checkout logic
…#2851)

* Make sure UPE methods are only enabled if the main gateway is enabled

* Add unit tests to verify UPE method is_enabled()

* Don't load the card payment method on classic checkouts if it's disabled

* Fix block checkouts if credit card isn't enabled

* Add the wc-stripe-is-deferred-intent element to all UPE fields and use 'class' instead of 'id'

* Tidy inline comments

* Fix typo in variable name

* Only make the main upe gateway available if cards are enabled and available
…outs (#2864)

* Update existing icons in the assets file to match client/payment-method-icons

* Display payment method icons on the block and classic checkout

* Remove "Pay with" from payment method titles

* Add the combined cards icon svg

* Add payment methods icons js file for accessing all payment method icons in a single export

* Add missing blank line

* Fix stretching of icons for some of the icons

* Remove new lines

* Update unit tests

* Fix failing unit test

* Fix erroneous "P"

* Remove 'Pay with' from payment method titles

* Remove "Pay with" from Sofort gateway

* Remove Pay with from iDEAL
…isabled (#2867)

* Prevent loading JS scripts when all payment methods are disabled

* Tidy inline comments
…ith dPE (#2866)

* Fix subscription renewals when an existing is used to purchase subscription

* Update deferred intent process_payment function to support setup intents

* Fixes changing a subscriptions payment method to an existing saved card

* Add inline comments to explain why level3 data might be missing

* Don't send level3 data with setup_intent requests

* Fix undefined variable

* fix docblock

* For change payment requests, call backwards compatible do_action hook and don't call payment_complete()

* Fix is_is_mandate_data_required() logic

* Update includes/payment-methods/class-wc-stripe-upe-payment-gateway.php

Co-authored-by: James Allan <[email protected]>

* Update client/api/index.js

Co-authored-by: James Allan <[email protected]>

* Only mark orders as complete if the intent has a success status and payment is not needed

* Fix purchasing a subscription with no upfront payment with a 3DS card

* Update includes/class-wc-stripe-helper.php

Co-authored-by: James Allan <[email protected]>

---------

Co-authored-by: James Allan <[email protected]>
* Second attempt for the reuse of payment intents

* Including new unit tests

* Fixing update payment intent tests + remove unused request params

* Unit tests for class-wc-stripe-upe-payment-gateway reusing payment intents

* Reverting unnecessary changes to test files

* Removing payment intent return from the update method

* Removing payment intent exception treatment when updating it

* Creating abstract validation method for required payment intent params

* Private method to build the base request for payment intents creation and update

* Adding level 3 data + order to the payment intent update and confirm endpoint

* Fix tests

* Fix payment method not saving when updating payment intent

* Fix tests

---------

Co-authored-by: Wesley Rosa <[email protected]>
Co-authored-by: Danae Millan <[email protected]>
…eckout (#2871)

* Add a new class WC_Stripe_Action_Scheduler_Service

This class is intended to handle ActionScheduler hooks.

* Add a method to the Stripe API class for updating a payment method

* Update the saved payment method billing address when checking out

* Add assertions to php unit tests

* Allow passing empty lines in the address property for updating a pm
…led (#2873)

* Hide sofort on the settings page when disabled for UPE

* Adjust tests not to expect Sofort in the available payment methods
…rred intent (#2883)

* Add support flags to Stripe UPE methods

* Set the wc-stripe-is-deferred-intent flag when processing payments via tokens on the block checkout

* Add bancontact and ideal to the list of gateways that require a mandate

* Set the subscriptions payment method ID when setting the payment token source

* Fix saved tokens for APMs like iDEAL, Bancontact and SEPA

* fix typo and fetch the payment method object

* Make sure to pass offsession flag to block payment elements if the cart contains a subs
cription or saved tokens are enabled

* Set the payment method ID on the subscription when the payment method is updated

* Set the order and subscription payment method to the upe gateway's ID

* Map payment method to the gateway ID should be recorded on the subscription

* Set payment method title and ID to the APM used

* Make sure UPE methods can call methods on the main instance of the UPE gateway

* Fix undefined $name error

* Reinstate the process payment function for upe methods

* Only attach hooks in the subscriptions trait once

* Process UPE payment method refunds via the UPE gateway

* Always use the source object's payment type when processing off session payments

* Use new helper function for determining the payment method id of a upe method object

* Remove APM payment methods in Stripe when their tokens are deleted locally (#2902)

* Check whether the deleted token belongs to a reusable gateway

Before, we were only checking it belonged to the main gateway. Since Split PE, APMs have their own gateway so we needed to change this check

* Move the try/catch blocks up in the method

* Add Bancontact, Ideal, and Sofort to the static list of reusable gateways

* Add subscription support for Sofort

* Add multiple subscription support flags to Bancontact, iDEAL, Sofort methods

---------

Co-authored-by: Danae Millan <[email protected]>
…ailed renewal with a saved card (#2906)

* Update add_payment_request_order_meta() to add deferred intent meta for 'stripe' gateway

* Don't add intent information to a subscription
* Refactor deleting local payment methods that don't exist in Stripe

* Create tokens for payment methods missing locally

* Handle exceptions when creating and deleting payment methods

* Add missing variable for the payment method type

* Bail out early when the token doesn't belong to our reusable payment gateways

* Retrieve the main gateway instance through WC_Stripe::get_main_stripe_gateway

Using this instead of creating a new instance of WC_Stripe_UPE_Payment_Gateway to avoid potential side-effects.

* Remove unused WC_Stripe_Payment_Tokens::get_original_payment_method_type method
…ds via My Account > Payment methods (#2918)

* WIP changes to fix add payment method for apms

* Remove Stripe SDK flag

* Revert "Remove Stripe SDK flag"

This reverts commit ec831b2.

* Prevent the add payment method form from submitting if the payment method redirects to a different URL

* Only pass the via SDK flag when processing setup intents via AJAX

* Create the token when processing add payment method redirect

* Override the add_payment_method() function so they are handled by the upe gateway object

* Remove extra space added in previous commit

* Add comment explaining need for use_stripe_sdk
…out if it requires 3DS confirmation (#2909)

* Pass the PM back to the JS to ensure it can be confirmed on the checkout if it requires 3DS confirmation

* Add further clarity to inline comment
…#2911)

* Fix pre-orders status when UPE is enabled

* Adding validation for latest charge value in payment intent

* Removing comments

* Fix tests

* Updating changelog and readme

* Reverting some changes are present in the base branch

---------

Co-authored-by: Wesley Rosa <[email protected]>
james-allan and others added 7 commits February 21, 2024 15:24
… while auth and capture is enabled (#2924)

* Payment methods which require automatic capture aren't available if manual capture is enabled

* Make sure Link is available when auth and capture is enabled

* Mock that automatic capture is enabled when testing payment method capabilities

* Mock that automatic capture is enabled when testing payment method capabilities

* Reinit settings after updating them

* Update includes/payment-methods/class-wc-stripe-upe-payment-method.php

Co-authored-by: Matt Allan <[email protected]>

---------

Co-authored-by: Matt Allan <[email protected]>
… fix it from overriding the stripe payment method title (#2915)

* Don't set the Stripe payment method title to whatever title is set on the subscription/order

* Update filter_gateway_title() to work in HPOS environments
…sic checkouts (#2930)

* Don't render the link payment method option on checkout

* Remove empty space added in merge resolution

* Alternative approach

* Add clarifying comment about why Link isn't available
* Retrieve the right payment method type instance before creating a token

* Fix string mismatch for token and payment method IDs

* Prevent SEPA tokens from before split PE from being displayed

* Update the logic behind how local tokens are synced with Stripe PaymentMethods

* Use the real APM for syncing SEPA payment methods

* Use constants for the strings the PaymentMethod object type prop

* Remove APM tokens from before split PE was in place
@a-danae a-danae marked this pull request as ready for review February 25, 2024 01:56
Mayisha and others added 7 commits February 26, 2024 00:04
* revert subscription check in multibanco

* add gateways to the WC gateways list as before.
- they were removed in PR#2839

* hide other stripe methods from payment settings page with css

* fix ordering in checkout page

* rename file and ignore css lint

* Use a separate method for deciding whether to include Multibanco in the gateways

* Don't include multibanco through the available gateways filter for UPE

---------

Co-authored-by: Danae Millan <[email protected]>
…rce > Settings > Payment instead of CSS (#2937)

* Remove CSS to hide payment gateways

* Hide all legacy gateways from settings page

* Update includes/admin/class-wc-stripe-settings-controller.php

Co-authored-by: James Allan <[email protected]>

---------

Co-authored-by: James Allan <[email protected]>
…act, Sofort purchases (#2933)

* Make sure SEPA, iDEAL, Bancontact, Sofort support pre-order purchases

* Fix saving payment methods while pre-orders are in the cart

* Update variable name to not conflict with Subscription integration variable

* For setup intents that require no action make sure we handle pre-orders correctly

* Only require that a payment method be saved if the order contains a pre-order that is charged upon release

* Only expect the PM to be saved if order is charged upon release

* Fix unit tests

* Fix error in phpunit fixes

* Remove requirement for maybe_process_pre_orders to be called

* Fix fatal?

* Undo previous change

* Make sure the functions are mocked to expect payment upfront

* Attach the filter before setting the ingregration hook flag
…ts that require action or require manual confirmation (#2952)

* Don't reuse payment intents that require action or manual confirmation

* Fix unit test
#2948)

* Add alipay to the list of methods returned by getPaymentMethodConstants()

* Properly redirect customers to alipay redirect URL

* Make sure Alipay is labelled consistently with our other UPE methods

* Make get_retrievable_type() return the stripe ID instead of null for non-reusable UPE methods

* Fix unit tests

* Update get_retrievable_type() unit tests

* More unit test fixes
@a-danae a-danae merged commit d4bfea0 into develop Feb 28, 2024
33 checks passed
@a-danae a-danae deleted the add/deferred-intent branch February 28, 2024 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants