. */ if ( ! defined( 'ABSPATH' ) ) { exit; } /** * Required minimums */ define( 'WC_PAYPAL_BRAINTREE_MIN_PHP_VER', '5.4.0' ); class WC_PayPal_Braintree_Loader { /** * @var Singleton The reference the *Singleton* instance of this class */ private static $instance; /** * Returns the *Singleton* instance of this class. * * @return Singleton The *Singleton* instance. */ public static function getInstance() { 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() { } /** @var whether or not we need to load code for / support subscriptions */ private $subscription_support_enabled = false; /** * Notices (array) * @var array */ public $notices = 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' ) ); // admin_notices is prioritized later to allow concrete classes to use admin_notices to push entries to the notices array add_action( 'admin_notices', array( $this, 'admin_notices' ), 15 ); // Don't hook anything else in the plugin if we're in an incompatible environment if ( self::get_environment_warning() ) { return; } add_action( 'plugins_loaded', array( $this, 'init_gateways' ), 0 ); add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'plugin_action_links' ) ); add_action( 'woocommerce_proceed_to_checkout', array( $this, 'possibly_add_paypal_checkout_button_to_cart' ), 50 ); add_action( 'wp', array( $this, 'possibly_cancel_checkout_with_paypal' ) ); add_action( 'wp_enqueue_scripts', array( $this, 'possibly_enqueue_scripts' ) ); add_action( 'woocommerce_available_payment_gateways', array( $this, 'possibly_disable_other_gateways' ) ); add_action( 'woocommerce_review_order_after_submit', array( $this, 'possibly_render_cancel_link' ) ); add_action( 'woocommerce_cart_emptied', array( $this, 'possibly_clear_session_data' ) ); add_filter( 'woocommerce_get_sections_checkout', array( $this, 'filter_checkout_sections' ) ); 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_gateway_title', array( $this, 'filter_gateway_title' ), 10, 2 ); if ( is_admin() ) { add_filter( 'woocommerce_order_actions', array( $this, 'add_capture_charge_order_action' ) ); add_action( 'woocommerce_order_action_paypalbraintree_paypal_capture_charge', array( $this, 'maybe_capture_charge' ) ); add_action( 'woocommerce_order_action_paypalbraintree_cards_capture_charge', array( $this, 'maybe_capture_charge' ) ); } } /** * Add capture action in edit order screen. * * @since 1.2.0 * @param array $actions Actions * @return array Actions */ public function add_capture_charge_order_action( $actions ) { if ( ! isset( $_REQUEST['post'] ) ) { return $actions; } $order = wc_get_order( $_REQUEST['post'] ); // bail if the order wasn't paid for with this gateway if ( 'paypalbraintree_paypal' !== $order->payment_method && 'paypalbraintree_cards' !== $order->payment_method ) { return $actions; } if ( 'yes' === get_post_meta( $order->id, '_pp_braintree_charge_captured', true ) ) { return $actions; } if ( ! is_array( $actions ) ) { $actions = array(); } $actions['paypalbraintree_paypal_capture_charge'] = esc_html__( 'Capture Charge', 'woocommerce-gateway-paypal-braintree' ); return $actions; } /** * 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 primary sanity check, automatically disable the plugin on activation if it doesn't * meet minimum requirements. * * Based on http://wptavern.com/how-to-prevent-wordpress-plugins-from-activating-on-sites-with-incompatible-hosting-environments */ public static function activation_check() { $environment_warning = self::get_environment_warning( true ); if ( $environment_warning ) { deactivate_plugins( plugin_basename( __FILE__ ) ); wp_die( $environment_warning ); } } /** * The backup sanity check, in case the plugin is activated in a weird way, * or the environment changes after activation. */ public function check_environment() { $environment_warning = self::get_environment_warning(); if ( $environment_warning && is_plugin_active( plugin_basename( __FILE__ ) ) ) { deactivate_plugins( plugin_basename( __FILE__ ) ); $this->add_admin_notice( 'bad_environment', 'error', $environment_warning ); if ( isset( $_GET['activate'] ) ) { unset( $_GET['activate'] ); } } $access_token = get_option( 'wc_paypal_braintree_merchant_access_token', '' ); if ( empty( $access_token ) && is_plugin_active( plugin_basename( __FILE__ ) ) ) { $setting_link = $this->get_setting_link(); $this->add_admin_notice( 'prompt_connect', 'notice notice-warning', __( 'PayPal powered by Braintree is almost ready. To get started, connect your Braintree account.', 'woocommerce-gateway-paypal-braintree' ) ); } } /** * 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( $during_activation = false ) { if ( version_compare( phpversion(), WC_PAYPAL_BRAINTREE_MIN_PHP_VER, '<' ) ) { if ( $during_activation ) { $message = __( 'The plugin could not be activated. The minimum PHP version required for this plugin is %1$s. You are running %2$s.', 'woocommerce-gateway-paypal-braintree', 'woocommerce-gateway-paypal-braintree' ); } else { $message = __( 'The WooCommerce PayPal Powered by Braintree plugin has been deactivated. The minimum PHP version required for this plugin is %1$s. You are running %2$s.', 'woocommerce-gateway-paypal-braintree' ); } return sprintf( $message, WC_PAYPAL_BRAINTREE_MIN_PHP_VER, phpversion() ); } if ( ! function_exists( 'curl_init' ) ) { if ( $during_activation ) { return __( 'The plugin could not be activated. cURL is not installed.', 'woocommerce-gateway-paypal-braintree' ); } return __( 'The WooCommerce PayPal Powered by Braintree plugin has been deactivated. cURL is not installed.', 'woocommerce-gateway-paypal-braintree' ); } return false; } /** * Adds plugin action links * * @since 1.0.0 */ public function plugin_action_links( $links ) { // On the plugin action links, we include a link to the gateway that lets you pay with credit/debit cards // (we could include a link to the PayPal one too, but that would be a lot of links, and you // can get to the PayPal one from the same page as the credit/debit cards one) if ( $this->subscription_support_enabled ) { $section_slug = strtolower( 'WC_Gateway_Paypal_Braintree_Pay_With_Card_Subscription' ); } else { $section_slug = strtolower( 'WC_Gateway_Paypal_Braintree_Pay_With_Card' ); } $setting_link = $this->get_setting_link(); $plugin_links = array( '' . __( 'Settings', 'woocommerce-gateway-paypal-braintree' ) . '', '' . __( 'Docs', 'woocommerce-gateway-paypal-braintree' ) . '', '' . __( 'Support', 'woocommerce-gateway-paypal-braintree' ) . '', ); return array_merge( $plugin_links, $links ); } /** * Get setting link. * * @return string Braintree checkout setting link */ public function get_setting_link() { $use_id_as_section = true; if ( function_exists( 'WC' ) ) { $use_id_as_section = version_compare( WC()->version, '2.6', '>=' ); } if ( $this->subscription_support_enabled ) { $section_slug = $use_id_as_section ? 'paypalbraintree_cards' : strtolower( 'WC_Gateway_Paypal_Braintree_Pay_With_Card_Subscription' ); } else { $section_slug = $use_id_as_section ? 'paypalbraintree_cards' : strtolower( 'WC_Gateway_Paypal_Braintree_Pay_With_Card' ); } return admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=' . $section_slug ); } /** * Display any notices we've collected thus far (e.g. for connection, disconnection) */ public function admin_notices() { foreach ( (array) $this->notices as $notice_key => $notice ) { echo "

"; echo wp_kses( $notice['message'], array( 'a' => array( 'href' => array() ) ) ); echo "

"; } } /** * 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_Payment_Gateway' ) ) { return; } require_once( plugin_basename( 'classes/class-wc-gateway-paypal-braintree.php' ) ); require_once( plugin_basename( 'classes/class-wc-gateway-paypal-braintree-pay-with-card.php' ) ); require_once( plugin_basename( 'classes/class-wc-gateway-paypal-braintree-pay-with-paypal.php' ) ); load_plugin_textdomain( 'woocommerce-gateway-paypal-braintree', false, trailingslashit( dirname( plugin_basename( __FILE__ ) ) ) ); add_filter( 'woocommerce_payment_gateways', array( $this, 'add_gateways' ) ); if ( $this->subscription_support_enabled ) { require_once( plugin_basename( 'classes/class-wc-gateway-paypal-braintree-subscription.php' ) ); require_once( plugin_basename( 'classes/class-wc-gateway-paypal-braintree-pay-with-card-subscription.php' ) ); require_once( plugin_basename( 'classes/class-wc-gateway-paypal-braintree-pay-with-paypal-subscription.php' ) ); } } /** * Add the gateways to WooCommerce * * @since 1.0.0 */ public function add_gateways( $methods ) { if ( $this->subscription_support_enabled ) { $methods[] = 'WC_Gateway_Paypal_Braintree_Pay_With_Card_Subscription'; $methods[] = 'WC_Gateway_Paypal_Braintree_Pay_With_PayPal_Subscription'; } else { $methods[] = 'WC_Gateway_Paypal_Braintree_Pay_With_Card'; $methods[] = 'WC_Gateway_Paypal_Braintree_Pay_With_PayPal'; } return $methods; } /** * Only if there are no subscriptions in the cart is it OK to add the Checkout with PayPal button to the cart view. * This is because we are unable to obtain a reusable token from the Checkout with PayPal flow that the cart view * uses. * * @since 1.0.0 */ public function possibly_add_paypal_checkout_button_to_cart() { if ( $this->does_cart_contain_any_subscriptions() ) { return; } // We need to pass amount and currency as data attribute to checkout // with PayPal container so that when cart is updated via AJAX we could // teardown and setup the button. $amount = WC()->cart->total; $currency = get_woocommerce_currency(); ?>
subscription_support_enabled ) { return false; } if ( ! class_exists( 'WC_Subscriptions_Cart' ) ) { return false; } return WC_Subscriptions_Cart::cart_contains_subscription(); } /** * possibly_enqueue_scripts * * Loads front side scripts when viewing cart or checkout pages * * @since 1.0.0 */ function possibly_enqueue_scripts() { if ( ! function_exists( 'is_checkout' ) || ! function_exists( 'is_cart' ) ) { return; } if ( ! is_checkout() && ! is_cart() ) { return; } // Make sure our gateways are enabled before we do anything if ( ! $this->are_our_gateways_enabled() ) { return; } // A merchant token is required for everything $merchant_access_token = get_option( 'wc_paypal_braintree_merchant_access_token', '' ); if ( empty( $merchant_access_token ) ) { return; } // Always enqueue styles for simplicity's sake (because not all styles are related to JavaScript manipulated elements) if ( is_checkout() ) { wp_register_style( 'paypal_braintree_styles', plugins_url( 'assets/css/checkout.css', __FILE__ ) ); } else { // cart wp_register_style( 'paypal_braintree_styles', plugins_url( 'assets/css/cart.css', __FILE__ ) ); } wp_enqueue_style( 'paypal_braintree_styles' ); // See if we should enqueue any JavaScript at all. $should_enqueue_checkout_script = $this->_is_hosted_fields_supported(); $should_enqueue_cart_script = $this->_is_checkout_from_cart_supported(); if ( ! $should_enqueue_cart_script && ! $should_enqueue_checkout_script ) { return; } $checkout_with_paypal = $this->_get_checkout_with_paypal_params(); $hosted_fields = $this->_get_hosted_field_params(); // Sanity check. if ( ! $checkout_with_paypal && ! $hosted_fields ) { return; } require_once( dirname( __FILE__ ) . '/braintree_sdk/lib/Braintree.php' ); $braintree_gateway = new Braintree_Gateway( array( 'accessToken' => $merchant_access_token, ) ); try { $client_token = $braintree_gateway->clientToken()->generate(); } catch ( Exception $e ) { $this->log( __FUNCTION__, 'Error: Unable to generate client token. Reason: ' . $e->getMessage() ); return; } $paypal_braintree_data = array( 'token' => $client_token, 'checkoutWithPayPal' => $checkout_with_paypal, 'checkoutWithPayPalContainer' => 'paypal-braintree-button-container', 'hostedFields' => $hosted_fields, ); // Allow things like subscriptions to filter the setup (e.g. to set checkoutWithPayPal singleUse to false) $paypal_braintree_data = apply_filters( 'wc_gateway_paypal_braintree_data', $paypal_braintree_data ); wp_register_script( 'paypal_braintree', 'https://js.braintreegateway.com/js/braintree-2.24.1.min.js', array( 'jquery' ) ); if ( $should_enqueue_checkout_script ) { wp_register_script( 'gateway_paypal_braintree', plugins_url( 'assets/js/checkout.js', __FILE__ ), array( 'jquery', 'paypal_braintree' ) ); } else if ( $should_enqueue_cart_script ) { wp_register_script( 'gateway_paypal_braintree', plugins_url( 'assets/js/cart.js', __FILE__ ), array( 'jquery', 'paypal_braintree', 'jquery-blockui' ) ); } wp_localize_script( 'gateway_paypal_braintree', 'paypalBraintreeData', $paypal_braintree_data ); wp_enqueue_script( 'gateway_paypal_braintree' ); } /** * Whether checkout with PayPal from cart page is supported. * * @since 1.2.2 * * @return bool Returns true if supported */ private function _is_checkout_from_cart_supported() { return is_cart() && $this->does_checkout_with_paypal_support_shop_currency() && ! $this->does_cart_contain_any_subscriptions(); } /** * Whether rendering hosted fields in checkout page is supported. * * @since 1.2.2 * * @return bool Returns true if supported */ private function _is_hosted_fields_supported() { return is_checkout() && ! $this->does_session_have_postback_data(); } /** * Get hosted field params that will be replaced by iframe via braintree JS. * * @since 1.2.2 * * @return bool|array False if hosted field is not supported otherwise returns * hosted field params */ private function _get_hosted_field_params() { if ( ! $this->_is_hosted_fields_supported( ) ) { return false; } return array( 'number' => array( 'selector' => '#wc-paypal-braintree-card-number', 'placeholder' => '0000000000000000', ), 'cvv' => array( 'selector' => '#wc-paypal-braintree-cvv', 'placeholder' => 'CVV', ), 'expirationDate' => array( 'selector' => '#wc-paypal-braintree-expiration-date', 'placeholder' => 'MM/YY', ), 'styles' => array( 'input' => array( 'font-size' => '12pt', 'color' => '#3A3A3A', 'font-family' => 'monospace', ) ), ); } /** * Get checkout with PayPal params. * * This params will be passed via wp_localize_script as options to braintree.setup * to render checkout with PayPal button in cart page. * * @since 1.2.2 * * @return bool|array */ private function _get_checkout_with_paypal_params() { $postback_class = 'WC_Gateway_Paypal_Braintree_Pay_With_PayPal'; if ( $this->subscription_support_enabled ) { $postback_class = 'WC_Gateway_Paypal_Braintree_Pay_With_PayPal_Subscription'; } // Note: The postback URL is only used for cart initiated Checkout with PayPal flow. $details_postback_url = false; if ( $this->_is_checkout_from_cart_supported() ) { $details_postback_url = WC()->api_request_url( $postback_class ); $details_postback_url = add_query_arg( 'action', 'checkout_details', $details_postback_url ); } // Only bother including Checkout with PayPal if the currency is supported // (Checkout with PayPal supports fewer currencies than hosted fields). $checkout_with_paypal = false; if ( $this->does_checkout_with_paypal_support_shop_currency() ) { $checkout_with_paypal = array( 'amount' => WC()->cart->total, 'currency' => get_woocommerce_currency(), 'singleUse' => true, 'detailsPostbackURL' => $details_postback_url ); } return $checkout_with_paypal; } /** * Returns true if our gateways are enabled, false otherwise * * @since 1.0.0 */ public function are_our_gateways_enabled() { // It doesn't matter which gateway we check, since setting changes are cloned between them $gateway_settings = get_option( 'woocommerce_paypalbraintree_paypal_settings', array() ); if ( empty( $gateway_settings ) ) { return false; } return ( "yes" === $gateway_settings['enabled'] ); } /** * When cart based Checkout with PayPal is in effect, disable other gateways on checkout * * @since 1.0.0 * @param array $gateways * @return array */ public function possibly_disable_other_gateways( $gateways ) { if ( WC_PayPal_Braintree_Loader::getInstance()->does_session_have_postback_data() ) { foreach ( $gateways as $id => $gateway ) { if ( $id !== 'paypalbraintree_paypal' ) { unset( $gateways[ $id ] ); } } } return $gateways; } /** * Gives the user a means to break out of the cart initiated Checkout with PayPal flow * * @since 1.0.0 */ public function possibly_cancel_checkout_with_paypal() { if ( function_exists( 'is_cart' ) && is_cart() && ! empty( $_GET['wc_paypal_braintree_clear_session'] ) ) { $this->possibly_clear_session_data(); wc_add_notice( __( 'You have cancelled Checkout with PayPal. Please try to process your order again.', 'woocommerce-gateway-paypal-braintree' ), 'notice' ); } } /** * When cart based Checkout with PayPal is in effect, we need to include a Cancel button on the * checkout form to give the user a means to throw away the token PayPal provided and possibly select * a different payment gateway. * * @since 1.0.0 */ public function possibly_render_cancel_link() { if ( ! $this->does_session_have_postback_data() ) { return; } echo sprintf( '%s', esc_url( add_query_arg( array( 'wc_paypal_braintree_clear_session' => true ), WC()->cart->get_cart_url() ) ), esc_html__( 'Cancel', 'woocommerce-gateway-paypal-braintree' ) ); } /** * Validate checkout with paypal supports the shop currency * Note: This is a narrower list than what braintree supports * https://developers.braintreepayments.com/guides/paypal/checkout-with-paypal/javascript/v2#currency-support * * @since 1.0.0 */ public function does_checkout_with_paypal_support_shop_currency() { $supported_currencies = array( 'USD', // US Dollar 'EUR', // Euro 'GBP', // British Pounds 'CAD', // Canadian Dollar 'AUD', // Australian Dollar 'DKK', // Danish Krone 'NOK', // Norwegian Krone 'PLN', // Polish Zloty 'SEK', // Swedish Krona 'CHF' // Swiss Franc ); return ( in_array( get_woocommerce_currency(), $supported_currencies ) ); } /** * Check if postback data is present * * @since 1.0.0 * @return bool */ public function does_session_have_postback_data() { return isset( WC()->session->paypal_braintree_postback ); } /** * Used when cart based Checkout with PayPal is in effect. Hooked to woocommerce_cart_emptied * Also called by WC_PayPal_Braintree_Loader::possibly_cancel_checkout_with_paypal * * @since 1.0.0 */ public function possibly_clear_session_data() { if ( $this->does_session_have_postback_data() ) { unset( WC()->session->paypal_braintree_postback ); } } /** * Returns form fields common to all the gateways this extension supports * * @since 1.0.0 */ public function get_shared_form_fields () { return array( 'enabled' => array( 'title' => __( 'Enable PayPal Powered by Braintree', 'woocommerce-gateway-paypal-braintree' ), 'label' => '', 'type' => 'checkbox', 'description' => __( 'This controls whether or not this gateway is enabled within WooCommerce.', 'woocommerce-gateway-paypal-braintree' ), 'default' => 'yes', 'desc_tip' => true ), 'title_paypal' => array( 'title' => __( 'PayPal Title', 'woocommerce-gateway-paypal-braintree' ), 'type' => 'text', 'description' => __( 'This controls the title which the user sees during checkout for PayPal.', 'woocommerce-gateway-paypal-braintree' ), 'default' => __( 'PayPal Account', 'woocommerce-gateway-paypal-braintree' ), 'desc_tip' => true ), 'description_paypal' => array( 'title' => __( 'PayPal Description', 'woocommerce-gateway-paypal-braintree' ), 'type' => 'text', 'description' => __( 'This controls the description which the user sees during checkout for PayPal.', 'woocommerce-gateway-paypal-braintree' ), 'default' => '', 'desc_tip' => true ), 'title_cards' => array( 'title' => __( 'Cards Title', 'woocommerce-gateway-paypal-braintree' ), 'type' => 'text', 'description' => __( 'This controls the title which the user sees during checkout for credit and debit cards.', 'woocommerce-gateway-paypal-braintree' ), 'default' => __( 'Credit or Debit Card (PayPal)', 'woocommerce-gateway-paypal-braintree' ), 'desc_tip' => true ), 'description_cards' => array( 'title' => __( 'Cards Description', 'woocommerce-gateway-paypal-braintree' ), 'type' => 'text', 'description' => __( 'This controls the description which the user sees during checkout for credit and debit cards.', 'woocommerce-gateway-paypal-braintree' ), 'default' => '', 'desc_tip' => true ), 'capture' => array( 'title' => __( 'Capture', 'woocommerce-gateway-paypal-braintree' ), 'label' => __( 'Capture charge immediately', 'woocommerce-gateway-paypal-braintree' ), 'type' => 'checkbox', 'description' => __( 'Whether or not to immediately capture the charge. When unchecked, the charge issues an authorization and will need to be captured later.', 'woocommerce-gateway-paypal-braintree' ), 'default' => 'yes' ), 'debug' => array( 'title' => __( 'Debug', 'woocommerce-gateway-paypal-braintree' ), 'label' => __( 'Enable debugging messages', 'woocommerce-gateway-paypal-braintree' ), 'type' => 'checkbox', 'description' => __( 'Sends debug messages to the WooCommerce System Status log.', 'woocommerce-gateway-paypal-braintree' ), 'default' => 'yes' ) ); } /** * Clones options from the passed gateway ID to its sibling * * @since 1.0.0 */ public function clone_fields_from_id( $src_gateway_id ) { $dest_gateway_id = ( $src_gateway_id === 'paypalbraintree_paypal' ) ? 'paypalbraintree_cards' : 'paypalbraintree_paypal'; $src_options = get_option( 'woocommerce_' . $src_gateway_id . '_settings' ); update_option( 'woocommerce_' . $dest_gateway_id . '_settings', $src_options ); } /** * We don't need both in the submenu, so filter out one or the other, depending * on what section we are looking at * * @since 1.0.0 */ public function filter_checkout_sections( $sections ) { // First, let's remove one of this extensions' gateways, since we don't want both // and we clone settings between them anyways // Take care not to filter away the current section we're on if it is one of ours $paypal_sections = array( 'paypalbraintree_paypal', ); $card_sections = array( 'paypalbraintree_cards', ); if ( version_compare( WC()->version, '2.6', '<' ) ) { $paypal_sections = array( 'wc_gateway_paypal_braintree_pay_with_paypal', 'wc_gateway_paypal_braintree_pay_with_paypal_subscription', ); $card_sections = array( 'wc_gateway_paypal_braintree_pay_with_card', 'wc_gateway_paypal_braintree_pay_with_card_subscription', ); } $current_section = isset( $_GET['section'] ) ? $_GET['section'] : ''; // If the current section is a paypal section, remove the card section, // otherwise, remove the paypal section $sections_to_remove = in_array( $current_section, $paypal_sections ) ? $card_sections : $paypal_sections; // And, let's also remove simplify commerce from the sections if it is not enabled and it is not the // current section. (Note: The option will be empty if it has never been enabled) $simplify_commerce_options = get_option( 'woocommerce_simplify_commerce_settings', array() ); $simplify_commerce_section = version_compare( WC()->version, '2.6', '<' ) ? 'wc_gateway_simplify_commerce' : 'simplify_commerce'; if ( empty( $simplify_commerce_options ) || ( "no" === $simplify_commerce_options['enabled'] ) ) { if ( $simplify_commerce_section !== $current_section ) { $sections_to_remove[] = $simplify_commerce_section; } if ( $simplify_commerce_section !== $current_section ) { $sections_to_remove[] = $simplify_commerce_section; } } foreach( $sections_to_remove as $section_to_remove ) { unset( $sections[$section_to_remove] ); } return $sections; } public function maybe_capture_charge( $order ) { if ( ! is_object( $order ) ) { $order = wc_get_order( $order ); } $this->capture_payment( $order->id ); return true; } /** * 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 ( in_array( $order->payment_method, array( 'paypalbraintree_cards', 'paypalbraintree_paypal' ) ) ) { $trans_id = get_post_meta( $order_id, '_transaction_id', true ); $captured = get_post_meta( $order_id, '_pp_braintree_charge_captured', true ); require_once( dirname( __FILE__ ) . '/braintree_sdk/lib/Braintree.php' ); $token = get_option( 'wc_paypal_braintree_merchant_access_token', '' ); $gateway = new Braintree_Gateway( array( 'accessToken' => $token, ) ); $transaction_details = false; if ( $trans_id ) { try { $transaction_details = $gateway->transaction()->find( $trans_id ); } catch ( Exception $e ) { $order->add_order_note( __( 'Unable to capture charge!', 'woocommerce-gateway-paypal-braintree' ) . ' ' . $e->getMessage() ); $this->log( __FUNCTION__, "Error: Unable to find transaction with transaction ID {$trans_id}. Reason: " . $e->getMessage() ); return; } } if ( $trans_id && 'authorized' === $transaction_details->status ) { try { $result = $gateway->transaction()->submitForSettlement( $trans_id, floatval( $order->order_total ) ); $order->add_order_note( sprintf( __( 'PayPal Braintree charge complete (Charge ID: %s)', 'woocommerce-gateway-paypal-braintree' ), $result->transaction->id ) ); update_post_meta( $order->id, '_pp_braintree_charge_captured', 'yes' ); } catch ( Exception $e ) { $order->add_order_note( __( 'Unable to capture charge!', 'woocommerce-gateway-paypal-braintree' ) . ' ' . $result->get_error_message() ); } } } } /** * Cancel authorization * * @param int $order_id */ public function cancel_payment( $order_id ) { $order = wc_get_order( $order_id ); if ( in_array( $order->payment_method, array( 'paypalbraintree_cards', 'paypalbraintree_paypal' ) ) ) { require_once( dirname( __FILE__ ) . '/braintree_sdk/lib/Braintree.php' ); $trans_id = get_post_meta( $order_id, '_transaction_id', true ); $token = get_option( 'wc_paypal_braintree_merchant_access_token', '' ); $gateway = new Braintree_Gateway( array( 'accessToken' => $token, ) ); $transaction_details = false; if ( $trans_id ) { try { $transaction_details = $gateway->transaction()->find( $trans_id ); } catch ( Exception $e ) { $this->log( __FUNCTION__, "Error: Unable to find transaction with transaction ID {$trans_id}. Reason: " . $e->getMessage() ); $order->add_order_note( __( 'Unable to void charge!', 'woocommerce-gateway-paypal-braintree' ) . ' ' . $e->getMessage() ); return; } } if ( $trans_id && 'authorized' === $transaction_details->status ) { try { $result = $gateway->transaction()->void( $trans_id ); $order->add_order_note( sprintf( __( 'PayPal Braintree charge voided (Charge ID: %s)', 'woocommerce-gateway-paypal-braintree' ), $result->transaction->id ) ); delete_post_meta( $order->id, '_pp_braintree_charge_captured' ); delete_post_meta( $order->id, '_transaction_id' ); } catch ( Exception $e ) { $this->log( __FUNCTION__, 'Error: Unable to void charge. Reason: ' . $e->getMessage() ); $order->add_order_note( __( 'Unable to void charge!', 'woocommerce-gateway-paypal-braintree' ) . ' ' . $e->getMessage() ); } } } } /** * Filter payment gateway title in edit order so that when title is empty * it will use default title. * * @param string $title Gateway title * @param string $id Gateway ID * * @return string Gateway title */ public function filter_gateway_title( $title, $id ) { if ( ! function_exists( 'get_current_screen' ) ) { return $title; } $screen = get_current_screen(); if ( is_object( $screen ) && 'shop_order' !== $screen->id ) { return $title; } if ( in_array( $id, array( 'paypalbraintree_paypal', 'paypalbraintree_cards' ) ) && empty( $title ) ) { $title = __( 'PayPal Powered by Braintree', 'woocommerce-gateway-paypal-braintree' ); } return $title; } /** * 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 * * @since 1.0.0 */ public function log( $context, $message ) { if ( empty( $this->log ) ) { $this->log = new WC_Logger(); } $this->log->add( 'woocommerce-gateway-paypal-braintree', $context . " - " . $message ); if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log( $context . " - " . $message ); } } } $GLOBALS['wc_paypal_braintree_loader'] = WC_PayPal_Braintree_Loader::getInstance(); register_activation_hook( __FILE__, array( 'WC_PayPal_Braintree_Loader', 'activation_check' ) );