version, '7.6', '>=' ) ) { // Add hooks for stock sync. add_action( 'woocommerce_reduce_order_item_stock', array( $this, 'maybe_stage_stock_updates_for_product' ), 10, 3 ); add_action( 'woocommerce_reduce_order_stock', array( $this, 'maybe_sync_staged_inventory_updates' ) ); } else { // @todo Remove this block when WooCommerce 7.6 is the minimum supported version. // ADD hooks for stock syncs based on changes from orders not from this gateway add_action( 'woocommerce_checkout_order_processed', array( $this, 'maybe_sync_stock_for_order_via_other_gateway' ), 10, 3 ); add_action( 'woocommerce_store_api_checkout_order_processed', array( $this, 'maybe_sync_stock_for_store_api_order_via_other_gateway' ), 10, 1 ); // Add specific hook for paypal IPN callback add_action( 'valid-paypal-standard-ipn-request', array( $this, 'maybe_sync_stock_for_order_via_paypal' ), 10, 1 ); } // ADD hooks to restore stock for pending and cancelled order status. add_action( 'woocommerce_order_status_cancelled', array( $this, 'maybe_sync_inventory_for_stock_increase' ), 1 ); add_action( 'woocommerce_order_status_pending', array( $this, 'maybe_sync_inventory_for_stock_increase' ), 1 ); // ADD hooks to listen to refunds on orders from other gateways. add_action( 'woocommerce_order_refunded', array( $this, 'maybe_sync_stock_for_refund_from_other_gateway' ), 10, 2 ); // Add gift card order item to the order edit screen. add_action( 'woocommerce_admin_order_items_after_fees', array( $this, 'add_admin_order_items' ) ); // Include gift card information in payment method info. add_filter( 'woocommerce_order_get_payment_method_title', array( $this, 'filter_payment_method_title' ), 10, 2 ); add_filter( 'woocommerce_gateway_title', array( $this, 'filter_gateway_title' ), 10, 2 ); // Add Gift Card "send-to" email address to the order meta. add_action( 'woocommerce_checkout_create_order_line_item', array( $this, 'add_gift_card_add_to_cart_details_to_order' ), 10, 4 ); add_action( 'woocommerce_add_order_again_cart_item', array( $this, 'reorder_gift_card' ) ); add_filter( 'woocommerce_order_item_display_meta_key', array( $this, 'modify_gift_card_line_item_key' ), 10, 3 ); add_action( 'wc_square_gift_card_activated', array( $this, 'trigger_email_for_gift_card_sent' ) ); add_filter( 'woocommerce_hidden_order_itemmeta', array( $this, 'hide_gift_card_line_item_meta' ) ); add_filter( 'woocommerce_get_order_item_totals', array( $this, 'filter_order_item_totals' ), 10, 2 ); add_action( 'woocommerce_admin_order_data_after_billing_address', array( $this, 'render_admin_missing_billing_details_notice' ) ); add_action( 'before_woocommerce_pay_form', array( $this, 'render_missing_billing_details_notice' ), 10, 1 ); add_filter( 'woocommerce_order_email_verification_required', array( $this, 'no_verification_on_guest_save' ) ); } /** * Ensures the Square order item meta is hidden. * * @since 2.0.0 * * @param string[] $hidden the hidden order item meta * @return string[] updated meta */ public function hide_square_order_item_meta( $hidden ) { $hidden[] = '_square_item_variation_id'; return $hidden; } /** * Add hooks to ensure PayPal IPN callbacks are added caches and considered for inventory changes * when the sync happens. This also adds the shutdown hook to ensure sync happens if needed at * a later stage. * * @since 2.1.1 * * @param array $posted values returned from PayPal Standard IPN callback. */ public function maybe_sync_stock_for_order_via_paypal( $posted ) { if ( empty( $posted['custom'] ) ) { return; } $raw_order = json_decode( $posted['custom'] ); if ( empty( $raw_order->order_id ) ) { return; } $order = wc_get_order( $raw_order->order_id ); if ( ! $order || ! $order instanceof \WC_Order ) { return; } $this->sync_stock_for_order( $order ); } /** * Checks if we should sync stock for this order. * We only sync for other gateways that Square will not be aware of. * * This functions sets a process in motion that gathers products that will be processed on shutdown. * * @since 2.0.8 * * @param int $order_id Order ID number. * @param array $posted_data Submitted order data. * @param WC_Order $order Order object. */ public function maybe_sync_stock_for_order_via_other_gateway( $order_id, $posted_data, $order ) { // Confirm we are not processing the order through the Square gateway. if ( ! $order instanceof \WC_Order || in_array( $order->get_payment_method(), $this->square_payment_gateways, true ) ) { return; } $this->sync_stock_for_order( $order ); } /** * Checks if we should sync stock for this order. * We only sync for other gateways that Square will not be aware of. * * This functions sets a process in motion that gathers products that will be processed on shutdown. * * @since 4.0.0 * * @param \WC_Order $order Order object. */ public function maybe_sync_stock_for_store_api_order_via_other_gateway( $order ) { // Confirm we are not processing the order through the Square gateway. if ( ! $order instanceof \WC_Order || in_array( $order->get_payment_method(), $this->square_payment_gateways, true ) ) { return; } $this->sync_stock_for_order( $order ); } /** * For a given order sync stock if inventory sync is enabled. * * @since 2.1.1 * * @param \WC_Order $order the order for which the stock must be synced. */ protected function sync_stock_for_order( $order ) { if ( ! wc_square()->get_settings_handler()->is_inventory_sync_enabled() ) { return; } $this->cache_previous_stock( $order ); add_action( 'woocommerce_product_set_stock', array( $this, 'maybe_stage_inventory_updates_for_product' ) ); add_action( 'woocommerce_variation_set_stock', array( $this, 'maybe_stage_inventory_updates_for_product' ) ); add_action( 'shutdown', array( $this, 'maybe_sync_staged_inventory_updates' ) ); } /** * Loop through order and cached previous stock values before they are reduced. * * @since 2.0.8 * * @param WC_Order $order Order object. */ private function cache_previous_stock( $order ) { // Loop over all items. foreach ( $order->get_items() as $item ) { if ( ! $item->is_type( 'line_item' ) ) { continue; } // Check to make sure it hasn't already been reduced. $product = $item->get_product(); $item_stock_reduced = $item->get_meta( '_reduced_stock', true ); if ( $item_stock_reduced || ! $product || ! $product->managing_stock() ) { continue; } $this->previous_stock[ $product->get_id() ] = $product->get_stock_quantity(); } } /** * Stages a product inventory update for sync with Square when a product stock is updated. * * @internal The staged values will be stored in product_to_sync * * @since 2.0.8 * * @param WC_Product $product the updated product with inventory updates. */ public function maybe_stage_inventory_updates_for_product( $product ) { // Do not add inventory changes if we are already doing a sync, or we are not syncing this product. if ( defined( 'DOING_SQUARE_SYNC' ) || ! $product || ! Product::is_synced_with_square( $product ) ) { return; } // Compare stock to get difference. $product_id = $product->get_id(); $previous = isset( $this->previous_stock[ $product_id ] ) ? $this->previous_stock[ $product_id ] : false; $current = $product->get_stock_quantity(); $adjustment = (int) $current - $previous; if ( false === $previous || 0 === $adjustment ) { return; } // Record what type of inventory action occurred. $this->products_to_sync[ $product_id ] = $adjustment; } /** * Stage inventory updates for products in the order. * This function only used for WooCommerce 7.6 and above. * * @param \WC_Order_Item_Product $item Order item data. * @param array $change Change Details. * @param \WC_Order $order Order data. * @return void * * @since 4.1.0 */ public function maybe_stage_stock_updates_for_product( $item, $change, $order ) { $product = $change['product'] ?? false; /** * Bail If * 1. Order is processed using Square payment gateway OR * 2. Inventory sync is not enabled OR * 3. Square sync is in progress OR * 4. Square sync is not enabled for the product */ if ( ! $order instanceof \WC_Order || in_array( $order->get_payment_method(), $this->square_payment_gateways, true ) || ! wc_square()->get_settings_handler()->is_inventory_sync_enabled() || defined( 'DOING_SQUARE_SYNC' ) || ! $product || ! Product::is_synced_with_square( $product ) ) { return; } // Get stock adjustment for the product. $product_id = $product->get_id(); $previous = $change['from'] ?? false; $current = $change['to'] ?? false; $adjustment = (int) $current - $previous; if ( false === $previous || false === $current || 0 === $adjustment ) { return; } // Stage the inventory update. $this->products_to_sync[ $product_id ] = $adjustment; } /** * Maybe restore stock for an order that was cancelled or moved to pending. * This is only for orders that were not processed through the Square gateway. * * @param int $order_id Order ID. * * @since 4.1.0 */ public function maybe_sync_inventory_for_stock_increase( $order_id ) { if ( ! wc_square()->get_settings_handler()->is_inventory_sync_enabled() ) { return; } // Confirm we are not processing the order through the Square gateway. $order = wc_get_order( $order_id ); if ( ! $order instanceof \WC_Order || in_array( $order->get_payment_method(), $this->square_payment_gateways, true ) ) { return; } $trigger_increase = $order->get_order_stock_reduced(); // Only continue if we're increasing stock. if ( ! $trigger_increase ) { return; } // Cache the product's previous stock value. add_action( 'woocommerce_variation_before_set_stock', array( $this, 'cache_product_previous_stock' ) ); add_action( 'woocommerce_product_before_set_stock', array( $this, 'cache_product_previous_stock' ) ); // Stage the inventory update. add_action( 'woocommerce_variation_set_stock', array( $this, 'maybe_stage_inventory_updates_for_product' ) ); add_action( 'woocommerce_product_set_stock', array( $this, 'maybe_stage_inventory_updates_for_product' ) ); // Sync the staged inventory updates. add_action( 'woocommerce_restore_order_stock', array( $this, 'maybe_sync_staged_inventory_updates' ) ); } /** * Cache the product's previous stock value. * * @param WC_Product $product Product object. * * @since 4.1.0 */ public function cache_product_previous_stock( $product ) { $this->previous_stock[ $product->get_id() ] = $product->get_stock_quantity(); } /** * Initializes a synchronization event for any staged inventory updates in this request. * * @internal * * @since 2.0.8 */ public function maybe_sync_staged_inventory_updates() { $inventory_adjustments = array(); foreach ( $this->products_to_sync as $product_id => $adjustment ) { $product = wc_get_product( $product_id ); if ( ! $product instanceof \WC_Product ) { continue; } $inventory_adjustment = Product::get_inventory_change_adjustment_type( $product, $adjustment ); if ( empty( $inventory_adjustment ) ) { continue; } $inventory_adjustments[] = $inventory_adjustment; } if ( empty( $inventory_adjustments ) ) { return; } wc_square()->log( 'New order from other gateway inventory syncing..' ); $idempotency_key = wc_square()->get_idempotency_key( md5( serialize( $inventory_adjustments ) ) . '_change_inventory' ); wc_square()->get_api()->batch_change_inventory( $idempotency_key, $inventory_adjustments ); // Reset the staged inventory updates. $this->products_to_sync = array(); } /** * Handle order refunds inventory/stock changes sync. * * @since 2.0.8 * * @param in $order_id * @param int $refund_id */ public function maybe_sync_stock_for_refund_from_other_gateway( $order_id, $refund_id ) { if ( ! wc_square()->get_settings_handler()->is_inventory_sync_enabled() ) { return; } // Confirm we are not processing the order through the Square gateway. $order = wc_get_order( $order_id ); if ( ! $order instanceof \WC_Order || in_array( $order->get_payment_method(), $this->square_payment_gateways, true ) ) { return; } // don't refund items if the "Restock refunded items" option is unchecked - maintains backwards compatibility if this function is called outside of the `woocommerce_order_refunded` do_action if ( isset( $_POST['restock_refunded_items'] ) ) { // Validate the user has permissions to process this request. if ( ! check_ajax_referer( 'order-item', 'security', false ) || ! current_user_can( 'edit_shop_orders' ) ) { return; } if ( 'false' === $_POST['restock_refunded_items'] ) { return; } } $refund = new \WC_Order_Refund( $refund_id ); $inventory_adjustments = array(); foreach ( $refund->get_items() as $item ) { if ( 'line_item' !== $item->get_type() ) { continue; } $product = $item->get_product(); if ( ! $product instanceof \WC_Product ) { continue; } $adjustment = -1 * ( $item->get_quantity() ); // we want a positive value to increase the stock and a negative number to decrease it. $inventory_adjustment = Product::get_inventory_change_adjustment_type( $product, $adjustment ); if ( empty( $inventory_adjustment ) ) { continue; } $inventory_adjustments[] = $inventory_adjustment; } if ( empty( $inventory_adjustments ) ) { return; } wc_square()->log( 'Order from other gateway Refund inventory updates syncing..' ); $idempotency_key = wc_square()->get_idempotency_key( md5( serialize( $inventory_adjustments ) ) . '_change_inventory' ); wc_square()->get_api()->batch_change_inventory( $idempotency_key, $inventory_adjustments ); } /** * Add gift card recipient data to order line item meta. * * @since 4.2.0 * * @param \WC_Order_Item_Product $item The order item product. * @param string $cart_item_key The cart item key. * @param array $values Values associated with a cart item key. * @param \WC_Order $order Woo Order. */ public function add_gift_card_add_to_cart_details_to_order( $item, $cart_item_key, $values, $order ) { $product = wc_get_product( $values['product_id'] ); if ( ! $product instanceof \WC_Product ) { return; } // Return if the product is not a gift card product. if ( ! Product::is_gift_card( $product ) ) { return; } // Add meta if a new gift card is purchased. if ( ! empty( $values['square-gift-card-send-to-email'] ) ) { if ( ! empty( $values['square-gift-card-sender-name'] ) ) { $item->add_meta_data( 'square-gift-card-sender-name', $values['square-gift-card-sender-name'] ); } $item->add_meta_data( 'square-gift-card-send-to-email', $values['square-gift-card-send-to-email'] ); $item->add_meta_data( '_square-gift-card-purchase-type', 'new' ); if ( ! empty( $values['square-gift-card-sent-to-first-name'] ) ) { $item->add_meta_data( 'square-gift-card-sent-to-first-name', $values['square-gift-card-sent-to-first-name'] ); } if ( ! empty( $values['square-gift-card-sent-to-message'] ) ) { $item->add_meta_data( 'square-gift-card-sent-to-message', $values['square-gift-card-sent-to-message'] ); } } // Add meta if an existing gift card is loaded with amount. if ( ! empty( $values['square-gift-card-gan'] ) ) { $item->add_meta_data( 'square-gift-card-gan', $values['square-gift-card-gan'] ); $item->add_meta_data( '_square-gift-card-purchase-type', 'load' ); } // Fallback when gift card product is added to card directly from the /shop page which // bypasses adding recipient email address, so we default to purchasing a new gift card // without a recipient email address. if ( empty( $values['square-gift-card-send-to-email'] ) && empty( $values['square-gift-card-gan'] ) ) { $item->add_meta_data( '_square-gift-card-purchase-type', 'new' ); } } /** * Adds gift card related order item meta to the order again cart item. * * @param array $cart_item_data Cart item data. * * @return array */ public function reorder_gift_card( $cart_item_data ) { // Disabling PHPCS check as nonce verification is done in the parent method. $order_id = absint( wp_unslash( $_GET['order_again'] ?? 0 ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( ! $order_id ) { return $cart_item_data; } $order = wc_get_order( $order_id ); $order_items = $order->get_items(); if ( empty( $order_items ) ) { return $cart_item_data; } $product = wc_get_product( $cart_item_data['product_id'] ); if ( ! Product::is_gift_card( $product ) ) { return $cart_item_data; } /** @var \WC_Order_Item $order_item */ foreach ( $order_items as $order_item ) { $order_item_data = $order_item->get_data(); $product = wc_get_product( $order_item_data['product_id'] ); if ( ! Product::is_gift_card( $product ) ) { continue; } $cart_item_data['square-gift-card-send-to-email'] = $order_item->get_meta( 'square-gift-card-send-to-email' ); $cart_item_data['square-gift-card-sender-name'] = $order_item->get_meta( 'square-gift-card-sender-name' ); $cart_item_data['square-gift-card-sent-to-first-name'] = $order_item->get_meta( 'square-gift-card-sent-to-first-name' ); $cart_item_data['square-gift-card-sent-to-message'] = $order_item->get_meta( 'square-gift-card-sent-to-message' ); } return $cart_item_data; } /** * Filters the meta key into a human-readable format. * * @since 4.2.0 * * @param string $display_key The value that will be displayed in the order line item. * @param \WC_Meta_Data $meta The order line item meta data object. * @param \WC_Order_Item_Product $order_item Instance of the order item product. * * @return string */ public function modify_gift_card_line_item_key( $display_key, $meta, $order_item ) { if ( 'square-gift-card-sender-name' === $meta->key ) { return __( "Sender's name", 'woocommerce-square' ); } if ( 'square-gift-card-send-to-email' === $meta->key ) { return __( "Recipient's email", 'woocommerce-square' ); } if ( 'square-gift-card-sent-to-first-name' === $meta->key ) { return __( "Recipient's name", 'woocommerce-square' ); } if ( 'square-gift-card-sent-to-message' === $meta->key ) { return __( 'Message', 'woocommerce-square' ); } if ( 'square-gift-card-gan' === $meta->key ) { return __( 'Gift card number', 'woocommerce-square' ); } return $display_key; } /** * Triggers an email to the recipient of the gift card. * * @since 4.2.0 * * @param \WC_Order $order WooCommerce order. */ public function trigger_email_for_gift_card_sent( $order ) { wc_square()->get_email_handler()->get_gift_card_sent()->trigger( $order ); } /** * Hides the meta that indicates the type of gift card purchase, * new or reload. * * @since 4.2.0 * * @param array $meta_array Array of line order item meta. * @return array */ public function hide_gift_card_line_item_meta( $meta_array ) { $meta_array[] = '_square-gift-card-purchase-type'; return $meta_array; } /** * Returns the type of gift card purchase type - `new` or `load`. * * - `new` indicates a new gift card is purchased. * - `load` indicates an existing gift card is loaded with additional funds. * * @since 4.2.0 * * @param \WC_Order $order WooCommerce order. * * @return string|boolean Types of gift card purchase, false otherwise. */ public static function get_gift_card_purchase_type( $order ) { $order_items = $order->get_items(); /** @var \WC_Order_Item_Product $order_item */ foreach ( $order_items as $order_item ) { $purchase_type = $order_item->get_meta( '_square-gift-card-purchase-type' ); if ( ! empty( $purchase_type ) ) { return $purchase_type; } } return false; } /** * Returns the gift card number from the order line item. * * @since 4.2.0 * * @param \WC_Order $order WooCommerce order. * * @return string|boolean The gift card number, false otherwise. */ public static function get_gift_card_gan( $order ) { $order_items = $order->get_items(); /** @var \WC_Order_Item_Product $order_item */ foreach ( $order_items as $order_item ) { $gan = $order_item->get_meta( 'square-gift-card-gan' ); if ( ! empty( $gan ) ) { return $gan; } } return false; } /** * Returns if the order was placed using a Square credit card. * * @since 3.7.0 * * @param \WC_Order $order WooCommerce order. * * @return boolean */ public static function is_tender_type_card( $order ) { return '1' === wc_square()->get_gateway( $order->get_payment_method() )->get_order_meta( $order, 'is_tender_type_card' ); } /** * @since 3.7.0 * * @param \WC_Order $order WooCommerce order. * * @return boolean */ public static function is_tender_type_gift_card( $order ) { return '1' === wc_square()->get_gateway( $order->get_payment_method() )->get_order_meta( $order, 'is_tender_type_gift_card' ); } /** * Returns if the order was placed using a Square cash app pay. * * @since 4.6.0 * * @param \WC_Order $order WooCommerce order. * * @return boolean */ public static function is_tender_type_cash_app_pay( $order ) { return '1' === wc_square()->get_gateway( $order->get_payment_method() )->get_order_meta( $order, 'is_tender_type_cash_app_wallet' ); } /** * Sets the amount charged on the gift card for the given order. * * @since 3.7.0 * * @param \WC_Order $order WooCommerce order. * @param float $amount The total amount charged on the gift card for the order. */ public static function set_gift_card_total_charged_amount( $order, $amount ) { wc_square()->get_gateway( $order->get_payment_method() )->update_order_meta( $order, 'gift_card_charged_amount', $amount ); } /** * Returns the amount charged on the gift card for the given order. * * @since 3.7.0 * * @param \WC_Order $order WooCommerce order. * * @return float */ public static function get_gift_card_total_charged_amount( $order ) { return (float) wc_square()->get_gateway( $order->get_payment_method() )->get_order_meta( $order, 'gift_card_charged_amount' ); } /** * Returns the last 4 digits of the gift card. * * @since 3.7.0 * * @param \WC_Order $order WooCommerce order. * * @return string */ public static function get_gift_card_last4( $order ) { return wc_square()->get_gateway( $order->get_payment_method() )->get_order_meta( $order, 'gift_card_last4' ); } /** * Sets the last 4 digits of the gift card. * * @since 3.7.0 * * @param \WC_Order $order WooCommerce order. * * @return string */ public static function set_gift_card_last4( $order, $number ) { return wc_square()->get_gateway( $order->get_payment_method() )->update_order_meta( $order, 'gift_card_last4', $number ); } /** * Returns the total amount that is refunded to the gift card. * * @since 3.7.0 * * @param \WC_Order $order WooCommerce order. * * @return float */ public static function get_gift_card_total_refunded_amount( $order ) { $amount = (float) wc_square()->get_gateway( $order->get_payment_method() )->get_order_meta( $order, 'gift_card_refunded_amount' ); $amount = empty( $amount ) ? 0 : $amount; return $amount; } /** * Sets the total amount that is refunded to the gift card. * * @since 3.7.0 * * @param \WC_Order $order WooCommerce order. * @param float $amount The total amount refunded to the gift card for the order. */ public static function set_gift_card_total_refunded_amount( $order, $amount ) { wc_square()->get_gateway( $order->get_payment_method() )->update_order_meta( $order, 'gift_card_refunded_amount', $amount ); } /** * Sets the total order amount before applying the gift card. * * @since 3.7.0 * * @param \WC_Order $order WooCommerce order. * @param float $amount */ public static function set_order_total_before_gift_card( $order, $amount ) { wc_square()->get_gateway( $order->get_payment_method() )->update_order_meta( $order, 'order_total_before_gift_card', $amount ); } /** * Gets the total order amount before applying the gift card. * * @since 3.7.0 * * @return float */ public static function get_order_total_before_gift_card( $order ) { return (float) wc_square()->get_gateway( $order->get_payment_method() )->get_order_meta( $order, 'order_total_before_gift_card' ); } /** * Displays the gift card details in the order item. * * @param int $order_id WooCommerce order ID. */ public function add_admin_order_items( $order_id ) { $order = wc_get_order( $order_id ); if ( ! self::is_tender_type_gift_card( $order ) ) { return; } ?>
   
- $order->get_currency() ) ) ); $refunded_amount = self::get_gift_card_total_refunded_amount( $order ); ?>
get_gateway( $order->get_payment_method() ); $gift_card_charged = $gateway->get_order_meta( $order, 'gift_card_partial_total' ); $other_gateway_charged = $gateway->get_order_meta( $order, 'other_gateway_partial_total' ); if ( empty( $other_gateway_charged ) ) { // Backward compatibility. $other_gateway_charged = $gateway->get_order_meta( $order, 'credit_card_partial_total' ); } $payment_method = ''; if ( $is_tender_card ) { $payment_method = esc_html__( 'Credit Card', 'woocommerce-square' ); } elseif ( $is_tender_cash_app ) { $payment_method = esc_html__( 'Cash App Pay', 'woocommerce-square' ); } return sprintf( /* translators: %1$s - Amount charged on gift card, %2$s - Amount charged on credit card. */ __( 'Square Gift Card (%1$s) and %2$s (%3$s)', 'woocommerce-square' ), get_woocommerce_currency_symbol( $order->get_currency() ) . Square_Helper::number_format( $gift_card_charged ), $payment_method ?? '', get_woocommerce_currency_symbol( $order->get_currency() ) . Square_Helper::number_format( $other_gateway_charged ) ); } if ( $is_tender_gift_card ) { return sprintf( /* translators: %1$s - Amount charged on gift card. */ __( 'Square Gift Card (%1$s)', 'woocommerce-square' ), get_woocommerce_currency_symbol( $order->get_currency() ) . $order->get_total() ); } return $value; } /** * Includes info regarding gift card in the payment gateway title. * * @since 3.7.0 * * @param string $value Gateway title. * @param string $id Plugin id. * * @return string */ public function filter_gateway_title( $value, $id ) { $plugin_gateways = wc_square()->get_gateway_ids() ?? array(); if ( ! in_array( $id, $plugin_gateways, true ) || ! is_admin() || ! function_exists( 'get_current_screen' ) ) { return $value; } $screen = get_current_screen(); if ( ! ( $screen && 'shop_order' === $screen->id ) ) { return $value; } if ( ! isset( $_GET['post'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended return $value; } $post_id = wc_clean( absint( $_GET['post'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended $order = wc_get_order( $post_id ); if ( ! $order instanceof \WC_Order ) { return $value; } return self::filter_payment_method_title( $value, $order ); } /** * Includes split payment details on the order details screen. * * @param array $total_rows Array of order details. * @param \WC_Order $order WooCommerce Order. * * @return array */ public function filter_order_item_totals( $total_rows, $order ) { $charge_type = wc_square()->get_gateway( $order->get_payment_method() )->get_order_meta( $order, 'charge_type' ); if ( Payment_Gateway::CHARGE_TYPE_PARTIAL !== $charge_type ) { return $total_rows; } $gift_card_partial_total = wc_square()->get_gateway( $order->get_payment_method() )->get_order_meta( $order, 'gift_card_partial_total' ); $other_gateway_partial_total = wc_square()->get_gateway( $order->get_payment_method() )->get_order_meta( $order, 'other_gateway_partial_total' ); if ( empty( $other_gateway_partial_total ) ) { // Backward compatibility. $other_gateway_partial_total = wc_square()->get_gateway( $order->get_payment_method() )->get_order_meta( $order, 'credit_card_partial_total' ); } $total_rows['order_total']['value'] = sprintf( /* translators: %1$s - Order total, %2$s - Amount charged on gift card, %3$s - Other payment method %4$s - Amount charged on credit card/cash app pay. */ esc_html__( '%1$s — Total split between gift card (%2$s) and %3$s (%4$s)', 'woocommerce-square' ), wp_kses_post( $total_rows['order_total']['value'] ), wp_kses_post( wc_price( $gift_card_partial_total, array( 'currency' => $order->get_currency() ) ) ), 'square_cash_app_pay' === $order->get_payment_method() ? esc_html__( 'cash app pay', 'woocommerce-square' ) : esc_html__( 'credit card', 'woocommerce-square' ), wp_kses_post( wc_price( $other_gateway_partial_total, array( 'currency' => $order->get_currency() ) ) ) ); return $total_rows; } /** * Renders a notice if the billing country is not set in manual order. * * @since 4.2.0 * @param \WC_Order $order */ public function render_admin_missing_billing_details_notice( $order ) { $created_via = $order->get_created_via(); if ( $order->is_paid() ) { return; } if ( ! ( '' === $created_via || 'admin' === $created_via ) ) { return; } $billing_country = $order->get_billing_country(); if ( ! empty( $billing_country ) ) { return; } ?> get_billing_country() ) ) { return; } require_once WC()->plugin_path() . '/includes/admin/wc-meta-box-functions.php'; ?> countries->get_address_fields( '', 'billing_' ) as $key => $field ) { if ( 'billing_email' === $key ) { continue; } if ( is_callable( array( $order, 'set_' . $key ) ) ) { $props[ $key ] = isset( $_POST[ $key ] ) ? wc_clean( wp_unslash( $_POST[ $key ] ) ) : ''; } else { $order->update_meta_data( $key, wc_clean( wp_unslash( $_POST[ $key ] ) ) ); } } $order->set_props( $props ); $order->add_order_note( esc_html__( 'Customer has updated their billing details from the Pay for order page.', 'woocommerce-square' ), 0, true ); $order->save(); } /** * Disables email verification when billing details are updated by guest on the * pay for order page. * * @since 4.2.0 * * @param bool $email_verification_required If email verification is required. * * @return boolean */ public function no_verification_on_guest_save( $email_verification_required ) { // Nonce already verified before filter `woocommerce_order_email_verification_required`. // phpcs:ignore WordPress.Security.NonceVerification.Missing if ( isset( $_POST['wc-square-save-guest-details'] ) ) { return false; } return $email_verification_required; } }