WooCommerce PayPal Powered by Braintree Payment Gateway - Version 1.2.1

Version Description

  • Fix - Issue where Subscriptions with free trial was not processed
  • Fix - Missing "Change Payment" button in "My Subscriptions" section
  • Tweak - Make enabled option default to 'yes'
  • Tweak - Add adnmin notice to setup / connect after plugin is activated
  • Fix - Consider more statuses (settling, submitted_for_settlement, settlement_pending) to mark order as in-processing
  • Fix - Issue where settings section rendered twice
Download this release

Release Info

Developer akeda
Plugin Icon 128x128 WooCommerce PayPal Powered by Braintree Payment Gateway
Version 1.2.1
Comparing to
See all releases

Code changes from version 1.2.0 to 1.2.1

classes/class-wc-gateway-paypal-braintree-subscription.php CHANGED
@@ -21,7 +21,8 @@ abstract class WC_Gateway_Paypal_Braintree_Subscription extends WC_Gateway_Paypa
21
  'subscription_amount_changes',
22
  'subscription_date_changes',
23
  'multiple_subscriptions',
24
- 'subscription_payment_method_change_admin'
 
25
  )
26
  );
27
 
@@ -40,7 +41,7 @@ abstract class WC_Gateway_Paypal_Braintree_Subscription extends WC_Gateway_Paypa
40
  */
41
  protected function order_contains_subscription( $order_id ) {
42
  return function_exists( 'wcs_order_contains_subscription' ) && ( wcs_order_contains_subscription( $order_id ) || wcs_order_contains_renewal( $order_id ) );
43
- }
44
 
45
  /**
46
  * process_payment
@@ -175,13 +176,26 @@ abstract class WC_Gateway_Paypal_Braintree_Subscription extends WC_Gateway_Paypa
175
  'orderId' => $order_id,
176
  'options' => array(
177
  'submitForSettlement' => true,
178
- 'storeInVaultOnSuccess' => true
179
  )
180
  );
181
 
182
  $sale_args = array_merge( $sale_args, $authentication );
183
 
184
- // We have a customer id now, so let's do the sale and store the payment method in the vault
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  $result = $gateway->transaction()->sale( $sale_args );
186
  if ( ! $result->success ) {
187
  $notice = sprintf( __( 'Error: PayPal Powered by Braintree was unable to complete the transaction. Please try again later or use another means of payment. Reason: %s', 'woocommerce-gateway-paypal-braintree' ), $error_message );
21
  'subscription_amount_changes',
22
  'subscription_date_changes',
23
  'multiple_subscriptions',
24
+ 'subscription_payment_method_change_admin',
25
+ 'subscription_payment_method_change_customer',
26
  )
27
  );
28
 
41
  */
42
  protected function order_contains_subscription( $order_id ) {
43
  return function_exists( 'wcs_order_contains_subscription' ) && ( wcs_order_contains_subscription( $order_id ) || wcs_order_contains_renewal( $order_id ) );
44
+ }
45
 
46
  /**
47
  * process_payment
176
  'orderId' => $order_id,
177
  'options' => array(
178
  'submitForSettlement' => true,
179
+ 'storeInVaultOnSuccess' => true,
180
  )
181
  );
182
 
183
  $sale_args = array_merge( $sale_args, $authentication );
184
 
185
+ // Process trial periods and possible coupon discounts.
186
+ if ( isset( $sale_args['amount'] ) && 0.00 === doubleval( $sale_args['amount'] ) ) {
187
+
188
+ $user_id = $order->get_user_id();
189
+ $this->log( __FUNCTION__, "Zero payment amount for trial or coupon. Order ID: $order_id, User ID: $user_id" );
190
+ $order->payment_complete();
191
+ return array(
192
+ 'result' => 'success',
193
+ 'redirect' => $this->get_return_url( $order ),
194
+ );
195
+
196
+ }
197
+
198
+ // We have a customer id now, so let's do the sale and store the payment method in the vault.
199
  $result = $gateway->transaction()->sale( $sale_args );
200
  if ( ! $result->success ) {
201
  $notice = sprintf( __( 'Error: PayPal Powered by Braintree was unable to complete the transaction. Please try again later or use another means of payment. Reason: %s', 'woocommerce-gateway-paypal-braintree' ), $error_message );
classes/class-wc-gateway-paypal-braintree.php CHANGED
@@ -16,7 +16,7 @@ abstract class WC_Gateway_Paypal_Braintree extends WC_Payment_Gateway {
16
  * Version
17
  * @var string
18
  */
