Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
74d095f
Add agent_commerce support
htdat Oct 6, 2025
e9e4e4e
Avoid to clash with the same payment_data but in different shapes wit…
htdat Oct 6, 2025
f45b3e1
Retrieve the agentic commerce token if it's provided
htdat Oct 6, 2025
be20987
Do not trigger Fraud_Prevention_Service for agentic commerce order
htdat Oct 6, 2025
ff08eb4
Update the handling of $is_agentic_commerce_request
htdat Oct 6, 2025
c8a9221
Fix PaymentInformation
htdat Oct 6, 2025
3463ea9
Use empty instead of isset
htdat Oct 7, 2025
9d61dd8
Merge branch 'develop' into add/support-agentic_commerce-in-core
htdat Oct 13, 2025
543bf1c
Improve the way to get the spt token
htdat Oct 13, 2025
a6793f0
Correct PHPDoc signature
htdat Oct 14, 2025
e1e285b
Add `spt` and use new util is_agentic_commerce_session, handle get_pa…
htdat Oct 14, 2025
223a9b3
Add feature flag
htdat Oct 14, 2025
33d0846
changelog
htdat Oct 14, 2025
4eec8a1
Revert "Add feature flag"
htdat Oct 15, 2025
1bb23cb
Merge branch 'develop' into add/support-agentic_commerce-in-core
htdat Oct 15, 2025
9ca7a5c
Fix + add tests
htdat Oct 15, 2025
77c84f4
fix Psalm
htdat Oct 15, 2025
6eb4e71
Merge branch 'develop' into add/support-agentic_commerce-in-core
htdat Oct 16, 2025
e20e959
Merge branch 'develop' into add/support-agentic_commerce-in-core
htdat Oct 21, 2025
e150d37
Merge branch 'develop' into add/support-agentic_commerce-in-core
htdat Oct 29, 2025
363ec6a
Merge branch 'develop' into add/support-agentic_commerce-in-core
htdat Oct 31, 2025
079269c
Merge branch 'develop' into add/support-agentic_commerce-in-core
htdat Nov 3, 2025
bc20e01
Merge branch 'develop' into add/support-agentic_commerce-in-core
RadoslavGeorgiev Nov 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 39 additions & 13 deletions includes/class-payment-information.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,13 @@ class Payment_Information {
*/
private $error = null;

/**
* Whether the current order is processed by Agentic Commerce.
*
* @var bool
*/
private $is_agentic_commerce_request = false;

/**
* Payment information constructor.
*
Expand All @@ -140,6 +147,7 @@ class Payment_Information {
* @param string $fingerprint The attached fingerprint.
* @param string $payment_method_stripe_id The Stripe ID of the payment method used for this payment.
* @param string $customer_id The WCPay Customer ID that owns the payment token.
* @param bool $is_agentic_commerce_request Whether the current order is processed by Agentic Commerce.
*
* @throws Invalid_Payment_Method_Exception When no payment method is found in the provided request.
*/
Expand All @@ -153,7 +161,8 @@ public function __construct(
?string $cvc_confirmation = null,
string $fingerprint = '',
?string $payment_method_stripe_id = null,
?string $customer_id = null
?string $customer_id = null,
bool $is_agentic_commerce_request = false
) {
if ( empty( $payment_method ) && empty( $token ) && ! \WC_Payments::is_network_saved_cards_enabled() ) {
// If network-wide cards are enabled, a payment method or token may not be specified and the platform default one will be used.
Expand All @@ -162,16 +171,17 @@ public function __construct(
'payment_method_not_provided'
);
}
$this->payment_method = $payment_method;
$this->order = $order;
$this->token = $token;
$this->payment_initiated_by = $payment_initiated_by ?? Payment_Initiated_By::CUSTOMER();
$this->manual_capture = $manual_capture ?? Payment_Capture_Type::AUTOMATIC();
$this->payment_type = $payment_type ?? Payment_Type::SINGLE();
$this->cvc_confirmation = $cvc_confirmation;
$this->fingerprint = $fingerprint;
$this->payment_method_stripe_id = $payment_method_stripe_id;
$this->customer_id = $customer_id;
$this->payment_method = $payment_method;
$this->order = $order;
$this->token = $token;
$this->payment_initiated_by = $payment_initiated_by ?? Payment_Initiated_By::CUSTOMER();
$this->manual_capture = $manual_capture ?? Payment_Capture_Type::AUTOMATIC();
$this->payment_type = $payment_type ?? Payment_Type::SINGLE();
$this->cvc_confirmation = $cvc_confirmation;
$this->fingerprint = $fingerprint;
$this->payment_method_stripe_id = $payment_method_stripe_id;
$this->customer_id = $customer_id;
$this->is_agentic_commerce_request = $is_agentic_commerce_request;
}

/**
Expand Down Expand Up @@ -271,11 +281,16 @@ public static function from_payment_request(
$cvc_confirmation = self::get_cvc_confirmation_from_request( $request );
$fingerprint = self::get_fingerprint_from_request( $request );

$is_agentic_commerce_request =
null !== $order
&& is_string( $order->get_meta( 'checkout_session_id', true ) )
&& isset( $request['wc-agentic_commerce-token'], $request['wc-agentic_commerce-provider'] );

if ( isset( $request['is_woopay'] ) && $request['is_woopay'] ) {
$order->add_meta_data( 'is_woopay', true, true );
$order->save_meta_data();
}
$payment_information = new Payment_Information( $payment_method, $order, $payment_type, $token, $payment_initiated_by, $manual_capture, $cvc_confirmation, $fingerprint, $payment_method_stripe_id );
$payment_information = new Payment_Information( $payment_method, $order, $payment_type, $token, $payment_initiated_by, $manual_capture, $cvc_confirmation, $fingerprint, $payment_method_stripe_id, null, $is_agentic_commerce_request );

if ( self::PAYMENT_METHOD_ERROR === $payment_method ) {
$error_message = $request['wcpay-payment-method-error-message'] ?? __( "We're not able to process this payment. Please try again later.", 'woocommerce-payments' );
Expand All @@ -295,7 +310,9 @@ public static function from_payment_request(
* @return string
*/
public static function get_payment_method_from_request( array $request ): string {
foreach ( [ 'wcpay-payment-method', 'wcpay-payment-method-sepa' ] as $key ) {
$keys_to_check = [ 'wc-agentic_commerce-token', 'wcpay-payment-method', 'wcpay-payment-method-sepa' ];

foreach ( $keys_to_check as $key ) {
if ( ! empty( $request[ $key ] ) ) {
$normalized = wc_clean( $request[ $key ] );
return is_string( $normalized ) ? $normalized : '';
Expand All @@ -304,6 +321,15 @@ public static function get_payment_method_from_request( array $request ): string
return '';
}

/**
* Whether this payment is processed by Agentic Commerce.
*
* @return bool
*/
public function is_agentic_commerce_request(): bool {
return $this->is_agentic_commerce_request;
}

/**
* Extract the payment token from the provided request.
*
Expand Down
35 changes: 30 additions & 5 deletions includes/class-wc-payment-gateway-wcpay.php
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ public function __construct(
$this->supports = [
'products',
'refunds',
'agentic_commerce',
];

if ( 'card' !== $this->stripe_id ) {
Expand Down Expand Up @@ -753,7 +754,9 @@ private function get_request_payment_data( \WP_REST_Request $request ) {
}
if ( ! empty( $request['payment_data'] ) ) {
foreach ( $request['payment_data'] as $data ) {
$payment_data[ sanitize_key( $data['key'] ) ] = wc_clean( $data['value'] );
if ( isset( $data['key'], $data['value'] ) ) {
$payment_data[ sanitize_key( $data['key'] ) ] = wc_clean( $data['value'] );
}
}
}

Expand Down Expand Up @@ -864,6 +867,24 @@ public function needs_setup() {
return parent::needs_setup() || ! empty( $account_status['error'] ) || ! $account_status['paymentsEnabled'];
}

/**
* Get the agentic commerce payment provider identifier.
*
* @return string Payment provider identifier.
*/
public function get_agentic_commerce_provider() {
return 'stripe';
}

/**
* Get the supported payment methods for agentic commerce.
*
* @return array Array of supported payment methods.
*/
public function get_agentic_commerce_payment_methods() {
return [ 'card' ];
}

/**
* Returns whether a store that is not in test mode needs to set https
* in the checkout
Expand Down Expand Up @@ -1118,7 +1139,8 @@ public function should_use_stripe_platform_on_checkout_page() {
* @throws Exception Error processing the payment.
*/
public function process_payment( $order_id ) {
$order = wc_get_order( $order_id );
$order = wc_get_order( $order_id );
$payment_information = $this->prepare_payment_information( $order );

try {
if ( 20 < strlen( $order->get_billing_phone() ) ) {
Expand All @@ -1128,7 +1150,10 @@ public function process_payment( $order_id ) {
);
}
// Check if session exists and we're currently not processing a WooPay request before instantiating `Fraud_Prevention_Service`.
if ( WC()->session && ! apply_filters( 'wcpay_is_woopay_store_api_request', false ) ) {
if ( WC()->session
&& ! apply_filters( 'wcpay_is_woopay_store_api_request', false )
&& ! $payment_information->is_agentic_commerce_request()
) {
$fraud_prevention_service = Fraud_Prevention_Service::get_instance();
// phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
if ( $fraud_prevention_service->is_enabled() && ! $fraud_prevention_service->verify_token( $_POST['wcpay-fraud-prevention-token'] ?? null ) ) {
Expand Down Expand Up @@ -1171,7 +1196,6 @@ public function process_payment( $order_id ) {
return $check_existing_intention;
}

$payment_information = $this->prepare_payment_information( $order );
return $this->process_payment_for_order( WC()->cart, $payment_information );
} catch ( Exception $e ) {
// We set this variable to be used in following checks.
Expand Down Expand Up @@ -2106,7 +2130,8 @@ public function get_payment_method_to_use_for_intent() {
* @return array List of payment methods.
*/
public function get_payment_method_types( $payment_information ): array {
$requested_payment_method = sanitize_text_field( wp_unslash( $_POST['payment_method'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification
// @todo - this change is temporary, must be fixed!
$requested_payment_method = sanitize_text_field( wp_unslash( $_POST['payment_method'] ?? 'card' ) ); // phpcs:ignore WordPress.Security.NonceVerification
$token = $payment_information->get_payment_token();

if ( ! empty( $requested_payment_method ) ) {
Expand Down
Loading