public function do_charge()
 {
     if (wp_verify_nonce($_POST['wp-simple-pay-pro-nonce'], 'charge_card')) {
         global $sc_options;
         $query_args = array();
         // Set redirect
         $redirect = $_POST['sc-redirect'];
         $fail_redirect = $_POST['sc-redirect-fail'];
         $failed = null;
         $message = '';
         // Get the credit card details submitted by the form
         $token = $_POST['stripeToken'];
         $amount = $_POST['sc-amount'];
         $description = $_POST['sc-description'];
         $store_name = $_POST['sc-name'];
         $currency = $_POST['sc-currency'];
         $details_placement = $_POST['sc-details-placement'];
         $charge = null;
         $sub = isset($_POST['sc_sub_id']);
         $interval = isset($_POST['sc_sub_interval']) ? $_POST['sc_sub_interval'] : 'month';
         $interval_count = isset($_POST['sc_sub_interval_count']) ? $_POST['sc_sub_interval_count'] : 1;
         $statement_description = isset($_POST['sc_sub_statement_description']) ? $_POST['sc_sub_statement_description'] : '';
         $setup_fee = isset($_POST['sc_sub_setup_fee']) ? $_POST['sc_sub_setup_fee'] : 0;
         $coupon = isset($_POST['sc_coup_coupon_code']) ? $_POST['sc_coup_coupon_code'] : '';
         $test_mode = isset($_POST['sc_test_mode']) ? $_POST['sc_test_mode'] : 'false';
         if ($sub) {
             $sub = !empty($_POST['sc_sub_id']) ? $_POST['sc_sub_id'] : 'custom';
         }
         Stripe_Checkout_Functions::set_key($test_mode);
         $meta = array();
         if (!empty($setup_fee)) {
             $meta['Setup Fee'] = Stripe_Checkout_Misc::to_formatted_amount($setup_fee, $currency);
         }
         $meta = apply_filters('sc_meta_values', $meta);
         try {
             if ($sub == 'custom') {
                 $timestamp = time();
                 $plan_id = $_POST['stripeEmail'] . '_' . $amount . '_' . $timestamp;
                 $name = __('Subscription:', 'sc_sub') . ' ' . Stripe_Checkout_Misc::to_formatted_amount($amount, $currency) . ' ' . strtoupper($currency) . '/' . $interval;
                 // Create a plan
                 $plan_args = array('amount' => $amount, 'interval' => $interval, 'name' => $name, 'currency' => $currency, 'id' => $plan_id, 'interval_count' => $interval_count);
                 if (!empty($statement_description)) {
                     $plan_args['statement_descriptor'] = $statement_description;
                 }
                 $new_plan = \Stripe\Plan::create($plan_args);
                 // Create a customer and charge
                 $new_customer = \Stripe\Customer::create(array('email' => $_POST['stripeEmail'], 'card' => $token, 'plan' => $plan_id, 'metadata' => $meta, 'account_balance' => $setup_fee));
             } else {
                 // Create new customer
                 $cust_args = array('email' => $_POST['stripeEmail'], 'card' => $token, 'plan' => $sub, 'metadata' => $meta, 'account_balance' => $setup_fee);
                 if (!empty($coupon)) {
                     $cust_args['coupon'] = $coupon;
                 }
                 $new_customer = \Stripe\Customer::create($cust_args);
                 // Set currency based on sub
                 $plan = \Stripe\Plan::retrieve($sub);
                 //echo $subscription . '<Br>';
                 $currency = strtoupper($plan->currency);
             }
             // We want to add the meta data and description to the actual charge so that users can still view the meta sent with a subscription + custom fields
             // the same way that they would normally view it without subscriptions installed.
             // We need the steps below to do this
             // First we get the latest invoice based on the customer ID
             $invoice = \Stripe\Invoice::all(array('customer' => $new_customer->id, 'limit' => 1));
             // If this is a trial we need to skip this part since a charge is not made
             $trial = $invoice->data[0]->lines->data[0]->plan->trial_period_days;
             if (empty($trial) || !empty($setup_fee)) {
                 // Now that we have the invoice object we can get the charge ID
                 $inv_charge = $invoice->data[0]->charge;
                 // Finally, with the charge ID we can update the specific charge and inject our meta data sent from Stripe Custom Fields
                 $ch = \Stripe\Charge::retrieve($inv_charge);
                 $charge = $ch;
                 if (!empty($meta)) {
                     $ch->metadata = $meta;
                 }
                 if (!empty($description)) {
                     $ch->description = $description;
                 }
                 $ch->save();
                 $query_args = array('charge' => $ch->id, 'store_name' => urlencode($store_name));
                 $failed = false;
             } else {
                 $sub_id = $invoice->data[0]->subscription;
                 if (!empty($description)) {
                     $customer = \Stripe\Customer::retrieve($new_customer->id);
                     $subscription = $customer->subscriptions->retrieve($sub_id);
                     $subscription->metadata = array('product' => $description);
                     $subscription->save();
                 }
                 $query_args = array('cust_id' => $new_customer->id, 'sub_id' => $sub_id, 'store_name' => urlencode($store_name));
                 $failed = false;
             }
         } catch (Exception $e) {
             // Something else happened, completely unrelated to Stripe
             $redirect = $fail_redirect;
             $failed = true;
             $e = $e->getJsonBody();
             $query_args = array('sub' => true, 'error_code' => $e['error']['type'], 'charge_failed' => true);
         }
         unset($_POST['stripeToken']);
         do_action('sc_redirect_before');
         if ($test_mode == 'true') {
             $query_args['test_mode'] = 'true';
         }
         if ('below' == $details_placement) {
             $query_args['details_placement'] = $details_placement;
         }
         if (!empty($trial) && empty($setup_fee)) {
             $query_args['trial'] = 1;
         }
         wp_redirect(esc_url_raw(add_query_arg(apply_filters('sc_redirect_args', $query_args, $charge), apply_filters('sc_redirect', $redirect, $failed))));
         exit;
     }
 }
 /**
  * Stripe TLS requirement.
  * https://support.stripe.com/questions/how-do-i-upgrade-my-stripe-integration-from-tls-1-0-to-tls-1-2
  */
 private static function stripe_tls_check($for_export)
 {
     global $sc_options;
     // Set Stripe API key. Force test key.
     Stripe_Checkout_Functions::set_key('true');
     $test_key = $sc_options->get_setting_value('test_secret_key');
     // If test key isn't set...
     if (empty($test_key)) {
         if ($for_export) {
             return __('Cannot test TLS 1.2 support until your Stripe Test Secret Key is entered.', 'stripe');
         } else {
             return '<mark class="error">' . __('Cannot test TLS 1.2 support until your Stripe Test Secret Key is entered.', 'stripe') . '</mark>';
         }
     }
     \Stripe\Stripe::$apiBase = 'https://api-tls12.stripe.com';
     try {
         \Stripe\Charge::all();
         if ($for_export) {
             return __('TLS 1.2 supported, no action required.', 'stripe');
         } else {
             return '<mark class="ok">' . __('TLS 1.2 supported, no action required.', 'stripe') . '</mark>';
         }
     } catch (\Stripe\Error\ApiConnection $e) {
         if ($for_export) {
             return sprintf(__('TLS 1.2 is not supported. You will need to upgrade your integration. See %1$s.', 'stripe'), 'https://stripe.com/blog/upgrading-tls');
         } else {
             return '<mark class="error">' . sprintf(__('TLS 1.2 is not supported. You will need to upgrade your integration. <a href="%1$s">Please read this</a> for more information.', 'stripe'), 'https://stripe.com/blog/upgrading-tls') . '</mark>';
         }
     }
 }
 /**
  * Get the instance for all the included classes
  */
 public function init()
 {
     Stripe_Checkout_Scripts::get_instance();
     Stripe_Checkout_Shortcodes::get_instance();
     if (is_admin()) {
         Stripe_Checkout_Admin::get_instance();
         Stripe_Checkout_Upgrade_Link::get_instance();
         Stripe_Checkout_Notices::get_instance();
         Stripe_Checkout_System_Status::get_instance();
     } else {
         Stripe_Checkout_Misc::get_instance();
         Stripe_Checkout_Functions::get_instance();
     }
 }
 public static function get_instance()
 {
     // If the single instance hasn't been set, set it now.
     if (null == self::$instance) {
         self::$instance = new self();
     }
     return self::$instance;
 }
 /**
  * Function to handle AJAX request for coupon check
  *
  * @since 2.0.0
  */
 function coup_ajax_check()
 {
     global $sc_options;
     $json = '';
     $code = $_POST['coupon'];
     $amount = $_POST['amount'];
     $json['coupon']['code'] = $code;
     $test_mode = $_POST['test_mode'];
     Stripe_Checkout_Functions::set_key($test_mode);
     try {
         $coupon = \Stripe\Coupon::retrieve(trim($code));
         if (!empty($coupon->percent_off)) {
             $json['coupon']['amountOff'] = $coupon->percent_off;
             $json['coupon']['type'] = 'percent';
             if ($coupon->percent_off == 100) {
                 $amount = 0;
             } else {
                 $amount = round($amount * ((100 - $coupon->percent_off) / 100));
             }
         } else {
             if (!empty($coupon->amount_off)) {
                 $json['coupon']['amountOff'] = $coupon->amount_off;
                 $json['coupon']['type'] = 'amount';
                 $amount = $amount - $coupon->amount_off;
                 if ($amount < 0) {
                     $amount = 0;
                 }
             }
         }
         // Set message to amount now before checking for errors
         $json['success'] = true;
         $json['message'] = $amount;
         if ($amount < 50) {
             $json['success'] = false;
             $json['message'] = __('Coupon entered puts the total below the required minimum amount.', 'stripe');
         }
     } catch (Exception $e) {
         // an exception was caught, so the code is invalid
         $json['success'] = false;
         $json['message'] = __('Invalid coupon code.', 'stripe');
     }
     // Return as JSON
     echo json_encode($json);
     die;
 }