19
- public $version = '1.0.0';
20
 
21
  /**
22
  * Checkout template for payment fields
@@ -386,15 +386,6 @@ abstract class WC_Gateway_Paypal_Braintree extends WC_Payment_Gateway {
386
  $checkout_settings_url = add_query_arg( 'tab', 'checkout', $general_settings_url );
387
  $gateway_settings_url = add_query_arg( 'section', strtolower( get_class( $this ) ), $checkout_settings_url );
388
 
389
- // Check for access token
390
- if ( empty( $this->merchant_access_token ) ) {
391
- WC_PayPal_Braintree_Loader::getInstance()->add_admin_notice(
392
- 'merchant_access_token_empty',
393
- 'error',
394
- sprintf( __( 'The PayPal Powered by Braintree gateway is enabled but not connected. Please complete connecting <a href="%s">here</a>.', 'woocommerce-gateway-paypal-braintree' ), $gateway_settings_url )
395
- );
396
- }
397
-
398
  // Check Currency
399
  if ( ! $this->is_shop_currency_supported() ) {
400
  WC_PayPal_Braintree_Loader::getInstance()->add_admin_notice(
@@ -848,30 +839,45 @@ abstract class WC_Gateway_Paypal_Braintree extends WC_Payment_Gateway {
848
  return false;
849
  }
850
 
851
- $transaction_id = $result->transaction->id;
 
 
 
 
 
852
 
853
- if ( 'settling' === $result->transaction->status ) {
854
- // Store captured value
855
  update_post_meta( $order->id, '_pp_braintree_charge_captured', 'yes' );
856
 
857
- $this->log( __FUNCTION__, "Info: Successfully processed payment, transaction id = $transaction_id" );
858
 
859
- // Payment complete
860
  $order->payment_complete( $transaction_id );
861
 
862
  $this->log( __FUNCTION__, "Info: Completed processing of payment for order $order_id" );
863
 
864
  // Add order note
865
  $order->add_order_note( sprintf( __( 'PayPal Braintree charge complete (Charge ID: %s)', 'woocommerce-gateway-paypal-braintree' ), $transaction_id ) );
866
- } else {
 
 
 
867
  update_post_meta( $order->id, '_pp_braintree_charge_captured', 'no' );
 
868
  add_post_meta( $order->id, '_transaction_id', $transaction_id, true );
869
 
870
- // Mark as on-hold
871
  $order->update_status( 'on-hold', sprintf( __( 'PayPal Braintree charge authorized (Charge ID: %s). Process order to take payment, or cancel to remove the pre-authorization.', 'woocommerce-gateway-paypal-braintree' ), $transaction_id ) );
872
 
873
  // Reduce stock levels
874
  $order->reduce_order_stock();
 
 
 
 
 
 
875
  }
876
 
877
  // on success, return thank you page redirect
@@ -881,7 +887,6 @@ abstract class WC_Gateway_Paypal_Braintree extends WC_Payment_Gateway {
881
  );
882
  }
883
 
884
-
885
  /**
886
  * Get the order's transaction url
887
  * @param WC_Order $order
16
  * Version
17
  * @var string
18
  */
19
+ public $version = '1.2.1';
20
 
