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>'; } } }
/** * Function to show the payment details after the purchase * * @since 1.0.0 */ public static function show_payment_details($content) { if (in_the_loop() && is_main_query()) { global $sc_options; $html = ''; $test_mode = isset($_GET['test_mode']) ? 'true' : 'false'; $details_placement = isset($_GET['details_placement']) ? $_GET['details_placement'] : 'above'; $charge_response = null; // Since this is a GET query arg I reset it here in case someone tries to submit it again with their own string written in the URL. // This helps ensure it can only be set to below or above. $details_placement = $details_placement == 'below' ? 'below' : 'above'; $is_above = $details_placement == 'below' ? 0 : 1; Stripe_Checkout_Functions::set_key($test_mode); // Successful charge output. if (isset($_GET['charge']) && !isset($_GET['charge_failed'])) { $charge_id = esc_html($_GET['charge']); // https://stripe.com/docs/api/php#charges $charge_response = \Stripe\Charge::retrieve($charge_id); if (null === $sc_options->get_setting_value('disable_success_message')) { $html = '<div class="sc-payment-details-wrap">' . "\n"; $html .= '<p>' . __('Congratulations. Your payment went through!', 'stripe') . '</p>' . "\n"; $html .= '<p>' . "\n"; if (!empty($charge_response->description)) { $html .= __("Here's what you purchased:", 'stripe') . '<br/>' . "\n"; $html .= esc_html($charge_response->description) . '<br/>' . "\n"; } if (isset($_GET['store_name']) && !empty($_GET['store_name'])) { $html .= __('From: ', 'stripe') . esc_html($_GET['store_name']) . '<br/>' . "\n"; } $html .= '<br/>' . "\n"; $html .= '<strong>' . __('Total Paid: ', 'stripe') . Stripe_Checkout_Misc::to_formatted_amount($charge_response->amount, $charge_response->currency) . ' ' . strtoupper($charge_response->currency) . '</strong>' . "\n"; $html .= '</p>' . "\n"; $html .= '<p>' . sprintf(__('Your transaction ID is: %s', 'stripe'), $charge_response->id) . '</p>' . "\n"; $html .= '</div>' . "\n"; if ($is_above) { $content = apply_filters('sc_payment_details', $html, $charge_response) . $content; } else { $content = $content . apply_filters('sc_payment_details', $html, $charge_response); } } do_action('sc_after_charge', $charge_response); } elseif (isset($_GET['charge_failed'])) { $charge_id = esc_html($_GET['charge']); $charge = \Stripe\Charge::retrieve($charge_id); // LITE ONLY: Payment details error included in payment details function. $html = '<div class="sc-payment-details-wrap sc-payment-details-error">' . "\n"; $html .= '<p>' . __('Sorry, but there has been an error processing your payment.', 'stripe') . '</p>' . "\n"; $html .= '<p>' . $charge->failure_message . '</p>'; $html .= '</div>' . "\n"; if ($is_above) { $content = apply_filters('sc_payment_details_error', $html) . $content; } else { $content = $content . apply_filters('sc_payment_details_error', $html); } do_action('sc_after_charge', $charge_response); } } return $content; }
/** * 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; }