Skip to content

Instantly share code, notes, and snippets.

@heldervilela
Created November 22, 2019 15:57
Show Gist options
  • Save heldervilela/f10d54334c0a50af0886df3cd727b8e2 to your computer and use it in GitHub Desktop.
Save heldervilela/f10d54334c0a50af0886df3cd727b8e2 to your computer and use it in GitHub Desktop.
Woo Checkout
<?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();
@NeffyBaby
Copy link

$available_gateways = WC()->payment_gateways->get_available_payment_gateways();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment