<?php
/**
* Handle payment success/cancelled redirection & webhook events
*
* @package Tutor\Ecommerce
* @author Themeum <support@themeum.com>
* @link https://themeum.com
* @since 3.0.0
*/
namespace Tutor\Ecommerce;
use TUTOR\Input;
use WP_REST_Server;
use WP_REST_Request;
/**
* Payment handler class.
*/
class PaymentHandler {
const AUTHORIZENET = 'authorizenet';
/**
* Register hooks
*
* @since 3.0.0
*/
public function __construct() {
add_action( 'rest_api_init', array( $this, 'register_webhook_route' ) );
add_filter( 'template_include', array( $this, 'load_order_status_template' ) );
}
/**
* Register route for handle webhook event.
*
* @since 3.0.0
*
* @return void
*/
public function register_webhook_route() {
register_rest_route(
'tutor/v1',
'/ecommerce-webhook',
array(
'methods' => WP_REST_Server::ALLMETHODS,
'callback' => array( $this, 'handle_ecommerce_webhook' ),
'permission_callback' => '__return_true', // Allows public access to the route.
)
);
// Register route for authorizenet.
register_rest_route(
'tutor/v1',
'/ecommerce-webhook/authorizenet',
array(
'methods' => WP_REST_Server::ALLMETHODS,
'callback' => array( $this, 'handle_ecommerce_webhook' ),
'permission_callback' => '__return_true', // Allows public access to the route.
)
);
}
/**
* Webhook request handler
*
* @since 3.0.0
*
* @param WP_REST_Request $request The request object.
*
* @return void
*/
public function handle_ecommerce_webhook( WP_REST_Request $request ) {
$webhook_data = (object) array(
'get' => $_GET,
'post' => $_POST,
'server' => $_SERVER,
'stream' => file_get_contents( 'php://input' ),
);
$route = $request->get_route() ?? null;
$payment_method = ! is_null( $route ) && strpos( $route, self::AUTHORIZENET ) ? self::AUTHORIZENET : Input::get( 'payment_method', 'paypal' );
$payment_gateways = apply_filters( 'tutor_gateways_with_class', Ecommerce::payment_gateways_with_ref(), $payment_method );
$payment_gateway_class = isset( $payment_gateways[ $payment_method ] )
? $payment_gateways[ $payment_method ]['gateway_class']
: null;
if ( $payment_gateway_class ) {
$payment = Ecommerce::get_payment_gateway_object( $payment_gateway_class );
$res = $payment->verify_webhook_signature( $webhook_data );
if ( is_object( $res ) && property_exists( $res, 'id' ) ) {
do_action( 'tutor_order_payment_updated', $res );
if ( property_exists( $res, 'redirectUrl' ) ) {
wp_safe_redirect( $res->redirectUrl );
exit();
}
}
}
}
/**
* Load order status template
*
* It will load success or failed template based on order status
*
* @since 3.0.0
*
* @param string $template Default template.
*
* @return string
*/
public function load_order_status_template( $template ) {
$user_id = get_current_user_id();
$placement_status = Input::get( 'tutor_order_placement' );
$order_id = Input::get( 'order_id', 0, Input::TYPE_INT );
if ( $placement_status && $order_id ) {
delete_transient( CheckoutController::PAY_NOW_ALERT_MSG_TRANSIENT_KEY . $user_id );
delete_transient( CheckoutController::PAY_NOW_ERROR_TRANSIENT_KEY . $user_id );
// Modify the page title.
add_filter(
'document_title_parts',
function ( $title ) use ( $placement_status ) {
$site_title = get_bloginfo( 'name' );
if ( 'success' === $placement_status ) {
$title['title'] = __( 'Order Placement Success', 'tutor' ) . ' - ' . $site_title;
} else {
$title['title'] = __( 'Order Placement Failed', 'tutor' ) . ' - ' . $site_title;
}
return $title;
}
);
if ( 'success' === $placement_status ) {
do_action( 'tutor_order_placement_success', $order_id );
tutor_load_template(
'ecommerce.order-placement-success',
array(
'order_status' => $placement_status,
'order_id' => $order_id,
)
);
} else {
do_action( 'tutor_order_placement_failed', $order_id );
tutor_load_template(
'ecommerce.order-placement-failed',
array(
'order_status' => $placement_status,
'order_id' => $order_id,
)
);
}
exit();
}
return $template;
}
}