WooCommerce PayPal Powered by Braintree Payment Gateway - Version 2.3.0

Version Description

Download this release

Release Info

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

Code changes from version 2.2.7 to 2.3.0

assets/js/frontend/wc-braintree.min.js CHANGED
@@ -1 +1 @@
1
- "use strict";var _get=function e(t,n,r){null===t&&(t=Function.prototype);var i=Object.getOwnPropertyDescriptor(t,n);if(void 0===i){var a=Object.getPrototypeOf(t);return null===a?void 0:e(a,n,r)}if("value"in i)return i.value;var o=i.get;return void 0!==o?o.call(r):void 0},_createClass=function(){function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),e}}();function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(function(){function o(e,t){if(!(e instanceof t))throw new Error("Bound instance method accessed before binding")}var s=[].indexOf;jQuery(document).ready(function(d){var e,r;function t(e){_classCallCheck(this,t),this.show_integration_ui=this.show_integration_ui.bind(this),this.hide_integration_ui=this.hide_integration_ui.bind(this),this.id=e.id,this.id_dasherized=e.id_dasherized,this.name=e.name,this.type=e.type,this.debug=e.debug,this.client_token_nonce=e.client_token_nonce,this.ajax_url=e.ajax_url,this.integration_error_message=e.integration_error_message,this.payment_error_message=e.payment_error_message,this.params=window.sv_wc_payment_gateway_payment_form_params}function a(e){_classCallCheck(this,a);var t=_possibleConstructorReturn(this,(a.__proto__||Object.getPrototypeOf(a)).call(this,e));return t.show_integration_ui=t.show_integration_ui.bind(t),t.hide_integration_ui=t.hide_integration_ui.bind(t),t.csc_required=e.csc_required,t.hosted_fields_styles=e.hosted_fields_styles,t.threeds=e.threeds,t.enabled_card_types=e.enabled_card_types,t.init(),t}function n(e){_classCallCheck(this,n);var t=_possibleConstructorReturn(this,(n.__proto__||Object.getPrototypeOf(n)).call(this,e));return t.do_integration_ready=t.do_integration_ready.bind(t),t.on_authorize=t.on_authorize.bind(t),t.get_linked_account_html=t.get_linked_account_html.bind(t),t.is_test_environment=e.is_test_environment,t.is_paypal_credit_enabled=e.is_paypal_credit_enabled,t.must_login_message=e.must_login_message,t.must_login_add_method_message=e.must_login_add_method_message,t.button_styles=e.button_styles,t.cart_payment_nonce=e.cart_payment_nonce,t.init(),t}return window.WC_Braintree_Payment_Form_Handler=(_createClass(t,[{key:"init",value:function(){return this.is_sdk_ready()?d("form.checkout").length?this.handle_checkout_page():d("form#order_review").length?this.handle_pay_page():d("form#add_payment_method").length?this.handle_add_payment_method_page():void 0:console.error("Braintree SDK is missing.")}},{key:"handle_checkout_page",value:function(){var e=this;return this.form=d("form.checkout"),this.form_ui_selector=".woocommerce-checkout-payment",d(document.body).on("updated_checkout",function(){if(!e.setting_up)return e.setup_braintree()}),d(document.body).on("updated_checkout",function(){return e.handle_saved_payment_methods()}),d(document.body).on("checkout_error",function(){return e.handle_checkout_error()}),this.form.on("checkout_place_order_"+this.id,function(){if(e.is_selected())return e.block_ui(),e.verify_form()})}},{key:"handle_checkout_error",value:function(){return this.unblock_ui()}},{key:"handle_pay_page",value:function(){var e=this;return this.form=d("form#order_review"),this.form_ui_selector="#payment",this.handle_saved_payment_methods(),this.setup_braintree(),this.form.submit(function(){if(e.is_selected())return e.block_ui(),e.verify_form()})}},{key:"handle_add_payment_method_page",value:function(){var e=this;return this.form=d("form#add_payment_method"),this.form_ui_selector="#payment",this.setup_braintree(),this.form.submit(function(){if(e.is_selected())return e.block_ui(),e.verify_form()})}},{key:"verify_form",value:function(){return!!this.using_payment_token()||!!this.has_payment_nonce()&&void 0}},{key:"submit_form",value:function(e){return d("input[name=wc_"+this.id+"_payment_nonce]").val(e),this.form.submit()}},{key:"handle_saved_payment_methods",value:function(){var e,n=this;if(e=d("div.js-wc-"+this.id_dasherized+"-new-payment-method-form"),d("input.js-wc-"+this.id_dasherized+"-payment-token").change(function(){return d("input.js-wc-"+n.id_dasherized+"-payment-token:checked").val()?e.slideUp(200):e.slideDown(200)}).change(),d("input#createaccount").change(function(e){var t;return t=d("input.js-wc-"+n.id_dasherized+"-tokenize-payment-method").closest("p.form-row"),d(e.target).is(":checked")?(t.slideDown(),t.next().show()):(t.hide(),t.next().hide())}),!d("input#createaccount").is(":checked"))return d("input#createaccount").change()}},{key:"setup_braintree",value:function(){return this.setting_up=!0,this.block_ui(),d("input[name=wc_"+this.id+"_payment_nonce]").val(""),this.create_client()}},{key:"create_client",value:function(){var r=this;return this.log("Creating client."),this.get_client_token().done(function(e){return e.success?braintree.client.create({authorization:e.data}).then(function(e){return r.client=e,r.log("Client ready."),r.setup_integration()}).catch(function(e){return r.handle_integration_error(e),r.unblock_ui()}):r.handle_integration_error(e.data)}).fail(function(e,t,n){return r.handle_integration_error({message:"Could not retrieve the client token via AJAX: "+n})}).always(function(){return r.unblock_ui()})}},{key:"get_client_token",value:function(){var e;return this.id,e={action:"wc_"+this.id+"_get_client_token",nonce:this.client_token_nonce},d.post(this.ajax_url,e)}},{key:"setup_integration",value:function(){var t=this;return this.log("Creating integration."),this.get_integration_class().create(this.get_integration_options()).then(function(e){return t.integration=e,t.show_integration_ui(),t.do_integration_ready(),d(document).trigger("wc_"+t.id+"_integration_ready",t.integration),t.log("Integration ready."),t.setting_up=!1}).catch(function(e){return t.handle_integration_error(e),t.unblock_ui(),t.setting_up=!1})}},{key:"refresh_braintree",value:function(){var e=this;if(null!=this.integration&&!this.refreshing&&!this.setting_up)return this.log("Refreshing integration."),this.refreshing=!0,this.block_ui(),this.integration.teardown(function(){return e.integration=null,e.refreshing=!1,e.setup_braintree()})}},{key:"teardown_braintree",value:function(){var e=this;if(null!=this.integration)return this.block_ui(),this.integration.teardown(function(){return e.integration=null,e.unblock_ui()})}},{key:"do_integration_ready",value:function(){}},{key:"get_integration_options",value:function(){return{client:this.client}}},{key:"get_integration_class",value:function(){}},{key:"handle_integration_error",value:function(e){return this.log("Integration error. "+e.message,e,"error"),this.hide_integration_ui(),this.unblock_ui()}},{key:"handle_payment_error",value:function(e){return this.log("Payment error. "+e.message,e,"error"),this.render_error(this.get_user_message(e)),this.unblock_ui()}},{key:"render_error",value:function(e){return d(".woocommerce-error, .woocommerce-message").remove(),this.form.prepend('<div class="woocommerce-error">'+e+"</div>").removeClass("processing").unblock(),d("html, body").animate({scrollTop:this.form.offset().top-100},1e3),d("input[name=wc_"+this.id+"_payment_nonce]").val(""),this.form.trigger("wc_"+this.id+"_rendered_error"),d(document.body).trigger("checkout_error"),this.unblock_ui()}},{key:"get_user_message",value:function(e){return this.payment_error_message}},{key:"show_integration_ui",value:function(){if(d("div.js-wc-"+this.id_dasherized+"-new-payment-method-form").find(".woocommerce-error").remove(),d("input#createaccount").length&&d("input#createaccount").is(":checked"))return d("div.js-wc-"+this.id_dasherized+"-new-payment-method-form").find(".form-row").show()}},{key:"hide_integration_ui",value:function(){return d("div.js-wc-"+this.id_dasherized+"-new-payment-method-form").prepend('<div class="woocommerce-error">'+this.integration_error_message+"</div>"),d("div.js-wc-"+this.id_dasherized+"-new-payment-method-form").find(".form-row").hide()}},{key:"block_ui",value:function(){return d(this.form_ui_selector).block({message:null,overlayCSS:{background:"#fff",opacity:.6}})}},{key:"unblock_ui",value:function(){return d(this.form_ui_selector).unblock()}},{key:"is_selected",value:function(){return this.get_selected_gateway_id()===this.id}},{key:"is_sdk_ready",value:function(){return"undefined"!=typeof braintree&&null!==braintree&&null!=braintree.client&&null!=this.get_integration_class()}},{key:"has_payment_nonce",value:function(){return this.form.find("input[name=wc_"+this.id+"_payment_nonce]").val()}},{key:"using_payment_token",value:function(){return this.form.find("input.js-wc-"+this.id_dasherized+"-payment-token:checked").val()}},{key:"get_selected_gateway_id",value:function(){return this.form.find("input[name=payment_method]:checked").val()}},{key:"log",value:function(e,t,n){var r=1<arguments.length&&void 0!==t?t:null;if(this.debug)return console.log(this.name+": "+e),r?console.log(r):void 0}}]),t),e=window.WC_Braintree_Credit_Card_Payment_Form_Handler=(_inherits(a,WC_Braintree_Payment_Form_Handler),_createClass(a,[{key:"handle_checkout_error",value:function(){return _get(a.prototype.__proto__||Object.getPrototypeOf(a.prototype),"handle_checkout_error",this).call(this),d("input[name=wc_"+this.id+"_payment_nonce]").val(""),d("input[name=wc-"+this.id_dasherized+"-card-type]").val(""),d("input[name=wc-"+this.id_dasherized+"-3d-secure-verified]").val(0)}},{key:"verify_form",value:function(){var e;return this.has_payment_nonce()||!this.csc_required&&this.using_payment_token()?(e=d("input.js-wc-braintree-credit-card-payment-token:checked"),this.should_verify_3d_secure_token(e)?(this.verify_3d_secure(e.data("nonce"),null,e),!1):_get(a.prototype.__proto__||Object.getPrototypeOf(a.prototype),"verify_form",this).call(this)):(this.tokenize_payment(),!1)}},{key:"tokenize_payment",value:function(){var t=this;return this.integration.tokenize().then(function(e){if(t.log("Payment method received.",e),null!=e.nonce&&null!=e.details&&null!=e.details.bin)return t.should_verify_3d_secure(e)?t.verify_3d_secure(e.nonce,e.details.bin):t.submit_form(e.nonce)}).catch(function(e){return t.handle_payment_error(e)})}},{key:"get_integration_options",value:function(){var e;return e={client:this.client,fields:{number:{selector:"#wc-braintree-credit-card-account-number-hosted",placeholder:d("#wc-braintree-credit-card-account-number-hosted").data("placeholder")},cvv:{selector:"#wc-braintree-credit-card-csc-hosted",placeholder:d("#wc-braintree-credit-card-csc-hosted").data("placeholder")},expirationDate:{selector:"#wc-braintree-credit-card-expiry-hosted",placeholder:d("#wc-braintree-credit-card-expiry-hosted").data("placeholder")}},styles:this.hosted_fields_styles},this.csc_required&&this.using_payment_token()&&(delete e.fields.number,delete e.fields.expirationDate),this.csc_required||delete e.fields.cvv,e}},{key:"get_integration_class",value:function(){return braintree.hostedFields}},{key:"do_integration_ready",value:function(){var t=this;return this.integration.on("cardTypeChange",function(e){return t.on_card_type_change(e)}),!this.csc_required&&d("input.js-wc-braintree-credit-card-payment-token:checked").val()&&this.teardown_braintree(),this.unblock_ui()}},{key:"handle_saved_payment_methods",value:function(){var e,t,n=this;return _get(a.prototype.__proto__||Object.getPrototypeOf(a.prototype),"handle_saved_payment_methods",this).call(this),t=d("div.js-wc-braintree-credit-card-new-payment-method-form"),e=d("div.wc-braintree-hosted-field-card-csc-parent"),d("input.js-wc-braintree-credit-card-payment-token").change(function(){return d("input.js-wc-braintree-credit-card-payment-token:checked").val()?n.csc_required&&e.hasClass("form-row-last")?(e.removeClass("form-row-last").addClass("form-row-first"),t.after(e),n.refresh_braintree()):void 0:(n.csc_required&&e.hasClass("form-row-first")&&(e.removeClass("form-row-first").addClass("form-row-last"),t.find("div.wc-braintree-hosted-field-card-expiry-parent").after(e)),n.refresh_braintree())}).change()}},{key:"get_user_message",value:function(e){var t,n,r,i;if(r=[],"CUSTOMER"===e.type)switch(e.code){case"HOSTED_FIELDS_FIELDS_EMPTY":this.csc_required&&r.push(this.params.cvv_missing),this.using_payment_token()||(r.push(this.params.card_number_missing),r.push(this.params.card_exp_date_invalid));break;case"HOSTED_FIELDS_FIELDS_INVALID":if(null!=e.details)for(t=0,n=(i=e.details.invalidFieldKeys).length;t<n;t++)switch(i[t]){case"number":r.push(this.params.card_number_invalid);break;case"cvv":r.push(this.params.cvv_length_invalid);break;case"expirationDate":r.push(this.params.card_exp_date_invalid)}}return r.length?r.join("<br/>"):_get(a.prototype.__proto__||Object.getPrototypeOf(a.prototype),"get_user_message",this).call(this)}},{key:"on_card_type_change",value:function(e){var t,n,r;if(null!=e.cards)return(t=d("#wc-braintree-credit-card-account-number-hosted")).attr("class",function(e,t){return t.replace(/(^|\s)card-type-\S+/g,"")}),e.cards.length?1===e.cards.length?(n=e.cards[0],d("input[name=wc-"+this.id_dasherized+"-card-type]").val(n.type),null!=n.type&&(r=n.type,0<=s.call(this.enabled_card_types,r))?t.addClass("card-type-"+n.type):t.addClass("card-type-invalid")):void 0:t.addClass("card-type-invalid")}},{key:"is_3d_secure_enabled",value:function(){return this.threeds.enabled&&null!=braintree.threeDSecure}},{key:"setup_integration",value:function(){var t=this;return this.threeds.enabled&&(this.threeds.enabled=this.client.getConfiguration().gatewayConfiguration.threeDSecureEnabled),this.is_3d_secure_enabled()?(d("input[name=wc-"+this.id_dasherized+"-3d-secure-enabled]").val(1),this.threeDSecure&&this.threeDSecure.teardown(),braintree.threeDSecure.create({version:2,client:this.client}).then(function(e){return t.threeDSecure=e,d(document.body).on("click","#wc-braintree-credit-card-3dsecure-container",function(e){return d(e.currentTarget).fadeOut(200),t.threeDSecure.cancelVerifyCard(),t.unblock_ui()}),_get(a.prototype.__proto__||Object.getPrototypeOf(a.prototype),"setup_integration",t).call(t)}).catch(function(e){return t.handle_integration_error(e)})):_get(a.prototype.__proto__||Object.getPrototypeOf(a.prototype),"setup_integration",this).call(this)}},{key:"should_verify_3d_secure",value:function(e){var t;return t=e.details.cardType,this.is_3d_secure_enabled()&&"CreditCard"===e.type&&0<=s.call(this.threeds.card_types,t)}},{key:"should_verify_3d_secure_token",value:function(e){if(this.is_3d_secure_enabled()&&e.val()&&e.data("nonce")&&!e.data("verified"))return!0}},{key:"verify_3d_secure",value:function(e,t,n){var r,i,a,o,s,_,c,u=this,l=2<arguments.length&&void 0!==n?n:null;return o=d("#billing_state").val(),a=d("#billing_country").val(),_=d("#shipping_state").val(),s=d("#shipping_country").val(),i=d("input[name=billing_first_name]").val()?{givenName:d("input[name=billing_first_name]").val().latinise(),surname:d("input[name=billing_last_name]").val().latinise(),phoneNumber:d("input[name=billing_phone]").val(),streetAddress:d("input[name=billing_address_1]").val(),extendedAddress:d("input[name=billing_address_2]").val(),locality:d("#billing_city").val(),region:"string"==typeof o&&o.length<=2?o:"",postalCode:d("input[name=billing_postcode]").val(),countryCodeAlpha2:"string"==typeof a&&a.length<=2?a:""}:{},r=d("input[name=shipping_first_name]").val()?{shippingGivenName:d("input[name=shipping_first_name]").val().latinise(),shippingSurname:d("input[name=shipping_last_name]").val().latinise(),shippingAddress:{streetAddress:d("input[name=shipping_address_1]").val(),extendedAddress:d("input[name=shipping_address_2]").val(),locality:d("input[name=shipping_city]").val(),region:"string"==typeof _&&_.length<=2?_:"",postalCode:d("input[name=shipping_postcode]").val(),countryCodeAlpha2:"string"==typeof s&&s.length<=2?s:""}}:{},c={nonce:e,amount:d("input[name=wc-"+this.id_dasherized+"-3d-secure-order-total]").val(),email:d("input[name=billing_email]").val(),billingAddress:i,additionalInformation:r,onLookupComplete:function(e,t){return u.log("3D Secure lookup complete.",e),t()}},"1"===d("input[name=wc-"+this.id_dasherized+"-cart-contains-subscription]").val()&&(c.challengeRequested=!0),this.log("Verifying 3D Secure.",c),this.threeDSecure.verifyCard(c).then(function(e){return u.log("3D Secure response received.",e),u.threeds.liability_shift_always_required&&!e.liabilityShifted?u.render_error(u.threeds.failure_message):(null!=l&&l.data("verified",!0),d("input[name=wc-"+u.id_dasherized+"-3d-secure-verified]").val(1),u.submit_form(e.nonce))}).catch(function(e){return u.handle_payment_error(e)})}},{key:"show_integration_ui",value:function(){return o(this,e),_get(a.prototype.__proto__||Object.getPrototypeOf(a.prototype),"show_integration_ui",this).call(this),d(".wc-braintree-hosted-field-parent").show()}},{key:"hide_integration_ui",value:function(){return o(this,e),_get(a.prototype.__proto__||Object.getPrototypeOf(a.prototype),"hide_integration_ui",this).call(this),d(".wc-braintree-hosted-field-parent").hide()}}]),a),r=window.WC_Braintree_PayPal_Payment_Form_Handler=(_inherits(n,WC_Braintree_Payment_Form_Handler),_createClass(n,[{key:"init",value:function(){var t=this;return _get(n.prototype.__proto__||Object.getPrototypeOf(n.prototype),"init",this).call(this),d("input[name=wc_"+this.id+"_payment_nonce]").val(this.cart_payment_nonce),d(document.body).on("click",'input[name="payment_method"], input.js-wc-braintree-paypal-payment-token',function(){return t.toggle_order_button()}),d(document.body).on("payment_method_selected",function(){return t.toggle_order_button()}),d(document.body).on("click",".wc-braintree-paypal-account .cancel",function(e){return e.preventDefault(),d(e.currentTarget).parent().remove(),t.setup_braintree()})}},{key:"toggle_order_button",value:function(){return!this.is_selected()||this.has_payment_nonce()||this.using_payment_token()?d("#place_order").show():d("#place_order").hide()}},{key:"verify_form",value:function(){var e;return e=_get(n.prototype.__proto__||Object.getPrototypeOf(n.prototype),"verify_form",this).call(this),this.has_payment_nonce()||this.using_payment_token()||this.render_error(this.must_login_message),e}},{key:"handle_payment_error",value:function(e){return _get(n.prototype.__proto__||Object.getPrototypeOf(n.prototype),"handle_payment_error",this).call(this,e),this.cart_payment_nonce=!1,this.setup_braintree()}},{key:"get_integration_class",value:function(){return braintree.paypalCheckout}},{key:"setup_braintree",value:function(){return this.cart_payment_nonce?this.unblock_ui():(_get(n.prototype.__proto__||Object.getPrototypeOf(n.prototype),"setup_braintree",this).call(this),d("input.js-wc-braintree-paypal-tokenize-payment-method").prop("disabled",!1),this.toggle_order_button())}},{key:"do_integration_ready",value:function(){var e,t=this;return o(this,r),this.cart_payment_nonce?this.unblock_ui():(e=this.is_single_use()?"checkout":"vault",this.render_button(this.integration.createPayment({flow:e,amount:this.get_order_amount(),currency:this.get_store_currency(),locale:this.get_store_locale()}),this.get_button_styles(),"#wc_braintree_paypal_container").then(function(){return d("#wc_braintree_paypal_container").css({width:"100%"}),t.unblock_ui()}).catch(function(e){return t.log("Could not render the PayPal button. "+e.message,e),t.hide_integration_ui(),t.unblock_ui()}))}},{key:"render_button",value:function(e,t,n){var r,i,a=this;return d(n).html(""),r=this.is_paypal_credit_enabled&&"USD"===this.get_store_currency()?{allowed:[paypal.FUNDING.CREDIT]}:{disallowed:[paypal.FUNDING.CREDIT]},i={env:this.is_test_environment?"sandbox":"production",commit:this.button_is_pay_now(),style:t,funding:r,payment:function(){return e},onAuthorize:function(e,t){return a.on_authorize(e,t)},onError:function(e){return a.handle_integration_error(e)}},paypal.Button.render(i,n)}},{key:"button_is_pay_now",value:function(){return!d("form#add_payment_method").length}},{key:"get_button_styles",value:function(){return this.button_styles}},{key:"on_authorize",value:function(e,t){var n=this;return o(this,r),this.block_ui(),this.integration.tokenizePayment(e).then(function(e){return n.log("Payment method tokenized.",e),n.set_payment_method(e)}).catch(function(e){return n.handle_payment_error(e),n.unblock_ui()})}},{key:"set_payment_method",value:function(e){return d("input[name=wc_"+this.id+"_payment_nonce]").val(e.nonce),d("#wc_braintree_paypal_container").html(this.get_linked_account_html(e.details)),this.is_single_use()&&d("input.js-wc-braintree-paypal-tokenize-payment-method").prop("disabled",!0),d("#place_order").show(),this.form.submit()}},{key:"handle_saved_payment_methods",value:function(){var t=this;return _get(n.prototype.__proto__||Object.getPrototypeOf(n.prototype),"handle_saved_payment_methods",this).call(this),d("input.js-wc-braintree-paypal-tokenize-payment-method").change(function(e){if(null!=t.integration&&d(e.target).is(":visible"))return t.block_ui(),t.do_integration_ready()}).change()}},{key:"get_linked_account_html",value:function(e){var t;return o(this,r),t=d("<div class='wc-"+this.id_dasherized+"-account'></div>"),null!=e.firstName&&null!=e.lastName&&t.append("<span class='name'>"+e.firstName+" "+e.lastName+"</span>"),t.append("<span class='email'>"+e.email+"</span>"),t.append("<a href='#' class='cancel'>Cancel</a>"),t}},{key:"is_single_use",value:function(){var e;return 0===(e=d("input[name=wc-braintree-paypal-tokenize-payment-method]")).length||("checkbox"===e.attr("type")?!e.is(":checked"):!e.val())}},{key:"get_order_amount",value:function(){return d("input[name=wc_braintree_paypal_amount]").val()}},{key:"get_store_currency",value:function(){return d("input[name=wc_braintree_paypal_currency]").val()}},{key:"get_store_locale",value:function(){return d("input[name=wc_braintree_paypal_locale]").val()}},{key:"is_sdk_ready",value:function(){return _get(n.prototype.__proto__||Object.getPrototypeOf(n.prototype),"is_sdk_ready",this).call(this)&&"undefined"!=typeof paypal&&null!==paypal}}]),n),window.WC_Braintree_PayPal_Cart_Handler=(_inherits(i,WC_Braintree_PayPal_Payment_Form_Handler),_createClass(i,[{key:"button_is_pay_now",value:function(){return!1}},{key:"set_payment_method",value:function(e){var t=this;if(null!=e.nonce)return e.wp_nonce=this.set_payment_method_nonce,d.ajax({type:"POST",url:this.cart_handler_url,data:e,dataType:"json"}).done(function(e){if(t.log("Cart response received.",e),null!=e.redirect_url)return window.location=e.redirect_url}).fail(function(e){return t.log("Error setting the PayPal cart data.",e,"error")}).always(function(){return t.unblock_ui()})}},{key:"is_single_use",value:function(){return"1"===d("input[name=wc_braintree_paypal_single_use]").val()}},{key:"has_payment_nonce",value:function(){return!1}}]),i);function i(e){_classCallCheck(this,i);var t=_possibleConstructorReturn(this,(i.__proto__||Object.getPrototypeOf(i)).call(this,e));return t.set_payment_method_nonce=e.set_payment_method_nonce,t.cart_handler_url=e.cart_handler_url,t.form=d("form.woocommerce-cart-form"),t.form_ui_selector="",t.setup_braintree(),d(document.body).on("updated_cart_totals",function(){return t.setup_braintree()}),t}})}).call(void 0);
1
+ "use strict";var _get=function e(t,n,r){null===t&&(t=Function.prototype);var i=Object.getOwnPropertyDescriptor(t,n);if(void 0===i){var a=Object.getPrototypeOf(t);return null===a?void 0:e(a,n,r)}if("value"in i)return i.value;var o=i.get;return void 0!==o?o.call(r):void 0},_createClass=function(){function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),e}}();function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(function(){function s(e,t){if(!(e instanceof t))throw new Error("Bound instance method accessed before binding")}var u=[].indexOf;jQuery(document).ready(function(d){var e,r,i;function t(e){_classCallCheck(this,t),this.show_integration_ui=this.show_integration_ui.bind(this),this.hide_integration_ui=this.hide_integration_ui.bind(this),this.id=e.id,this.id_dasherized=e.id_dasherized,this.name=e.name,this.type=e.type,this.debug=e.debug,this.client_token_nonce=e.client_token_nonce,this.ajax_url=e.ajax_url,this.integration_error_message=e.integration_error_message,this.payment_error_message=e.payment_error_message,this.params=window.sv_wc_payment_gateway_payment_form_params}function a(e){_classCallCheck(this,a);var t=_possibleConstructorReturn(this,(a.__proto__||Object.getPrototypeOf(a)).call(this,e));return t.show_integration_ui=t.show_integration_ui.bind(t),t.hide_integration_ui=t.hide_integration_ui.bind(t),t.csc_required=e.csc_required,t.hosted_fields_styles=e.hosted_fields_styles,t.threeds=e.threeds,t.enabled_card_types=e.enabled_card_types,t.init(),t}function n(e){_classCallCheck(this,n);var t=_possibleConstructorReturn(this,(n.__proto__||Object.getPrototypeOf(n)).call(this,e));return t.do_integration_ready=t.do_integration_ready.bind(t),t.on_authorize=t.on_authorize.bind(t),t.get_linked_account_html=t.get_linked_account_html.bind(t),t.is_test_environment=e.is_test_environment,t.is_paypal_credit_enabled=e.is_paypal_credit_enabled,t.must_login_message=e.must_login_message,t.must_login_add_method_message=e.must_login_add_method_message,t.button_styles=e.button_styles,t.cart_payment_nonce=e.cart_payment_nonce,t.init(),t}function o(e){_classCallCheck(this,o);var t=_possibleConstructorReturn(this,(o.__proto__||Object.getPrototypeOf(o)).call(this,e));return t.set_payment_method_nonce=e.set_payment_method_nonce,t.cart_handler_url=e.cart_handler_url,t.form=d("form.woocommerce-cart-form"),t.form_ui_selector="",t.setup_braintree(),d(document.body).on("updated_cart_totals",function(){return t.setup_braintree()}),t}return window.WC_Braintree_Payment_Form_Handler=(_createClass(t,[{key:"init",value:function(){return this.is_sdk_ready()?d("form.checkout").length?this.handle_checkout_page():d("form#order_review").length?this.handle_pay_page():d("form#add_payment_method").length?this.handle_add_payment_method_page():void 0:console.error("Braintree SDK is missing.")}},{key:"handle_checkout_page",value:function(){var e=this;return this.form=d("form.checkout"),this.form_ui_selector=".woocommerce-checkout-payment",d(document.body).on("updated_checkout",function(){if(!e.setting_up)return e.setup_braintree()}),d(document.body).on("updated_checkout",function(){return e.handle_saved_payment_methods()}),d(document.body).on("checkout_error",function(){return e.handle_checkout_error()}),this.form.on("checkout_place_order_"+this.id,function(){if(e.is_selected())return e.block_ui(),e.verify_form()})}},{key:"handle_checkout_error",value:function(){return this.unblock_ui()}},{key:"handle_pay_page",value:function(){var e=this;return this.form=d("form#order_review"),this.form_ui_selector="#payment",this.handle_saved_payment_methods(),this.setup_braintree(),this.form.submit(function(){if(e.is_selected())return e.block_ui(),e.verify_form()})}},{key:"handle_add_payment_method_page",value:function(){var e=this;return this.form=d("form#add_payment_method"),this.form_ui_selector="#payment",this.setup_braintree(),this.form.submit(function(){if(e.is_selected())return e.block_ui(),e.verify_form()})}},{key:"verify_form",value:function(){return!!this.using_payment_token()||!!this.has_payment_nonce()&&void 0}},{key:"submit_form",value:function(e){return d("input[name=wc_"+this.id+"_payment_nonce]").val(e),this.form.submit()}},{key:"handle_saved_payment_methods",value:function(){var e,n=this;if(e=d("div.js-wc-"+this.id_dasherized+"-new-payment-method-form"),d("input.js-wc-"+this.id_dasherized+"-payment-token").change(function(){return d("input.js-wc-"+n.id_dasherized+"-payment-token:checked").val()?e.slideUp(200):e.slideDown(200)}).change(),d("input#createaccount").change(function(e){var t;return t=d("input.js-wc-"+n.id_dasherized+"-tokenize-payment-method").closest("p.form-row"),d(e.target).is(":checked")?(t.slideDown(),t.next().show()):(t.hide(),t.next().hide())}),!d("input#createaccount").is(":checked"))return d("input#createaccount").change()}},{key:"setup_braintree",value:function(){return this.setting_up=!0,this.block_ui(),d("input[name=wc_"+this.id+"_payment_nonce]").val(""),this.create_client()}},{key:"create_client",value:function(){var r=this;return this.log("Creating client."),this.get_client_token().done(function(e){return e.success?braintree.client.create({authorization:e.data}).then(function(e){return r.client=e,r.log("Client ready."),r.setup_integration()}).catch(function(e){return r.handle_integration_error(e),r.unblock_ui()}):r.handle_integration_error(e.data)}).fail(function(e,t,n){return r.handle_integration_error({message:"Could not retrieve the client token via AJAX: "+n})}).always(function(){return r.unblock_ui()})}},{key:"get_client_token",value:function(){var e;return this.id,e={action:"wc_"+this.id+"_get_client_token",nonce:this.client_token_nonce},d.post(this.ajax_url,e)}},{key:"setup_integration",value:function(){var t=this;return this.log("Creating integration."),this.get_integration_class().create(this.get_integration_options()).then(function(e){return t.integration=e,t.show_integration_ui(),t.do_integration_ready(),d(document).trigger("wc_"+t.id+"_integration_ready",t.integration),t.log("Integration ready."),t.setting_up=!1}).catch(function(e){return t.handle_integration_error(e),t.unblock_ui(),t.setting_up=!1})}},{key:"refresh_braintree",value:function(){var e=this;if(null!=this.integration&&!this.refreshing&&!this.setting_up)return this.log("Refreshing integration."),this.refreshing=!0,this.block_ui(),this.integration.teardown(function(){return e.integration=null,e.refreshing=!1,e.setup_braintree()})}},{key:"teardown_braintree",value:function(){var e=this;if(null!=this.integration)return this.block_ui(),this.integration.teardown(function(){return e.integration=null,e.unblock_ui()})}},{key:"do_integration_ready",value:function(){}},{key:"get_integration_options",value:function(){return{client:this.client}}},{key:"get_integration_class",value:function(){}},{key:"handle_integration_error",value:function(e){return this.log("Integration error. "+e.message,e,"error"),this.hide_integration_ui(),this.unblock_ui()}},{key:"handle_payment_error",value:function(e){return this.log("Payment error. "+e.message,e,"error"),this.render_error(this.get_user_message(e)),this.unblock_ui()}},{key:"render_error",value:function(e){return d(".woocommerce-error, .woocommerce-message").remove(),this.form.prepend('<div class="woocommerce-error">'+e+"</div>").removeClass("processing").unblock(),d("html, body").animate({scrollTop:this.form.offset().top-100},1e3),d("input[name=wc_"+this.id+"_payment_nonce]").val(""),this.form.trigger("wc_"+this.id+"_rendered_error"),d(document.body).trigger("checkout_error"),this.unblock_ui()}},{key:"get_user_message",value:function(e){return this.payment_error_message}},{key:"show_integration_ui",value:function(){if(d("div.js-wc-"+this.id_dasherized+"-new-payment-method-form").find(".woocommerce-error").remove(),d("input#createaccount").length&&d("input#createaccount").is(":checked"))return d("div.js-wc-"+this.id_dasherized+"-new-payment-method-form").find(".form-row").show()}},{key:"hide_integration_ui",value:function(){return d("div.js-wc-"+this.id_dasherized+"-new-payment-method-form").prepend('<div class="woocommerce-error">'+this.integration_error_message+"</div>"),d("div.js-wc-"+this.id_dasherized+"-new-payment-method-form").find(".form-row").hide()}},{key:"block_ui",value:function(){return d(this.form_ui_selector).block({message:null,overlayCSS:{background:"#fff",opacity:.6}})}},{key:"unblock_ui",value:function(){return d(this.form_ui_selector).unblock()}},{key:"is_selected",value:function(){return this.get_selected_gateway_id()===this.id}},{key:"is_sdk_ready",value:function(){return"undefined"!=typeof braintree&&null!==braintree&&null!=braintree.client&&null!=this.get_integration_class()}},{key:"has_payment_nonce",value:function(){return this.form.find("input[name=wc_"+this.id+"_payment_nonce]").val()}},{key:"using_payment_token",value:function(){return this.form.find("input.js-wc-"+this.id_dasherized+"-payment-token:checked").val()}},{key:"get_selected_gateway_id",value:function(){return this.form.find("input[name=payment_method]:checked").val()}},{key:"log",value:function(e,t,n){var r=1<arguments.length&&void 0!==t?t:null;if(this.debug)return console.log(this.name+": "+e),r?console.log(r):void 0}}]),t),e=window.WC_Braintree_Credit_Card_Payment_Form_Handler=(_inherits(a,WC_Braintree_Payment_Form_Handler),_createClass(a,[{key:"handle_checkout_error",value:function(){return _get(a.prototype.__proto__||Object.getPrototypeOf(a.prototype),"handle_checkout_error",this).call(this),d("input[name=wc_"+this.id+"_payment_nonce]").val(""),d("input[name=wc-"+this.id_dasherized+"-card-type]").val(""),d("input[name=wc-"+this.id_dasherized+"-3d-secure-verified]").val(0)}},{key:"verify_form",value:function(){var e;return this.has_payment_nonce()||!this.csc_required&&this.using_payment_token()?(e=d("input.js-wc-braintree-credit-card-payment-token:checked"),this.should_verify_3d_secure_token(e)?(this.verify_3d_secure(e.data("nonce"),null,e),!1):_get(a.prototype.__proto__||Object.getPrototypeOf(a.prototype),"verify_form",this).call(this)):(this.tokenize_payment(),!1)}},{key:"tokenize_payment",value:function(){var t=this;return this.integration.tokenize().then(function(e){if(t.log("Payment method received.",e),null!=e.nonce&&null!=e.details&&null!=e.details.bin)return t.should_verify_3d_secure(e)?t.verify_3d_secure(e.nonce,e.details.bin):t.submit_form(e.nonce)}).catch(function(e){return t.handle_payment_error(e)})}},{key:"get_integration_options",value:function(){var e;return e={client:this.client,fields:{number:{selector:"#wc-braintree-credit-card-account-number-hosted",placeholder:d("#wc-braintree-credit-card-account-number-hosted").data("placeholder")},cvv:{selector:"#wc-braintree-credit-card-csc-hosted",placeholder:d("#wc-braintree-credit-card-csc-hosted").data("placeholder")},expirationDate:{selector:"#wc-braintree-credit-card-expiry-hosted",placeholder:d("#wc-braintree-credit-card-expiry-hosted").data("placeholder")}},styles:this.hosted_fields_styles},this.csc_required&&this.using_payment_token()&&(delete e.fields.number,delete e.fields.expirationDate),this.csc_required||delete e.fields.cvv,e}},{key:"get_integration_class",value:function(){return braintree.hostedFields}},{key:"do_integration_ready",value:function(){var t=this;return this.integration.on("cardTypeChange",function(e){return t.on_card_type_change(e)}),!this.csc_required&&d("input.js-wc-braintree-credit-card-payment-token:checked").val()&&this.teardown_braintree(),this.unblock_ui()}},{key:"handle_saved_payment_methods",value:function(){var e,t,n=this;return _get(a.prototype.__proto__||Object.getPrototypeOf(a.prototype),"handle_saved_payment_methods",this).call(this),t=d("div.js-wc-braintree-credit-card-new-payment-method-form"),e=d("div.wc-braintree-hosted-field-card-csc-parent"),d("input.js-wc-braintree-credit-card-payment-token").change(function(){return d("input.js-wc-braintree-credit-card-payment-token:checked").val()?n.csc_required&&e.hasClass("form-row-last")?(e.removeClass("form-row-last").addClass("form-row-first"),t.after(e),n.refresh_braintree()):void 0:(n.csc_required&&e.hasClass("form-row-first")&&(e.removeClass("form-row-first").addClass("form-row-last"),t.find("div.wc-braintree-hosted-field-card-expiry-parent").after(e)),n.refresh_braintree())}).change()}},{key:"get_user_message",value:function(e){var t,n,r,i;if(r=[],"CUSTOMER"===e.type)switch(e.code){case"HOSTED_FIELDS_FIELDS_EMPTY":this.csc_required&&r.push(this.params.cvv_missing),this.using_payment_token()||(r.push(this.params.card_number_missing),r.push(this.params.card_exp_date_invalid));break;case"HOSTED_FIELDS_FIELDS_INVALID":if(null!=e.details)for(t=0,n=(i=e.details.invalidFieldKeys).length;t<n;t++)switch(i[t]){case"number":r.push(this.params.card_number_invalid);break;case"cvv":r.push(this.params.cvv_length_invalid);break;case"expirationDate":r.push(this.params.card_exp_date_invalid)}}return r.length?r.join("<br/>"):_get(a.prototype.__proto__||Object.getPrototypeOf(a.prototype),"get_user_message",this).call(this)}},{key:"on_card_type_change",value:function(e){var t,n,r;if(null!=e.cards)return(t=d("#wc-braintree-credit-card-account-number-hosted")).attr("class",function(e,t){return t.replace(/(^|\s)card-type-\S+/g,"")}),e.cards.length?1===e.cards.length?(n=e.cards[0],d("input[name=wc-"+this.id_dasherized+"-card-type]").val(n.type),null!=n.type&&(r=n.type,0<=u.call(this.enabled_card_types,r))?t.addClass("card-type-"+n.type):t.addClass("card-type-invalid")):void 0:t.addClass("card-type-invalid")}},{key:"is_3d_secure_enabled",value:function(){return this.threeds.enabled&&null!=braintree.threeDSecure}},{key:"setup_integration",value:function(){var t=this;return this.threeds.enabled&&(this.threeds.enabled=this.client.getConfiguration().gatewayConfiguration.threeDSecureEnabled),this.is_3d_secure_enabled()?(d("input[name=wc-"+this.id_dasherized+"-3d-secure-enabled]").val(1),this.threeDSecure&&this.threeDSecure.teardown(),braintree.threeDSecure.create({version:2,client:this.client}).then(function(e){return t.threeDSecure=e,d(document.body).on("click","#wc-braintree-credit-card-3dsecure-container",function(e){return d(e.currentTarget).fadeOut(200),t.threeDSecure.cancelVerifyCard(),t.unblock_ui()}),_get(a.prototype.__proto__||Object.getPrototypeOf(a.prototype),"setup_integration",t).call(t)}).catch(function(e){return t.handle_integration_error(e)})):_get(a.prototype.__proto__||Object.getPrototypeOf(a.prototype),"setup_integration",this).call(this)}},{key:"should_verify_3d_secure",value:function(e){var t;return t=e.details.cardType,this.is_3d_secure_enabled()&&"CreditCard"===e.type&&0<=u.call(this.threeds.card_types,t)}},{key:"should_verify_3d_secure_token",value:function(e){if(this.is_3d_secure_enabled()&&e.val()&&e.data("nonce")&&!e.data("verified"))return!0}},{key:"verify_3d_secure",value:function(e,t,n){var r,i,a,o,_,s,u,c=this,l=2<arguments.length&&void 0!==n?n:null;return o=d("#billing_state").val(),a=d("#billing_country").val(),s=d("#shipping_state").val(),_=d("#shipping_country").val(),i=d("input[name=billing_first_name]").val()?{givenName:d("input[name=billing_first_name]").val().latinise(),surname:d("input[name=billing_last_name]").val().latinise(),phoneNumber:d("input[name=billing_phone]").val(),streetAddress:d("input[name=billing_address_1]").val(),extendedAddress:d("input[name=billing_address_2]").val(),locality:d("#billing_city").val(),region:"string"==typeof o&&o.length<=2?o:"",postalCode:d("input[name=billing_postcode]").val(),countryCodeAlpha2:"string"==typeof a&&a.length<=2?a:""}:{},r=d("input[name=shipping_first_name]").val()?{shippingGivenName:d("input[name=shipping_first_name]").val().latinise(),shippingSurname:d("input[name=shipping_last_name]").val().latinise(),shippingAddress:{streetAddress:d("input[name=shipping_address_1]").val(),extendedAddress:d("input[name=shipping_address_2]").val(),locality:d("input[name=shipping_city]").val(),region:"string"==typeof s&&s.length<=2?s:"",postalCode:d("input[name=shipping_postcode]").val(),countryCodeAlpha2:"string"==typeof _&&_.length<=2?_:""}}:{},u={nonce:e,amount:d("input[name=wc-"+this.id_dasherized+"-3d-secure-order-total]").val(),email:d("input[name=billing_email]").val(),billingAddress:i,additionalInformation:r,onLookupComplete:function(e,t){return c.log("3D Secure lookup complete.",e),t()}},"1"===d("input[name=wc-"+this.id_dasherized+"-cart-contains-subscription]").val()&&(u.challengeRequested=!0),this.log("Verifying 3D Secure.",u),this.threeDSecure.verifyCard(u).then(function(e){return c.log("3D Secure response received.",e),c.threeds.liability_shift_always_required&&!e.liabilityShifted?c.render_error(c.threeds.failure_message):(null!=l&&l.data("verified",!0),d("input[name=wc-"+c.id_dasherized+"-3d-secure-verified]").val(1),c.submit_form(e.nonce))}).catch(function(e){return c.handle_payment_error(e)})}},{key:"show_integration_ui",value:function(){return s(this,e),_get(a.prototype.__proto__||Object.getPrototypeOf(a.prototype),"show_integration_ui",this).call(this),d(".wc-braintree-hosted-field-parent").show()}},{key:"hide_integration_ui",value:function(){return s(this,e),_get(a.prototype.__proto__||Object.getPrototypeOf(a.prototype),"hide_integration_ui",this).call(this),d(".wc-braintree-hosted-field-parent").hide()}}]),a),r=window.WC_Braintree_PayPal_Payment_Form_Handler=(_inherits(n,WC_Braintree_Payment_Form_Handler),_createClass(n,[{key:"init",value:function(){var t=this;return _get(n.prototype.__proto__||Object.getPrototypeOf(n.prototype),"init",this).call(this),d("input[name=wc_"+this.id+"_payment_nonce]").val(this.cart_payment_nonce),d(document.body).on("click",'input[name="payment_method"], input.js-wc-braintree-paypal-payment-token',function(){return t.toggle_order_button()}),d(document.body).on("payment_method_selected",function(){return t.toggle_order_button()}),d(document.body).on("click",".wc-braintree-paypal-account .cancel",function(e){return e.preventDefault(),d(e.currentTarget).parent().remove(),t.setup_braintree()})}},{key:"toggle_order_button",value:function(){return!this.is_selected()||this.has_payment_nonce()||this.using_payment_token()?d("#place_order").show():d("#place_order").hide()}},{key:"verify_form",value:function(){var e;return e=_get(n.prototype.__proto__||Object.getPrototypeOf(n.prototype),"verify_form",this).call(this),this.has_payment_nonce()||this.using_payment_token()||this.render_error(this.must_login_message),e}},{key:"handle_payment_error",value:function(e){return _get(n.prototype.__proto__||Object.getPrototypeOf(n.prototype),"handle_payment_error",this).call(this,e),this.cart_payment_nonce=!1,this.setup_braintree()}},{key:"get_integration_class",value:function(){return braintree.paypalCheckout}},{key:"setup_braintree",value:function(){return this.cart_payment_nonce?this.unblock_ui():(_get(n.prototype.__proto__||Object.getPrototypeOf(n.prototype),"setup_braintree",this).call(this),d("input.js-wc-braintree-paypal-tokenize-payment-method").prop("disabled",!1),this.toggle_order_button())}},{key:"do_integration_ready",value:function(){var e,t=this;return s(this,r),this.cart_payment_nonce?this.unblock_ui():(e=this.is_single_use()?"checkout":"vault",this.render_button(this.integration.createPayment({flow:e,amount:this.get_order_amount(),currency:this.get_store_currency(),locale:this.get_store_locale()}),this.get_button_styles(),"#wc_braintree_paypal_container").then(function(){return d("#wc_braintree_paypal_container").css({width:"100%"}),t.unblock_ui()}).catch(function(e){return t.log("Could not render the PayPal button. "+e.message,e),t.hide_integration_ui(),t.unblock_ui()}))}},{key:"render_button",value:function(e,t,n){var r,i,a=this;return d(n).html(""),r=this.is_paypal_credit_enabled&&"USD"===this.get_store_currency()?{allowed:[paypal.FUNDING.CREDIT]}:{disallowed:[paypal.FUNDING.CREDIT]},i={env:this.is_test_environment?"sandbox":"production",commit:this.button_is_pay_now(),style:t,funding:r,payment:function(){return e},onAuthorize:function(e,t){return a.on_authorize(e,t)},onError:function(e){return a.handle_integration_error(e)}},paypal.Button.render(i,n)}},{key:"button_is_pay_now",value:function(){return!d("form#add_payment_method").length}},{key:"get_button_styles",value:function(){return this.button_styles}},{key:"on_authorize",value:function(e,t){var n=this;return s(this,r),this.block_ui(),this.integration.tokenizePayment(e).then(function(e){return n.log("Payment method tokenized.",e),n.set_payment_method(e)}).catch(function(e){return n.handle_payment_error(e),n.unblock_ui()})}},{key:"set_payment_method",value:function(e){return d("input[name=wc_"+this.id+"_payment_nonce]").val(e.nonce),d("#wc_braintree_paypal_container").html(this.get_linked_account_html(e.details)),this.is_single_use()&&d("input.js-wc-braintree-paypal-tokenize-payment-method").prop("disabled",!0),d("#place_order").show(),this.form.submit()}},{key:"handle_saved_payment_methods",value:function(){var t=this;return _get(n.prototype.__proto__||Object.getPrototypeOf(n.prototype),"handle_saved_payment_methods",this).call(this),d("input.js-wc-braintree-paypal-tokenize-payment-method").change(function(e){if(null!=t.integration&&d(e.target).is(":visible"))return t.block_ui(),t.do_integration_ready()}).change()}},{key:"get_linked_account_html",value:function(e){var t;return s(this,r),t=d("<div class='wc-"+this.id_dasherized+"-account'></div>"),null!=e.firstName&&null!=e.lastName&&t.append("<span class='name'>"+e.firstName+" "+e.lastName+"</span>"),t.append("<span class='email'>"+e.email+"</span>"),t.append("<a href='#' class='cancel'>Cancel</a>"),t}},{key:"is_single_use",value:function(){var e;return 0===(e=d("input[name=wc-braintree-paypal-tokenize-payment-method]")).length||("checkbox"===e.attr("type")?!e.is(":checked"):!e.val())}},{key:"get_order_amount",value:function(){return d("input[name=wc_braintree_paypal_amount]").val()}},{key:"get_store_currency",value:function(){return d("input[name=wc_braintree_paypal_currency]").val()}},{key:"get_store_locale",value:function(){return d("input[name=wc_braintree_paypal_locale]").val()}},{key:"is_sdk_ready",value:function(){return _get(n.prototype.__proto__||Object.getPrototypeOf(n.prototype),"is_sdk_ready",this).call(this)&&"undefined"!=typeof paypal&&null!==paypal}}]),n),window.WC_Braintree_PayPal_Cart_Handler=(_inherits(o,WC_Braintree_PayPal_Payment_Form_Handler),_createClass(o,[{key:"button_is_pay_now",value:function(){return!1}},{key:"set_payment_method",value:function(e){var t=this;if(null!=e.nonce)return e.wp_nonce=this.set_payment_method_nonce,d.ajax({type:"POST",url:this.cart_handler_url,data:e,dataType:"json"}).done(function(e){if(t.log("Cart response received.",e),null!=e.redirect_url)return window.location=e.redirect_url}).fail(function(e){return t.log("Error setting the PayPal cart data.",e,"error")}).always(function(){return t.unblock_ui()})}},{key:"is_single_use",value:function(){return"1"===d("input[name=wc_braintree_paypal_single_use]").val()}},{key:"has_payment_nonce",value:function(){return!1}}]),o),i=window.WC_Braintree_PayPal_Product_Button_Handler=(_inherits(_,WC_Braintree_PayPal_Payment_Form_Handler),_createClass(_,[{key:"handle_product_page",value:function(){return this.product_form={element:d("form.cart"),is_variable:d("form.cart").hasClass("variations_form")},this.should_validate_product_data&&this.product_form.element.on("change",this.validate_product_button),this.product_form.is_variable&&d(document.body).on("woocommerce_variation_has_changed",this.validate_product_button),this.validate_product_button()}},{key:"do_integration_ready",value:function(){if(s(this,i),_get(_.prototype.__proto__||Object.getPrototypeOf(_.prototype),"do_integration_ready",this).call(this),this.is_product_page)return this.validate_product_button()}},{key:"validate_product_button",value:function(){if(s(this,i),this.product_form.is_variable&&this.product_form.element.find(".single_add_to_cart_button").is(".disabled"))this.hide_button();else{if(!this.should_validate_product_data)return this.show_button();this.validate_product_data(this.show_button,this.hide_button)}}},{key:"validate_product_data",value:function(t,n){return s(this,i),d.ajax({type:"POST",url:this.validate_product_url,data:{wp_nonce:this.validate_product_nonce,product_id:d("input[name=wc_braintree_paypal_product_id]").val(),cart_form:d("form.cart").serialize()}}).done(function(e){return e.data.is_valid?t():n()}).fail(n)}},{key:"hide_button",value:function(){return d("#wc_braintree_paypal_container").slideUp()}},{key:"show_button",value:function(){return d("#wc_braintree_paypal_container").slideDown()}},{key:"button_is_pay_now",value:function(){return!1}},{key:"set_payment_method",value:function(e){var t,n=this;if(null!=e.nonce)return(t=e).wp_nonce=this.product_checkout_nonce,t.product_id=d("input[name=wc_braintree_paypal_product_id]").val(),t.cart_form=d("form.cart").serialize(),d.ajax({type:"POST",url:this.product_checkout_url,data:t,dataType:"json"}).done(function(e){if(n.log("Cart response received.",e),null!=e.redirect_url)return window.location=e.redirect_url}).fail(function(e){return n.log("Error setting the PayPal cart data.",e,"error")}).always(function(){return n.unblock_ui()})}},{key:"is_single_use",value:function(){return"1"===d("input[name=wc_braintree_paypal_single_use]").val()}},{key:"has_payment_nonce",value:function(){return!1}}]),_);function _(e){_classCallCheck(this,_);var t=_possibleConstructorReturn(this,(_.__proto__||Object.getPrototypeOf(_)).call(this,e));return t.do_integration_ready=t.do_integration_ready.bind(t),t.validate_product_button=t.validate_product_button.bind(t),t.validate_product_data=t.validate_product_data.bind(t),t.product_checkout_nonce=e.product_checkout_nonce,t.product_checkout_url=e.product_checkout_url,t.is_product_page=e.is_product_page,t.validate_product_url=e.validate_product_url,t.validate_product_nonce=e.validate_product_nonce,t.should_validate_product_data=e.should_validate_product_data,t.form=d("form.woocommerce-cart-form"),t.form_ui_selector="",t.is_product_page&&t.handle_product_page(),t.setup_braintree(),d(document.body).on("updated_cart_totals",function(){return t.setup_braintree()}),t}})}).call(void 0);
class-wc-braintree.php CHANGED
@@ -88,7 +88,7 @@ class WC_Braintree extends WC_Braintree_Framework\SV_WC_Payment_Gateway_Plugin {
88
 
89
 
90
  /** plugin version number */
91
- const VERSION = '2.2.7';
92
 
93
  /** Braintree JS SDK version */
94
  const BRAINTREE_JS_SDK_VERSION = '3.48.0';
@@ -111,9 +111,6 @@ class WC_Braintree extends WC_Braintree_Framework\SV_WC_Payment_Gateway_Plugin {
111
  /** PayPal gateway ID */
112
  const PAYPAL_GATEWAY_ID = 'braintree_paypal';
113
 
114
- /** @var \WC_Braintree_PayPal_Cart the PayPal cart handler instance */
115
- protected $paypal_cart;
116
-
117
  /** @var \WC_Braintree_Frontend the frontend instance */
118
  protected $frontend;
119
 
@@ -150,11 +147,8 @@ class WC_Braintree extends WC_Braintree_Framework\SV_WC_Payment_Gateway_Plugin {
150
  $this->includes();
151
 
152
  // handle Braintree Auth connect/disconnect
153
- add_action( 'admin_init', array( $this, 'handle_auth_connect' ) );
154
- add_action( 'admin_init', array( $this, 'handle_auth_disconnect' ) );
155
-
156
- // maybe initialize the PayPal cart handler on the cart page
157
- add_action( 'init', array( $this, 'maybe_init_paypal_cart' ) );
158
  }
159
 
160
 
@@ -184,7 +178,16 @@ class WC_Braintree extends WC_Braintree_Framework\SV_WC_Payment_Gateway_Plugin {
184
  require_once( $this->get_plugin_path() . '/includes/payment-forms/class-wc-braintree-hosted-fields-payment-form.php' );
185
  require_once( $this->get_plugin_path() . '/includes/payment-forms/class-wc-braintree-paypal-payment-form.php' );
186
 
187
- require_once( $this->get_plugin_path() . '/includes/class-wc-braintree-paypal-cart.php' );
 
 
 
 
 
 
 
 
 
188
  }
189
 
190
 
@@ -364,16 +367,11 @@ class WC_Braintree extends WC_Braintree_Framework\SV_WC_Payment_Gateway_Plugin {
364
  * Initializes the PayPal cart handler.
365
  *
366
  * @since 2.0.0
 
367
  */
368
  public function maybe_init_paypal_cart() {
369
 
370
- $gateway = $this->get_gateway( self::PAYPAL_GATEWAY_ID );
371
-
372
- if ( ! $gateway->is_available() ) {
373
- return;
374
- }
375
-
376
- $this->paypal_cart = new WC_Braintree_PayPal_Cart( $gateway );
377
  }
378
 
379
 
@@ -381,11 +379,11 @@ class WC_Braintree extends WC_Braintree_Framework\SV_WC_Payment_Gateway_Plugin {
381
  * Gets the PayPal cart handler instance.
382
  *
383
  * @since 2.0.0
384
- * @return \WC_Braintree_PayPal_Cart
385
  */
386
  public function get_paypal_cart_instance() {
387
 
388
- return $this->paypal_cart;
389
  }
390
 
391
 
88
 
89
 
90
  /** plugin version number */
91
+ const VERSION = '2.3.0';
92
 
93
  /** Braintree JS SDK version */
94
  const BRAINTREE_JS_SDK_VERSION = '3.48.0';
111
  /** PayPal gateway ID */
112
  const PAYPAL_GATEWAY_ID = 'braintree_paypal';
113
 
 
 
 
114
  /** @var \WC_Braintree_Frontend the frontend instance */
115
  protected $frontend;
116
 
147
  $this->includes();
148
 
149
  // handle Braintree Auth connect/disconnect
150
+ add_action( 'admin_init', [ $this, 'handle_auth_connect' ] );
151
+ add_action( 'admin_init', [ $this, 'handle_auth_disconnect' ] );
 
 
 
152
  }
153
 
154
 
178
  require_once( $this->get_plugin_path() . '/includes/payment-forms/class-wc-braintree-hosted-fields-payment-form.php' );
179
  require_once( $this->get_plugin_path() . '/includes/payment-forms/class-wc-braintree-paypal-payment-form.php' );
180
 
181
+ // payment buttons
182
+ require_once( $this->get_plugin_path() . '/includes/PayPal/Buttons/Abstract_Button.php' );
183
+ require_once( $this->get_plugin_path() . '/includes/PayPal/Buttons/Cart.php' );
184
+ require_once( $this->get_plugin_path() . '/includes/PayPal/Buttons/Product.php' );
185
+
186
+ // integrations
187
+ if ( $this->is_plugin_active( 'woocommerce-product-addons.php' ) ) {
188
+
189
+ $this->load_class( '/includes/Integrations/Product_Addons.php', '\\WC_Braintree\\Integrations\\Product_Addons' );
190
+ }
191
  }
192
 
193
 
367
  * Initializes the PayPal cart handler.
368
  *
369
  * @since 2.0.0
370
+ * @deprecated since 2.3.0
371
  */
372
  public function maybe_init_paypal_cart() {
373
 
374
+ WC_Braintree_Framework\SV_WC_Plugin_Compatibility::wc_deprecated_function( __METHOD__, '2.3.0' );
 
 
 
 
 
 
375
  }
376
 
377
 
379
  * Gets the PayPal cart handler instance.
380
  *
381
  * @since 2.0.0
382
+ * @deprecated since 2.3.0
383
  */
384
  public function get_paypal_cart_instance() {
385
 
386
+ WC_Braintree_Framework\SV_WC_Plugin_Compatibility::wc_deprecated_function( __METHOD__, '2.3.0' );
387
  }
388
 
389
 
i18n/languages/woocommerce-gateway-paypal-powered-by-braintree.pot CHANGED
@@ -2,10 +2,10 @@
2
  # This file is distributed under the same license as the WooCommerce PayPal Powered by Braintree Gateway package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: WooCommerce PayPal Powered by Braintree Gateway 2.2.7\n"
6
  "Report-Msgid-Bugs-To: "
7
  "https://woocommerce.com/my-account/marketplace-ticket-form/\n"
8
- "POT-Creation-Date: 2019-09-12 16:05:02+00:00\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=utf-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
@@ -19,52 +19,52 @@ msgid ""
19
  "not installed."
20
  msgstr ""
21
 
22
- #: class-wc-braintree.php:251
23
  msgid "Connected successfully."
24
  msgstr ""
25
 
26
- #: class-wc-braintree.php:254
27
  msgid "There was an error connecting your Braintree account. Please try again."
28
  msgstr ""
29
 
30
- #: class-wc-braintree.php:284
31
  msgid "Invalid connection request"
32
  msgstr ""
33
 
34
- #: class-wc-braintree.php:326
35
  msgid "Disconnected successfully."
36
  msgstr ""
37
 
38
- #: class-wc-braintree.php:351
39
  msgid "Invalid disconnect request"
40
  msgstr ""
41
 
42
- #: class-wc-braintree.php:448
43
  msgid ""
44
  "Heads up! You've enabled advanced fraud tools for Braintree. Please make "
45
  "sure that advanced fraud tools are also enabled in your Braintree account. "
46
  "Need help? See the %1$sdocumentation%2$s."
47
  msgstr ""
48
 
49
- #: class-wc-braintree.php:466
50
  msgid ""
51
  "PayPal powered by Braintree is almost ready. To get started, %1$sconnect "
52
  "your Braintree account%2$s."
53
  msgstr ""
54
 
55
- #: class-wc-braintree.php:478
56
  msgid ""
57
  "Upgrade successful! WooCommerce Braintree deactivated, and PayPal Powered "
58
  "by Braintree has been %1$sconfigured with your previous settings%2$s."
59
  msgstr ""
60
 
61
- #: class-wc-braintree.php:491
62
  msgid ""
63
  "WooCommerce is not being forced over SSL -- Using PayPal with Braintree "
64
  "requires that checkout to be forced over SSL."
65
  msgstr ""
66
 
67
- #: class-wc-braintree.php:526
68
  #. translators: Placeholders: %1$s - payment gateway name tag, %2$s - <a> tag,
69
  #. %3$s - </a> tag
70
  msgid ""
@@ -76,14 +76,18 @@ msgstr ""
76
  msgid "WooCommerce PayPal Powered by Braintree Gateway"
77
  msgstr ""
78
 
79
- #: class-wc-braintree.php:632
80
  msgid "Configure Credit Card"
81
  msgstr ""
82
 
83
- #: class-wc-braintree.php:632
84
  msgid "Configure PayPal"
85
  msgstr ""
86
 
 
 
 
 
87
  #: includes/api/class-wc-braintree-api-response-message-helper.php:137
88
  msgid ""
89
  "Sorry, we cannot process your transaction. The PayPal account is either "
@@ -154,10 +158,6 @@ msgstr ""
154
  msgid "%1$s Account Saved: %2$s"
155
  msgstr ""
156
 
157
- #: includes/class-wc-braintree-paypal-cart.php:391
158
- msgid "Cancel"
159
- msgstr ""
160
-
161
  #: includes/class-wc-gateway-braintree-credit-card.php:77
162
  msgid "Braintree (Credit Card)"
163
  msgstr ""
@@ -259,140 +259,148 @@ msgid ""
259
  "method or contact us to complete your transaction."
260
  msgstr ""
261
 
262
- #: includes/class-wc-gateway-braintree-paypal.php:68
263
  msgid "Braintree (PayPal)"
264
  msgstr ""
265
 
266
- #: includes/class-wc-gateway-braintree-paypal.php:69
267
  msgid "Allow customers to securely pay using their PayPal account via Braintree."
268
  msgstr ""
269
 
270
- #: includes/class-wc-gateway-braintree-paypal.php:150
271
  msgid "Token ID"
272
  msgstr ""
273
 
274
- #: includes/class-wc-gateway-braintree-paypal.php:155
275
  msgid "Email"
276
  msgstr ""
277
 
278
- #: includes/class-wc-gateway-braintree-paypal.php:193
279
  msgid "Use a new PayPal account"
280
  msgstr ""
281
 
282
- #: includes/class-wc-gateway-braintree-paypal.php:197
283
  msgid "PayPal Accounts"
284
  msgstr ""
285
 
286
- #: includes/class-wc-gateway-braintree-paypal.php:218
287
  msgid "Unlink"
288
  msgstr ""
289
 
290
- #: includes/class-wc-gateway-braintree-paypal.php:240
291
  msgid "Button Appearance"
292
  msgstr ""
293
 
294
- #: includes/class-wc-gateway-braintree-paypal.php:245
295
  msgid "Button Color"
296
  msgstr ""
297
 
298
- #: includes/class-wc-gateway-braintree-paypal.php:247
299
  msgid "Gold"
300
  msgstr ""
301
 
302
- #: includes/class-wc-gateway-braintree-paypal.php:248
303
  msgid "Blue"
304
  msgstr ""
305
 
306
- #: includes/class-wc-gateway-braintree-paypal.php:249
307
  msgid "Silver"
308
  msgstr ""
309
 
310
- #: includes/class-wc-gateway-braintree-paypal.php:250
311
  msgid "White"
312
  msgstr ""
313
 
314
- #: includes/class-wc-gateway-braintree-paypal.php:251
315
  msgid "Black"
316
  msgstr ""
317
 
318
- #: includes/class-wc-gateway-braintree-paypal.php:258
319
  msgid "Button Size"
320
  msgstr ""
321
 
322
- #: includes/class-wc-gateway-braintree-paypal.php:260
323
  msgid "Medium"
324
  msgstr ""
325
 
326
- #: includes/class-wc-gateway-braintree-paypal.php:261
327
  msgid "Large"
328
  msgstr ""
329
 
330
- #: includes/class-wc-gateway-braintree-paypal.php:262
331
  msgid "Responsive"
332
  msgstr ""
333
 
334
- #: includes/class-wc-gateway-braintree-paypal.php:269
335
  msgid "Button Shape"
336
  msgstr ""
337
 
338
- #: includes/class-wc-gateway-braintree-paypal.php:278
339
  msgid "PayPal Credit"
340
  msgstr ""
341
 
342
- #: includes/class-wc-gateway-braintree-paypal.php:281
343
  msgid "Show the PayPal credit button beneath the standard PayPal button"
344
  msgstr ""
345
 
346
- #: includes/class-wc-gateway-braintree-paypal.php:282
347
  msgid "Currently disabled because PayPal Credit is only available for US merchants"
348
  msgstr ""
349
 
350
- #: includes/class-wc-gateway-braintree-paypal.php:291
 
 
 
 
 
 
 
 
351
  msgid "Enable Cart Checkout"
352
  msgstr ""
353
 
354
- #: includes/class-wc-gateway-braintree-paypal.php:293
355
  msgid "Allow customers to check out with PayPal from the Cart page"
356
  msgstr ""
357
 
358
- #: includes/class-wc-gateway-braintree-paypal.php:372
359
  msgid "Preview"
360
  msgstr ""
361
 
362
- #: includes/class-wc-gateway-braintree-paypal.php:496
363
  #. translators: Placeholders: %1$s - payment method title (e.g. PayPal), %2$s -
364
  #. transaction environment (either Sandbox or blank string), %3$s - type of
365
  #. transaction (either Authorization or Payment)
366
  msgid "%1$s %2$s %3$s Approved"
367
  msgstr ""
368
 
369
- #: includes/class-wc-gateway-braintree-paypal.php:498
370
- #: includes/class-wc-gateway-braintree.php:1336
371
  msgid "Sandbox"
372
  msgstr ""
373
 
374
- #: includes/class-wc-gateway-braintree-paypal.php:499
375
  msgid "Authorization"
376
  msgstr ""
377
 
378
- #: includes/class-wc-gateway-braintree-paypal.php:499
379
  msgid "Payment"
380
  msgstr ""
381
 
382
- #: includes/class-wc-gateway-braintree-paypal.php:505
383
  #. translators: Placeholders: %s - transaction ID
384
  msgid "(Transaction ID %s)"
385
  msgstr ""
386
 
387
- #: includes/class-wc-gateway-braintree-paypal.php:526
388
  msgid "PayPal Account Saved: %s"
389
  msgstr ""
390
 
391
- #: includes/class-wc-gateway-braintree-paypal.php:605
392
  msgid "PayPal"
393
  msgstr ""
394
 
395
- #: includes/class-wc-gateway-braintree-paypal.php:619
396
  msgid ""
397
  "Click the PayPal icon below to sign into your PayPal account and pay "
398
  "securely."
@@ -536,23 +544,27 @@ msgstr ""
536
  msgid "Add merchant account ID for %s"
537
  msgstr ""
538
 
539
- #: includes/class-wc-gateway-braintree.php:712
 
 
 
 
540
  msgid "Add merchant account ID for "
541
  msgstr ""
542
 
543
- #: includes/class-wc-gateway-braintree.php:810
544
  msgid "Merchant Account ID (%s)"
545
  msgstr ""
546
 
547
- #: includes/class-wc-gateway-braintree.php:821
548
  msgid "Enter merchant account ID"
549
  msgstr ""
550
 
551
- #: includes/class-wc-gateway-braintree.php:822
552
  msgid "Remove this merchant account ID"
553
  msgstr ""
554
 
555
- #: includes/class-wc-gateway-braintree.php:1336
556
  msgid "Production"
557
  msgstr ""
558
 
@@ -568,13 +580,13 @@ msgstr ""
568
  msgid "Expiration (MMYY)"
569
  msgstr ""
570
 
571
- #: includes/payment-forms/class-wc-braintree-paypal-payment-form.php:82
572
  msgid ""
573
  "Please click the \"PayPal\" button below to log into your PayPal account "
574
  "before placing your order."
575
  msgstr ""
576
 
577
- #: includes/payment-forms/class-wc-braintree-paypal-payment-form.php:83
578
  msgid ""
579
  "Please click the \"PayPal\" button below to log into your PayPal account "
580
  "before adding your payment method."
@@ -598,7 +610,7 @@ msgid ""
598
  "retired WooCommerce Braintree plugin."
599
  msgstr ""
600
 
601
- #: woocommerce-gateway-paypal-powered-by-braintree.php:206
602
  msgid ""
603
  "The minimum PHP version required for this plugin is %1$s. You are running "
604
  "%2$s."
@@ -630,12 +642,12 @@ msgctxt "Payment Method Type"
630
  msgid "Type"
631
  msgstr ""
632
 
633
- #: includes/class-wc-gateway-braintree-paypal.php:271
634
  msgctxt "button shape option"
635
  msgid "Pill"
636
  msgstr ""
637
 
638
- #: includes/class-wc-gateway-braintree-paypal.php:272
639
  msgctxt "button shape option"
640
  msgid "Rectangle"
641
  msgstr ""
2
  # This file is distributed under the same license as the WooCommerce PayPal Powered by Braintree Gateway package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: WooCommerce PayPal Powered by Braintree Gateway 2.3.0\n"
6
  "Report-Msgid-Bugs-To: "
7
  "https://woocommerce.com/my-account/marketplace-ticket-form/\n"
8
+ "POT-Creation-Date: 2019-10-03 05:34:51+00:00\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=utf-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
19
  "not installed."
20
  msgstr ""
21
 
22
+ #: class-wc-braintree.php:254
23
  msgid "Connected successfully."
24
  msgstr ""
25
 
26
+ #: class-wc-braintree.php:257
27
  msgid "There was an error connecting your Braintree account. Please try again."
28
  msgstr ""
29
 
30
+ #: class-wc-braintree.php:287
31
  msgid "Invalid connection request"
32
  msgstr ""
33
 
34
+ #: class-wc-braintree.php:329
35
  msgid "Disconnected successfully."
36
  msgstr ""
37
 
38
+ #: class-wc-braintree.php:354
39
  msgid "Invalid disconnect request"
40
  msgstr ""
41
 
42
+ #: class-wc-braintree.php:446
43
  msgid ""
44
  "Heads up! You've enabled advanced fraud tools for Braintree. Please make "
45
  "sure that advanced fraud tools are also enabled in your Braintree account. "
46
  "Need help? See the %1$sdocumentation%2$s."
47
  msgstr ""
48
 
49
+ #: class-wc-braintree.php:464
50
  msgid ""
51
  "PayPal powered by Braintree is almost ready. To get started, %1$sconnect "
52
  "your Braintree account%2$s."
53
  msgstr ""
54
 
55
+ #: class-wc-braintree.php:476
56
  msgid ""
57
  "Upgrade successful! WooCommerce Braintree deactivated, and PayPal Powered "
58
  "by Braintree has been %1$sconfigured with your previous settings%2$s."
59
  msgstr ""
60
 
61
+ #: class-wc-braintree.php:489
62
  msgid ""
63
  "WooCommerce is not being forced over SSL -- Using PayPal with Braintree "
64
  "requires that checkout to be forced over SSL."
65
  msgstr ""
66
 
67
+ #: class-wc-braintree.php:524
68
  #. translators: Placeholders: %1$s - payment gateway name tag, %2$s - <a> tag,
69
  #. %3$s - </a> tag
70
  msgid ""
76
  msgid "WooCommerce PayPal Powered by Braintree Gateway"
77
  msgstr ""
78
 
79
+ #: class-wc-braintree.php:630
80
  msgid "Configure Credit Card"
81
  msgstr ""
82
 
83
+ #: class-wc-braintree.php:630
84
  msgid "Configure PayPal"
85
  msgstr ""
86
 
87
+ #: includes/PayPal/Buttons/Abstract_Button.php:510
88
+ msgid "Cancel"
89
+ msgstr ""
90
+
91
  #: includes/api/class-wc-braintree-api-response-message-helper.php:137
92
  msgid ""
93
  "Sorry, we cannot process your transaction. The PayPal account is either "
158
  msgid "%1$s Account Saved: %2$s"
159
  msgstr ""
160
 
 
 
 
 
161
  #: includes/class-wc-gateway-braintree-credit-card.php:77
162
  msgid "Braintree (Credit Card)"
163
  msgstr ""
259
  "method or contact us to complete your transaction."
260
  msgstr ""
261
 
262
+ #: includes/class-wc-gateway-braintree-paypal.php:75
263
  msgid "Braintree (PayPal)"
264
  msgstr ""
265
 
266
+ #: includes/class-wc-gateway-braintree-paypal.php:76
267
  msgid "Allow customers to securely pay using their PayPal account via Braintree."
268
  msgstr ""
269
 
270
+ #: includes/class-wc-gateway-braintree-paypal.php:183
271
  msgid "Token ID"
272
  msgstr ""
273
 
274
+ #: includes/class-wc-gateway-braintree-paypal.php:188
275
  msgid "Email"
276
  msgstr ""
277
 
278
+ #: includes/class-wc-gateway-braintree-paypal.php:226
279
  msgid "Use a new PayPal account"
280
  msgstr ""
281
 
282
+ #: includes/class-wc-gateway-braintree-paypal.php:230
283
  msgid "PayPal Accounts"
284
  msgstr ""
285
 
286
+ #: includes/class-wc-gateway-braintree-paypal.php:251
287
  msgid "Unlink"
288
  msgstr ""
289
 
290
+ #: includes/class-wc-gateway-braintree-paypal.php:273
291
  msgid "Button Appearance"
292
  msgstr ""
293
 
294
+ #: includes/class-wc-gateway-braintree-paypal.php:278
295
  msgid "Button Color"
296
  msgstr ""
297
 
298
+ #: includes/class-wc-gateway-braintree-paypal.php:280
299
  msgid "Gold"
300
  msgstr ""
301
 
302
+ #: includes/class-wc-gateway-braintree-paypal.php:281
303
  msgid "Blue"
304
  msgstr ""
305
 
306
+ #: includes/class-wc-gateway-braintree-paypal.php:282
307
  msgid "Silver"
308
  msgstr ""
309
 
310
+ #: includes/class-wc-gateway-braintree-paypal.php:283
311
  msgid "White"
312
  msgstr ""
313
 
314
+ #: includes/class-wc-gateway-braintree-paypal.php:284
315
  msgid "Black"
316
  msgstr ""
317
 
318
+ #: includes/class-wc-gateway-braintree-paypal.php:291
319
  msgid "Button Size"
320
  msgstr ""
321
 
322
+ #: includes/class-wc-gateway-braintree-paypal.php:293
323
  msgid "Medium"
324
  msgstr ""
325
 
326
+ #: includes/class-wc-gateway-braintree-paypal.php:294
327
  msgid "Large"
328
  msgstr ""
329
 
330
+ #: includes/class-wc-gateway-braintree-paypal.php:295
331
  msgid "Responsive"
332
  msgstr ""
333
 
334
+ #: includes/class-wc-gateway-braintree-paypal.php:302
335
  msgid "Button Shape"
336
  msgstr ""
337
 
338
+ #: includes/class-wc-gateway-braintree-paypal.php:311
339
  msgid "PayPal Credit"
340
  msgstr ""
341
 
342
+ #: includes/class-wc-gateway-braintree-paypal.php:314
343
  msgid "Show the PayPal credit button beneath the standard PayPal button"
344
  msgstr ""
345
 
346
+ #: includes/class-wc-gateway-braintree-paypal.php:315
347
  msgid "Currently disabled because PayPal Credit is only available for US merchants"
348
  msgstr ""
349
 
350
+ #: includes/class-wc-gateway-braintree-paypal.php:324
351
+ msgid "Buy Now on Product Pages"
352
+ msgstr ""
353
+
354
+ #: includes/class-wc-gateway-braintree-paypal.php:325
355
+ msgid "Add the PayPal Buy Now button to product pages."
356
+ msgstr ""
357
+
358
+ #: includes/class-wc-gateway-braintree-paypal.php:331
359
  msgid "Enable Cart Checkout"
360
  msgstr ""
361
 
362
+ #: includes/class-wc-gateway-braintree-paypal.php:333
363
  msgid "Allow customers to check out with PayPal from the Cart page"
364
  msgstr ""
365
 
366
+ #: includes/class-wc-gateway-braintree-paypal.php:412
367
  msgid "Preview"
368
  msgstr ""
369
 
370
+ #: includes/class-wc-gateway-braintree-paypal.php:536
371
  #. translators: Placeholders: %1$s - payment method title (e.g. PayPal), %2$s -
372
  #. transaction environment (either Sandbox or blank string), %3$s - type of
373
  #. transaction (either Authorization or Payment)
374
  msgid "%1$s %2$s %3$s Approved"
375
  msgstr ""
376
 
377
+ #: includes/class-wc-gateway-braintree-paypal.php:538
378
+ #: includes/class-wc-gateway-braintree.php:1337
379
  msgid "Sandbox"
380
  msgstr ""
381
 
382
+ #: includes/class-wc-gateway-braintree-paypal.php:539
383
  msgid "Authorization"
384
  msgstr ""
385
 
386
+ #: includes/class-wc-gateway-braintree-paypal.php:539
387
  msgid "Payment"
388
  msgstr ""
389
 
390
+ #: includes/class-wc-gateway-braintree-paypal.php:545
391
  #. translators: Placeholders: %s - transaction ID
392
  msgid "(Transaction ID %s)"
393
  msgstr ""
394
 
395
+ #: includes/class-wc-gateway-braintree-paypal.php:566
396
  msgid "PayPal Account Saved: %s"
397
  msgstr ""
398
 
399
+ #: includes/class-wc-gateway-braintree-paypal.php:658
400
  msgid "PayPal"
401
  msgstr ""
402
 
403
+ #: includes/class-wc-gateway-braintree-paypal.php:672
404
  msgid ""
405
  "Click the PayPal icon below to sign into your PayPal account and pay "
406
  "securely."
544
  msgid "Add merchant account ID for %s"
545
  msgstr ""
546
 
547
+ #: includes/class-wc-gateway-braintree.php:614
548
+ msgid "Add merchant account ID"
549
+ msgstr ""
550
+
551
+ #: includes/class-wc-gateway-braintree.php:713
552
  msgid "Add merchant account ID for "
553
  msgstr ""
554
 
555
+ #: includes/class-wc-gateway-braintree.php:811
556
  msgid "Merchant Account ID (%s)"
557
  msgstr ""
558
 
559
+ #: includes/class-wc-gateway-braintree.php:822
560
  msgid "Enter merchant account ID"
561
  msgstr ""
562
 
563
+ #: includes/class-wc-gateway-braintree.php:823
564
  msgid "Remove this merchant account ID"
565
  msgstr ""
566
 
567
+ #: includes/class-wc-gateway-braintree.php:1337
568
  msgid "Production"
569
  msgstr ""
570
 
580
  msgid "Expiration (MMYY)"
581
  msgstr ""
582
 
583
+ #: includes/payment-forms/class-wc-braintree-paypal-payment-form.php:83
584
  msgid ""
585
  "Please click the \"PayPal\" button below to log into your PayPal account "
586
  "before placing your order."
587
  msgstr ""
588
 
589
+ #: includes/payment-forms/class-wc-braintree-paypal-payment-form.php:84
590
  msgid ""
591
  "Please click the \"PayPal\" button below to log into your PayPal account "
592
  "before adding your payment method."
610
  "retired WooCommerce Braintree plugin."
611
  msgstr ""
612
 
613
+ #: woocommerce-gateway-paypal-powered-by-braintree.php:211
614
  msgid ""
615
  "The minimum PHP version required for this plugin is %1$s. You are running "
616
  "%2$s."
642
  msgid "Type"
643
  msgstr ""
644
 
645
+ #: includes/class-wc-gateway-braintree-paypal.php:304
646
  msgctxt "button shape option"
647
  msgid "Pill"
648
  msgstr ""
649
 
650
+ #: includes/class-wc-gateway-braintree-paypal.php:305
651
  msgctxt "button shape option"
652
  msgid "Rectangle"
653
  msgstr ""
includes/Integrations/Product_Addons.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WooCommerce Braintree Gateway
4
+ *
5
+ * This source file is subject to the GNU General Public License v3.0
6
+ * that is bundled with this package in the file license.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.html
9
+ * If you did not receive a copy of the license and are unable to
10
+ * obtain it through the world-wide-web, please send an email
11
+ * to license@woocommerce.com so we can send you a copy immediately.
12
+ *
13
+ * DISCLAIMER
14
+ *
15
+ * Do not edit or add to this file if you wish to upgrade WooCommerce Braintree Gateway to newer
16
+ * versions in the future. If you wish to customize WooCommerce Braintree Gateway for your
17
+ * needs please refer to http://docs.woocommerce.com/document/braintree/
18
+ *
19
+ * @package WC-Braintree/Integrations
20
+ * @author WooCommerce
21
+ * @copyright Copyright: (c) 2016-2019, Automattic, Inc.
22
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
23
+ */
24
+
25
+ namespace WC_Braintree\Integrations;
26
+
27
+ use WC_Braintree\PayPal\Buttons;
28
+ use WC_Braintree\Plugin_Framework as WC_Braintree_Framework;
29
+
30
+ defined( 'ABSPATH' ) or exit;
31
+
32
+ /**
33
+ * Product Add-ons integration class.
34
+ *
35
+ * @since 2.3.0
36
+ */
37
+ class Product_Addons {
38
+
39
+
40
+ /**
41
+ * Constructs the product add-ons integration class.
42
+ *
43
+ * @since 2.3.0
44
+ */
45
+ public function __construct() {
46
+
47
+ add_filter( 'wc_braintree_paypal_product_button_should_validate_product_data', '__return_true', 10, 2 );
48
+ add_filter( 'wc_braintree_paypal_product_button_validate_product_data', [ $this, 'validate_product_data' ], 10, 2 );
49
+ add_action( 'wc_braintree_paypal_before_product_button_add_to_cart', [ $this, 'prepare_product_data_for_addons' ], 10, 4 );
50
+ }
51
+
52
+
53
+ /**
54
+ * Validates the product data for displaying the product button.
55
+ *
56
+ * @since 2.3.0
57
+ *
58
+ * @param bool $is_valid
59
+ * @param Buttons\Product $product_button product button instance
60
+ * @return bool
61
+ */
62
+ public function validate_product_data( $is_valid, $product_button ) {
63
+
64
+ if ( $is_valid && isset( $GLOBALS['Product_Addon_Cart'] ) ) {
65
+
66
+ $cart_handler = $GLOBALS['Product_Addon_Cart'];
67
+
68
+ if ( $cart_handler instanceof \WC_Product_Addons_Cart ) {
69
+
70
+ $product_id = (int) WC_Braintree_Framework\SV_WC_Helper::get_post( 'product_id' );
71
+ $serialized = WC_Braintree_Framework\SV_WC_Helper::get_post( 'cart_form' );
72
+ $post_data = [];
73
+
74
+ if ( ! empty( $serialized ) ) {
75
+ parse_str( $serialized, $post_data );
76
+ }
77
+
78
+ $quantity = isset( $post_data['quantity'] ) ? (int) $post_data['quantity'] : 1;
79
+
80
+ // keep a reference to currently-enqueued notices, to restore to this point after validation
81
+ $notices = wc_get_notices();
82
+
83
+ $is_valid = (bool) $cart_handler->validate_add_cart_item( $is_valid, $product_id, $quantity, $post_data );
84
+
85
+ // restore notices from before validation, to prevent notices generated by this validation from displaying on subsequent page loads
86
+ wc_set_notices( $notices );
87
+ }
88
+ }
89
+
90
+ return $is_valid;
91
+ }
92
+
93
+
94
+ /**
95
+ * Prepares the data for product add-ons before adding the product to the cart.
96
+ *
97
+ * @since 2.3.0
98
+ *
99
+ * @param int $product_id product ID
100
+ * @param int $quantity quantity
101
+ * @param int $variation_id product variation ID
102
+ * @param array $cart_data cart data
103
+ */
104
+ public function prepare_product_data_for_addons( $product_id, $quantity, $variation_id, $cart_data ) {
105
+
106
+ // transpose product add-on data to $_POST for compatibility
107
+ foreach ( $cart_data as $key => $value ) {
108
+
109
+ if ( 0 === stripos( $key, 'addon-' ) ) {
110
+ $_POST[ $key ] = $value;
111
+ }
112
+ }
113
+ }
114
+
115
+
116
+ }
includes/{class-wc-braintree-paypal-cart.php → PayPal/Buttons/Abstract_Button.php} RENAMED
@@ -16,146 +16,182 @@
16
  * versions in the future. If you wish to customize WooCommerce Braintree Gateway for your
17
  * needs please refer to http://docs.woocommerce.com/document/braintree/
18
  *
19
- * @package WC-Braintree/Gateway
20
  * @author WooCommerce
21
  * @copyright Copyright: (c) 2016-2019, Automattic, Inc.
22
  * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
23
  */
24
 
 
 
25
  use WC_Braintree\Plugin_Framework as WC_Braintree_Framework;
26
 
27
  defined( 'ABSPATH' ) or exit;
28
 
29
  /**
30
- * The PayPal cart handler class.
31
- *
32
- * Sets up the actions & filters for handling PayPal's cart functionality.
33
  *
34
- * @since 2.0.0
35
  */
36
- class WC_Braintree_PayPal_Cart {
37
 
38
 
39
- /** @var \WC_Gateway_Braintree_PayPal $gateway the PayPal gateway object */
40
  protected $gateway;
41
 
 
 
 
42
 
43
  /**
44
- * Constructs the class.
45
  *
46
- * @since 2.0.0
47
- * @param \WC_Gateway_Braintree_PayPal $gateway the PayPal gateway object
 
48
  */
49
- public function __construct( WC_Gateway_Braintree_PayPal $gateway ) {
50
 
51
  $this->gateway = $gateway;
52
 
53
- if ( $gateway->cart_checkout_enabled() ) {
54
  $this->add_hooks();
55
  }
56
  }
57
 
58
 
59
  /**
60
- * Adds the necessary actions & filters.
61
  *
62
- * @since 2.0.0
 
 
63
  */
64
- protected function add_hooks() {
 
 
 
65
 
66
- // add the PayPal button below "Proceed to Checkout"
67
- add_action( 'woocommerce_proceed_to_checkout', array( $this, 'render' ), 50 );
 
 
 
 
 
68
 
69
  // handle the PayPal token generated by Braintree JS
70
- add_action( 'woocommerce_api_' . strtolower( get_class( $this->get_gateway() ) ), array( $this, 'handle_wc_api' ) );
71
 
72
  // set the checkout address value if it's available from the PayPal session
73
- add_filter( 'woocommerce_checkout_get_value', array( $this, 'set_checkout_value' ), 10, 2 );
74
 
75
  // set the "Ship to different address" checkbox based on PayPal session data
76
- add_filter( 'woocommerce_ship_to_different_address_checked', array( $this, 'set_ship_to_different_address' ) );
77
 
78
  // disable all other gateways at checkout when confirming payment
79
- add_action( 'woocommerce_available_payment_gateways', array( $this, 'disable_other_gateways' ) );
80
 
81
  // add styles for the cart & confirmation page
82
- add_action( 'wp_head', array( $this, 'enqueue_styles' ) );
83
 
84
  // add a "Cancel" link below the order button at checkout confirmation
85
- add_action( 'woocommerce_review_order_after_submit', array( $this, 'render_cancel_link' ) );
86
 
87
  // clear the session data when the cart is emptied
88
- add_action( 'woocommerce_cart_emptied', array( $this, 'clear_session_data' ) );
89
  }
90
 
91
 
92
  /**
93
- * Renders the PayPal button markup and related JS data.
94
  *
95
- * @since 2.0.0
96
  */
97
  public function render() {
98
 
99
  $this->clear_session_data();
100
-
101
- // if there are subscriptions or pre-orders in the cart and the user
102
- // already has some stored tokens, then we can halt the cart checkout
103
- // feature since the customer will likely have a better experience
104
- // choosing a stored payment method using our standard checkout flow.
105
- if ( ! $this->is_single_use() && ( ! $this->get_gateway()->tokenization_enabled() || $this->user_has_tokens() ) ) {
106
- return;
107
- }
108
-
109
  $this->render_button();
110
-
111
  $this->render_js();
112
  }
113
 
 
 
 
 
 
 
 
 
 
 
 
 
114
 
115
  /**
116
- * Renders the PayPal button markup.
117
  *
118
- * @since 2.0.0
 
 
119
  */
120
- public function render_button() {
121
 
122
- $total = WC()->cart->total;
123
 
124
- ?>
 
 
 
 
 
125
 
126
- <div id="wc_braintree_paypal_container"></div>
127
- <input type="hidden" name="wc_braintree_paypal_amount" value="<?php echo esc_attr( WC_Braintree_Framework\SV_WC_Helper::number_format( $total, 2 ) ); ?>" />
128
- <input type="hidden" name="wc_braintree_paypal_currency" value="<?php echo esc_attr( get_woocommerce_currency() ); ?>" />
129
- <input type="hidden" name="wc_braintree_paypal_locale" value="<?php echo esc_attr( $this->get_gateway()->get_safe_locale() ); ?>" />
130
- <input type="hidden" name="wc_braintree_paypal_single_use" value="<?php echo (int) $this->is_single_use(); ?>" />
131
 
132
- <?php
 
 
 
 
 
 
133
  }
134
 
135
 
136
  /**
137
- * Renders the PayPal button JS.
138
  *
139
- * @since 2.0.0
 
 
140
  */
141
- public function render_js() {
142
 
143
  $params = $this->get_gateway()->get_payment_form_instance()->get_payment_form_handler_js_params();
144
 
145
- $params['button_styles']['label'] = 'checkout';
 
 
 
 
 
 
 
 
 
 
 
 
 
146
 
147
  /**
148
- * Filters the PayPal cart button style parameters.
149
- *
150
- * See https://developer.paypal.com/docs/integration/direct/express-checkout/integration-jsv4/customize-button/
151
  *
152
- * @since 2.1.0
153
  *
154
- * @param array $styles style parameters
 
155
  */
156
- $params['button_styles'] = (array) apply_filters( 'wc_' . $this->get_gateway()->get_id() . '_cart_button_styles', $params['button_styles'] );
157
-
158
- $params = array_merge( [
159
  'id' => $this->get_gateway()->get_id(),
160
  'id_dasherized' => $this->get_gateway()->get_id_dasherized(),
161
  'name' => $this->get_gateway()->get_method_title(),
@@ -163,104 +199,187 @@ class WC_Braintree_PayPal_Cart {
163
  'client_token_nonce' => wp_create_nonce( 'wc_' . $this->get_gateway()->get_id() . '_get_client_token' ),
164
  'set_payment_method_nonce' => wp_create_nonce( 'wc_' . $this->get_gateway()->get_id() . '_cart_set_payment_method' ),
165
  'cart_handler_url' => add_query_arg( 'wc-api', get_class( $this->get_gateway() ), home_url() )
166
- ], $params );
 
167
 
168
- wc_enqueue_js( sprintf( 'window.wc_%1$s_handler = new WC_Braintree_PayPal_Cart_Handler( %2$s );', esc_js( $this->get_gateway()->get_id() ), json_encode( $params ) ) );
 
 
 
 
 
 
 
 
 
 
169
  }
170
 
171
 
172
  /**
173
- * Handles the request made to the WC API after the JS has generated a token.
174
  *
175
- * @since 2.0.0
176
  */
177
- public function handle_wc_api() {
 
 
 
 
 
 
 
 
 
 
178
 
179
- if ( ! wp_verify_nonce( WC_Braintree_Framework\SV_WC_Helper::get_post( 'wp_nonce' ), 'wc_' . $this->get_gateway()->get_id() . '_cart_set_payment_method' ) ) {
180
- return;
181
- }
182
 
183
- WC()->session->set( 'wc_braintree_paypal_cart_nonce', WC_Braintree_Framework\SV_WC_Helper::get_post( 'nonce' ) );
 
 
 
 
 
 
184
 
185
- if ( ! empty( $_POST['details'] ) ) {
186
- $this->set_customer_data( $_POST['details'] );
187
- }
188
 
189
- wp_send_json( array(
190
- 'redirect_url' => wc_get_checkout_url(),
191
- ) );
 
 
 
 
 
192
  }
193
 
194
 
195
  /**
196
- * Sets the customer address session data from a PayPal token request.
197
  *
198
- * @since 2.0.0
199
- * @param array $data the customer data
 
200
  */
201
- protected function set_customer_data( $data = array() ) {
202
 
203
- // if there is no data to set, bail
204
- if ( ! is_array( $data ) || empty( $data ) ) {
205
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  }
207
 
208
- $data = wp_parse_args( $data, array(
209
- 'email' => '',
210
- 'payerId' => '',
211
- 'firstName' => '',
212
- 'lastName' => '',
213
- 'phone' => '',
214
- 'countryCode' => '',
215
- 'shippingAddress' => array(),
216
- 'billingAddress' => array(),
217
- ) );
218
 
219
- $address_defaults = array(
220
- 'streetAddress' => '',
221
- 'extendedAddress' => '',
222
- 'locality' => '',
223
- 'region' => '',
224
- 'postalCode' => '',
225
- 'countryCodeAlpha2' => '',
226
- );
227
 
228
- $billing_address = wp_parse_args( $data['billingAddress'], $address_defaults );
229
- $shipping_address = wp_parse_args( $data['shippingAddress'], $address_defaults );
230
 
231
- $details = array(
232
- 'billing' => array(
233
- 'first_name' => $data['firstName'],
234
- 'last_name' => $data['lastName'],
235
- 'email' => $data['email'],
236
- 'phone' => $data['phone'],
237
- 'country' => $billing_address['countryCodeAlpha2'],
238
- 'address_1' => $billing_address['streetAddress'],
239
- 'address_2' => $billing_address['extendedAddress'],
240
- 'city' => $billing_address['locality'],
241
- 'state' => $billing_address['region'],
242
- 'postcode' => $billing_address['postalCode'],
243
- ),
244
- 'shipping' => array(
245
- 'first_name' => $data['firstName'],
246
- 'last_name' => $data['lastName'],
247
- 'country' => $shipping_address['countryCodeAlpha2'],
248
- 'address_1' => $shipping_address['streetAddress'],
249
- 'address_2' => $shipping_address['extendedAddress'],
250
- 'city' => $shipping_address['locality'],
251
- 'state' => $shipping_address['region'],
252
- 'postcode' => $shipping_address['postalCode'],
253
- ),
254
- );
255
 
256
- WC()->session->set( 'wc_braintree_paypal_cart_customer_details', $details );
 
 
 
 
 
 
 
 
 
257
  }
258
 
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  /**
261
  * Sets the checkout address value if it's available from the PayPal session.
262
  *
263
- * @since 2.0.0
 
264
  * @param null $value
265
  * @param string $key the checkout field key
266
  * @return string|null
@@ -295,18 +414,18 @@ class WC_Braintree_PayPal_Cart {
295
  /**
296
  * Sets the "Ship to different address" checkbox based on PayPal session data.
297
  *
298
- * @since 2.0.0
 
299
  * @param bool $checked
300
  * @return bool
301
  */
302
  public function set_ship_to_different_address( $checked ) {
303
 
304
- $details = WC()->session->get( 'wc_braintree_paypal_cart_customer_details', array() );
305
 
306
  if ( ! empty( $details ) ) {
307
 
308
- unset( $details['billing']['email'] );
309
- unset( $details['billing']['phone'] );
310
 
311
  if ( empty( $details['shipping'] ) ) {
312
  $checked = false;
@@ -346,7 +465,7 @@ class WC_Braintree_PayPal_Cart {
346
  /**
347
  * Adds styles for the cart & confirmation page.
348
  *
349
- * @since 2.0.0
350
  */
351
  public function enqueue_styles() {
352
 
@@ -377,121 +496,140 @@ class WC_Braintree_PayPal_Cart {
377
  /**
378
  * Renders a "Cancel" link.
379
  *
380
- * @since 2.0.0
381
  */
382
  public function render_cancel_link() {
383
 
384
- if ( ! $this->is_checkout_confirmation() ) {
385
  return;
386
  }
387
 
388
  printf(
389
  '<a href="%1$s" class="wc-' . sanitize_html_class( $this->get_gateway()->get_id_dasherized() ) . '-cancel">%2$s</a>',
390
- esc_url( add_query_arg( array( 'wc_' . $this->get_gateway()->get_id() . '_clear_session' => true ), wc_get_cart_url() ) ),
391
  esc_html__( 'Cancel', 'woocommerce-gateway-paypal-powered-by-braintree' )
392
  );
 
 
393
  }
394
 
395
 
396
  /**
397
- * Determines if the current view is at Checkout, confirming the cart PayPal
398
- * purchase.
399
  *
400
- * @since 2.0.0
401
- * @return bool
 
402
  */
403
- public function is_checkout_confirmation() {
404
 
405
- return is_checkout() && $this->get_gateway()->is_available() && $this->get_cart_nonce();
406
- }
 
 
407
 
 
 
 
 
 
 
 
 
 
 
408
 
409
- /**
410
- * Gets the cart nonce from the session, if any.
411
- *
412
- * @since 2.0.0
413
- * @return string
414
- */
415
- public function get_cart_nonce() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
416
 
417
- return WC()->session->get( 'wc_braintree_paypal_cart_nonce', '' );
418
  }
419
 
420
 
421
  /**
422
- * Clears any PayPal cart session data.
423
  *
424
- * @since 2.0.0
 
 
425
  */
426
- public function clear_session_data() {
427
 
428
- unset( WC()->session->wc_braintree_paypal_cart_nonce );
429
- unset( WC()->session->wc_braintree_paypal_cart_customer_details );
430
  }
431
 
432
 
433
  /**
434
- * Determines if the PayPal token should be considered "single use".
435
  *
436
- * This is primarily dependent on if there are subscriptions or Pre-Orders
437
- * present in the cart.
438
  *
439
- * @since 2.0.0
440
- * @return bool
441
  */
442
- public function is_single_use() {
443
-
444
- $single_use = true;
445
-
446
- if ( $this->get_gateway()->get_plugin()->is_pre_orders_active() && \WC_Pre_Orders_Cart::cart_contains_pre_order() && \WC_Pre_Orders_Product::product_is_charged_upon_release( \WC_Pre_Orders_Cart::get_pre_order_product() ) ) {
447
- $single_use = false;
448
- }
449
-
450
- if ( $this->get_gateway()->get_plugin()->is_subscriptions_active() && ( \WC_Subscriptions_Cart::cart_contains_subscription() || wcs_cart_contains_renewal() ) ) {
451
- $single_use = false;
452
- }
453
 
454
- return $single_use;
455
  }
456
 
457
 
458
  /**
459
- * Determines if the current user has any saved tokens.
460
  *
461
- * @since 2.0.0
462
- * @return bool
463
  */
464
- protected function user_has_tokens() {
465
-
466
- $token_count = 0;
467
-
468
- if ( $this->get_gateway()->tokenization_enabled() && is_user_logged_in() ) {
469
-
470
- foreach ( $this->get_gateway()->get_payment_tokens_handler()->get_tokens( get_current_user_id() ) as $token ) {
471
-
472
- // skip this token if it's not a PayPal account
473
- if ( ! $token->is_paypal_account() ) {
474
- continue;
475
- }
476
-
477
- $token_count++;
478
- }
479
- }
480
 
481
- return $token_count > 0;
 
 
 
482
  }
483
 
484
 
485
  /**
486
- * Gets the PayPal gateway object.
 
 
487
  *
488
- * @since 2.0.0
489
  * @return \WC_Gateway_Braintree_PayPal
490
  */
491
  protected function get_gateway() {
492
-
493
  return $this->gateway;
494
  }
495
 
496
 
497
- }
16
  * versions in the future. If you wish to customize WooCommerce Braintree Gateway for your
17
  * needs please refer to http://docs.woocommerce.com/document/braintree/
18
  *
19
+ * @package WC-Braintree/Buttons
20
  * @author WooCommerce
21
  * @copyright Copyright: (c) 2016-2019, Automattic, Inc.
22
  * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
23
  */
24
 
25
+ namespace WC_Braintree\PayPal\Buttons;
26
+
27
  use WC_Braintree\Plugin_Framework as WC_Braintree_Framework;
28
 
29
  defined( 'ABSPATH' ) or exit;
30
 
31
  /**
32
+ * Abstract PayPal button class.
 
 
33
  *
34
+ * @since 2.3.0
35
  */
36
+ abstract class Abstract_Button {
37
 
38
 
39
+ /** @var \WC_Gateway_Braintree_PayPal PayPal gateway instance */
40
  protected $gateway;
41
 
42
+ /** @var bool tracks whether a cancel link has been rendered from any button */
43
+ static protected $rendered_cancel_link = false;
44
+
45
 
46
  /**
47
+ * Constructs the button handler.
48
  *
49
+ * @since 2.3.0
50
+ *
51
+ * @param \WC_Gateway_Braintree_PayPal $gateway the gateway instance
52
  */
53
+ public function __construct( $gateway ) {
54
 
55
  $this->gateway = $gateway;
56
 
57
+ if ( $this->is_enabled() ) {
58
  $this->add_hooks();
59
  }
60
  }
61
 
62
 
63
  /**
64
+ * Checks if this button should be enabled or not.
65
  *
66
+ * @since 2.3.0
67
+ *
68
+ * @return bool
69
  */
70
+ protected function is_enabled() {
71
+ // override in concrete classes
72
+ return false;
73
+ }
74
 
75
+
76
+ /**
77
+ * Adds any actions and filters needed for the button.
78
+ *
79
+ * @since 2.3.0
80
+ */
81
+ protected function add_hooks() {
82
 
83
  // handle the PayPal token generated by Braintree JS
84
+ add_action( 'woocommerce_api_' . strtolower( get_class( $this->get_gateway() ) ), [ $this, 'handle_wc_api' ] );
85
 
86
  // set the checkout address value if it's available from the PayPal session
87
+ add_filter( 'woocommerce_checkout_get_value', [ $this, 'set_checkout_value' ], 10, 2 );
88
 
89
  // set the "Ship to different address" checkbox based on PayPal session data
90
+ add_filter( 'woocommerce_ship_to_different_address_checked', [ $this, 'set_ship_to_different_address' ] );
91
 
92
  // disable all other gateways at checkout when confirming payment
93
+ add_action( 'woocommerce_available_payment_gateways', [ $this, 'disable_other_gateways' ] );
94
 
95
  // add styles for the cart & confirmation page
96
+ add_action( 'wp_head', [ $this, 'enqueue_styles' ] );
97
 
98
  // add a "Cancel" link below the order button at checkout confirmation
99
+ add_action( 'woocommerce_review_order_after_submit', [ $this, 'render_cancel_link' ] );
100
 
101
  // clear the session data when the cart is emptied
102
+ add_action( 'woocommerce_cart_emptied', [ $this, 'clear_session_data' ] );
103
  }
104
 
105
 
106
  /**
107
+ * Renders the button markup and JS.
108
  *
109
+ * @since 2.3.0
110
  */
111
  public function render() {
112
 
113
  $this->clear_session_data();
 
 
 
 
 
 
 
 
 
114
  $this->render_button();
 
115
  $this->render_js();
116
  }
117
 
118
+ /**
119
+ * Handles the request made to the WC API after the JS has generated a token.
120
+ *
121
+ * @since 2.3.0
122
+ */
123
+ public function handle_wc_api() {
124
+
125
+ if ( $this->is_wc_api_request_valid() ) {
126
+ $this->process_wc_api_request();
127
+ }
128
+ }
129
+
130
 
131
  /**
132
+ * Validates a WC API request.
133
  *
134
+ * @since 2.3.0
135
+ *
136
+ * @return bool
137
  */
138
+ abstract protected function is_wc_api_request_valid();
139
 
 
140
 
141
+ /**
142
+ * Processes a WC API request after the JS has generated a token.
143
+ *
144
+ * @since 2.3.0
145
+ */
146
+ protected function process_wc_api_request() {
147
 
148
+ WC()->session->set( 'wc_braintree_paypal_cart_nonce', WC_Braintree_Framework\SV_WC_Helper::get_post( 'nonce' ) );
 
 
 
 
149
 
150
+ if ( ! empty( $_POST['details'] ) ) {
151
+ $this->set_customer_data( $_POST['details'] );
152
+ }
153
+
154
+ wp_send_json( [
155
+ 'redirect_url' => wc_get_checkout_url(),
156
+ ] );
157
  }
158
 
159
 
160
  /**
161
+ * Gets the array of form handler JS params.
162
  *
163
+ * @since 2.3.0
164
+ *
165
+ * @return array
166
  */
167
+ protected function get_form_handler_params() {
168
 
169
  $params = $this->get_gateway()->get_payment_form_instance()->get_payment_form_handler_js_params();
170
 
171
+ $params['cart_payment_nonce'] = $this->get_cart_nonce();
172
+
173
+ return $params;
174
+ }
175
+
176
+
177
+ /**
178
+ * Gets the JS handler params.
179
+ *
180
+ * @since 2.3.0
181
+ *
182
+ * @return array
183
+ */
184
+ protected function get_js_handler_params() {
185
 
186
  /**
187
+ * Filters the JS handler params.
 
 
188
  *
189
+ * @since 2.3.0
190
  *
191
+ * @param array params
192
+ * @param Abstract_Button button handler instance
193
  */
194
+ return (array) apply_filters( 'wc_' . $this->get_gateway()->get_id() . '_button_js_handler_params', array_merge( [
 
 
195
  'id' => $this->get_gateway()->get_id(),
196
  'id_dasherized' => $this->get_gateway()->get_id_dasherized(),
197
  'name' => $this->get_gateway()->get_method_title(),
199
  'client_token_nonce' => wp_create_nonce( 'wc_' . $this->get_gateway()->get_id() . '_get_client_token' ),
200
  'set_payment_method_nonce' => wp_create_nonce( 'wc_' . $this->get_gateway()->get_id() . '_cart_set_payment_method' ),
201
  'cart_handler_url' => add_query_arg( 'wc-api', get_class( $this->get_gateway() ), home_url() )
202
+ ], $this->get_form_handler_params(), $this->get_additional_js_handler_params() ), $this );
203
+ }
204
 
205
+
206
+ /**
207
+ * Gets additional JS Handler params - Override in concrete classes.
208
+ *
209
+ * @since 2.3.0
210
+ *
211
+ * @return array
212
+ */
213
+ protected function get_additional_js_handler_params() {
214
+
215
+ return [];
216
  }
217
 
218
 
219
  /**
220
+ * Renders the PayPal button JS.
221
  *
222
+ * @since 2.3.0
223
  */
224
+ protected function render_js() {
225
+
226
+ wc_enqueue_js(
227
+ sprintf(
228
+ 'window.%1$s = new %2$s(%3$s); window.%1$s.init()',
229
+ esc_attr( $this->get_js_handler_object_name() ),
230
+ esc_attr( $this->get_js_handler_name() ),
231
+ json_encode( $this->get_js_handler_params() )
232
+ )
233
+ );
234
+ }
235
 
 
 
 
236
 
237
+ /**
238
+ * Renders the PayPal button markup.
239
+ *
240
+ * @since 2.3.0
241
+ */
242
+ public function render_button() {
243
+ ?>
244
 
245
+ <div id="<?php echo esc_attr( 'wc_' . $this->get_gateway()->get_id() . '_container' ); ?>"></div>
 
 
246
 
247
+ <?php foreach ( $this->get_button_params() as $key => $value ) : ?>
248
+
249
+ <input type="hidden"
250
+ name="<?php echo esc_attr( 'wc_' . $this->get_gateway()->get_id() . '_' . $key ); ?>"
251
+ value="<?php echo esc_attr( $value ); ?>"
252
+ />
253
+
254
+ <?php endforeach;
255
  }
256
 
257
 
258
  /**
259
+ * Gets an array of params for rendering the button HTML.
260
  *
261
+ * @since 2.3.0
262
+ *
263
+ * @return array
264
  */
265
+ protected function get_button_params() {
266
 
267
+ /**
268
+ * Filters the markup params for a button.
269
+ *
270
+ * @since 2.3.0
271
+ *
272
+ * @param array params
273
+ * @param Abstract_Button button handler instance
274
+ */
275
+ return (array) apply_filters( 'wc_' . $this->get_gateway()->get_id() . '_button_markup_params', array_merge( [
276
+ 'amount' => WC_Braintree_Framework\SV_WC_Helper::number_format( $this->get_button_total() ),
277
+ 'currency' => $this->get_button_currency(),
278
+ 'locale' => $this->get_button_locale(),
279
+ 'single_use' => $this->is_single_use(),
280
+ ], $this->get_additional_button_params() ), $this );
281
+ }
282
+
283
+
284
+ /**
285
+ * Gets additional button params for the button markup - override in concrete classes.
286
+ *
287
+ * @since 2.3.0
288
+ *
289
+ * @return array
290
+ */
291
+ protected function get_additional_button_params() {
292
+ return [];
293
+ }
294
+
295
+
296
+ /**
297
+ * Determines if the PayPal token should be considered "single use".
298
+ *
299
+ * This is primarily dependent on if there are subscriptions or Pre-Orders
300
+ * present in the cart.
301
+ *
302
+ * @since 2.3.0
303
+ *
304
+ * @return bool
305
+ */
306
+ protected function is_single_use() {
307
+
308
+ $single_use = true;
309
+
310
+ if ( $this->get_gateway()->get_plugin()->is_pre_orders_active() && \WC_Pre_Orders_Cart::cart_contains_pre_order() && \WC_Pre_Orders_Product::product_is_charged_upon_release( \WC_Pre_Orders_Cart::get_pre_order_product() ) ) {
311
+ $single_use = false;
312
  }
313
 
314
+ if ( $this->get_gateway()->get_plugin()->is_subscriptions_active() && ( \WC_Subscriptions_Cart::cart_contains_subscription() || wcs_cart_contains_renewal() ) ) {
315
+ $single_use = false;
316
+ }
 
 
 
 
 
 
 
317
 
318
+ return $single_use;
319
+ }
 
 
 
 
 
 
320
 
 
 
321
 
322
+ /**
323
+ * Gets the total amount the button should charge - override in concrete classes.
324
+ *
325
+ * @since 2.3.0
326
+ *
327
+ * @return float
328
+ */
329
+ protected function get_button_total() {
330
+ return 0.0;
331
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
 
333
+
334
+ /**
335
+ * Gets the currency to be used for the button.
336
+ *
337
+ * @since 2.3.0
338
+ *
339
+ * @return string
340
+ */
341
+ protected function get_button_currency() {
342
+ return get_woocommerce_currency();
343
  }
344
 
345
 
346
+ /**
347
+ * Gets the locale to be used for the button.
348
+ *
349
+ * @since 2.3.0
350
+ *
351
+ * @return string
352
+ */
353
+ protected function get_button_locale() {
354
+ return $this->get_gateway()->get_safe_locale();
355
+ }
356
+
357
+
358
+ /**
359
+ * Gets the JS handler object name.
360
+ *
361
+ * @since 2.3.0
362
+ *
363
+ * @return string
364
+ */
365
+ abstract protected function get_js_handler_object_name();
366
+
367
+
368
+ /**
369
+ * Gets the JS handler class name.
370
+ *
371
+ * @since 2.3.0
372
+ *
373
+ * @return string
374
+ */
375
+ abstract protected function get_js_handler_name();
376
+
377
+
378
  /**
379
  * Sets the checkout address value if it's available from the PayPal session.
380
  *
381
+ * @since 2.3.0
382
+ *
383
  * @param null $value
384
  * @param string $key the checkout field key
385
  * @return string|null
414
  /**
415
  * Sets the "Ship to different address" checkbox based on PayPal session data.
416
  *
417
+ * @since 2.3.0
418
+ *
419
  * @param bool $checked
420
  * @return bool
421
  */
422
  public function set_ship_to_different_address( $checked ) {
423
 
424
+ $details = WC()->session->get( 'wc_braintree_paypal_cart_customer_details', [] );
425
 
426
  if ( ! empty( $details ) ) {
427
 
428
+ unset( $details['billing']['email'], $details['billing']['phone'] );
 
429
 
430
  if ( empty( $details['shipping'] ) ) {
431
  $checked = false;
465
  /**
466
  * Adds styles for the cart & confirmation page.
467
  *
468
+ * @since 2.3.0
469
  */
470
  public function enqueue_styles() {
471
 
496
  /**
497
  * Renders a "Cancel" link.
498
  *
499
+ * @since 2.3.0
500
  */
501
  public function render_cancel_link() {
502
 
503
+ if ( self::$rendered_cancel_link || ! $this->is_checkout_confirmation() ) {
504
  return;
505
  }
506
 
507
  printf(
508
  '<a href="%1$s" class="wc-' . sanitize_html_class( $this->get_gateway()->get_id_dasherized() ) . '-cancel">%2$s</a>',
509
+ esc_url( add_query_arg( [ 'wc_' . $this->get_gateway()->get_id() . '_clear_session' => true ], wc_get_cart_url() ) ),
510
  esc_html__( 'Cancel', 'woocommerce-gateway-paypal-powered-by-braintree' )
511
  );
512
+
513
+ self::$rendered_cancel_link = true;
514
  }
515
 
516
 
517
  /**
518
+ * Sets the customer address session data from a PayPal token request.
 
519
  *
520
+ * @since 2.3.0
521
+ *
522
+ * @param array $data the customer data
523
  */
524
+ protected function set_customer_data( $data = [] ) {
525
 
526
+ // if there is no data to set, bail
527
+ if ( ! is_array( $data ) || empty( $data ) ) {
528
+ return;
529
+ }
530
 
531
+ $data = wp_parse_args( $data, [
532
+ 'email' => '',
533
+ 'payerId' => '',
534
+ 'firstName' => '',
535
+ 'lastName' => '',
536
+ 'phone' => '',
537
+ 'countryCode' => '',
538
+ 'shippingAddress' => [],
539
+ 'billingAddress' => [],
540
+ ] );
541
 
542
+ $address_defaults = [
543
+ 'streetAddress' => '',
544
+ 'extendedAddress' => '',
545
+ 'locality' => '',
546
+ 'region' => '',
547
+ 'postalCode' => '',
548
+ 'countryCodeAlpha2' => '',
549
+ ];
550
+
551
+ $billing_address = wp_parse_args( $data['billingAddress'], $address_defaults );
552
+ $shipping_address = wp_parse_args( $data['shippingAddress'], $address_defaults );
553
+
554
+ $details = [
555
+ 'billing' => [
556
+ 'first_name' => $data['firstName'],
557
+ 'last_name' => $data['lastName'],
558
+ 'email' => $data['email'],
559
+ 'phone' => $data['phone'],
560
+ 'country' => $billing_address['countryCodeAlpha2'],
561
+ 'address_1' => $billing_address['streetAddress'],
562
+ 'address_2' => $billing_address['extendedAddress'],
563
+ 'city' => $billing_address['locality'],
564
+ 'state' => $billing_address['region'],
565
+ 'postcode' => $billing_address['postalCode'],
566
+ ],
567
+ 'shipping' => [
568
+ 'first_name' => $data['firstName'],
569
+ 'last_name' => $data['lastName'],
570
+ 'country' => $shipping_address['countryCodeAlpha2'],
571
+ 'address_1' => $shipping_address['streetAddress'],
572
+ 'address_2' => $shipping_address['extendedAddress'],
573
+ 'city' => $shipping_address['locality'],
574
+ 'state' => $shipping_address['region'],
575
+ 'postcode' => $shipping_address['postalCode'],
576
+ ],
577
+ ];
578
 
579
+ WC()->session->set( 'wc_braintree_paypal_cart_customer_details', $details );
580
  }
581
 
582
 
583
  /**
584
+ * Determines if the current view is at Checkout, confirming the cart PayPal purchase.
585
  *
586
+ * @since 2.3.0
587
+ *
588
+ * @return bool
589
  */
590
+ public function is_checkout_confirmation() {
591
 
592
+ return $this->get_gateway()->get_payment_form_instance()->is_checkout_confirmation();
 
593
  }
594
 
595
 
596
  /**
597
+ * Gets the cart nonce from the session, if any.
598
  *
599
+ * @since 2.3.0
 
600
  *
601
+ * @return string
 
602
  */
603
+ public function get_cart_nonce() {
 
 
 
 
 
 
 
 
 
 
604
 
605
+ return $this->get_gateway()->get_payment_form_instance()->get_cart_nonce();
606
  }
607
 
608
 
609
  /**
610
+ * Clears any PayPal cart session data.
611
  *
612
+ * @since 2.3.0
 
613
  */
614
+ public function clear_session_data() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
615
 
616
+ unset(
617
+ WC()->session->wc_braintree_paypal_cart_nonce,
618
+ WC()->session->wc_braintree_paypal_cart_customer_details
619
+ );
620
  }
621
 
622
 
623
  /**
624
+ * Returns the gateway instance.
625
+ *
626
+ * @since 2.3.0
627
  *
 
628
  * @return \WC_Gateway_Braintree_PayPal
629
  */
630
  protected function get_gateway() {
 
631
  return $this->gateway;
632
  }
633
 
634
 
635
+ }
includes/PayPal/Buttons/Cart.php ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WooCommerce Braintree Gateway
4
+ *
5
+ * This source file is subject to the GNU General Public License v3.0
6
+ * that is bundled with this package in the file license.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.html
9
+ * If you did not receive a copy of the license and are unable to
10
+ * obtain it through the world-wide-web, please send an email
11
+ * to license@woocommerce.com so we can send you a copy immediately.
12
+ *
13
+ * DISCLAIMER
14
+ *
15
+ * Do not edit or add to this file if you wish to upgrade WooCommerce Braintree Gateway to newer
16
+ * versions in the future. If you wish to customize WooCommerce Braintree Gateway for your
17
+ * needs please refer to http://docs.woocommerce.com/document/braintree/
18
+ *
19
+ * @package WC-Braintree/Buttons
20
+ * @author WooCommerce
21
+ * @copyright Copyright: (c) 2016-2019, Automattic, Inc.
22
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
23
+ */
24
+
25
+ namespace WC_Braintree\PayPal\Buttons;
26
+
27
+ use WC_Braintree\Plugin_Framework as WC_Braintree_Framework;
28
+
29
+ defined( 'ABSPATH' ) or exit;
30
+
31
+ /**
32
+ * Cart page button class.
33
+ *
34
+ * @since 2.3.0
35
+ */
36
+ class Cart extends Abstract_Button {
37
+
38
+
39
+ /**
40
+ * Checks if this button should be enabled or not.
41
+ *
42
+ * @since 2.3.0
43
+ *
44
+ * @return bool
45
+ */
46
+ protected function is_enabled() {
47
+
48
+ return $this->get_gateway()->cart_checkout_enabled();
49
+ }
50
+
51
+
52
+ /**
53
+ * Adds any actions and filters needed for the button.
54
+ *
55
+ * @since 2.3.0
56
+ */
57
+ protected function add_hooks() {
58
+
59
+ parent::add_hooks();
60
+
61
+ // add the PayPal button below "Proceed to Checkout"
62
+ add_action( 'woocommerce_proceed_to_checkout', [ $this, 'render' ], 50 );
63
+ }
64
+
65
+
66
+ /**
67
+ * Validates the WC API request.
68
+ *
69
+ * @since 2.3.0
70
+ *
71
+ * @return bool
72
+ */
73
+ protected function is_wc_api_request_valid() {
74
+
75
+ return (bool) wp_verify_nonce( WC_Braintree_Framework\SV_WC_Helper::get_post( 'wp_nonce' ), 'wc_' . $this->get_gateway()->get_id() . '_cart_set_payment_method' );
76
+ }
77
+
78
+
79
+ /**
80
+ * Renders the PayPal button JS.
81
+ *
82
+ * @since 2.3.0
83
+ *
84
+ * @return array
85
+ */
86
+ protected function get_form_handler_params() {
87
+
88
+ $params = parent::get_form_handler_params();
89
+
90
+ $params['button_styles']['label'] = 'checkout';
91
+
92
+ /**
93
+ * Filters the PayPal cart button style parameters.
94
+ *
95
+ * See https://developer.paypal.com/docs/integration/direct/express-checkout/integration-jsv4/customize-button/
96
+ *
97
+ * @since 2.1.0
98
+ *
99
+ * @param array $styles style parameters
100
+ */
101
+ $params['button_styles'] = (array) apply_filters( 'wc_' . $this->get_gateway()->get_id() . '_cart_button_styles', $params['button_styles'] );
102
+
103
+ return $params;
104
+ }
105
+
106
+
107
+ /**
108
+ * Gets the total amount the button should charge.
109
+ *
110
+ * @since 2.3.0
111
+ *
112
+ * @return float
113
+ */
114
+ protected function get_button_total() {
115
+
116
+ return WC()->cart->total;
117
+ }
118
+
119
+
120
+ /**
121
+ * Gets the JS handler class name.
122
+ *
123
+ * @since 2.3.0
124
+ *
125
+ * @return string
126
+ */
127
+ protected function get_js_handler_name() {
128
+ return 'WC_Braintree_PayPal_Cart_Handler';
129
+ }
130
+
131
+
132
+ /**
133
+ * Gets the JS handler object name.
134
+ *
135
+ * @since 2.3.0
136
+ *
137
+ * @return string
138
+ */
139
+ protected function get_js_handler_object_name() {
140
+ return 'wc_braintree_paypal_cart_handler';
141
+ }
142
+
143
+
144
+ }
includes/PayPal/Buttons/Product.php ADDED
@@ -0,0 +1,338 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WooCommerce Braintree Gateway
4
+ *
5
+ * This source file is subject to the GNU General Public License v3.0
6
+ * that is bundled with this package in the file license.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.html
9
+ * If you did not receive a copy of the license and are unable to
10
+ * obtain it through the world-wide-web, please send an email
11
+ * to license@woocommerce.com so we can send you a copy immediately.
12
+ *
13
+ * DISCLAIMER
14
+ *
15
+ * Do not edit or add to this file if you wish to upgrade WooCommerce Braintree Gateway to newer
16
+ * versions in the future. If you wish to customize WooCommerce Braintree Gateway for your
17
+ * needs please refer to http://docs.woocommerce.com/document/braintree/
18
+ *
19
+ * @package WC-Braintree/Buttons
20
+ * @author WooCommerce
21
+ * @copyright Copyright: (c) 2016-2019, Automattic, Inc.
22
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
23
+ */
24
+
25
+ namespace WC_Braintree\PayPal\Buttons;
26
+
27
+ use WC_Braintree\Plugin_Framework as WC_Braintree_Framework;
28
+
29
+ defined( 'ABSPATH' ) or exit;
30
+
31
+ /**
32
+ * Product page button class.
33
+ *
34
+ * @since 2.3.0
35
+ */
36
+ class Product extends Abstract_Button {
37
+
38
+
39
+ /** @var \WC_Product|null|false the product object if on a product page or false if not on a product page */
40
+ protected $product;
41
+
42
+
43
+ /**
44
+ * Checks if this button should be enabled or not.
45
+ *
46
+ * @since 2.3.0
47
+ *
48
+ * @return bool
49
+ */
50
+ protected function is_enabled() {
51
+
52
+ return (bool) $this->get_gateway()->product_page_buy_now_enabled();
53
+ }
54
+
55
+
56
+ /**
57
+ * Adds necessary actions and filters for this button.
58
+ *
59
+ * @since 2.3.0
60
+ */
61
+ protected function add_hooks() {
62
+
63
+ parent::add_hooks();
64
+
65
+ add_action( 'wp', function() { $this->init_product(); } );
66
+
67
+ add_action( 'woocommerce_api_' . strtolower( get_class( $this->get_gateway() ) ) . '_product_button_checkout', [ $this, 'handle_wc_api' ] );
68
+
69
+ if ( $this->should_validate_product_data() ) {
70
+ add_action( 'woocommerce_api_' . strtolower( get_class( $this->get_gateway() ) ) . '_validate_product_data', [ $this, 'validate_product_data' ] );
71
+ }
72
+ }
73
+
74
+
75
+ /**
76
+ * Initializes the product page buy now button.
77
+ *
78
+ * @internal
79
+ *
80
+ * @since 2.3.0
81
+ */
82
+ public function init_product() {
83
+
84
+ if ( ! is_product() || ! $this->get_product() ) {
85
+ return;
86
+ }
87
+
88
+ add_action( 'woocommerce_before_add_to_cart_button', [ $this, 'render' ] );
89
+ }
90
+
91
+
92
+ /**
93
+ * Gets the form handler params.
94
+ *
95
+ * @since 2.3.0
96
+ */
97
+ protected function get_form_handler_params() {
98
+
99
+ $params = parent::get_form_handler_params();
100
+
101
+ $params['button_styles']['label'] = 'buynow';
102
+ $params['button_styles']['layout'] = 'horizontal';
103
+
104
+ /**
105
+ * Filters the PayPal product button style parameters.
106
+ *
107
+ * See https://developer.paypal.com/docs/integration/direct/express-checkout/integration-jsv4/customize-button/
108
+ *
109
+ * @since 2.3.0
110
+ *
111
+ * @param array $styles style parameters
112
+ */
113
+ $params['button_styles'] = (array) apply_filters( 'wc_' . $this->get_gateway()->get_id() . '_product_button_styles', $params['button_styles'] );
114
+
115
+ return $params;
116
+ }
117
+
118
+
119
+ /**
120
+ * Validates a WC API request.
121
+ *
122
+ * @since 2.3.0
123
+ *
124
+ * @return bool
125
+ */
126
+ protected function is_wc_api_request_valid() {
127
+
128
+ return (bool) wp_verify_nonce( WC_Braintree_Framework\SV_WC_Helper::get_post( 'wp_nonce' ), 'wc_' . $this->get_gateway()->get_id() . '_product_button_checkout' );
129
+ }
130
+
131
+
132
+ /**
133
+ * Processes a WC API request that contains data from the button JS response.
134
+ *
135
+ * @since 2.3.0
136
+ */
137
+ protected function process_wc_api_request() {
138
+
139
+ $product_id = (int) WC_Braintree_Framework\SV_WC_Helper::get_post( 'product_id' );
140
+ $product = wc_get_product( $product_id );
141
+
142
+ if ( ! $product instanceof \WC_Product ) {
143
+ wp_send_json_error( 'Invalid Product Data' );
144
+ }
145
+
146
+ $serialized = WC_Braintree_Framework\SV_WC_Helper::get_post( 'cart_form' );
147
+ $cart_data = [];
148
+
149
+ if ( ! empty( $serialized ) ) {
150
+ parse_str( $serialized, $cart_data );
151
+ }
152
+
153
+ $quantity = isset( $cart_data['quantity'] ) ? (int) $cart_data['quantity'] : 1;
154
+ $variation_id = isset( $cart_data['variation_id'] ) ? (int) $cart_data['variation_id'] : 0;
155
+
156
+ do_action( 'wc_' . $this->get_gateway()->get_id() . '_before_product_button_add_to_cart', $product_id, $quantity, $variation_id, $cart_data );
157
+
158
+ try {
159
+
160
+ WC()->cart->empty_cart();
161
+ WC()->cart->add_to_cart( $product->get_id(), max( $quantity, 1 ), $variation_id );
162
+
163
+ parent::process_wc_api_request();
164
+
165
+ // generic Exception to catch any exceptions that may be thrown by third-party code during add_to_cart()
166
+ } catch ( \Exception $e) {
167
+
168
+ $this->get_gateway()->get_plugin()->log( 'Error while processing button callback: ' . $e->getMessage() );
169
+
170
+ wp_send_json_error( 'An error occurred while processing the PayPal button callback.' );
171
+ }
172
+ }
173
+
174
+
175
+ /**
176
+ * Determines if product data should be validated before displaying a buy button.
177
+ *
178
+ * @since 2.3.0
179
+ *
180
+ * @return bool
181
+ */
182
+ public function should_validate_product_data() {
183
+
184
+ /**
185
+ * Filters whether the product data should be validated for this product button to be shown.
186
+ *
187
+ * @since 2.3.0
188
+ *
189
+ * @param bool $should_validate
190
+ * @param Product $product product button instance
191
+ */
192
+ return (bool) apply_filters( 'wc_' . $this->get_gateway()->get_id() . '_product_button_should_validate_product_data', true, $this );
193
+ }
194
+
195
+
196
+ /**
197
+ * Validates product add-ons via AJAX to show/hide the PayPal button appropriately.
198
+ *
199
+ * @since 2.3.0
200
+ */
201
+ public function validate_product_data() {
202
+
203
+ if ( ! wp_verify_nonce( WC_Braintree_Framework\SV_WC_Helper::get_post( 'wp_nonce' ), 'wc_' . $this->get_gateway()->get_id() . '_validate_product_data' ) ) {
204
+ return;
205
+ }
206
+
207
+ /**
208
+ * Validates the product data for displaying the product button.
209
+ *
210
+ * @since 2.3.0
211
+ *
212
+ * @param bool $is_valid
213
+ * @param Product $product product button instance
214
+ */
215
+ $is_valid = (bool) apply_filters( 'wc_' . $this->get_gateway()->get_id() . '_product_button_validate_product_data', true, $this );
216
+
217
+ wp_send_json_success( [ 'is_valid' => $is_valid ] );
218
+ }
219
+
220
+
221
+ /**
222
+ * Gets any additional JS handler params needed for this button.
223
+ *
224
+ * @since 2.3.0
225
+ *
226
+ * @return array
227
+ */
228
+ protected function get_additional_js_handler_params() {
229
+
230
+ return [
231
+ 'is_product_page' => is_product(),
232
+ 'product_checkout_url' => add_query_arg( 'wc-api', strtolower( get_class( $this->get_gateway() ) . '_product_button_checkout' ), home_url() ),
233
+ 'product_checkout_nonce' => wp_create_nonce( 'wc_' . $this->get_gateway()->get_id() . '_product_button_checkout' ),
234
+ 'validate_product_url' => add_query_arg( 'wc-api', strtolower( get_class( $this->get_gateway() ) . '_validate_product_data' ), home_url() ),
235
+ 'validate_product_nonce' => wp_create_nonce( 'wc_' . $this->get_gateway()->get_id() . '_validate_product_data' ),
236
+ 'should_validate_product_data' => $this->should_validate_product_data(),
237
+ ];
238
+ }
239
+
240
+
241
+ /**
242
+ * Gets additional button markup params.
243
+ *
244
+ * @since 2.3.0
245
+ *
246
+ * @return array
247
+ */
248
+ protected function get_additional_button_params() {
249
+
250
+ $params = [];
251
+
252
+ if ( $this->get_product() ) {
253
+ $params['product_id'] = $this->get_product()->get_id();
254
+ }
255
+
256
+ return $params;
257
+ }
258
+
259
+
260
+ /**
261
+ * Gets the product total.
262
+ *
263
+ * @since 2.3.0
264
+ *
265
+ * @return float
266
+ */
267
+ protected function get_button_total() {
268
+
269
+ return $this->get_product() ? $this->get_product()->get_price() : 0.0;
270
+ }
271
+
272
+
273
+ /**
274
+ * Gets the JS handler class name.
275
+ *
276
+ * @since 2.3.0
277
+ *
278
+ * @return string
279
+ */
280
+ protected function get_js_handler_object_name() {
281
+ return 'wc_braintree_paypal_product_button_handler';
282
+ }
283
+
284
+
285
+ /**
286
+ * Gets the JS handler class name.
287
+ *
288
+ * @since 2.3.0
289
+ *
290
+ * @return string
291
+ */
292
+ protected function get_js_handler_name() {
293
+ return 'WC_Braintree_PayPal_Product_Button_Handler';
294
+ }
295
+
296
+
297
+ /**
298
+ * Returns whether the button is for single-use transaction or not.
299
+ *
300
+ * @since 2.3.0
301
+ *
302
+ * @return bool
303
+ */
304
+ protected function is_single_use() {
305
+
306
+ $single_use = true;
307
+
308
+ if ( $this->get_gateway()->get_plugin()->is_pre_orders_active() && \WC_Pre_Orders_Product::product_is_charged_upon_release( $this->get_product() ) ) {
309
+ $single_use = false;
310
+ }
311
+
312
+ if ( $this->get_gateway()->get_plugin()->is_subscriptions_active() && \WC_Subscriptions_Product::is_subscription( $this->get_product() ) ) {
313
+ $single_use = false;
314
+ }
315
+
316
+ return $single_use;
317
+ }
318
+
319
+
320
+ /**
321
+ * Gets the product page product object, or false if not on a product page.
322
+ *
323
+ * @since 2.3.0
324
+ *
325
+ * @return \WC_Product|false
326
+ */
327
+ protected function get_product() {
328
+
329
+ if ( null === $this->product ) {
330
+
331
+ $product = wc_get_product( get_the_ID() );
332
+ $this->product = $product instanceof \WC_Product ? $product : false;
333
+ }
334
+
335
+ return $this->product;
336
+ }
337
+
338
+ }
includes/api/requests/class-wc-braintree-api-transaction-request.php CHANGED
@@ -206,7 +206,7 @@ class WC_Braintree_API_Transaction_Request extends WC_Braintree_API_Request {
206
  'firstName' => $this->get_order_prop( 'billing_first_name' ),
207
  'lastName' => $this->get_order_prop( 'billing_last_name' ),
208
  'company' => $this->get_order_prop( 'billing_company' ),
209
- 'phone' => WC_Braintree_Framework\SV_WC_Helper::str_truncate( preg_replace( '/[^\d-().]/', '', $this->get_order_prop( 'billing_phone' ) ), 14, '' ),
210
  'email' => $this->get_order_prop( 'billing_email' ),
211
  );
212
  }
206
  'firstName' => $this->get_order_prop( 'billing_first_name' ),
207
  'lastName' => $this->get_order_prop( 'billing_last_name' ),
208
  'company' => $this->get_order_prop( 'billing_company' ),
209
+ 'phone' => WC_Braintree_Framework\SV_WC_Helper::str_truncate( preg_replace( '/[^\d\-().]/', '', $this->get_order_prop( 'billing_phone' ) ), 14, '' ),
210
  'email' => $this->get_order_prop( 'billing_email' ),
211
  );
212
  }
includes/class-wc-gateway-braintree-paypal.php CHANGED
@@ -22,6 +22,7 @@
22
  * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
23
  */
24
 
 
25
  use WC_Braintree\Plugin_Framework as WC_Braintree_Framework;
26
 
27
  defined( 'ABSPATH' ) or exit;
@@ -41,6 +42,9 @@ class WC_Gateway_Braintree_PayPal extends WC_Gateway_Braintree {
41
  /** @var bool whether cart checkout is enabled */
42
  protected $enable_cart_checkout;
43
 
 
 
 
44
  /** @var bool whether paypal credit is enabled */
45
  protected $enable_paypal_credit;
46
 
@@ -53,6 +57,9 @@ class WC_Gateway_Braintree_PayPal extends WC_Gateway_Braintree {
53
  /** @var string button shape */
54
  protected $button_shape;
55
 
 
 
 
56
 
57
  /**
58
  * Initialize the gateway
@@ -89,6 +96,8 @@ class WC_Gateway_Braintree_PayPal extends WC_Gateway_Braintree {
89
  )
90
  );
91
 
 
 
92
  // tweak some frontend text so it matches PayPal
93
  add_filter( 'gettext', array( $this, 'tweak_payment_methods_text' ), 10, 3 );
94
 
@@ -107,6 +116,27 @@ class WC_Gateway_Braintree_PayPal extends WC_Gateway_Braintree {
107
  }
108
 
109
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  /**
111
  * Enqueues the PayPal JS scripts
112
  *
@@ -133,7 +163,10 @@ class WC_Gateway_Braintree_PayPal extends WC_Gateway_Braintree {
133
  */
134
  public function is_payment_form_page() {
135
 
136
- return parent::is_payment_form_page() || is_cart();
 
 
 
137
  }
138
 
139
 
@@ -280,13 +313,20 @@ class WC_Gateway_Braintree_PayPal extends WC_Gateway_Braintree {
280
  'disabled' => ! $this->is_paypal_credit_supported(),
281
  'label' => __( 'Show the PayPal credit button beneath the standard PayPal button', 'woocommerce-gateway-paypal-powered-by-braintree' ),
282
  'description' => ! $this->is_paypal_credit_supported() ? __( 'Currently disabled because PayPal Credit is only available for US merchants', 'woocommerce-gateway-paypal-powered-by-braintree' ) : '',
283
- 'default' => 'no',
284
  );
285
 
286
  $form_fields['button_preview'] = [
287
  'type' => 'button_preview',
288
  ];
289
 
 
 
 
 
 
 
 
290
  $form_fields['enable_cart_checkout'] = array(
291
  'title' => __( 'Enable Cart Checkout', 'woocommerce-gateway-paypal-powered-by-braintree' ),
292
  'type' => 'checkbox',
@@ -592,6 +632,19 @@ class WC_Gateway_Braintree_PayPal extends WC_Gateway_Braintree {
592
  /** Getters ***************************************************************/
593
 
594
 
 
 
 
 
 
 
 
 
 
 
 
 
 
595
  /**
596
  * Get the default payment method title, which is configurable within the
597
  * admin and displayed on checkout
@@ -692,6 +745,27 @@ class WC_Gateway_Braintree_PayPal extends WC_Gateway_Braintree {
692
  }
693
 
694
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
695
  /**
696
  * Determines if PayPal Credit is enabled.
697
  *
22
  * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
23
  */
24
 
25
+ use WC_Braintree\PayPal\Buttons;
26
  use WC_Braintree\Plugin_Framework as WC_Braintree_Framework;
27
 
28
  defined( 'ABSPATH' ) or exit;
42
  /** @var bool whether cart checkout is enabled */
43
  protected $enable_cart_checkout;
44
 
45
+ /** @var bool whether buy now buttons should be added to product pages */
46
+ protected $enable_product_buy_now;
47
+
48
  /** @var bool whether paypal credit is enabled */
49
  protected $enable_paypal_credit;
50
 
57
  /** @var string button shape */
58
  protected $button_shape;
59
 
60
+ /** @var Buttons\Abstract_Button[] PayPal button handler instances */
61
+ protected $button_handlers = [];
62
+
63
 
64
  /**
65
  * Initialize the gateway
96
  )
97
  );
98
 
99
+ $this->init_paypal_buttons();
100
+
101
  // tweak some frontend text so it matches PayPal
102
  add_filter( 'gettext', array( $this, 'tweak_payment_methods_text' ), 10, 3 );
103
 
116
  }
117
 
118
 
119
+ /**
120
+ * Initializes any PayPal buttons that may be required on the current page.
121
+ *
122
+ * @since 2.3.0
123
+ */
124
+ protected function init_paypal_buttons() {
125
+
126
+ if ( ! $this->is_available() ) {
127
+ return;
128
+ }
129
+
130
+ if ( $this->product_page_buy_now_enabled() ) {
131
+ $this->button_handlers['product'] = new Buttons\Product( $this );
132
+ }
133
+
134
+ if ( $this->cart_checkout_enabled() ) {
135
+ $this->button_handlers['cart'] = new Buttons\Cart( $this );
136
+ }
137
+ }
138
+
139
+
140
  /**
141
  * Enqueues the PayPal JS scripts
142
  *
163
  */
164
  public function is_payment_form_page() {
165
 
166
+ $product = wc_get_product( get_the_ID() );
167
+ $is_product_page = $product instanceof \WC_Product;
168
+
169
+ return parent::is_payment_form_page() || is_cart() || ( $is_product_page && $this->product_page_buy_now_enabled() );
170
  }
171
 
172
 
313
  'disabled' => ! $this->is_paypal_credit_supported(),
314
  'label' => __( 'Show the PayPal credit button beneath the standard PayPal button', 'woocommerce-gateway-paypal-powered-by-braintree' ),
315
  'description' => ! $this->is_paypal_credit_supported() ? __( 'Currently disabled because PayPal Credit is only available for US merchants', 'woocommerce-gateway-paypal-powered-by-braintree' ) : '',
316
+ 'default' => 'yes',
317
  );
318
 
319
  $form_fields['button_preview'] = [
320
  'type' => 'button_preview',
321
  ];
322
 
323
+ $form_fields['enable_product_buy_now'] = [
324
+ 'title' => __( 'Buy Now on Product Pages', 'woocommerce-gateway-paypal-powered-by-braintree' ),
325
+ 'label' => __( 'Add the PayPal Buy Now button to product pages.', 'woocommerce-gateway-paypal-powered-by-braintree' ),
326
+ 'type' => 'checkbox',
327
+ 'default' => 'yes',
328
+ ];
329
+
330
  $form_fields['enable_cart_checkout'] = array(
331
  'title' => __( 'Enable Cart Checkout', 'woocommerce-gateway-paypal-powered-by-braintree' ),
332
  'type' => 'checkbox',
632
  /** Getters ***************************************************************/
633
 
634
 
635
+ /**
636
+ * Gets the array of instantiated button handlers.
637
+ *
638
+ * @since 2.3.0
639
+ *
640
+ * @return Buttons\Abstract_Button[]
641
+ */
642
+ public function get_button_handlers() {
643
+
644
+ return $this->button_handlers;
645
+ }
646
+
647
+
648
  /**
649
  * Get the default payment method title, which is configurable within the
650
  * admin and displayed on checkout
745
  }
746
 
747
 
748
+ /**
749
+ * Determines if buy now buttons should be added to the product pages.
750
+ *
751
+ * @since 2.3.0
752
+ *
753
+ * @return bool
754
+ */
755
+ public function product_page_buy_now_enabled() {
756
+
757
+ /**
758
+ * Filters whether product page buy now buttons are enabled.
759
+ *
760
+ * @since 2.3.0
761
+ *
762
+ * @param bool $enabled whether product buy now buttons are enabled in the settings
763
+ * @param \WC_Gateway_Braintree_PayPal $gateway gateway object
764
+ */
765
+ return (bool) apply_filters( 'wc_braintree_paypal_product_buy_now_enabled', 'no' !== $this->enable_product_buy_now, $this );
766
+ }
767
+
768
+
769
  /**
770
  * Determines if PayPal Credit is enabled.
771
  *
includes/class-wc-gateway-braintree.php CHANGED
@@ -611,6 +611,9 @@ class WC_Gateway_Braintree extends WC_Braintree_Framework\SV_WC_Payment_Gateway_
611
  ?>
612
  <tr valign="top">
613
  <th scope="row" class="titledesc">
 
 
 
614
  <select id="wc_braintree_merchant_account_id_currency" class="wc-enhanced-select">
615
  <?php foreach ( get_woocommerce_currencies() as $code => $name ) : ?>
616
  <option <?php selected( $code, $base_currency ); ?> value="<?php echo esc_attr( $code ); ?>">
@@ -618,9 +621,7 @@ class WC_Gateway_Braintree extends WC_Braintree_Framework\SV_WC_Payment_Gateway_
618
  </option>
619
  <?php endforeach; ?>
620
  </select>
621
- </th>
622
- <td class="forminp">
623
- <a href="#" class="button js-add-merchant-account-id"><?php echo esc_html( $button_text ); ?></a>
624
  </td>
625
  </tr>
626
  <?php
611
  ?>
612
  <tr valign="top">
613
  <th scope="row" class="titledesc">
614
+ <?php esc_html_e( 'Add merchant account ID', 'woocommerce-gateway-paypal-powered-by-braintree' ); ?>
615
+ </th>
616
+ <td class="forminp">
617
  <select id="wc_braintree_merchant_account_id_currency" class="wc-enhanced-select">
618
  <?php foreach ( get_woocommerce_currencies() as $code => $name ) : ?>
619
  <option <?php selected( $code, $base_currency ); ?> value="<?php echo esc_attr( $code ); ?>">
621
  </option>
622
  <?php endforeach; ?>
623
  </select>
624
+ <p><a href="#" class="button js-add-merchant-account-id"><?php echo esc_html( $button_text ); ?></a></p>
 
 
625
  </td>
626
  </tr>
627
  <?php
includes/payment-forms/class-wc-braintree-paypal-payment-form.php CHANGED
@@ -22,6 +22,7 @@
22
  * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
23
  */
24
 
 
25
  use WC_Braintree\Plugin_Framework as WC_Braintree_Framework;
26
 
27
  defined( 'ABSPATH' ) or exit;
@@ -82,13 +83,39 @@ class WC_Braintree_PayPal_Payment_Form extends WC_Braintree_Payment_Form {
82
  'must_login_message' => __( 'Please click the "PayPal" button below to log into your PayPal account before placing your order.', 'woocommerce-gateway-paypal-powered-by-braintree' ),
83
  'must_login_add_method_message' => __( 'Please click the "PayPal" button below to log into your PayPal account before adding your payment method.', 'woocommerce-gateway-paypal-powered-by-braintree' ),
84
  'button_styles' => wp_parse_args( $button_styles, $default_button_styles ), // ensure all expected parameters are present after filtering to avoid JS errors
85
- 'cart_payment_nonce' => ( $cart_handler = $this->get_gateway()->get_plugin()->get_paypal_cart_instance() ) ? $cart_handler->get_cart_nonce() : '',
86
  ] );
87
 
88
  return $params;
89
  }
90
 
91
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  /**
93
  * Renders the payment form description.
94
  *
@@ -98,13 +125,9 @@ class WC_Braintree_PayPal_Payment_Form extends WC_Braintree_Payment_Form {
98
  */
99
  public function render_payment_form_description() {
100
 
101
- $cart_handler = $this->get_gateway()->get_plugin()->get_paypal_cart_instance();
102
-
103
- if ( $cart_handler && $cart_handler->is_checkout_confirmation() ) {
104
- return;
105
  }
106
-
107
- parent::render_payment_form_description();
108
  }
109
 
110
 
@@ -117,13 +140,9 @@ class WC_Braintree_PayPal_Payment_Form extends WC_Braintree_Payment_Form {
117
  */
118
  public function render_saved_payment_methods() {
119
 
120
- $cart_handler = $this->get_gateway()->get_plugin()->get_paypal_cart_instance();
121
-
122
- if ( $cart_handler && $cart_handler->is_checkout_confirmation() ) {
123
- return;
124
  }
125
-
126
- parent::render_saved_payment_methods();
127
  }
128
 
129
 
22
  * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
23
  */
24
 
25
+ use WC_Braintree\PayPal\Buttons\Abstract_Button;
26
  use WC_Braintree\Plugin_Framework as WC_Braintree_Framework;
27
 
28
  defined( 'ABSPATH' ) or exit;
83
  'must_login_message' => __( 'Please click the "PayPal" button below to log into your PayPal account before placing your order.', 'woocommerce-gateway-paypal-powered-by-braintree' ),
84
  'must_login_add_method_message' => __( 'Please click the "PayPal" button below to log into your PayPal account before adding your payment method.', 'woocommerce-gateway-paypal-powered-by-braintree' ),
85
  'button_styles' => wp_parse_args( $button_styles, $default_button_styles ), // ensure all expected parameters are present after filtering to avoid JS errors
86
+ 'cart_payment_nonce' => $this->get_cart_nonce(),
87
  ] );
88
 
89
  return $params;
90
  }
91
 
92
 
93
+ /**
94
+ * Gets the cart nonce from the session, if any.
95
+ *
96
+ * @since 2.3.0
97
+ *
98
+ * @return string
99
+ */
100
+ public function get_cart_nonce() {
101
+
102
+ return WC()->session->get( 'wc_braintree_paypal_cart_nonce', '' );
103
+ }
104
+
105
+
106
+ /**
107
+ * Determines if the current view is at Checkout, confirming the cart PayPal purchase.
108
+ *
109
+ * @since 2.3.0
110
+ *
111
+ * @return bool
112
+ */
113
+ public function is_checkout_confirmation() {
114
+
115
+ return is_checkout() && $this->get_gateway()->is_available() && $this->get_cart_nonce();
116
+ }
117
+
118
+
119
  /**
120
  * Renders the payment form description.
121
  *
125
  */
126
  public function render_payment_form_description() {
127
 
128
+ if ( ! $this->is_checkout_confirmation() ) {
129
+ parent::render_payment_form_description();
 
 
130
  }
 
 
131
  }
132
 
133
 
140
  */
141
  public function render_saved_payment_methods() {
142
 
143
+ if ( ! $this->is_checkout_confirmation() ) {
144
+ parent::render_saved_payment_methods();
 
 
145
  }
 
 
146
  }
147
 
148
 
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: ecommerce, e-commerce, commerce, woothemes, wordpress ecommerce, store, sa
4
  Requires at least: 4.4
5
  Tested up to: 5.2.3
6
  Requires PHP: 5.4
7
- Stable tag: 2.2.7
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
@@ -124,6 +124,12 @@ New feature requests and bugs reports can be made in the plugin forum.
124
 
125
  == Changelog ==
126
 
 
 
 
 
 
 
127
  = 2019.09.12 - version 2.2.7 =
128
  * Fix - Fix JavaScript error blocking payments with 3D Secure from the Pay Order page
129
 
4
  Requires at least: 4.4
5
  Tested up to: 5.2.3
6
  Requires PHP: 5.4
7
+ Stable tag: 2.3.0
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
124
 
125
  == Changelog ==
126
 
127
+ = 2019.10.03 - version 2.3.0 =
128
+ * Feature - PayPal buy-now buttons can now be added to product pages
129
+ * Tweak - Enable PayPal Credit by default on new installs
130
+ * Fix - Fix a styling issue with the merchant account ID field in settings
131
+ * Fix - Fix a bug with a regular expression being used in PHP 7.3+
132
+
133
  = 2019.09.12 - version 2.2.7 =
134
  * Fix - Fix JavaScript error blocking payments with 3D Secure from the Pay Order page
135
 
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInitd968a3ef969d8cb7fb8dfff28d337837::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit925e102bad64dd22618e8624d9f99af4::getLoader();
vendor/composer/LICENSE CHANGED
@@ -1,4 +1,3 @@
1
-
2
  Copyright (c) Nils Adermann, Jordi Boggiano
3
 
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -18,4 +17,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
  THE SOFTWARE.
21
-
 
1
  Copyright (c) Nils Adermann, Jordi Boggiano
2
 
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
17
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
  THE SOFTWARE.
 
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInitd968a3ef969d8cb7fb8dfff28d337837
6
  {
7
  private static $loader;
8
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInitd968a3ef969d8cb7fb8dfff28d337837
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInitd968a3ef969d8cb7fb8dfff28d337837', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInitd968a3ef969d8cb7fb8dfff28d337837', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
- call_user_func(\Composer\Autoload\ComposerStaticInitd968a3ef969d8cb7fb8dfff28d337837::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit925e102bad64dd22618e8624d9f99af4
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit925e102bad64dd22618e8624d9f99af4', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit925e102bad64dd22618e8624d9f99af4', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
+ call_user_func(\Composer\Autoload\ComposerStaticInit925e102bad64dd22618e8624d9f99af4::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInitd968a3ef969d8cb7fb8dfff28d337837
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
  'B' =>
@@ -33,9 +33,9 @@ class ComposerStaticInitd968a3ef969d8cb7fb8dfff28d337837
33
  public static function getInitializer(ClassLoader $loader)
34
  {
35
  return \Closure::bind(function () use ($loader) {
36
- $loader->prefixLengthsPsr4 = ComposerStaticInitd968a3ef969d8cb7fb8dfff28d337837::$prefixLengthsPsr4;
37
- $loader->prefixDirsPsr4 = ComposerStaticInitd968a3ef969d8cb7fb8dfff28d337837::$prefixDirsPsr4;
38
- $loader->prefixesPsr0 = ComposerStaticInitd968a3ef969d8cb7fb8dfff28d337837::$prefixesPsr0;
39
 
40
  }, null, ClassLoader::class);
41
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit925e102bad64dd22618e8624d9f99af4
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
  'B' =>
33
  public static function getInitializer(ClassLoader $loader)
34
  {
35
  return \Closure::bind(function () use ($loader) {
36
+ $loader->prefixLengthsPsr4 = ComposerStaticInit925e102bad64dd22618e8624d9f99af4::$prefixLengthsPsr4;
37
+ $loader->prefixDirsPsr4 = ComposerStaticInit925e102bad64dd22618e8624d9f99af4::$prefixDirsPsr4;
38
+ $loader->prefixesPsr0 = ComposerStaticInit925e102bad64dd22618e8624d9f99af4::$prefixesPsr0;
39
 
40
  }, null, ClassLoader::class);
41
  }
woocommerce-gateway-paypal-powered-by-braintree.php CHANGED
@@ -5,7 +5,7 @@
5
  * Description: Receive credit card or PayPal 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: WooCommerce
7
  * Author URI: http://woocommerce.com/
8
- * Version: 2.2.7
9
  * Text Domain: woocommerce-gateway-paypal-powered-by-braintree
10
  * Domain Path: /i18n/languages/
11
  *
@@ -165,6 +165,11 @@ class WC_PayPal_Braintree_Loader {
165
 
166
  wp_die( $environment_warning );
167
  }
 
 
 
 
 
168
  }
169
 
170
  /**
5
  * Description: Receive credit card or PayPal 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: WooCommerce
7
  * Author URI: http://woocommerce.com/
8
+ * Version: 2.3.0
9
  * Text Domain: woocommerce-gateway-paypal-powered-by-braintree
10
  * Domain Path: /i18n/languages/
11
  *
165
 
166
  wp_die( $environment_warning );
167
  }
168
+
169
+ // enable the PayPal gateway on activation
170
+ $paypal_settings = get_option( 'woocommerce_braintree_paypal_settings', [] );
171
+ $paypal_settings['enabled'] = 'yes';
172
+ update_option( 'woocommerce_braintree_paypal_settings', $paypal_settings );
173
  }
174
 
175
  /**