21
  /**
22
  * Checkout template for payment fields
386
  $checkout_settings_url = add_query_arg( 'tab', 'checkout', $general_settings_url );
387
  $gateway_settings_url = add_query_arg( 'section', strtolower( get_class( $this ) ), $checkout_settings_url );
388
 
 
 
 
 
 
 
 
 
 
389
  // Check Currency
390
  if ( ! $this->is_shop_currency_supported() ) {
391
  WC_PayPal_Braintree_Loader::getInstance()->add_admin_notice(
839
  return false;
840
  }
841
 
842
+ $transaction_id = $result->transaction->id;
843
+ $maybe_settled_later = array(
844
+ Braintree_Transaction::SETTLING,
845
+ Braintree_Transaction::SETTLEMENT_PENDING,
846
+ Braintree_Transaction::SUBMITTED_FOR_SETTLEMENT,
847
+ );
848
 
849
+ if ( in_array( $result->transaction->status, $maybe_settled_later ) ) {
850
+ // Store captured value.
851
  update_post_meta( $order->id, '_pp_braintree_charge_captured', 'yes' );
852
 
853
+ $this->log( __FUNCTION__, sprintf( 'Info: Successfully processed payment, transaction id = %s, status = %s', $transaction_id, $result->transaction->status ) );
854
 
855
+ // Payment complete.
856
  $order->payment_complete( $transaction_id );
857
 
858
  $this->log( __FUNCTION__, "Info: Completed processing of payment for order $order_id" );
859
 
860
  // Add order note
861
  $order->add_order_note( sprintf( __( 'PayPal Braintree charge complete (Charge ID: %s)', 'woocommerce-gateway-paypal-braintree' ), $transaction_id ) );
862
+ } else if ( Braintree_Transaction::AUTHORIZED === $result->transaction->status ) {
863
+
864
+ $this->log( __FUNCTION__, sprintf( 'Info: Successfully authorized transaction id = %s, status = %s', $transaction_id, $result->transaction->status ) );
865
+
866
  update_post_meta( $order->id, '_pp_braintree_charge_captured', 'no' );
867
+
868
  add_post_meta( $order->id, '_transaction_id', $transaction_id, true );
869
 
870
+ // Mark as on-hold.
871
  $order->update_status( 'on-hold', sprintf( __( 'PayPal Braintree charge authorized (Charge ID: %s). Process order to take payment, or cancel to remove the pre-authorization.', 'woocommerce-gateway-paypal-braintree' ), $transaction_id ) );
872
 
873
  // Reduce stock levels
874
  $order->reduce_order_stock();
875
+
876
+ } else {
877
+
878
+ $this->log( __FUNCTION__, sprintf( 'Info: unhandled transaction id = %s, status = %s', $transaction_id, $result->transaction->status ) );
879
+
880
+ $order->update_status( 'on-hold', sprintf( __( 'Transaction was submitted to PayPal Braintree but not handled by WooCommerce order, transaction_id: %s, status: %s. Order was put in-hold.', 'woocommerce-gateway-paypal-braintree' ), $transaction_id, $tresult->transaction->status ) );
881
  }
882
 
883
  // on success, return thank you page redirect
887
  );
888
  }
889
 
 
890
  /**
891
  * Get the order's transaction url
892
  * @param WC_Order $order
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: automattic, woothemes, akeda, allendav, royho, slash1andy, woosteve, spraveenitpro, mikedmoore, fernashes, shellbeezy
3
  Tags: ecommerce, e-commerce, commerce, woothemes, wordpress ecommerce, store, sales, sell, shop, shopping, cart, checkout, configurable, paypal, braintree
4
  Requires at least: 4.4
5
- Tested up to: 4.4
6
- Stable tag: 1.2.0
7
  License: GPLv3
8
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
9
 
@@ -73,6 +73,10 @@ Yes it does - production and sandbox mode is driven by how you connect. You may
73
 
74
  For help setting up and configuring, please refer to our [user guide](http://docs.woothemes.com/document/woocommerce-gateway-paypal-powered-by-braintree/)
75
 
 
 
 
 
76
  = Where can I get support or talk to other users? =
77
 
78
  If you get stuck, you can ask for help in the Plugin Forum.
@@ -96,6 +100,14 @@ New feature requests and bugs reports can be made in the plugin forum.
96
 
97
  == Changelog ==
98
 
 
 
 
 
 
 
 
 
99
  = 1.2.0 =
100
  * Replace array initialization code that causes a fatal error on PHP 5.2 or earlier. PHP 5.4+ is still required, but this code prevented the compatibility check from running and displaying the version requirements
101
  * Update to the latest Braintree SDK (3.8.0)
2
  Contributors: automattic, woothemes, akeda, allendav, royho, slash1andy, woosteve, spraveenitpro, mikedmoore, fernashes, shellbeezy
3
  Tags: ecommerce, e-commerce, commerce, woothemes, wordpress ecommerce, store, sales, sell, shop, shopping, cart, checkout, configurable, paypal, braintree
4
  Requires at least: 4.4
5
+ Tested up to: 4.5.2
6
+ Stable tag: 1.2.1
7
  License: GPLv3
8
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
9
 
73
 
74
  For help setting up and configuring, please refer to our [user guide](http://docs.woothemes.com/document/woocommerce-gateway-paypal-powered-by-braintree/)
75
 
76
+ = Why isn't PayPal working? Credit cards work fine. =
77
+
78
+ Make sure PayPal is enabled on your Braintree account by following the [Braintree PayPal Setup Guide](https://articles.braintreepayments.com/guides/paypal/setup-guide).
79
+
80
  = Where can I get support or talk to other users? =
81
 
82
  If you get stuck, you can ask for help in the Plugin Forum.
100
 
101
  == Changelog ==
102
 
103
+ = 1.2.1 =
104
+ * Fix - Issue where Subscriptions with free trial was not processed
105
+ * Fix - Missing "Change Payment" button in "My Subscriptions" section
106
+ * Tweak - Make enabled option default to 'yes'
107
+ * Tweak - Add adnmin notice to setup / connect after plugin is activated
108
+ * Fix - Consider more statuses (settling, submitted_for_settlement, settlement_pending) to mark order as in-processing
109
+ * Fix - Issue where settings section rendered twice
110
+
111
  = 1.2.0 =
112
  * Replace array initialization code that causes a fatal error on PHP 5.2 or earlier. PHP 5.4+ is still required, but this code prevented the compatibility check from running and displaying the version requirements
113
  * Update to the latest Braintree SDK (3.8.0)
woocommerce-gateway-paypal-powered-by-braintree.php CHANGED
@@ -5,7 +5,7 @@
5
  * Description: Receive payments using Paypal Powered by Braintree. A server with cURL, SSL support, and a valid SSL certificate is required (for security reasons) for this gateway to function. Requires PHP 5.4+
6
  * Author: WooThemes
7
  * Author URI: http://woothemes.com/
8
- * Version: 1.2.0
9
  *
10
  * Copyright (c) 2016 WooThemes
11
  *
@@ -188,6 +188,13 @@ class WC_PayPal_Braintree_Loader {
188
  unset( $_GET['activate'] );
189
  }
190
  }
 
 
 
 
 
 
 
191
  }
192
 
193
  /**
@@ -233,21 +240,39 @@ class WC_PayPal_Braintree_Loader {
233
  $section_slug = strtolower( 'WC_Gateway_Paypal_Braintree_Pay_With_Card' );
234
  }
235
 
 
 
236
  $plugin_links = array(
237
- '<a href="' . admin_url( 'admin.php?page=wc-settings&tab=checkout&section=' . $section_slug ) . '">' . __( 'Settings', 'woocommerce-gateway-paypal-braintree' ) . '</a>',
238
  '<a href="http://docs.woothemes.com/document/woocommerce-gateway-paypal-powered-by-braintree/">' . __( 'Docs', 'woocommerce-gateway-paypal-braintree' ) . '</a>',
239
  '<a href="http://support.woothemes.com/">' . __( 'Support', 'woocommerce-gateway-paypal-braintree' ) . '</a>',
240
  );
241
  return array_merge( $plugin_links, $links );
242
  }
243
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
 
245
  /**
246
  * Display any notices we've collected thus far (e.g. for connection, disconnection)
247
  */
