<?php
defined('ABSPATH') || exit;
class WC_Shortcode_Checkout
{
public static function get($atts)
{
return WC_Shortcodes::shortcode_wrapper(array(__CLASS__, 'output'), $atts);
}
public static function output($atts)
{
global $wp;
if (is_null(WC()->cart)) {
return;
}
if (isset($_GET['order']) && isset($_GET['key'])) {
wc_deprecated_argument(__CLASS__ . '->' . __FUNCTION__, '2.1', '"order" is no longer used to pass an order ID. Use the order-pay or order-received endpoint instead.');
$order_id = absint($_GET['order']);
$order = wc_get_order($order_id);
if ($order && $order->has_status('pending')) {
$wp->query_vars['order-pay'] = absint($_GET['order']);
} else {
$wp->query_vars['order-received'] = absint($_GET['order']);
}
}
if (!empty($wp->query_vars['order-pay'])) {
self::order_pay($wp->query_vars['order-pay']);
} elseif (isset($wp->query_vars['order-received'])) {
self::order_received($wp->query_vars['order-received']);
} else {
self::checkout();
}
}
private static function order_pay($order_id)
{
do_action('before_woocommerce_pay');
$order_id = absint($order_id);
if (isset($_GET['pay_for_order'], $_GET['key']) && $order_id) {
try {
$order_key = isset($_GET['key']) ? wc_clean(wp_unslash($_GET['key'])) : '';
$order = wc_get_order($order_id);
if (!$order || $order->get_id() !== $order_id || !hash_equals($order->get_order_key(), $order_key)) {
throw new Exception(__('Sorry, this order is invalid and cannot be paid for.', 'woocommerce'));
}
if (!current_user_can('pay_for_order', $order_id) && !is_user_logged_in()) {
echo '<div class="woocommerce-info">' . esc_html__('Please log in to your account below to continue to the payment form.', 'woocommerce') . '</div>';
woocommerce_login_form(array('redirect' => $order->get_checkout_payment_url()));
return;
}
if (!$order->get_user_id() && is_user_logged_in()) {
if ($order->get_billing_email() !== wp_get_current_user()->user_email) {
wc_print_notice(__('You are paying for a guest order. Please continue with payment only if you recognize this order.', 'woocommerce'), 'error');
}
}
if (!current_user_can('pay_for_order', $order_id)) {
throw new Exception(__('This order cannot be paid for. Please contact us if you need assistance.', 'woocommerce'));
}
if (!$order->needs_payment()) {
throw new Exception(sprintf(__('This order’s status is “%s”—it cannot be paid for. Please contact us if you need assistance.', 'woocommerce'), wc_get_order_status_name($order->get_status())));
}
if (!$order->has_status(wc_get_is_pending_statuses())) {
$quantities = array();
foreach ($order->get_items() as $item_key => $item) {
if ($item && is_callable(array($item, 'get_product'))) {
$product = $item->get_product();
if (!$product) {
continue;
}
$quantities[$product->get_stock_managed_by_id()] = isset($quantities[$product->get_stock_managed_by_id()]) ? $quantities[$product->get_stock_managed_by_id()] + $item->get_quantity() : $item->get_quantity();
}
}
foreach ($order->get_items() as $item_key => $item) {
if ($item && is_callable(array($item, 'get_product'))) {
$product = $item->get_product();
if (!$product) {
continue;
}
if (!apply_filters('woocommerce_pay_order_product_in_stock', $product->is_in_stock(), $product, $order)) {
throw new Exception(sprintf(__('Sorry, "%s" is no longer in stock so this order cannot be paid for. We apologize for any inconvenience caused.', 'woocommerce'), $product->get_name()));
}
if (!$product->managing_stock() || $product->backorders_allowed()) {
continue;
}
$held_stock = wc_get_held_stock_quantity($product, $order->get_id());
$required_stock = $quantities[$product->get_stock_managed_by_id()];
if (!apply_filters('woocommerce_pay_order_product_has_enough_stock', $product->get_stock_quantity() >= $held_stock + $required_stock, $product, $order)) {
throw new Exception(sprintf(__('Sorry, we do not have enough "%1$s" in stock to fulfill your order (%2$s available). We apologize for any inconvenience caused.', 'woocommerce'), $product->get_name(), wc_format_stock_quantity_for_display($product->get_stock_quantity() - $held_stock, $product)));
}
}
}
}
WC()->customer->set_props(array('billing_country' => $order->get_billing_country() ? $order->get_billing_country() : null, 'billing_state' => $order->get_billing_state() ? $order->get_billing_state() : null, 'billing_postcode' => $order->get_billing_postcode() ? $order->get_billing_postcode() : null));
WC()->customer->save();
$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
if (count($available_gateways)) {
current($available_gateways)->set_current();
}
wc_get_template('checkout/form-pay.php', array('order' => $order, 'available_gateways' => $available_gateways, 'order_button_text' => apply_filters('woocommerce_pay_order_button_text', __('Pay for order', 'woocommerce'))));
} catch (Exception $e) {
wc_print_notice($e->getMessage(), 'error');
}
} elseif ($order_id) {
$order_key = isset($_GET['key']) ? wc_clean(wp_unslash($_GET['key'])) : '';
$order = wc_get_order($order_id);
if ($order && $order->get_id() === $order_id && hash_equals($order->get_order_key(), $order_key)) {
if ($order->needs_payment()) {
wc_get_template('checkout/order-receipt.php', array('order' => $order));
} else {
wc_print_notice(sprintf(__('This order’s status is “%s”—it cannot be paid for. Please contact us if you need assistance.', 'woocommerce'), wc_get_order_status_name($order->get_status())), 'error');
}
} else {
wc_print_notice(__('Sorry, this order is invalid and cannot be paid for.', 'woocommerce'), 'error');
}
} else {
wc_print_notice(__('Invalid order.', 'woocommerce'), 'error');
}
do_action('after_woocommerce_pay');
}
private static function order_received($order_id = 0)
{
$order = false;
$order_id = apply_filters('woocommerce_thankyou_order_id', absint($order_id));
$order_key = apply_filters('woocommerce_thankyou_order_key', empty($_GET['key']) ? '' : wc_clean(wp_unslash($_GET['key'])));
if ($order_id > 0) {
$order = wc_get_order($order_id);
if (!$order || !hash_equals($order->get_order_key(), $order_key)) {
$order = false;
}
}
unset(WC()->session->order_awaiting_payment);
if ($order && $order->is_created_via('admin')) {
$order->set_customer_ip_address(WC_Geolocation::get_ip_address());
$order->save();
}
wc_empty_cart();
wc_get_template('checkout/thankyou.php', array('order' => $order));
}
private static function checkout()
{
do_action('woocommerce_before_checkout_form_cart_notices');
if (WC()->cart->is_empty() && !is_customize_preview() && apply_filters('woocommerce_checkout_redirect_empty_cart', true)) {
return;
}
do_action('woocommerce_check_cart_items');
WC()->cart->calculate_totals();
$checkout = WC()->checkout();
if (empty($_POST) && wc_notice_count('error') > 0) {
wc_get_template('checkout/cart-errors.php', array('checkout' => $checkout));
wc_clear_notices();
} else {
$non_js_checkout = !empty($_POST['woocommerce_checkout_update_totals']);
if (wc_notice_count('error') === 0 && $non_js_checkout) {
wc_add_notice(__('The order totals have been updated. Please confirm your order by pressing the "Place order" button at the bottom of the page.', 'woocommerce'));
}
wc_get_template('checkout/form-checkout.php', array('checkout' => $checkout));
}
}
}