public function __construct()
 {
     $this->id = 'paypalbraintree_paypal';
     parent::__construct();
     $this->icon = plugins_url('../assets/images/payments/PP_logo_h_100x26.png', __FILE__);
     $this->checkout_template = 'checkout/paypal-braintree-pay-with-paypal.php';
     $this->title = $this->get_option('title_paypal');
     $this->description = $this->get_option('description_paypal');
 }
 /**
  * WC_Gateway_Paypal_Braintree_Pay_With_Card constructor.
  */
 public function __construct()
 {
     $this->id = 'paypalbraintree_cards';
     parent::__construct();
     /**
      * Filter the accepted credit card icons for Paypal Powered by Braintree.
      *
      * @param string $card_icons_url disployed on the checkout page.
      */
     $this->icon = apply_filters('wc_gateway_paypal_braintree_card_icons_image_url', plugins_url('../assets/images/payments/payment-method-cards.png', __FILE__));
     $this->checkout_template = 'checkout/paypal-braintree-pay-with-card.php';
     $this->title = $this->get_option('title_cards');
     $this->description = $this->get_option('description_cards');
 }
 /**
  * process_payment
  *
  * Completes the initial payment on the subscription order
  *
  * Although PayPal Braintree supports subscription products (they call them plans),
  * they don't support the wide variety of intervals we do, nor multiple subscription
  * products in a single order.
  *
  * So, this extension does all the subscription work itself, storing a customer
  * in the vault on the first payment, and using those stored credentials for
  * renewal orders
  *
  * @param  int $order_id
  * @return mixed
  */
 public function process_payment($order_id)
 {
     // If the order contains no subscriptions, just let the parent process it
     if (!$this->order_contains_subscription($order_id)) {
         return parent::process_payment($order_id);
     }
     $order = new WC_Order($order_id);
     $this->log(__FUNCTION__, "Info: Beginning processing of payment for (subscription) order {$order_id} for the amount of {$order->order_total}");
     $this->log(__FUNCTION__, "Info: Merchant ID = {$this->merchant_id}");
     $paypal_braintree_nonce = self::get_posted_variable('paypalbraintree_nonce');
     if (empty($paypal_braintree_nonce)) {
         $this->log(__FUNCTION__, 'Error: The paypal_braintree_nonce was unexpectedly empty');
         wc_add_notice(__('Error: PayPal Powered by Braintree did not supply a payment nonce. Please try again later or use another means of payment.', 'woocommerce-gateway-paypal-braintree'), 'error');
         return false;
     }
     $user_id = $order->get_user_id();
     if (!is_user_logged_in()) {
         $this->log(__FUNCTION__, 'Error: No user logged in / being created for the initial subscription payment');
         wc_add_notice(__('Error: You must login or create an account before you can purchase a subscription.', 'woocommerce-gateway-paypal-braintree'), 'error');
         return false;
     }
     // Create the gateway instance up front
     require_once dirname(__FILE__) . '/../braintree_sdk/lib/Braintree.php';
     $gateway = new Braintree_Gateway(array('accessToken' => $this->merchant_access_token));
     // Check their user meta for a stored braintree customer id
     $braintree_customer_id = get_user_meta($user_id, '_wc_paypal_braintree_customer_id', true);
     if (empty($braintree_customer_id)) {
         $this->log(__FUNCTION__, 'Info: Did not find braintree customer id on user meta. Need to create customer');
         // Create a new customer id, passing the nonce so we can add the card to the vault
         // ref https://developers.braintreepayments.com/reference/request/customer/create/php
         $customer_args = array('firstName' => $order->billing_first_name, 'lastName' => $order->billing_last_name, 'company' => $order->billing_company, 'phone' => $order->billing_phone, 'email' => $order->billing_email, 'paymentMethodNonce' => $paypal_braintree_nonce);
         try {
             $result = $gateway->customer()->create($customer_args);
         } catch (Exception $e) {
             $this->log(__FUNCTION__, 'Error: Unable to create customer. Reason: ' . $e->getMessage());
             wc_add_notice(__('Error: PayPal Powered by Braintree was unable to create a customer record for you. Please try again later or use another means of payment.', 'woocommerce-gateway-paypal-braintree'), 'error');
             return false;
         }
         if (!$result->success) {
             $this->log(__FUNCTION__, "Error: Unable to create customer: {$result->message}");
             wc_add_notice(__('Error: PayPal Powered by Braintree was unable to create a customer record for you. Please try again later or use another means of payment.', 'woocommerce-gateway-paypal-braintree'), 'error');
             return false;
         }
         $braintree_customer_id = $result->customer->id;
         update_user_meta($user_id, '_wc_paypal_braintree_customer_id', $braintree_customer_id);
         $this->log(__FUNCTION__, "Info: Created customer successfully - braintree customer id = {$braintree_customer_id}");
         $payment_methods = $result->customer->paymentMethods;
         $payment_method_token = '';
         foreach ((array) $payment_methods as $payment_method) {
             if ($payment_method->default) {
                 $payment_method_token = $payment_method->token;
             }
         }
         $authentication = array('paymentMethodToken' => $payment_method_token);
     } else {
         // We found the braintree customer id in the customer's meta
         $this->log(__FUNCTION__, "Info: Found a braintree customer id in the users meta - customer id = {$braintree_customer_id}");
         $authentication = array('paymentMethodNonce' => $paypal_braintree_nonce);
     }
     $sale_args = $this->generate_sales_args($order, $braintree_customer_id);
     $sale_args = array_merge($sale_args, $authentication);
     $transaction_id = '';
     // Process trial periods and possible coupon discounts.
     if (isset($sale_args['amount']) && 0.0 === doubleval($sale_args['amount'])) {
         $user_id = $order->get_user_id();
         $this->log(__FUNCTION__, "Zero payment amount for trial or coupon. Order ID: {$order_id}, User ID:  {$user_id}");
         $customer = $gateway->customer()->find($braintree_customer_id);
         $payment_method_token = '';
         foreach ((array) $customer->paymentMethods as $payment_method) {
             if ($payment_method->default) {
                 $payment_method_token = $payment_method->token;
             }
         }
     } else {
         // charges more than zero should be sent away
         // We have a customer id now, so let's do the sale and store the payment method in the vault.
         $result = $gateway->transaction()->sale($sale_args);
         if (!$result->success) {
             $notice = sprintf(__('Error: PayPal Powered by Braintree was unable to complete the transaction. Please try again later or use another means of payment. Reason: %s', 'woocommerce-gateway-paypal-braintree'), $error_message);
             wc_add_notice($notice, 'error');
             $this->log(__FUNCTION__, "Error: Unable to complete transaction. Reason: {$result->message}");
             return false;
         }
         $transaction_id = $result->transaction->id;
         $this->log(__FUNCTION__, "Info: Successfully processed initial payment, transaction id = {$transaction_id}");
         $credit_card_meta = $result->transaction->creditCard;
         $payment_method_token = $credit_card_meta['token'];
         if (empty($payment_method_token)) {
             $this->log(__FUNCTION__, 'Info: Customer used the paypal subflow');
             $paypal_meta = $result->transaction->paypal;
             $payment_method_token = $paypal_meta['token'];
         } else {
             $this->log(__FUNCTION__, 'Info: Customer used the credit card subflow');
         }
         $braintree_customer_id = $result->transaction->customer['id'];
     }
     if (empty($payment_method_token)) {
         $this->log(__FUNCTION__, 'Warning: Initial payment succeeded, but no token was provided by the gateway for recurring payments.');
     }
     // Save the customer ID in each subscription for this order for later use during renewal
     if (empty($braintree_customer_id)) {
         $this->log(__FUNCTION__, 'Warning: Initial payment succeeded, but no braintree customer ID was provided by the gateway for recurring payments.');
     } else {
         $this->log(__FUNCTION__, "Info: Saving to subscription(s) recurring payment braintree customer ID {$braintree_customer_id}");
     }
     // Note: A single order may contain multiple subscriptions
     // Save the token in each subscription for this order for later use during renewal
     foreach (wcs_get_subscriptions_for_order($order->id) as $subscription) {
         update_post_meta($subscription->id, '_wc_paypal_braintree_payment_method_token', $payment_method_token);
         update_post_meta($subscription->id, '_wc_paypal_braintree_customer_id', $braintree_customer_id);
     }
     $order->payment_complete($transaction_id);
     $this->log(__FUNCTION__, "Info: Completed processing of payment for order {$order_id}");
     return array('result' => 'success', 'redirect' => $this->get_return_url($order));
 }