248
  public function admin_notices() {
249
  foreach ( (array) $this->notices as $notice_key => $notice ) {
250
- echo "<div class='" . esc_attr( sanitize_html_class( $notice['class'] ) ) . "'><p>";
251
  echo wp_kses( $notice['message'], array( 'a' => array( 'href' => array() ) ) );
252
  echo "</p></div>";
253
  }
@@ -601,7 +626,7 @@ class WC_PayPal_Braintree_Loader {
601
  'label' => '',
602
  'type' => 'checkbox',
603
  'description' => __( 'This controls whether or not this gateway is enabled within WooCommerce.', 'woocommerce-gateway-paypal-braintree' ),
604
- 'default' => 'no',
605
  'desc_tip' => true
606
  ),
607
  'title_paypal' => array(
@@ -677,17 +702,26 @@ class WC_PayPal_Braintree_Loader {
677
  // and we clone settings between them anyways
678
 
679
  // Take care not to filter away the current section we're on if it is one of ours
680
-
681
  $paypal_sections = array(
682
- 'wc_gateway_paypal_braintree_pay_with_paypal',
683
- 'wc_gateway_paypal_braintree_pay_with_paypal_subscription'
684
  );
685
 
686
  $card_sections = array(
687
- 'wc_gateway_paypal_braintree_pay_with_card',
688
- 'wc_gateway_paypal_braintree_pay_with_card_subscription'
689
  );
690
 
 
 
 
 
 
 
 
 
 
 
 
 
691
  $current_section = isset( $_GET['section'] ) ? $_GET['section'] : '';
692
 
693
  // If the current section is a paypal section, remove the card section,
@@ -698,12 +732,13 @@ class WC_PayPal_Braintree_Loader {
698
  // current section. (Note: The option will be empty if it has never been enabled)
699
 
700
  $simplify_commerce_options = get_option( 'woocommerce_simplify_commerce_settings', array() );
 
701
  if ( empty( $simplify_commerce_options ) || ( "no" === $simplify_commerce_options['enabled'] ) ) {
702
- if ( 'wc_gateway_simplify_commerce' !== $current_section ) {
703
- $sections_to_remove[] = 'wc_gateway_simplify_commerce';
704
  }
705
- if ( 'wc_addons_gateway_simplify_commerce' !== $current_section ) {
706
- $sections_to_remove[] = 'wc_addons_gateway_simplify_commerce';
707
  }
708
  }
709
 
5
  * Description: Receive payments using Paypal Powered by Braintree. A server with cURL, SSL support, and a valid SSL certificate is required (for security reasons) for this gateway to function. Requires PHP 5.4+
6
  * Author: WooThemes
7
  * Author URI: http://woothemes.com/
8
+ * Version: 1.2.1
9
  *
10
  * Copyright (c) 2016 WooThemes
11
  *
188
  unset( $_GET['activate'] );
189
  }
190
  }
191
+
192
+ $access_token = get_option( 'wc_paypal_braintree_merchant_access_token', '' );
193
+ if ( empty( $access_token ) && is_plugin_active( plugin_basename( __FILE__ ) ) ) {
194
+ $setting_link = $this->get_setting_link();
195
+
196
+ $this->add_admin_notice( 'prompt_connect', 'notice notice-warning', __( 'PayPal powered by Braintree is almost ready. To get started, <a href="' . $setting_link . '">connect your Braintree account</a>.', 'woocommerce-gateway-paypal-braintree' ) );
197
+ }
198
  }
199
 
200
  /**
240
  $section_slug = strtolower( 'WC_Gateway_Paypal_Braintree_Pay_With_Card' );
241
  }
242
 
243
+ $setting_link = $this->get_setting_link();
244
+
245
  $plugin_links = array(
246
+ '<a href="' . $setting_link . '">' . __( 'Settings', 'woocommerce-gateway-paypal-braintree' ) . '</a>',
247
  '<a href="http://docs.woothemes.com/document/woocommerce-gateway-paypal-powered-by-braintree/">' . __( 'Docs', 'woocommerce-gateway-paypal-braintree' ) . '</a>',
248
  '<a href="http://support.woothemes.com/">' . __( 'Support', 'woocommerce-gateway-paypal-braintree' ) . '</a>',
249
  );
250
  return array_merge( $plugin_links, $links );
251
  }
252
 
253
+ /**
254
+ * Get setting link.
255
+ *
256
+ * @return string Braintree checkout setting link
257
+ */
258
+ public function get_setting_link() {
259
+ $use_id_as_section = version_compare( WC()->version, '2.6', '>=' );
260
+
261
+ if ( $this->subscription_support_enabled ) {
262
+ $section_slug = $use_id_as_section ? 'paypalbraintree_cards' : strtolower( 'WC_Gateway_Paypal_Braintree_Pay_With_Card_Subscription' );
263
+ } else {
264
+ $section_slug = $use_id_as_section ? 'paypalbraintree_cards' : strtolower( 'WC_Gateway_Paypal_Braintree_Pay_With_Card' );
265
+ }
266
+
267
+ return admin_url( 'admin.php?page=wc-settings&tab=checkout&section=' . $section_slug );
268
+ }
269
 
270
  /**
271
  * Display any notices we've collected thus far (e.g. for connection, disconnection)
272
  */
273
  public function admin_notices() {
274
  foreach ( (array) $this->notices as $notice_key => $notice ) {
275
+ echo "<div class='" . esc_attr( $notice['class'] ) . "'><p>";
276
  echo wp_kses( $notice['message'], array( 'a' => array( 'href' => array() ) ) );
277
  echo "</p></div>";
278
  }
626
  'label' => '',
627
  'type' => 'checkbox',
628
  'description' => __( 'This controls whether or not this gateway is enabled within WooCommerce.', 'woocommerce-gateway-paypal-braintree' ),
629
+ 'default' => 'yes',
630
  'desc_tip' => true
631
  ),
632
  'title_paypal' => array(
702
  // and we clone settings between them anyways
703
 
704
  // Take care not to filter away the current section we're on if it is one of ours
 
705
  $paypal_sections = array(
706
+ 'paypalbraintree_paypal',
 
707
  );
708
 
709
  $card_sections = array(
710
+ 'paypalbraintree_cards',
 
711
  );
712
 
713
+ if ( version_compare( WC()->version, '2.6', '<' ) ) {
714
+ $paypal_sections = array(
715
+ 'wc_gateway_paypal_braintree_pay_with_paypal',
716
+ 'wc_gateway_paypal_braintree_pay_with_paypal_subscription',
717
+ );
718
+
719
+ $card_sections = array(
720
+ 'wc_gateway_paypal_braintree_pay_with_card',
721
+ 'wc_gateway_paypal_braintree_pay_with_card_subscription',
722
+ );
723
+ }
724
+
725
  $current_section = isset( $_GET['section'] ) ? $_GET['section'] : '';
726
 
727
  // If the current section is a paypal section, remove the card section,
732
  // current section. (Note: The option will be empty if it has never been enabled)
733
 
734
  $simplify_commerce_options = get_option( 'woocommerce_simplify_commerce_settings', array() );
735
+ $simplify_commerce_section = version_compare( WC()->version, '2.6', '<' ) ? 'wc_gateway_simplify_commerce' : 'simplify_commerce';
736
  if ( empty( $simplify_commerce_options ) || ( "no" === $simplify_commerce_options['enabled'] ) ) {
737
+ if ( $simplify_commerce_section !== $current_section ) {
738
+ $sections_to_remove[] = $simplify_commerce_section;
739
  }
740
+ if ( $simplify_commerce_section !== $current_section ) {
741
+ $sections_to_remove[] = $simplify_commerce_section;
742
  }
743
  }
744