Skip to content

Conversation

@daledupreez
Copy link
Contributor

Related to:

Changes proposed in this Pull Request:

This PR explores implementing the necessary logic in the Stripe gateway to support the Agentic Commerce protocol (agenticcommerce.dev; GitHub), building on work from @ebinnion and @htdat in woocommerce/woocommerce#61271.

Gaps

We don't have Agentic Commerce support enabled for our Stripe accounts, so we're not able to fully test this end to end at the moment, but the code does attempt to call the Stripe payment_intents API with a shared payment token (and fails after multiple internal retries).

Beyond that, theare are also the following gaps:

  • I've made an assumption that we'll get full details for the payment method back from the payment intent creation, but we may need another API call to get those details
  • I haven't added an option to control the behaviour in addition to the feature flag -- I only have one enabled flag, and we likely need to offer a toggle as well as the feature flag, so we might need separate available and enabled flags.
  • I haven't tested "normal" checkout at all - that probably needs some cleanup too
  • I haven't yet explored what happens with various special types of products that have different flows, like subscriptions or pre-orders, nor have I looked at whether we can or should support any kind of off-session payments.

Implementation approach

At a high level, I've created a sub-gateway specifically for this payment method, using optimized checkout as a model for something similar, where we don't know until later on which payment method is actually being used, and as a way to control the payment approach being available at all.

I'd be more than happy to take any and all feedback or suggestions, as I definitely consider this a proof of concept rather than a solid implementation.

I've genrally tried to re-use code within the plugin, but have made some changes to areas of the code that were expecting a payment method to be present before purchase, and added some special cases where we don't want actions

Testing instructions

Setup

You'll need a site with the following:

  • WooCommerce latest
  • The Stripe plugin built from this branch
  • Enable the Agentic Commerce feature flag for WooCommerce Core: wp option update woocommerce_feature_agentic_checkout_enabled 'yes'
  • Enable the Agentic Commerce feature flag for Stripe: wp option update _wcstripe_feature_shared_payment_token 'yes'
  • Ensure you have one or more products on the site
  • It will also help if you have logging enabled for the Stripe gateway

Actual testing

  • Run the following bash script to make an API call to the checkout session API with the following adjustments:
    • Modify TEST_API_BASE to your test site's host and port
    • Modify the id value to reference a product ID that exists on your site
TEST_API_BASE='http://localhost:8888/wp-json/wc/agentic/v1/checkout_sessions';
SESSION_ID=$(curl -X POST $TEST_API_BASE \
    -H "Content-Type: application/json" \
    -d '{
      "items": [{"id": "12", "quantity": 2}],
      "buyer": {
        "first_name": "Hello",
        "last_name": "Test",
        "email": "[email protected]"
      },
      "fulfillment_address": {
        "line_one": "1234 Chat Road",
        "line_two": "Apt 101",
        "city": "San Francisco",
        "state": "CA",
        "country": "US",
        "postal_code": "94131"
      }
    }' | jq | tee create_response.json | jq -r .id) && echo "SESSION_ID: $SESSION_ID"
  • Run the following bash script to try and check out:
curl -X POST "$TEST_API_BASE/{$SESSION_ID}/complete" \
    -H "Content-Type: application/json" \
    -d '{
    "buyer": {
      "first_name": "John",
      "last_name": "Smith",
      "email": "[email protected]",
      "phone_number": "15552003434"
    },
    "payment_data": {
      "token": "spt_card_visa",
      "provider": "stripe",
      "billing_address": {
        "name": "John Smith",
        "line_one": "1234 Chat Road,",
        "line_two": "",
        "city": "San Francisco",
        "state": "CA",
        "country": "US",
        "postal_code": "94131"
      }
    }
  }' | jq | tee complete_response.json | jq

The checkout step is not actually working at the moment, and works through multiple retries, so it can take quite a while to return. You can check the Stripe debug logs to see what data is being sent as part of the requests to Stripe.


  • Covered with tests (or have a good reason not to test in description ☝️)
  • Tested on mobile (or does not apply)

Changelog entry

  • This Pull Request does not require a changelog entry. (Comment required below)
Changelog Entry Comment

Comment

Post merge

@daledupreez daledupreez requested review from a team, Mayisha, Copilot, ebinnion, htdat and wjrosa and removed request for a team October 10, 2025 14:25
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements support for the Agentic Commerce protocol in the Stripe gateway, enabling the use of shared payment tokens for payment processing. The implementation introduces a new payment method class specifically for handling agentic commerce transactions while reusing existing gateway infrastructure.

Key changes:

  • Added a new shared payment token payment method class for Agentic Commerce
  • Modified payment processing logic to handle shared payment tokens instead of traditional payment methods
  • Added feature flag support for controlling Agentic Commerce availability

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
class-wc-stripe-upe-payment-method.php Added shared payment token enabled property to base payment method class
class-wc-stripe-upe-payment-method-shared-payment-token.php New payment method class implementing Agentic Commerce support
class-wc-stripe-upe-payment-gateway.php Modified payment processing to handle shared payment tokens and detect agentic commerce requests
class-wc-stripe-payment-methods.php Added constant for shared payment token payment method
class-wc-stripe.php Added require statement for new shared payment token class
class-wc-stripe-intent-controller.php Updated intent creation logic to support shared payment tokens
class-wc-stripe-feature-flags.php Added feature flag for shared payment token functionality

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@htdat
Copy link

htdat commented Oct 13, 2025

I've made an assumption that we'll get full details for the payment method back from the payment intent creation, but we may need another API call to get those details

Yes, this is confirmed in Stripe docs: When you confirm a PaymentIntent this way, the payment_method field automatically populates with a new payment method that’s reproduced from the one originally used by the buyer to create the SPT..

I haven't added an option to control the behaviour in addition to the feature flag -- I only have one enabled flag, and we likely need to offer a toggle as well as the feature flag, so we might need separate available and enabled flags.

AFAIK, this is only available in US at the moment. And yeah, we might not display UI to enable this feature.

I haven't yet explored what happens with various special types of products that have different flows, like subscriptions or pre-orders, nor have I looked at whether we can or should support any kind of off-session payments.

The current protocol is not telling anything about subscriptions or pre-orders yet, so it's safe to exclude them.

I also read somewhere that right now ChatGPT only supports a single product for each purchase, so the more completed flow such as one digital product + one physical product is not supported.

* @return string|null The shared payment token, or null if it is not found.
*/
private function get_agentic_commerce_payment_token_from_request( ?WC_Order $order = null ): ?string {
if ( ! $order ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should log some of the checks from this method.

*/
class WC_Stripe_UPE_Payment_Method_Shared_Payment_Token extends WC_Stripe_UPE_Payment_Method {

const STRIPE_ID = WC_Stripe_Payment_Methods::SHARED_PAYMENT_TOKEN;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be a good candidate to keep the payment method constant value (instead of WC_Stripe_Payment_Methods).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wjrosa, I am not sure what you mean by this comment. Could you rephrase to help me understand?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, I mentioned we should consider moving the constant value later for both the shared payment token and OC. I meant this line above could be a candidate for that. Later, we could change:

	const STRIPE_ID = WC_Stripe_Payment_Methods::SHARED_PAYMENT_TOKEN;

to

	const STRIPE_ID = 'shared_payment_token';

And use WC_Stripe_UPE_Payment_Method_Shared_Payment_Token::STRIPE_ID everywhere

*
* @return string
*/
public function get_testing_instructions( $show_optimized_checkout_instruction = false ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another method to refactor later

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.

3 participants