Automattic\WooCommerce\StoreApi\Routes\V1
Checkout::get_route_post_response │ protected │ WC 1.0
Process an order.
- Obtain Draft Order
- Process Request
- Process Customer
- Validate Order
- Process Payment
Метод класса: Checkout{}
Хуки из метода
Возвращает
\WP_REST_Response|\WP_Error
.
Использование
// protected - в коде основоного (родительского) или дочернего класса $result = $this->get_route_post_response( $request );
- $request(WP_REST_Request) (обязательный)
- Request object.
Код Checkout::get_route_post_response() Checkout::get route post response WC 9.9.3
protected function get_route_post_response( \WP_REST_Request $request ) { wc_log_order_step( '[Store API #1] Place Order flow initiated', null, false, true ); $validation_callback = $this->validate_callback( $request ); if ( is_wp_error( $validation_callback ) ) { return $validation_callback; } /** * Ensure required permissions based on store settings are valid to place the order. */ $this->validate_user_can_place_order(); /** * Before triggering validation, ensure totals are current and in turn, things such as shipping costs are present. * This is so plugins that validate other cart data (e.g. conditional shipping and payments) can access this data. */ $this->cart_controller->calculate_totals(); /** * Validate that the cart is not empty. */ $this->cart_controller->validate_cart_not_empty(); wc_log_order_step( '[Store API #2] Cart validated' ); /** * Validate items and fix violations before the order is processed. */ $this->cart_controller->validate_cart(); /** * Persist customer session data from the request first so that OrderController::update_addresses_from_cart * uses the up-to-date customer address. */ $this->update_customer_from_request( $request ); wc_log_order_step( '[Store API #3] Updated customer data from request' ); /** * Create (or update) Draft Order and process request data. */ $this->create_or_update_draft_order( $request ); wc_log_order_step( '[Store API #4] Created/Updated draft order', array( 'order_object' => $this->order ) ); $this->update_order_from_request( $request ); wc_log_order_step( '[Store API #5] Updated order with posted data', array( 'order_object' => $this->order ) ); $this->process_customer( $request ); wc_log_order_step( '[Store API #6] Created and/or persisted customer data from order', array( 'order_object' => $this->order ) ); /** * Validate updated order before payment is attempted. */ $this->order_controller->validate_order_before_payment( $this->order ); wc_log_order_step( '[Store API #7] Validated order data', array( 'order_object' => $this->order ) ); /** * Hold coupons for the order as soon as the draft order is created. */ try { // $this->order->get_billing_email() is already validated by validate_order_before_payment() $this->order->hold_applied_coupons( $this->order->get_billing_email() ); } catch ( \Exception $e ) { // Turn the Exception into a RouteException for the API. throw new RouteException( 'woocommerce_rest_coupon_reserve_failed', esc_html( $e->getMessage() ), 400 ); } /** * Reserve stock for the order. * * In the shortcode based checkout, when POSTing the checkout form the order would be created and fire the * `woocommerce_checkout_order_created` action. This in turn would trigger the `wc_reserve_stock_for_order` * function so that stock would be held pending payment. * * Via the block based checkout and Store API we already have a draft order, but when POSTing to the /checkout * endpoint we do the same; reserve stock for the order to allow time to process payment. * * Note, stock is only "held" while the order has the status wc-checkout-draft or pending. Stock is freed when * the order changes status, or there is an exception. * * @see ReserveStock::get_query_for_reserved_stock() * * @since 9.2 Stock is no longer held for all draft orders, nor on non-POST requests. See https://github.com/woocommerce/woocommerce/issues/44231 * @since 9.2 Uses wc_reserve_stock_for_order() instead of using the ReserveStock class directly. */ try { wc_reserve_stock_for_order( $this->order ); } catch ( ReserveStockException $e ) { throw new RouteException( esc_html( $e->getErrorCode() ), esc_html( $e->getMessage() ), esc_html( $e->getCode() ) ); } wc_log_order_step( '[Store API #8] Reserved stock for order', array( 'order_object' => $this->order ) ); wc_do_deprecated_action( '__experimental_woocommerce_blocks_checkout_order_processed', array( $this->order, ), '6.3.0', 'woocommerce_store_api_checkout_order_processed', 'This action was deprecated in WooCommerce Blocks version 6.3.0. Please use woocommerce_store_api_checkout_order_processed instead.' ); wc_do_deprecated_action( 'woocommerce_blocks_checkout_order_processed', array( $this->order, ), '7.2.0', 'woocommerce_store_api_checkout_order_processed', 'This action was deprecated in WooCommerce Blocks version 7.2.0. Please use woocommerce_store_api_checkout_order_processed instead.' ); // Set the order status to 'pending' as an initial step. // This allows the order to proceed towards completion. The hook // 'woocommerce_store_api_checkout_order_processed' (fired below) can be used // to set a custom status *after* this point. // If payment isn't needed, the custom status is kept. If payment is needed, // the payment gateway's statuses take precedence. $this->order->update_status( 'pending' ); /** * Fires before an order is processed by the Checkout Block/Store API. * * This hook informs extensions that $order has completed processing and is ready for payment. * * This is similar to existing core hook woocommerce_checkout_order_processed. We're using a new action: * - To keep the interface focused (only pass $order, not passing request data). * - This also explicitly indicates these orders are from checkout block/StoreAPI. * * @since 7.2.0 * * @see https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3238 * @example See docs/examples/checkout-order-processed.md * @param \WC_Order $order Order object. */ do_action( 'woocommerce_store_api_checkout_order_processed', $this->order ); /** * Process the payment and return the results. */ $payment_result = new PaymentResult(); if ( $this->order->needs_payment() ) { $this->process_payment( $request, $payment_result ); } else { $this->process_without_payment( $request, $payment_result ); } wc_log_order_step( '[Store API #9] Order processed', array( 'order_object' => $this->order, 'processed_with_payment' => $this->order->needs_payment() ? 'yes' : 'no', 'payment_status' => $payment_result->status, ), true ); return $this->prepare_item_for_response( (object) [ 'order' => wc_get_order( $this->order ), 'payment_result' => $payment_result, ], $request ); }