Last active
April 23, 2019 09:57
Star
You must be signed in to star a gist
[Pro Sites] - Custom Gateway Skeleton. Basic Parts to set up a custom gateway for Pro Sites plugin.
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 | |
/** | |
* Plugin Name: [Pro Sites] - Custom Gateway Skeleton | |
* Plugin URI: https://premium.wpmudev.org/ | |
* Description: Basic Parts to set up a custom gateway for Pro Sites plugin | |
* Author: Panos Lyrakis @ WPMUDEV | |
* Author URI: https://premium.wpmudev.org/ | |
* License: GPLv2 or later | |
*/ | |
if ( ! defined( 'ABSPATH' ) ) { | |
exit; | |
} | |
if ( ! class_exists( 'WPMUDEV_MS_Custom_Gateway_Skeleton' ) ) { | |
class WPMUDEV_MS_Custom_Gateway_Skeleton { | |
/** | |
* ID of the gateway. | |
* | |
* @var string | |
* | |
* @since Unknown | |
*/ | |
private static $id = 'thrivecart'; | |
private static $_instance = null; | |
// Some custom parameters specific to gateway | |
// These paramaters are for custom webhook | |
private static $webhook = 'ps-thrivecart-getway'; | |
private static $webhook_tag = 'thrive-cart-webhook'; | |
// This param is for linking to gateway | |
private static $gateway_url = 'https://thrivecart.com/'; | |
private static $thrivecart_action = 'wpmudev_ps_thrivecart'; | |
// This parameters are the ones set in settings() method. | |
// We use the same names as we used in the settings fields. No restriction though | |
private static $thrivecart_buttontext = null; | |
private static $thrivecart_thankyou = null; | |
public static function get_instance() { | |
if( is_null( self::$_instance ) ){ | |
self::$_instance = new WPMUDEV_MS_Custom_Gateway_Skeleton(); | |
} | |
return self::$_instance; | |
} | |
private function __construct() { | |
add_action( 'init', array( $this, 'setup' ) ); | |
add_action( 'parse_request', array( $this, 'parse_request' ) ); | |
add_action( self::$thrivecart_action, array( $this, 'webhook_handler' ) ); | |
} | |
public function setup() { | |
global $psts; | |
self::$thrivecart_buttontext = $psts->get_setting( 'thrivecart_buttontext' ); | |
self::$thrivecart_thankyou = $psts->get_setting( 'thrivecart_thankyou' ); | |
if ( empty( self::$thrivecart_buttontext ) ) { | |
self::$thrivecart_buttontext = 'Checkout'; | |
} | |
$this->add_rewrite_rules_tags(); | |
$this->add_rewrite_rules(); | |
$this->prepare_gateway_setting(); | |
} | |
/** | |
* Get gateway's title name. Required in order to show up in active gateways dropdown in admin | |
* | |
* @since Unknown | |
* | |
* @return array | |
*/ | |
public static function get_name() { | |
return array( | |
self::$id => __( 'Thrivecart', 'psts' ), | |
); | |
} | |
/** | |
* Render the gateway form in front end. Required by Pro Sites in order to display the gateway's checkout form in checkout page | |
* | |
* @param array $render_data Data for render. | |
* @param array $args Arguments for the form. | |
* @param int $blog_id Blog ID. | |
* @param string $domain Site domain. | |
* | |
* @since Unknown | |
* | |
* @return string | |
*/ | |
public static function render_gateway( $render_data = array(), $args, $blog_id, $domain ) { | |
global $psts, $current_user; | |
// Set the default values. | |
$activation_key = $user_name = $new_blog = $customer = false; | |
$button_product_url = self::$gateway_url . 'product_url_here/'; | |
$url_params = array(); | |
// First we need to clear caches. | |
ProSites_Helper_Cache::refresh_cache(); | |
// Set new/upgrading blog data to render data array. | |
foreach ( array( 'new_blog_details', 'upgraded_blog_details', 'activation_key' ) as $key ) { | |
$render_data[ $key ] = isset( $render_data[ $key ] ) ? $render_data[ $key ] : ProSites_Helper_Session::session( $key ); | |
} | |
// New blog data. | |
$blog_data = empty( $render_data['new_blog_details'] ) ? array() : $render_data['new_blog_details']; | |
// Set period and levels. | |
$period = empty( $blog_data['period'] ) ? ProSites_Helper_ProSite::default_period() : (int) $blog_data['period']; | |
$level = empty( $blog_data['level'] ) ? 0 : (int) $blog_data['level']; | |
$level = empty( $render_data['upgraded_blog_details']['level'] ) ? $level : (int) $render_data['upgraded_blog_details']['level']; | |
// We need to get the email. | |
$email = self::get_email( $render_data ); | |
// Current action. | |
$action = self::from_request( 'action', false, 'get' ); | |
// Set a flag that it is new blog. | |
if ( ProSites_Helper_ProSite::allow_new_blog() && ( self::from_request( 'new_blog' ) || 'new_blog' === $action ) ) { | |
$new_blog = true; | |
} | |
// If blog id is found in url. | |
$bid = self::from_request( 'bid', $blog_id, 'get' ); | |
// If blog id is found in url. | |
$bid = self::from_request( 'bid', $blog_id, 'get' ); | |
// If blog id is found in url. | |
if ( ! empty( $bid ) ) { | |
// Blog exists so probably might need to get info from Gateway's API, eg for use info instead of : | |
if ( ! empty( $blog_data ) ) { | |
// Get the data. | |
$username = empty( $blog_data['username'] ) ? '' : $blog_data['username']; | |
$user_email = empty( $blog_data['email'] ) ? '' : $blog_data['email']; | |
$blogname = empty( $blog_data['blogname'] ) ? '' : $blog_data['blogname']; | |
$blog_title = empty( $blog_data['title'] ) ? '' : $blog_data['title']; | |
} | |
} | |
// This is a new blog. | |
if ( isset( $render_data['activation_key'] ) ) { | |
// Get the activation key. | |
$activation_key = $render_data['activation_key']; | |
// If new blog details is found. | |
if ( ! empty( $blog_data ) ) { | |
// Get the data. | |
$username = empty( $blog_data['username'] ) ? '' : $blog_data['username']; | |
$user_email = empty( $blog_data['email'] ) ? '' : $blog_data['email']; | |
$blogname = empty( $blog_data['blogname'] ) ? '' : $blog_data['blogname']; | |
$blog_title = empty( $blog_data['title'] ) ? '' : $blog_data['title']; | |
} | |
// Since this is a new blog, there is no blog_id as it is still in signups table. We need to use the activation key in button params. | |
$url_params['activation_key'] = $activation_key; | |
} | |
$url_params['username'] = $username; | |
$url_params['user_email'] = $user_email; | |
$url_params['blogname'] = $blogname; | |
$url_params['blog_title'] = $blog_title; | |
$button_product_url .= http_build_query( $url_params ); | |
ob_start(); | |
?> | |
<h3><?php esc_html_e( 'Checkout Using Thrivecard Checkout Expirience', 'psts' ); ?></h3> | |
<p><?php esc_attr_e( 'The world\'s easiest and most powerful cart platform', 'psts' ); ?></p> | |
<form action="<?php echo $button_product_url; ?>"> | |
<input type="submit" value="<?php echo self::$thrivecart_buttontext; ?>" /> | |
</form> | |
<?php | |
return ob_get_clean(); | |
} | |
/** | |
* Handles the HTTP Request sent from Thrivecart to site's webhook | |
* | |
* | |
* @since Unknown | |
* | |
* @return bool | |
*/ | |
public function webhook_handler() { | |
global $psts; | |
/* | |
* If we are here it means that we have some HTTP Request to the Webhook we have set in this site. | |
* | |
* Depending on the Request we can retrieve the input with $_POST or file_get_contents | |
*/ | |
$input = $_POST; | |
// OR | |
// $input = @file_get_contents( 'php://input' ); | |
// You might need to decode json: | |
// $json = json_decode( $input ); | |
// The request from the getway should include information about site/blog, payment and user | |
// For site it should include the activation key, especially for first payment. | |
// If it is a subscription and this is a recurring payment it can contain the blog_id too | |
// For the site it should also contain the level id. From the level id we can get the level name with: | |
// $level_name = $psts->get_level_setting( {RETRIEVED ID}, 'name' ); | |
// For payment it should contain : | |
// A transaction code. This can be stored in a custom table | |
// A transaction/event type. For insance it can be a notification for a subscription creation or update. Or it could be for a successfull or failed payment. Lets not forget about cancellations too. | |
// If the transaction type is a successfull payment for a new site ( new site could be when there is no blog_id in HTTP Request. It depends ), | |
// we need to activate that signup: | |
//$result = ProSites_Helper_Registration::activate_blog( | |
// {ACTIVATION KEY FROM HTTP REQUEST}, | |
// {CHECK IF IS ON TRIAL}, | |
// {PERIOD FROM REQUEST}, | |
// {LEVEL FROM REQUEST}, | |
// {EXPIRE TIMESTAMP - CALCULATE OR FROM REQUEST}, | |
// {IF IT IS RECURRING : true OR false} | |
//); | |
// In case of a new or recurring payment, you will need to extend the Pro Site level for the blog. You can use the Pro Sites method `$psts->extend()`: | |
// $psts->extend( | |
//{BLOG ID}, | |
//{PERIOD TIMESTAMP}, | |
//{GATEWAY ID : self::$id}, | |
//{LEVEL}, | |
//{AMOUNT PAID}, | |
//{EXPIRATION TIMESTAMP}, | |
//{IS RECURRING _ true or false}, | |
//{SEND A MANUAL NOTIFIACTION - set it to false}, | |
//{TYPE OF EXTENSION, - manual or trial. You can leave it blank}, | |
//{ON TRIAL - true or false} | |
//); | |
// Upon a Cancellation event we will need to cancel site's Pro Site level: | |
//$psts->withdraw( {BLOG ID} ); | |
// You might need some custom option for that blog | |
//update_blog_option( {BLOG ID}, 'psts_thrivecart_canceled', 1 ); | |
} | |
private function prepare_gateway_setting() { | |
//add_action( 'psts_gateway_settings', array( $this, 'settings' ) ); | |
// For Gateway settings | |
// 1. Add gateway admin tab | |
add_filter( 'prosites_gateways_tabs', array( $this, 'settings_tab' ) ); | |
// 2. Load the content for the Gateway Settings | |
add_action( 'psts_settings_page', array( $this, 'settings' ) ); | |
// 2. Add the tab callback function. That callbck is the one that will fetch the settings content | |
//add_filter( 'prosites_settings_tabs_render_callback', array( $this, 'settings_tab_callback' ), 20, 2 ); | |
} | |
public function settings_tab( $tabs ) { | |
$tabs[ self::$id ] = array( | |
'header_save_button' => true, | |
'button_name' => 'button_name', | |
'title' => 'Thrivecart', | |
'desc' => array( 'Use the Thrivecart checkout!' ), | |
'url' => "admin.php?page=psts-gateways&tab=" . self::$id | |
); | |
return $tabs; | |
} | |
public function settings_tab_callback( $render_callback, $active_tab ) { | |
if ( $active_tab == self::$id ) { | |
$render_callback = array( get_class(), 'settings' ); | |
} | |
return $render_callback; | |
} | |
public function settings() { | |
global $psts; | |
ProSites_Helper_Settings::settings_header( ProSites_Helper_Tabs_Gateways::get_active_tab() ); | |
$class_name = get_class(); | |
$active_gateways = (array) $psts->get_setting('gateways_enabled'); | |
$checked = in_array( $class_name, $active_gateways ) ? 'on' : 'off'; | |
/** | |
* IMPORTANT !! | |
* You need at least one form element with name `psts[]`. Else settings won't be saved. Elemnts without `psts[]` name won't be set to PS settings | |
*/ | |
?> | |
<div class="inside"> | |
<p class="description"> | |
Learn more about <a href="https://thrivecart.com/" target="_blank"><?php _e( 'Thrivecart here »', 'psts' ); ?></a> | |
</p> | |
<p> | |
<?php | |
printf( | |
__( 'To use Thrivecart you must enter this webook url <strong>%1$s</strong> in your Thrivecart account under <strong>Settings > API & Webhooks > Webhooks & notifications</strong>.', 'psts' ), | |
network_site_url( self::$webhook . DIRECTORY_SEPARATOR . self::$webhook_tag ) | |
); | |
?> | |
</p> | |
<table class="form-table"> | |
<tr> | |
<th scope="row"><?php _e( 'Enable Gateway', 'psts' ) ?></th> | |
<td> | |
<input type="hidden" name="gateway" value="<?php echo esc_attr( $class_name ); ?>" /> | |
<input type="checkbox" name="gateway_active" value="1" <?php checked( $checked, 'on' ); ?> /> | |
<input type="hidden" name="submit_gateways" /> | |
</td> | |
</tr> | |
<tr valign="top"> | |
<th scope="row" class="psts-help-div psts-thrivecart-thankyou"><?php echo esc_html__( 'Thank You Message', 'psts' ) . $psts->help_text( esc_html__( 'Displayed on successful checkout. HTML allowed', 'psts' ) ); ?></th> | |
<td> | |
<textarea name="psts[thrivecart_thankyou]" type="text" rows="4" wrap="soft" id="thrivecart_thankyou" style="width: 100%"><?php echo esc_textarea( stripslashes( $psts->get_setting( 'thrivecart_thankyou' ) ) ); ?></textarea> | |
</td> | |
</tr> | |
<tr valign="top"> | |
<th scope="row" class="psts-help-div psts-thrivecart-buttontext"><?php echo esc_html__( 'Button text', 'psts' ) . $psts->help_text( esc_html__( 'The text on the buttons that will re-direct to Thrivecart checkout page', 'psts' ) ); ?></th> | |
<td> | |
<input type="text" name="psts[thrivecart_buttontext]" id="thrivecart_buttontext" value="<?php echo esc_textarea( stripslashes( $psts->get_setting( 'thrivecart_thankyou' ) ) ); ?>" /> | |
</td> | |
</tr> | |
</table> | |
</div> | |
<?php | |
} | |
public function parse_request( &$wp ) { | |
if( array_key_exists( self::$webhook_tag, $wp->query_vars ) ) { | |
do_action( self::$thrivecart_action ); | |
die(0); | |
} | |
} | |
protected function add_rewrite_rules_tags() { | |
add_rewrite_tag( '%' . self::$webhook_tag . '%', '([^&]+)' ); | |
} | |
protected function add_rewrite_rules() { | |
//To use like http://site.com/ps-thrivecart-getway/payment-notification/ | |
add_rewrite_rule( '^' . self::$webhook . '/([^/]*)/?', 'index.php?' . self::$webhook_tag . '=$matches[1]', 'top' ); | |
} | |
// Helper functions taken from Stripe Gateway that ws created by Joel James ♥ | |
/** | |
* Get a value from $_POST global. | |
* | |
* @param string $string String name. | |
* @param mixed $default Default value. | |
* @param string $type Type of request. | |
* | |
* @since Unknown | |
* | |
* @return mixed | |
*/ | |
public static function from_request( $string, $default = false, $type = 'post' ) { | |
switch ( $type ) { | |
case 'post': | |
// Get data from post. | |
$value = isset( $_POST[ $string ] ) ? $_POST[ $string ] : false; // input var okay. | |
break; | |
case 'get': | |
$value = isset( $_GET[ $string ] ) ? $_GET[ $string ] : false; // input var okay. | |
break; | |
default: | |
$value = isset( $_REQUEST[ $string ] ) ? $_REQUEST[ $string ] : false; // input var okay. | |
} | |
// If empty return default value. | |
if ( ! empty( $value ) ) { | |
return $value; | |
} | |
return $default; | |
} | |
/** | |
* Get email for the current registration. | |
* | |
* | |
* @param array $process_data Process data. | |
* | |
* @since Unknown | |
* | |
* @return string|false | |
*/ | |
private static function get_email( $process_data = array() ) { | |
global $current_user; | |
// First try to get the email. | |
$email = empty( $current_user->user_email ) ? false : $current_user->user_email; | |
// Email is empty so try to get user email. | |
if ( empty( $email ) ) { | |
// Let's try to get signup email. | |
$email = self::from_request( 'user_email' ); | |
} | |
// Email is empty. | |
if ( empty( $email ) ) { | |
// Let's try to get signup email. | |
$email = self::from_request( 'signup_email' ); | |
} | |
// Again email is empty. | |
if ( empty( $email ) ) { | |
// Let's try to get from blog email. | |
$email = self::from_request( 'blog_email' ); | |
} | |
// In case if email is not set, try to get from process data. | |
if ( empty( $email ) && isset( $process_data['new_blog_details']['user_email'] ) ) { | |
$email = $process_data['new_blog_details']['user_email']; | |
} | |
return $email; | |
} | |
} | |
if ( ! function_exists( 'wpmudev_ms_custom_gateway_skeleton' ) ) { | |
function wpmudev_ms_custom_gateway_skeleton(){ | |
return WPMUDEV_MS_Custom_Gateway_Skeleton::get_instance(); | |
}; | |
add_action( 'plugins_loaded', 'wpmudev_ms_custom_gateway_skeleton', 10 ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment