Created
November 22, 2019 15:57
-
-
Save heldervilela/f10d54334c0a50af0886df3cd727b8e2 to your computer and use it in GitHub Desktop.
Woo Checkout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Login endpoint. | |
* | |
* @package @@pkg.name | |
* @version @@pkg.version | |
* @author @@pkg.author | |
* @license @@pkg.license | |
*/ | |
namespace PressCare\Admin\Api\Checkout; | |
use PressCare\API\Inc\Factory\Utils; | |
use WP_REST_Response; | |
use WP_Error; | |
use WP_REST_Server; | |
use Exception; | |
use \WC_Checkout; | |
use \WC_Validation; | |
include_once PC_API_PLUGIN_DIR . '../woocommerce/includes/class-wc-checkout.php'; | |
class Process extends WC_Checkout { | |
/** | |
* Posted data. | |
* | |
* @var string | |
*/ | |
protected $posted_data = ''; | |
/** | |
* Endpoint namespace. | |
* | |
* @var string | |
*/ | |
protected $namespace = 'v1'; | |
/** | |
* Route base. | |
* | |
* @var string | |
*/ | |
protected $rest_endpoint = 'checkout/process'; | |
public | |
function __construct() { | |
add_action( 'rest_api_init', function () { | |
/** | |
* Filter feed | |
* | |
* @since 1.0.0 | |
* @access public | |
* @endpoint /wp-json/v1/checkout/process (POST) | |
* | |
* @return object | |
*/ | |
register_rest_route( $this->namespace, '/' . $this->rest_endpoint, [ | |
'methods' => WP_REST_Server::CREATABLE, | |
'callback' => [ $this, 'process_checkout' ], | |
'permission_callback' => function ( $request ) { | |
if ( current_user_can( 'customer' ) ) { | |
return true; | |
} | |
} | |
] ); | |
} ); | |
} | |
/** | |
* Update Order. | |
* | |
* @access public | |
* @since 1.0.0 | |
* @link /woocommerce/includes/class-wc-ajax.php / checkout() | |
* | |
* @param array $data | |
* | |
* @return WP_Error|WP_REST_Response | |
*/ | |
public | |
function process_checkout( $data = [] ) { | |
wc_clear_notices(); | |
wc_maybe_define_constant( 'WOOCOMMERCE_CHECKOUT', true ); | |
wc_set_time_limit( 0 ); | |
$response = [ | |
"code" => "order-processed", | |
"data" => [], | |
]; | |
if ( WC()->cart->is_empty() ) { | |
/* translators: %s: shop cart url */ | |
return new WP_Error( 'empty-cart', __( 'Your form contains some errors, please correct it in order to complete the purchase.', '@@pkg.textdomain' ), [ 'status' => 403 ] ); | |
} | |
$this->posted_data = $this->get_posted_data(); | |
// First fields validate | |
$fields_errors = $this->validate_fields(); | |
if ( ! empty( $fields_errors ) ) { | |
return new WP_Error( 'form-contain-errors', __( 'Your form contains some errors, please correct it in order to complete the purchase.', '@@pkg.textdomain' ), [ | |
'status' => 403, | |
'errors' => $fields_errors | |
] ); | |
} | |
// Update session for customer and totals. | |
$errors = new WP_Error(); | |
$fields_errors = []; | |
$this->update_session( $this->posted_data ); | |
// Validate posted data and cart items before proceeding. | |
// $this->validate_checkout( $this->posted_data, $errors ); | |
foreach ( $errors->get_error_messages() as $message ) { | |
$fields_errors['alert'] = wp_strip_all_tags( $message ); | |
} | |
if ( empty( $response['error'] ) ) { | |
$this->process_customer( $this->posted_data ); | |
$order_id = $this->create_order( $this->posted_data ); | |
$order = wc_get_order( $order_id ); | |
if ( is_wp_error( $order_id ) ) { | |
return new WP_Error( 'validation-failed', $order_id->get_error_message(), [ 'status' => 403 ] ); | |
} | |
if ( ! $order ) { | |
return new WP_Error( 'unable-to-process', __( 'Unable to create order.', '@@pkg.textdomain' ), [ 'status' => 403 ] ); | |
} | |
do_action( 'woocommerce_checkout_order_processed', $order_id, $this->posted_data, $order ); | |
if ( WC()->cart->needs_payment() ) { | |
$result = $this->process_order_payment( $order_id, $this->posted_data['payment_method'] ); | |
if ( isset( $result['result'] ) && $result['result'] === 'success' ) { | |
$response['data'] = [ | |
'needs_payment' => true, | |
'key' => $order->get_order_key() | |
]; | |
// Redirect to order | |
WC()->cart->empty_cart( false ); | |
if ( strpos( $result['redirect'], site_url() ) !== false ) { | |
$response['data']['redirect'] = false; | |
} // Redirect to 3d secure | |
else { | |
$response['data']['redirect'] = $result['redirect']; | |
} | |
} else { | |
$notices = wc_get_notices( 'error' ); | |
$message = esc_html__( 'Sorry, we are unable to process your payment at this time. Please retry later.', '@@pkg.textdomain' ); | |
if ( ! empty( $notices ) ) { | |
$message = end( $notices ); | |
} | |
return new WP_Error( 'process-payment-error', $message, [ 'status' => 403 ] ); | |
} | |
} // Without payment | |
else { | |
$result = $this->process_order_without_payment( $order_id ); | |
$response['data']['key'] = $order->get_order_key(); | |
$response['data']['needs_payment'] = false; | |
} | |
} else { | |
return new WP_Error( 'form-contain-errors', __( 'Your form contains some errors, please correct it in order to complete the purchase.', '@@pkg.textdomain' ), [ | |
'status' => 403, | |
'errors' => $fields_errors | |
] ); | |
} | |
return new WP_REST_Response( $response, 200 ); | |
} | |
/** | |
* Process an order that does require payment. | |
* | |
* @since 3.0.0 | |
* | |
* @param int $order_id Order ID. | |
* @param string $payment_method Payment method. | |
* | |
* @return mixed|void | |
*/ | |
protected | |
function process_order_payment( $order_id, $payment_method ) { | |
$available_gateways = WC()->payment_gateways->get_available_payment_gateways(); | |
if ( ! isset( $available_gateways[ $payment_method ] ) ) { | |
return; | |
} | |
// Store Order ID in session so it can be re-used after payment failure. | |
WC()->session->set( 'order_awaiting_payment', $order_id ); | |
// Process Payment. | |
$result = $available_gateways[ $payment_method ]->process_payment( $order_id ); | |
$result = apply_filters( 'woocommerce_payment_successful_result', $result, $order_id ); | |
return $result; | |
} | |
/** | |
* Process an order that doesn't require payment. | |
* | |
* @since 3.0.0needs_payment | |
* | |
* @param int $order_id Order ID. | |
* | |
* @return array | |
*/ | |
protected | |
function process_order_without_payment( $order_id ) { | |
$order = wc_get_order( $order_id ); | |
$order->payment_complete(); | |
return array( | |
'result' => 'success', | |
'redirect' => apply_filters( 'woocommerce_checkout_no_payment_needed_redirect', $order->get_checkout_order_received_url(), $order ), | |
); | |
} | |
/** | |
* Get order details. | |
* | |
* @since 3.0.0needs_payment | |
* | |
* @param int $order_id Order ID. | |
* | |
* @return array | |
*/ | |
protected | |
function get_order_details( $order ) { | |
$response = [ | |
'key' => $order->get_order_key(), | |
]; | |
return $response; | |
} | |
/** | |
* Validate fields. | |
* | |
* @since 3.0.0needs_payment | |
* | |
* @param int $order_id Order ID. | |
* | |
* @return array | |
*/ | |
protected | |
function validate_fields() { | |
$errors = []; | |
$this->validate_required( 'billing_first_name', $errors ); | |
$this->validate_required( 'billing_last_name', $errors ); | |
$this->validate_required( 'billing_country', $errors ); | |
$this->validate_required( 'billing_address_1', $errors ); | |
$this->validate_required( 'billing_city', $errors ); | |
$this->validate_required( 'billing_postcode', $errors ); | |
$this->validate_required( 'billing_phone', $errors ); | |
$this->validate_required( 'billing_email', $errors ); | |
$this->validate_required( 'billing_vat', $errors ); | |
$this->is_postcode( 'billing_postcode', 'billing_country', $errors ); | |
$this->is_phone( 'billing_phone', $errors ); | |
$this->is_email( 'billing_email', $errors ); | |
if ( $this->posted_data['ship_to_different_address'] === 'true' ) { | |
$this->validate_required( 'shipping_first_name', $errors ); | |
$this->validate_required( 'shipping_last_name', $errors ); | |
$this->validate_required( 'shipping_country', $errors ); | |
$this->validate_required( 'shipping_address_1', $errors ); | |
$this->validate_required( 'shipping_postcode', $errors ); | |
$this->validate_required( 'shipping_city', $errors ); | |
$this->is_postcode( 'shipping_postcode', 'shipping_country', $errors ); | |
} | |
$this->validate_required( 'payment_method', $errors ); | |
if( $this->posted_data[ 'payment_method' ] === 'stripe' && empty( $_POST['stripe_source'] ) ) { | |
$errors[ 'stripe_source' ] = __( 'The credit card is required.', '@@pkg.textdomain' ); | |
} | |
return $errors; | |
} | |
/** | |
* Validate required fields. | |
* | |
* @access public | |
* @since 1.0.0 | |
* | |
* @param string $field | |
* @param string $label | |
* @param array $errors | |
*/ | |
public | |
function validate_required( $field = '', &$errors ) { | |
if ( $this->posted_data[ $field ] === '' ) { | |
$errors[ $field ] = __( 'This field is required.', '@@pkg.textdomain' ); | |
} | |
} | |
/** | |
* Validate postcode | |
* | |
* @access public | |
* @since 1.0.0 | |
* | |
* @param string $field | |
* @param string $label | |
* @param array $errors | |
*/ | |
private | |
function is_postcode( $field = '', $country, &$errors ) { | |
if ( ! WC_Validation::is_postcode( $this->posted_data[ $field ], $this->posted_data[ $country ] ) ) { | |
$errors[ $field ] = __( 'This is not a valid postcode / ZIP.', '@@pkg.textdomain' ); | |
} | |
} | |
/** | |
* Validate postcode | |
* | |
* @access public | |
* @since 1.0.0 | |
* | |
* @param string $field | |
* @param string $label | |
* @param array $errors | |
*/ | |
private | |
function is_phone( $field = '', &$errors ) { | |
if ( ! WC_Validation::is_phone( $this->posted_data[ $field ] ) ) { | |
$errors[ $field ] = __( 'This is not a valid phone number.', '@@pkg.textdomain' ); | |
} | |
} | |
/** | |
* Validate email | |
* | |
* @access public | |
* @since 1.0.0 | |
* | |
* @param string $field | |
* @param string $label | |
* @param array $errors | |
*/ | |
private | |
function is_email( $field = '', &$errors ) { | |
if ( ! is_email( $this->posted_data[ $field ] ) ) { | |
$errors[ $field ] = __( 'This is not a valid email address.', '@@pkg.textdomain' ); | |
} | |
} | |
} | |
new Process(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
$available_gateways = WC()->payment_gateways->get_available_payment_gateways();