Skip to content

Commit 921e99c

Browse files
Merge pull request #4356 from woocommerce/dev/PCP-5866-update-ec_token
Allow ReplaceCart endpoint to (re)create token (5866)
2 parents 0081fbe + 95d26ae commit 921e99c

5 files changed

Lines changed: 575 additions & 10 deletions

File tree

modules/ppcp-store-sync/src/Endpoint/AgenticRestEndpoint.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,8 @@ protected function create_local_cart( PayPalCart $cart, string $ec_token ): stri
207207
return $this->session_handler->create_cart_session( $cart, $ec_token );
208208
}
209209

210-
protected function store_local_cart( string $cart_id, PayPalCart $cart ): bool {
211-
return $this->session_handler->update_cart_session( $cart_id, $cart );
210+
protected function store_local_cart( string $cart_id, PayPalCart $cart, ?string $ec_token = null ): bool {
211+
return $this->session_handler->update_cart_session( $cart_id, $cart, $ec_token );
212212
}
213213

214214
protected function flush_local_cart( string $cart_id ): bool {

modules/ppcp-store-sync/src/Endpoint/ReplaceCartEndpoint.php

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,17 @@ public function register_routes(): void {
5656
/**
5757
* Replace an existing cart with new data.
5858
*
59+
* Per PayPal specs, the PUT endpoint may create a new PayPal order when:
60+
* - The cart doesn't have an ec_token yet (POST validation failed)
61+
* - The existing ec_token has expired
62+
*
5963
* @param WP_REST_Request $request The REST request.
6064
* @return WP_REST_Response The REST response.
6165
*/
6266
public function replace_cart( WP_REST_Request $request ): WP_REST_Response {
6367
$cart_id = $request->get_param( 'cart_id' );
6468

65-
// Verify cart exists.
69+
// Verify cart exists and get current session data.
6670
$session = $this->get_stored_cart( $cart_id );
6771

6872
if ( $session instanceof AgenticError ) {
@@ -75,8 +79,24 @@ public function replace_cart( WP_REST_Request $request ): WP_REST_Response {
7579
return $this->error( $store_cart );
7680
}
7781

78-
// Replace the cart session (preserving ec_token).
79-
$update_result = $this->store_local_cart( $cart_id, $store_cart->paypal_cart() );
82+
// Determine if we need to create a new PayPal order.
83+
$existing_token = $session['ec_token'] ?? '';
84+
$new_token = null;
85+
86+
if ( empty( $existing_token ) && $store_cart->validation()->is_empty() ) {
87+
$new_token = $this->order_manager->create_order( $store_cart->paypal_cart() ) ?: null;
88+
89+
$this->logger->info(
90+
'[REST] PUT created new PayPal order',
91+
array(
92+
'cart_id' => $cart_id,
93+
'new_token' => $new_token ?? '(none - order creation failed)',
94+
)
95+
);
96+
}
97+
98+
// Update the cart session, passing new token when one was created.
99+
$update_result = $this->store_local_cart( $cart_id, $store_cart->paypal_cart(), $new_token );
80100

81101
if ( ! $update_result ) {
82102
return $this->error_not_found(
@@ -88,7 +108,11 @@ public function replace_cart( WP_REST_Request $request ): WP_REST_Response {
88108
);
89109
}
90110

91-
$store_cart->set_paypal_order( $session['ec_token'] );
111+
// Only inject the token into the response when a new one was created.
112+
if ( $new_token ) {
113+
$store_cart->set_paypal_order( $new_token );
114+
}
115+
92116
$response = $this->response_factory->from_cart( $store_cart, $cart_id );
93117

94118
return $this->cart_details( $response, 200 );

modules/ppcp-store-sync/src/Session/AgenticSessionHandler.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,12 @@ public function load_cart_session( string $session_id ): ?array {
108108
/**
109109
* Update an existing cart session.
110110
*
111-
* @param string $session_id The session ID.
112-
* @param PayPalCart $cart The updated cart.
111+
* @param string $session_id The session ID.
112+
* @param PayPalCart $cart The updated cart.
113+
* @param string|null $ec_token Optional new token; when omitted the existing token is kept.
113114
* @return bool True on success.
114115
*/
115-
public function update_cart_session( string $session_id, PayPalCart $cart ): bool {
116+
public function update_cart_session( string $session_id, PayPalCart $cart, ?string $ec_token = null ): bool {
116117
// Load the session first.
117118
$existing = $this->load_cart_session( $session_id );
118119
if ( ! $existing ) {
@@ -121,7 +122,7 @@ public function update_cart_session( string $session_id, PayPalCart $cart ): boo
121122

122123
$data = array(
123124
'cart' => $cart->to_array(),
124-
'ec_token' => $existing['ec_token'],
125+
'ec_token' => $ec_token ?? $existing['ec_token'],
125126
'created' => $existing['created'],
126127
'modified' => time(),
127128
);

0 commit comments

Comments
 (0)