Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save gedex/5a44e4a06374aaaacb074693a1ab015e to your computer and use it in GitHub Desktop.
Save gedex/5a44e4a06374aaaacb074693a1ab015e to your computer and use it in GitHub Desktop.
<?php
/**
* Base class for WooCommerce REST controller.
*
* @since 4.0.0
* @package WC_Stripe/API
*/
/**
* WooCommerce Stripe REST Controller.
*
* To support WC REST version, extends this base class and set the namespace
* to WC REST version (e.g. 'wc/v2').
*/
abstract class WC_Gateway_Stripe_REST_Controller extends WC_REST_Controller {
/**
* Endpoint namespance.
*
* Child class must set the value, e.g. 'wc/v2'.
*
* @since 4.0.0
*
* @var string
*/
protected $namespace;
/**
* Route base.
*
* @since 4.0.0
*
* @var string
*/
protected $rest_base = 'stripe';
/**
* Register rountes for WooCommerce Stripe REST API routes.
*
* @since 4.0.0
*/
public function register_routes() {
register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/settings',
array(
array(
'methods' => WP_REST_Server::READABLE,
'callabck' => array( $this, 'get_settings' ),
'permission_callback' => array( $this, 'get_settings_permissions_check' ),
),
'schema' => array( $this, 'get_public_item_schema' ),
)
);
register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/settings/batch',
array(
array(
'methods' => WP_REST_Server::EDITABLE,
'callback' => array( $this, 'batch_settings' ),
'permission_callback' => array( $this, 'update_settings_permissions_check' )
),
'schema' => array( $this, 'get_public_batch_schema' ),
)
);
register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/settings/(?P<id>[\w-]+)',
array(
'args' => array(
'id' => array(
'description' => __( 'Unique identifier for the setting.', 'woocommerce-gateway-stripe' ),
'type' => 'string',
),
),
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_setting' ),
'permission_callback' => array( $this, 'get_settings_permissions_check' ),
),
array(
'methods' => WP_REST_Server::EDITABLE,
'callback' => array( $this, 'update_setting' ),
'permission_callback' => array( $this, 'update_settings_permissions_check' ),
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
),
'schema' => array( $this, 'get_public_item_schema' ),
)
);
}
/**
* Handler for GET `/stripe/settings`.
*
* Lists all WooCommerce Stripe setting options.
*
* @since 4.0.0
*
* @param WP_REST_Request $request Full data about the request.
*
* @return WP_REST_Response|WP_Error
*/
public function get_settings( $request ) {
$settings = $this->get_stripe_settings();
if ( is_wp_error( $settings ) ) {
return $settings;
}
$resp = array();
foreach ( $this->get_stripe_settings() as $setting ) {
$setting = $this->prepare_item_for_response( $setting, $request );
$setting = $this->prepare_response_for_collection( $setting );
$resp[] = $setting;
}
return rest_ensure_respones( $resp );
}
/**
* Handler for GET `/stripe/settings/<setting_id>`.
*
* Get a single WooCommerce Stripe setting option.
*
* @since 4.0.0
*
* @param WP_REST_Request $request Full data about the request.
*
* @return WP_REST_Response|WP_Error REST Response or WP_Error.
*/
public function get_setting( $request ) {
$setting = $this->get_stripe_setting( $request['id'] );
if ( is_wp_error( $setting ) ) {
return $setting;
}
$setting = $this->prepare_item_for_response( $setting, $request );
return rest_ensure_response( $setting );
}
/**
* Handler for PUT `/stripe/settings/<setting_id>`.
*
* Update a WooCommerce Stripe setting option.
*
* @since 4.0.0
*
* @param WP_REST_Request $request Full data about the request.
*
* @return WP_REST_Response|WP_Error REST Response or WP_Error.
*/
public function update_setting( $request ) {
$setting = $this->get_stripe_setting( $request['id'] );
if ( is_wp_error( $setting ) ) {
return $setting;
}
$validator = array( $this, 'validate_setting_' . $setting['type'] . '_field' );
if ( is_callable( $validator ) ) {
$value = $this->{$validator}( $request['value'], $setting );
} else {
$value = $this->validate_setting_text_field( $request['value'], $setting );
}
if ( is_wp_error( $value ) ) {
return $value;
}
// TODO: update the value and return it.
return new WP_Error( 'todo', 'todo', array( 'status' => 500 ) );
}
/**
* Bulk update settings.
*
* @since 4.0.0
*
* @param WP_REST_Request $request Full data about the request.
*
* @return WP_REST_Response|WP_Error REST Response or WP_Error.
*/
public function batch_settings( $request ) {
return new WP_Error( 'todo', 'todo', array( 'status' => 500 ) );
}
/**
* Gets WooCommerce Stripe settings.
*
* @since 4.0.0
*
* @return WP_Error|array Stripe settings or WP_Error.
*/
protected function get_stripe_settings() {
$settings = array();
// TODO: make sure all payment methods in 4.0.0 are supported. This initial
// work is based off of master branch at a point where 4.0.0 is not
// merged yet.
foreach ( array( 'stripe' ) as $payment_method_id ) {
$payment_method_settings = $this->get_payment_method_settings( $payment_method_id );
if ( is_wp_error( $payment_method_settings ) ) {
return $payment_method_settings;
}
$settings = array_merge( $settings, $payment_method_settings );
}
return $settings;
}
/**
* Gets a single WooCommerce Stripe setting option from a given setting ID.
*
* @param string $setting_id Setting ID.
*
* @return WP_Error|array Stripe setting or WP_Error.
*/
protected function get_stripe_setting( $setting_id ) {
$invalid_setting_error = new WP_Error(
'woocommerce_stripe_settings_rest__invalid_setting',
__( 'Invalid setting.', 'woocommerce-gateway-stripe' ),
array( 'status' => 404 )
);
if ( empty( $setting_id ) ) {
return $invalid_setting_error;
}
$settings = $this->get_stripe_settings();
if ( is_wp_error( $settings ) ) {
return $settings;
}
$setting_key = array_keys( wp_list_pluck( $settings, 'id' ), $setting_id );
if ( empty( $setting_key ) ) {
return $invalid_setting_error;
}
$setting = $settings[ $setting_key[0] ];
if ( ! $this->is_setting_type_valid( $setting['type'] ) ) {
return $invalid_setting_error;
}
return $setting;
}
/**
* Get settings of a given payment method ID.
*
* Since 4.0.0, WooCommerce Stripe supports Sources in which it offers
* multiple payment methods. Each payment method is a single class with
* unique payment ID and has its own settings.
*
* @since 4.0.0
*
* @param string $payment_method_id Payment method ID.
*
* @return WP_Error|array Settings or WP_Error if payment_method_id is invalid.
*/
protected function get_payment_method_settings( $payment_method_id ) {
switch ( $payment_method_id ) {
case 'stripe':
// TODO: path is updated in 4.0.0 branch. This initial work
// is based off of master branch at a point where 4.0.0 is not
// merged yet.
$setting_fields = include( WC_STRIPE_PLUGIN_PATH . '/includes/settings-stripe.php' );
$setting_values = get_option( 'woocommerce_stripe_settings', array() );
break;
case 'stripe_bancontact':
$setting_fields = include( WC_STRIPE_PLUGIN_PATH . '/includes/admin/stripe-bancontact-settings.php' );
$setting_values = get_option( 'woocommerce_stripe_settings', array() );
break;
default:
return new WP_Error(
'woocommerce_stripe_settings_rest__invalid_payment_method',
__( 'Invalid payment method.', 'woocommerce-gateway-stripe' ),
array(
'status' => 404,
)
);
}
$settings = array();
foreach ( $setting_fields as $key => $setting ) {
if ( ! $this->is_setting_type_valid( $setting['type'] ) ) {
continue;
}
$setting = $this->filter_setting( $setting );
$default = isset( $setting['default'] ) ? $setting['default'] : '';
$setting['id'] = sprintf( 'woocommerce_%1$s_%2$s', $payment_method_id, $key );
$setting['payment_method_id'] = $payment_method_id;
$setting['value'] = isset( $setting_values[ $key ] ) ? $setting_values[ $key ] : $default;
if ( ! isset( $setting['desc'] ) ) {
$setting['desc'] = '';
}
// desc_tip accepts bool or string. When it's `true` it means
// to display `desc` as tool tip in UI.
if ( isset( $setting['desc_tip'] ) ) {
$setting['tip'] = true === $setting['desc_tip'] ? $setting['desc'] : $setting['desc_tip'];
unset( $setting['desc_tip'] );
} else {
$setting['tip'] = '';
}
}
return $settings;
}
/**
* Filters out unexpected setting properties / keys.
*
* @since 4.0.0
*
* @param array $setting Single setting option.
*
* @return array Clean setting.
*/
protected function filter_setting( $setting ) {
$setting = array_intersect_key(
$setting,
array_flip(
array_filter(
array_keys( $setting ),
array( $this, 'is_setting_key_valid' )
)
)
);
if ( empty( $setting['options'] ) ) {
unset( $setting['options'] );
}
return $setting;
}
/**
* Prepare a single setting object for response.
*
* @since 4.0.0
*
* @param object $item Setting object.
* @param WP_REST_Request $request Requst object.
*
* @return WP_REST_Response $response Response.
*/
public function prepare_item_for_response( $item, $request ) {
$resp = $this->add_additional_fields_to_object( $item, $request );
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
$resp = $this->filter_response_by_context( $resp, $context );
$resp = rest_ensure_response( $resp );
$resp->add_links( $this->prepare_setting_links( $resp['id'] ) );
return $resp;
}
/**
* Prepare setting links to be set in the response.
*
* @param string $setting_id Setting ID.
*
* @return array Setting links.
*/
public function prepare_setting_links( $setting_id ) {
return array(
'self' => array(
'href' => rest_url( sprintf( '/%s/%s/settings/%s', $this->namespace, $this->rest_base, $setting_id ) ),
),
'collection' => array(
'href' => rest_url( sprintf( '/%s/%s/settings', $this->namespace, $this->rest_base ) ),
),
);
}
/**
* Make sure the current user has access to read settings.
*
* @since 4.0.0
*
* @param WP_REST_Request $request Full data about the request.
* @return WP_Error|boolean
*/
public function get_settings_permissions_check( $request ) {
if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) {
return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-gateway-stripe' ), array( 'status' => rest_authorization_required_code() ) );
}
return true;
}
/**
* Make sure the current user has access to update settings.
*
* @since 4.0.0
*
* @param WP_REST_Request $request Full data about the request.
* @return WP_Error|boolean
*/
public function update_settings_permissions_check( $request ) {
if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) {
return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce-gateway-stripe' ), array( 'status' => rest_authorization_required_code() ) );
}
return true;
}
/**
* Checks whether given setting key is valid or not.
*
* @since 4.0.0
*
* @param string $key Setting key.
*
* @return bool Returns true if key is valid.
*/
protected function is_setting_key_valid( $key ) {
return in_array(
$key,
array(
'id',
'label',
'description',
'default',
'tip',
'placeholder',
'type',
'options',
'value',
'option_key',
)
);
}
/**
* Checks whether a given setting type is valid or not.
*
* @since 4.0.0
*
* @param string $type Setting type.
*
* @return bool Returns true if type is valid.
*/
protected function is_setting_type_valid( $type ) {
return in_array(
$type,
array(
'text',
'email',
'number',
'password',
'textarea',
'select',
'radio',
'checkbox',
)
);
}
/**
* Get settings schema.
*
* @since 4.0.0
*
* @return array Settings schema.
*/
public function get_item_schema() {
return $this->add_additional_fields_schema( array(
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => 'setting',
'type' => 'object',
'properties' => array(
'id' => array(
'description' => __( 'A unique identifier for the setting.', 'woocommerce' ),
'type' => 'string',
'arg_options' => array(
'sanitize_callback' => 'sanitize_title',
),
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'payment_method_id' => array(
'description' => __( 'Payment method ID.', 'woocommerce' ),
'type' => 'string',
'arg_options' => array(
'sanitize_callback' => 'sanitize_title',
),
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'label' => array(
'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ),
'type' => 'string',
'arg_options' => array(
'sanitize_callback' => 'sanitize_text_field',
),
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'description' => array(
'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ),
'type' => 'string',
'arg_options' => array(
'sanitize_callback' => 'sanitize_text_field',
),
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'value' => array(
'description' => __( 'Setting value.', 'woocommerce' ),
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
'default' => array(
'description' => __( 'Default value for the setting.', 'woocommerce' ),
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'tip' => array(
'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ),
'type' => 'string',
'arg_options' => array(
'sanitize_callback' => 'sanitize_text_field',
),
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'placeholder' => array(
'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ),
'type' => 'string',
'arg_options' => array(
'sanitize_callback' => 'sanitize_text_field',
),
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'type' => array(
'description' => __( 'Type of setting.', 'woocommerce' ),
'type' => 'string',
'arg_options' => array(
'sanitize_callback' => 'sanitize_text_field',
),
'context' => array( 'view', 'edit' ),
'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ),
'readonly' => true,
),
'options' => array(
'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce' ),
'type' => 'object',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
),
) );
}
}
<?php
/**
* WooCommerce Stripe Controller v1.
*
* @package WC_Stripe/API
*/
/**
* WooCommerce Stripe REST Controller for WC REST API v1
*/
class WC_Gateway_Stripe_REST_Controller_V1 extends WC_Gateway_Stripe_REST_Controller {
/**
* Endpoint namespace.
*
* @var string
*/
protected $namespace = 'wc/v1';
}
<?php
/**
* WooCommerce Stripe Controller v2.
*
* @package WC_Stripe/API
*/
/**
* WooCommerce Stripe REST Controller for WC REST API v2
*/
class WC_Gateway_Stripe_REST_Controller_V2 extends WC_Gateway_Stripe_REST_Controller {
/**
* Endpoint namespace.
*
* @var string
*/
protected $namespace = 'wc/v2';
}
<?php
/*
* Plugin Name: WooCommerce Stripe Gateway
* Plugin URI: https://wordpress.org/plugins/woocommerce-gateway-stripe/
* Description: Take credit card payments on your store using Stripe.
* Author: WooCommerce
* Author URI: https://woocommerce.com/
* Version: 3.2.2
* Requires at least: 4.4
* Tested up to: 4.8
* Text Domain: woocommerce-gateway-stripe
* Domain Path: /languages
*
* Copyright (c) 2017 WooCommerce
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Required minimums and constants
*/
define( 'WC_STRIPE_VERSION', '3.2.2' );
define( 'WC_STRIPE_MIN_PHP_VER', '5.6.0' );
define( 'WC_STRIPE_MIN_WC_VER', '2.5.0' );
define( 'WC_STRIPE_MAIN_FILE', __FILE__ );
define( 'WC_STRIPE_PLUGIN_URL', untrailingslashit( plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ) ) );
define( 'WC_STRIPE_PLUGIN_PATH', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
if ( ! class_exists( 'WC_Stripe' ) ) :
class WC_Stripe {
/**
* @var Singleton The reference the *Singleton* instance of this class
*/
private static $instance;
/**
* @var Reference to logging class.
*/
private static $log;
/**
* Returns the *Singleton* instance of this class.
*
* @return Singleton The *Singleton* instance.
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Private clone method to prevent cloning of the instance of the
* *Singleton* instance.
*
* @return void
*/
private function __clone() {}
/**
* Private unserialize method to prevent unserializing of the *Singleton*
* instance.
*
* @return void
*/
private function __wakeup() {}
/**
* Flag to indicate whether or not we need to load code for / support subscriptions.
*
* @var bool
*/
private $subscription_support_enabled = false;
/**
* Flag to indicate whether or not we need to load support for pre-orders.
*
* @since 3.0.3
*
* @var bool
*/
private $pre_order_enabled = false;
/**
* Notices (array)
* @var array
*/
public $notices = array();
/**
* Array of REST Controller instances.
*
* Key is controller's classname and value is the class instance.
*
* @var array
*/
private $rest_controllers = array();
/**
* Protected constructor to prevent creating a new instance of the
* *Singleton* via the `new` operator from outside of this class.
*/
protected function __construct() {
add_action( 'admin_init', array( $this, 'check_environment' ) );
add_action( 'admin_notices', array( $this, 'admin_notices' ), 15 );
add_action( 'plugins_loaded', array( $this, 'init' ) );
}
/**
* Init the plugin after plugins_loaded so environment variables are set.
*/
public function init() {
// Don't hook anything else in the plugin if we're in an incompatible environment
if ( self::get_environment_warning() ) {
return;
}
include_once( dirname( __FILE__ ) . '/includes/class-wc-stripe-api.php' );
include_once( dirname( __FILE__ ) . '/includes/class-wc-stripe-customer.php' );
// Init the gateway itself
$this->init_gateways();
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'plugin_action_links' ) );
add_action( 'woocommerce_order_status_on-hold_to_processing', array( $this, 'capture_payment' ) );
add_action( 'woocommerce_order_status_on-hold_to_completed', array( $this, 'capture_payment' ) );
add_action( 'woocommerce_order_status_on-hold_to_cancelled', array( $this, 'cancel_payment' ) );
add_action( 'woocommerce_order_status_on-hold_to_refunded', array( $this, 'cancel_payment' ) );
add_filter( 'woocommerce_get_customer_payment_tokens', array( $this, 'woocommerce_get_customer_payment_tokens' ), 10, 3 );
add_action( 'woocommerce_payment_token_deleted', array( $this, 'woocommerce_payment_token_deleted' ), 10, 2 );
add_action( 'woocommerce_payment_token_set_default', array( $this, 'woocommerce_payment_token_set_default' ) );
add_action( 'wp_ajax_stripe_dismiss_request_api_notice', array( $this, 'dismiss_request_api_notice' ) );
add_action( 'wp_ajax_stripe_dismiss_apple_pay_notice', array( $this, 'dismiss_apple_pay_notice' ) );
add_action( 'rest_api_init', array( $this, 'register_rest_routes' ) );
include_once( dirname( __FILE__ ) . '/includes/class-wc-stripe-payment-request.php' );
}
/**
* Allow this class and other classes to add slug keyed notices (to avoid duplication)
*/
public function add_admin_notice( $slug, $class, $message ) {
$this->notices[ $slug ] = array(
'class' => $class,
'message' => $message,
);
}
/**
* The backup sanity check, in case the plugin is activated in a weird way,
* or the environment changes after activation. Also handles upgrade routines.
*/
public function check_environment() {
if ( ! defined( 'IFRAME_REQUEST' ) && ( WC_STRIPE_VERSION !== get_option( 'wc_stripe_version' ) ) ) {
$this->install();
do_action( 'woocommerce_stripe_updated' );
}
$environment_warning = self::get_environment_warning();
if ( $environment_warning && is_plugin_active( plugin_basename( __FILE__ ) ) ) {
$this->add_admin_notice( 'bad_environment', 'error', $environment_warning );
}
// Check if secret key present. Otherwise prompt, via notice, to go to
// setting.
if ( ! class_exists( 'WC_Stripe_API' ) ) {
include_once( dirname( __FILE__ ) . '/includes/class-wc-stripe-api.php' );
}
$secret = WC_Stripe_API::get_secret_key();
if ( empty( $secret ) && ! ( isset( $_GET['page'], $_GET['section'] ) && 'wc-settings' === $_GET['page'] && 'stripe' === $_GET['section'] ) ) {
$setting_link = $this->get_setting_link();
$this->add_admin_notice( 'prompt_connect', 'notice notice-warning', sprintf( __( 'Stripe is almost ready. To get started, <a href="%s">set your Stripe account keys</a>.', 'woocommerce-gateway-stripe' ), $setting_link ) );
}
}
/**
* Updates the plugin version in db
*
* @since 3.1.0
* @version 3.1.0
* @return bool
*/
private static function _update_plugin_version() {
delete_option( 'wc_stripe_version' );
update_option( 'wc_stripe_version', WC_STRIPE_VERSION );
return true;
}
/**
* Dismiss the Google Payment Request API Feature notice.
*
* @since 3.1.0
* @version 3.1.0
*/
public function dismiss_request_api_notice() {
update_option( 'wc_stripe_show_request_api_notice', 'no' );
}
/**
* Dismiss the Apple Pay Feature notice.
*
* @since 3.1.0
* @version 3.1.0
*/
public function dismiss_apple_pay_notice() {
update_option( 'wc_stripe_show_apple_pay_notice', 'no' );
}
/**
* Register REST API routes.
*
* @since 4.0.0
*/
public function register_rest_routes() {
if ( class_exists( 'WC_REST_Controller' ) ) {
return;
}
require_once( WC_STRIPE_PLUGIN_PATH . '/includes/api/abstract-wc-gateway-stripe-rest-controller.php' );
require_once( WC_STRIPE_PLUGIN_PATH . '/includes/api/class-wc-gateway-stripe-rest-controller-v1.php' );
require_once( WC_STRIPE_PLUGIN_PATH . '/includes/api/class-wc-gateway-stripe-rest-controller-v2.php' );
$controllers = array(
'WC_Gateway_Stripe_REST_Controller_V1',
'WC_Gateway_Stripe_REST_Controller_V2',
);
foreach ( $controllers as $controller ) {
$this->rest_controllers[ $controller ] = new $controller();
$this->rest_controllers[ $controller ]->register_routes();
}
}
/**
* Handles upgrade routines.
*
* @since 3.1.0
* @version 3.1.0
*/
public function install() {
if ( ! defined( 'WC_STRIPE_INSTALLING' ) ) {
define( 'WC_STRIPE_INSTALLING', true );
}
$this->_update_plugin_version();
}
/**
* Checks the environment for compatibility problems. Returns a string with the first incompatibility
* found or false if the environment has no problems.
*/
static function get_environment_warning() {
if ( version_compare( phpversion(), WC_STRIPE_MIN_PHP_VER, '<' ) ) {
$message = __( 'WooCommerce Stripe - The minimum PHP version required for this plugin is %1$s. You are running %2$s.', 'woocommerce-gateway-stripe' );
return sprintf( $message, WC_STRIPE_MIN_PHP_VER, phpversion() );
}
if ( ! defined( 'WC_VERSION' ) ) {
return __( 'WooCommerce Stripe requires WooCommerce to be activated to work.', 'woocommerce-gateway-stripe' );
}
if ( version_compare( WC_VERSION, WC_STRIPE_MIN_WC_VER, '<' ) ) {
$message = __( 'WooCommerce Stripe - The minimum WooCommerce version required for this plugin is %1$s. You are running %2$s.', 'woocommerce-gateway-stripe' );
return sprintf( $message, WC_STRIPE_MIN_WC_VER, WC_VERSION );
}
if ( ! function_exists( 'curl_init' ) ) {
return __( 'WooCommerce Stripe - cURL is not installed.', 'woocommerce-gateway-stripe' );
}
return false;
}
/**
* Adds plugin action links
*
* @since 1.0.0
*/
public function plugin_action_links( $links ) {
$setting_link = $this->get_setting_link();
$plugin_links = array(
'<a href="' . $setting_link . '">' . __( 'Settings', 'woocommerce-gateway-stripe' ) . '</a>',
'<a href="https://docs.woocommerce.com/document/stripe/">' . __( 'Docs', 'woocommerce-gateway-stripe' ) . '</a>',
'<a href="https://woocommerce.com/contact-us/">' . __( 'Support', 'woocommerce-gateway-stripe' ) . '</a>',
);
return array_merge( $plugin_links, $links );
}
/**
* Get setting link.
*
* @since 1.0.0
*
* @return string Setting link
*/
public function get_setting_link() {
$use_id_as_section = function_exists( 'WC' ) ? version_compare( WC()->version, '2.6', '>=' ) : false;
$section_slug = $use_id_as_section ? 'stripe' : strtolower( 'WC_Gateway_Stripe' );
return admin_url( 'admin.php?page=wc-settings&tab=checkout&section=' . $section_slug );
}
/**
* Display any notices we've collected thus far (e.g. for connection, disconnection)
*/
public function admin_notices() {
$show_request_api_notice = get_option( 'wc_stripe_show_request_api_notice' );
$show_apple_pay_notice = get_option( 'wc_stripe_show_apple_pay_notice' );
if ( empty( $show_apple_pay_notice ) ) {
// @TODO remove this notice in the future.
?>
<div class="notice notice-warning wc-stripe-apple-pay-notice is-dismissible"><p><?php echo sprintf( esc_html__( 'New Feature! Stripe now supports %s. Your customers can now purchase your products even faster. Apple Pay has been enabled by default.', 'woocommerce-gateway-stripe' ), '<a href="https://woocommerce.com/apple-pay/">Apple Pay</a>'); ?></p></div>
<script type="application/javascript">
jQuery( '.wc-stripe-apple-pay-notice' ).on( 'click', '.notice-dismiss', function() {
var data = {
action: 'stripe_dismiss_apple_pay_notice'
};
jQuery.post( '<?php echo admin_url( 'admin-ajax.php' ); ?>', data );
});
</script>
<?php
}
if ( empty( $show_request_api_notice ) ) {
// @TODO remove this notice in the future.
?>
<div class="notice notice-warning wc-stripe-request-api-notice is-dismissible"><p><?php esc_html_e( 'New Feature! Stripe now supports Google Payment Request. Your customers can now use mobile phones with supported browsers such as Chrome to make purchases easier and faster.', 'woocommerce-gateway-stripe' ); ?></p></div>
<script type="application/javascript">
jQuery( '.wc-stripe-request-api-notice' ).on( 'click', '.notice-dismiss', function() {
var data = {
action: 'stripe_dismiss_request_api_notice'
};
jQuery.post( '<?php echo admin_url( 'admin-ajax.php' ); ?>', data );
});
</script>
<?php
}
foreach ( (array) $this->notices as $notice_key => $notice ) {
echo "<div class='" . esc_attr( $notice['class'] ) . "'><p>";
echo wp_kses( $notice['message'], array( 'a' => array( 'href' => array() ) ) );
echo '</p></div>';
}
}
/**
* Initialize the gateway. Called very early - in the context of the plugins_loaded action
*
* @since 1.0.0
*/
public function init_gateways() {
if ( class_exists( 'WC_Subscriptions_Order' ) && function_exists( 'wcs_create_renewal_order' ) ) {
$this->subscription_support_enabled = true;
}
if ( class_exists( 'WC_Pre_Orders_Order' ) ) {
$this->pre_order_enabled = true;
}
if ( ! class_exists( 'WC_Payment_Gateway' ) ) {
return;
}
if ( class_exists( 'WC_Payment_Gateway_CC' ) ) {
include_once( dirname( __FILE__ ) . '/includes/class-wc-gateway-stripe.php' );
include_once( dirname( __FILE__ ) . '/includes/class-wc-stripe-apple-pay.php' );
} else {
include_once( dirname( __FILE__ ) . '/includes/legacy/class-wc-gateway-stripe.php' );
include_once( dirname( __FILE__ ) . '/includes/legacy/class-wc-gateway-stripe-saved-cards.php' );
}
load_plugin_textdomain( 'woocommerce-gateway-stripe', false, plugin_basename( dirname( __FILE__ ) ) . '/languages' );
add_filter( 'woocommerce_payment_gateways', array( $this, 'add_gateways' ) );
$load_addons = (
$this->subscription_support_enabled
||
$this->pre_order_enabled
);
if ( $load_addons ) {
require_once( dirname( __FILE__ ) . '/includes/class-wc-gateway-stripe-addons.php' );
}
}
/**
* Add the gateways to WooCommerce
*
* @since 1.0.0
*/
public function add_gateways( $methods ) {
if ( $this->subscription_support_enabled || $this->pre_order_enabled ) {
$methods[] = 'WC_Gateway_Stripe_Addons';
} else {
$methods[] = 'WC_Gateway_Stripe';
}
return $methods;
}
/**
* List of currencies supported by Stripe that has no decimals.
*
* @return array $currencies
*/
public static function no_decimal_currencies() {
return array(
'bif', // Burundian Franc
'djf', // Djiboutian Franc
'jpy', // Japanese Yen
'krw', // South Korean Won
'pyg', // Paraguayan Guaraní
'vnd', // Vietnamese Đồng
'xaf', // Central African Cfa Franc
'xpf', // Cfp Franc
'clp', // Chilean Peso
'gnf', // Guinean Franc
'kmf', // Comorian Franc
'mga', // Malagasy Ariary
'rwf', // Rwandan Franc
'vuv', // Vanuatu Vatu
'xof', // West African Cfa Franc
);
}
/**
* Stripe uses smallest denomination in currencies such as cents.
* We need to format the returned currency from Stripe into human readable form.
*
* @param object $balance_transaction
* @param string $type Type of number to format
*/
public static function format_number( $balance_transaction, $type = 'fee' ) {
if ( ! is_object( $balance_transaction ) ) {
return;
}
if ( in_array( strtolower( $balance_transaction->currency ), self::no_decimal_currencies() ) ) {
if ( 'fee' === $type ) {
return $balance_transaction->fee;
}
return $balance_transaction->net;
}
if ( 'fee' === $type ) {
return number_format( $balance_transaction->fee / 100, 2, '.', '' );
}
return number_format( $balance_transaction->net / 100, 2, '.', '' );
}
/**
* Capture payment when the order is changed from on-hold to complete or processing
*
* @param int $order_id
*/
public function capture_payment( $order_id ) {
$order = wc_get_order( $order_id );
if ( 'stripe' === ( version_compare( WC_VERSION, '3.0.0', '<' ) ? $order->payment_method : $order->get_payment_method() ) ) {
$charge = get_post_meta( $order_id, '_stripe_charge_id', true );
$captured = get_post_meta( $order_id, '_stripe_charge_captured', true );
if ( $charge && 'no' === $captured ) {
$result = WC_Stripe_API::request( array(
'amount' => $order->get_total() * 100,
'expand[]' => 'balance_transaction',
), 'charges/' . $charge . '/capture' );
if ( is_wp_error( $result ) ) {
$order->add_order_note( __( 'Unable to capture charge!', 'woocommerce-gateway-stripe' ) . ' ' . $result->get_error_message() );
} else {
$order->add_order_note( sprintf( __( 'Stripe charge complete (Charge ID: %s)', 'woocommerce-gateway-stripe' ), $result->id ) );
update_post_meta( $order_id, '_stripe_charge_captured', 'yes' );
// Store other data such as fees
update_post_meta( $order_id, 'Stripe Payment ID', $result->id );
update_post_meta( $order_id, '_transaction_id', $result->id );
if ( isset( $result->balance_transaction ) && isset( $result->balance_transaction->fee ) ) {
// Fees and Net needs to both come from Stripe to be accurate as the returned
// values are in the local currency of the Stripe account, not from WC.
$fee = ! empty( $result->balance_transaction->fee ) ? self::format_number( $result->balance_transaction, 'fee' ) : 0;
$net = ! empty( $result->balance_transaction->net ) ? self::format_number( $result->balance_transaction, 'net' ) : 0;
update_post_meta( $order_id, 'Stripe Fee', $fee );
update_post_meta( $order_id, 'Net Revenue From Stripe', $net );
}
}
}
}
}
/**
* Cancel pre-auth on refund/cancellation
*
* @param int $order_id
*/
public function cancel_payment( $order_id ) {
$order = wc_get_order( $order_id );
if ( 'stripe' === ( version_compare( WC_VERSION, '3.0.0', '<' ) ? $order->payment_method : $order->get_payment_method() ) ) {
$charge = get_post_meta( $order_id, '_stripe_charge_id', true );
if ( $charge ) {
$result = WC_Stripe_API::request( array(
'amount' => $order->get_total() * 100,
), 'charges/' . $charge . '/refund' );
if ( is_wp_error( $result ) ) {
$order->add_order_note( __( 'Unable to refund charge!', 'woocommerce-gateway-stripe' ) . ' ' . $result->get_error_message() );
} else {
$order->add_order_note( sprintf( __( 'Stripe charge refunded (Charge ID: %s)', 'woocommerce-gateway-stripe' ), $result->id ) );
delete_post_meta( $order_id, '_stripe_charge_captured' );
delete_post_meta( $order_id, '_stripe_charge_id' );
}
}
}
}
/**
* Gets saved tokens from API if they don't already exist in WooCommerce.
* @param array $tokens
* @return array
*/
public function woocommerce_get_customer_payment_tokens( $tokens, $customer_id, $gateway_id ) {
if ( is_user_logged_in() && 'stripe' === $gateway_id && class_exists( 'WC_Payment_Token_CC' ) ) {
$stripe_customer = new WC_Stripe_Customer( $customer_id );
$stripe_cards = $stripe_customer->get_cards();
$stored_tokens = array();
foreach ( $tokens as $token ) {
$stored_tokens[] = $token->get_token();
}
foreach ( $stripe_cards as $card ) {
if ( ! in_array( $card->id, $stored_tokens ) ) {
$token = new WC_Payment_Token_CC();
$token->set_token( $card->id );
$token->set_gateway_id( 'stripe' );
$token->set_card_type( strtolower( $card->brand ) );
$token->set_last4( $card->last4 );
$token->set_expiry_month( $card->exp_month );
$token->set_expiry_year( $card->exp_year );
$token->set_user_id( $customer_id );
$token->save();
$tokens[ $token->get_id() ] = $token;
}
}
}
return $tokens;
}
/**
* Delete token from Stripe
*/
public function woocommerce_payment_token_deleted( $token_id, $token ) {
if ( 'stripe' === $token->get_gateway_id() ) {
$stripe_customer = new WC_Stripe_Customer( get_current_user_id() );
$stripe_customer->delete_card( $token->get_token() );
}
}
/**
* Set as default in Stripe
*/
public function woocommerce_payment_token_set_default( $token_id ) {
$token = WC_Payment_Tokens::get( $token_id );
if ( 'stripe' === $token->get_gateway_id() ) {
$stripe_customer = new WC_Stripe_Customer( get_current_user_id() );
$stripe_customer->set_default_card( $token->get_token() );
}
}
/**
* Checks Stripe minimum order value authorized per currency
*/
public static function get_minimum_amount() {
// Check order amount
switch ( get_woocommerce_currency() ) {
case 'USD':
case 'CAD':
case 'EUR':
case 'CHF':
case 'AUD':
case 'SGD':
$minimum_amount = 50;
break;
case 'GBP':
$minimum_amount = 30;
break;
case 'DKK':
$minimum_amount = 250;
break;
case 'NOK':
case 'SEK':
$minimum_amount = 300;
break;
case 'JPY':
$minimum_amount = 5000;
break;
case 'MXN':
$minimum_amount = 1000;
break;
case 'HKD':
$minimum_amount = 400;
break;
default:
$minimum_amount = 50;
break;
}
return $minimum_amount;
}
/**
* What rolls down stairs
* alone or in pairs,
* and over your neighbor's dog?
* What's great for a snack,
* And fits on your back?
* It's log, log, log
*/
public static function log( $message ) {
if ( empty( self::$log ) ) {
self::$log = new WC_Logger();
}
self::$log->add( 'woocommerce-gateway-stripe', $message );
}
}
$GLOBALS['wc_stripe'] = WC_Stripe::get_instance();
endif;
@gedex
Copy link
Author

gedex commented Jul 24, 2017

Saved the work I made for WC Stripe REST API. Apparently, WC has Payment Gateways API which covers planned REST API for WC Stripe.

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