/**
  * Process the payment
  */
 function process_payment($order_id)
 {
     global $woocommerce;
     if (class_exists('WC_Subscriptions_Order') && WC_Subscriptions_Order::order_contains_subscription($order_id)) {
         $order = new WC_Order($order_id);
         $stripe_token = isset($_POST['stripe_token']) ? woocommerce_clean($_POST['stripe_token']) : '';
         // Use Stripe CURL API for payment
         try {
             $post_data = array();
             $customer_id = 0;
             // Check if paying via customer ID
             if (isset($_POST['stripe_customer_id']) && $_POST['stripe_customer_id'] !== 'new' && is_user_logged_in()) {
                 $customer_ids = get_user_meta(get_current_user_id(), '_stripe_customer_id', false);
                 if (isset($customer_ids[$_POST['stripe_customer_id']]['customer_id'])) {
                     $customer_id = $customer_ids[$_POST['stripe_customer_id']]['customer_id'];
                 } else {
                     throw new Exception(__('Invalid card.', 'wc_stripe'));
                 }
             } elseif (empty($stripe_token)) {
                 throw new Exception(__('Please make sure your card details have been entered correctly and that your browser supports JavaScript.', 'wc_stripe'));
             }
             if (method_exists('WC_Subscriptions_Order', 'get_total_initial_payment')) {
                 $initial_payment = WC_Subscriptions_Order::get_total_initial_payment($order);
             } else {
                 $initial_payment = WC_Subscriptions_Order::get_sign_up_fee($order) + WC_Subscriptions_Order::get_price_per_period($order);
             }
             $customer_response = $this->add_customer_to_order($order, $customer_id, $stripe_token);
             if ($initial_payment > 0) {
                 $payment_response = $this->process_subscription_payment($order, $initial_payment);
             }
             if (is_wp_error($customer_response)) {
                 throw new Exception($customer_response->get_error_message());
             } else {
                 if (isset($payment_response) && is_wp_error($payment_response)) {
                     throw new Exception($payment_response->get_error_message());
                 } else {
                     // Payment complete
                     $order->payment_complete();
                     // Remove cart
                     $woocommerce->cart->empty_cart();
                     // Activate subscriptions
                     WC_Subscriptions_Manager::activate_subscriptions_for_order($order);
                     // Store token
                     if ($stripe_token) {
                         update_post_meta($order->id, '_stripe_token', $stripe_token);
                     }
                     // Return thank you page redirect
                     return array('result' => 'success', 'redirect' => $this->get_return_url($order));
                 }
             }
         } catch (Exception $e) {
             $woocommerce->add_error(__('Error:', 'wc_stripe') . ' "' . $e->getMessage() . '"');
             return;
         }
     } else {
         return parent::process_payment($order_id);
     }
 }
 /**
  * Process the subscription
  *
  * @param int $order_id
  * @return array
  */
 public function process_subscription($order_id)
 {
     $order = wc_get_order($order_id);
     $token = isset($_POST['simplify_token']) ? wc_clean($_POST['simplify_token']) : '';
     try {
         if (empty($token)) {
             $error_msg = __('Please make sure your card details have been entered correctly and that your browser supports JavaScript.', 'woocommerce');
             if ('yes' == $this->sandbox) {
                 $error_msg .= ' ' . __('Developers: Please make sure that you\'re including jQuery and there are no JavaScript errors on the page.', 'woocommerce');
             }
             throw new Simplify_ApiException($error_msg);
         }
         // Create customer
         $customer = Simplify_Customer::createCustomer(array('token' => $token, 'email' => $order->billing_email, 'name' => trim($order->billing_first_name . ' ' . $order->billing_last_name), 'reference' => $order->id));
         if (is_object($customer) && '' != $customer->id) {
             $customer_id = wc_clean($customer->id);
             // Store the customer ID in the order
             update_post_meta($order_id, '_simplify_customer_id', $customer_id);
         } else {
             $error_msg = __('Error creating user in Simplify Commerce.', 'woocommerce');
             throw new Simplify_ApiException($error_msg);
         }
         $initial_payment = WC_Subscriptions_Order::get_total_initial_payment($order);
         if ($initial_payment > 0) {
             $payment_response = $this->process_subscription_payment($order, $initial_payment);
         }
         if (isset($payment_response) && is_wp_error($payment_response)) {
             throw new Exception($payment_response->get_error_message());
         } else {
             // Remove cart
             WC()->cart->empty_cart();
             // Return thank you page redirect
             return array('result' => 'success', 'redirect' => $this->get_return_url($order));
         }
     } catch (Simplify_ApiException $e) {
         if ($e instanceof Simplify_BadRequestException && $e->hasFieldErrors() && $e->getFieldErrors()) {
             foreach ($e->getFieldErrors() as $error) {
                 wc_add_notice($error->getFieldName() . ': "' . $error->getMessage() . '" (' . $error->getErrorCode() . ')', 'error');
             }
         } else {
             wc_add_notice($e->getMessage(), 'error');
         }
         return array('result' => 'fail', 'redirect' => '');
     }
 }
 /**
  * Process the subscription
  *
  * @param  int $order_id
  * @return array
  */
 public function process_subscription($order_id)
 {
     $order = new WC_Order($order_id);
     if ($this->sandbox == 'yes') {
         $error_msg .= ' ' . __('Developers: Please make sure that you\'re including jQuery and there are no JavaScript errors on the page.', 'woocommerce-payment-gateway-boilerplate');
     }
     $initial_payment = WC_Subscriptions_Order::get_total_initial_payment($order);
     if ($initial_payment > 0) {
         $payment_response = $this->process_subscription_payment($order, $initial_payment);
     }
     if (isset($payment_response) && is_wp_error($payment_response)) {
         throw new Exception($payment_response->get_error_message());
     } else {
         // Remove cart
         WC()->cart->empty_cart();
         // Return thank you page redirect
         return array('result' => 'success', 'redirect' => $this->get_return_url($order));
     }
     return array('result' => 'fail', 'redirect' => '');
 }
 /**
  * Process the subscription.
  *
  * @param WC_Order $order
  *
  * @return array
  */
 protected function process_subscription($order_id)
 {
     try {
         $order = new WC_Order($order_id);
         if (!isset($_POST['iugu_token'])) {
             if ('yes' == $this->debug) {
                 $this->log->add($this->id, 'Error doing the subscription for order ' . $order->get_order_number() . ': Missing the "iugu_token".');
             }
             $error_msg = __('Please make sure your card details have been entered correctly and that your browser supports JavaScript.', 'iugu-woocommerce');
             throw new Exception($error_msg);
         }
         // Create customer payment method.
         $payment_method_id = $this->api->create_customer_payment_method($order, $_POST['iugu_token']);
         if (!$payment_method_id) {
             if ('yes' == $this->debug) {
                 $this->log->add($this->id, 'Invalid customer method ID for order ' . $order->get_order_number());
             }
             $error_msg = __('An error occurred while trying to save your data. Please contact us for get help.', 'iugu-woocommerce');
             throw new Exception($error_msg);
         }
         // Save the payment method ID in order data.
         update_post_meta($order->id, '_iugu_customer_payment_method_id', $payment_method_id);
         // Try to do an initial payment.
         $initial_payment = WC_Subscriptions_Order::get_total_initial_payment($order);
         if ($initial_payment > 0) {
             $payment_response = $this->process_subscription_payment($order, $initial_payment);
         }
         if (isset($payment_response) && is_wp_error($payment_response)) {
             throw new Exception($payment_response->get_error_message());
         } else {
             // Remove cart
             $this->api->empty_card();
             // Return thank you page redirect
             return array('result' => 'success', 'redirect' => $this->get_return_url($order));
         }
     } catch (Exception $e) {
         $this->api->add_error('<strong>' . esc_attr($this->title) . '</strong>: ' . $e->getMessage());
         return array('result' => 'fail', 'redirect' => '');
     }
 }
 /**
  * Process the subscription.
  *
  * @param WC_Order $order
  *
  * @return array
  */
 protected function process_subscription($order_id)
 {
     try {
         $order = new WC_Order($order_id);
         // Try to do an initial payment.
         $initial_payment = WC_Subscriptions_Order::get_total_initial_payment($order);
         if ($initial_payment > 0) {
             $payment_response = $this->process_subscription_payment($order, $initial_payment);
         }
         if (isset($payment_response) && is_wp_error($payment_response)) {
             throw new Exception($payment_response->get_error_message());
         } else {
             // Remove cart
             $this->api->empty_card();
             // Return thank you page redirect
             return array('result' => 'success', 'redirect' => $this->get_return_url($order));
         }
     } catch (Exception $e) {
         $this->api->add_error('<strong>' . esc_attr($this->title) . '</strong>: ' . $e->getMessage());
         return array('result' => 'fail', 'redirect' => '');
     }
 }
 public function request_access_code($order, $method = 'ProcessPayment', $trx_type = 'Purchase')
 {
     $customer_ip = get_post_meta($order->id, '_customer_ip_address', true);
     // Check if order is for a subscription, if it is check for fee and charge that
     if (class_exists('WC_Subscriptions_Order') && WC_Subscriptions_Order::order_contains_subscription($order->id)) {
         if (0 == WC_Subscriptions_Order::get_total_initial_payment($order)) {
             $method = 'CreateTokenCustomer';
         } else {
             $method = 'TokenPayment';
         }
         $trx_type = 'Recurring';
         $order_total = WC_Subscriptions_Order::get_total_initial_payment($order) * 100;
     } else {
         $order_total = $order->get_total() * 100.0;
     }
     // set up request object
     $request = array('Method' => $method, 'TransactionType' => $trx_type, 'RedirectUrl' => str_replace('https:', 'http:', add_query_arg(array('wc-api' => 'WC_Gateway_EWAY', 'order_id' => $order->id, 'order_key' => $order->order_key, 'sig_key' => md5($order->order_key . 'WOO' . $order->id)), home_url('/'))), 'IPAddress' => $customer_ip, 'DeviceID' => '0b38ae7c3c5b466f8b234a8955f62bdd', 'PartnerID' => '0b38ae7c3c5b466f8b234a8955f62bdd', 'Payment' => array('TotalAmount' => $order_total, 'CurrencyCode' => get_woocommerce_currency(), 'InvoiceDescription' => apply_filters('woocommerce_eway_description', '', $order), 'InvoiceNumber' => ltrim($order->get_order_number(), _x('#', 'hash before order number', 'woocommerce')), 'InvoiceReference' => $order->id), 'Customer' => array('FirstName' => $order->billing_first_name, 'LastName' => $order->billing_last_name, 'CompanyName' => substr($order->billing_company, 0, 50), 'Street1' => $order->billing_address_1, 'Street2' => $order->billing_address_2, 'City' => $order->billing_city, 'State' => $order->billing_state, 'PostalCode' => $order->billing_postcode, 'Country' => $order->billing_country, 'Email' => $order->billing_email, 'Phone' => $order->billing_phone));
     // Add customer ID if logged in
     if (is_user_logged_in()) {
         $request['Options'][] = array('customerID' => get_current_user_id());
     }
     return $this->perform_request('/CreateAccessCode.json', json_encode($request));
 }
 /**
  * Records a payment on a subscription.
  *
  * @param int $user_id The id of the user who owns the subscription. 
  * @param string $subscription_key A subscription key of the form obtained by @see get_subscription_key( $order_id, $product_id )
  * @since 1.0
  */
 public static function process_subscription_payment($user_id, $subscription_key)
 {
     // Store a record of the subscription payment date
     $subscription = self::get_subscription($subscription_key);
     $subscription['completed_payments'][] = gmdate('Y-m-d H:i:s');
     // Reset failed payment count & suspension count
     $subscription['failed_payments'] = $subscription['suspension_count'] = 0;
     self::update_users_subscriptions($user_id, array($subscription_key => $subscription));
     // Make sure subscriber is marked as a "Paying Customer"
     self::mark_paying_customer($subscription['order_id']);
     // Make sure subscriber has default role
     self::update_users_role($user_id, 'default_subscriber_role');
     // Log payment on order
     $order = new WC_Order($subscription['order_id']);
     $item = WC_Subscriptions_Order::get_item_by_product_id($order, $subscription['product_id']);
     // Free trial & no-signup fee, no payment received
     if (0 == WC_Subscriptions_Order::get_total_initial_payment($order) && 1 == count($subscription['completed_payments'])) {
         if (WC_Subscriptions_Order::requires_manual_renewal($subscription['order_id'])) {
             $order_note = sprintf(__('Free trial commenced for subscription "%s"', 'woocommerce-subscriptions'), $item['name']);
         } else {
             $order_note = sprintf(__('Recurring payment authorized for subscription "%s"', 'woocommerce-subscriptions'), $item['name']);
         }
     } else {
         $order_note = sprintf(__('Payment received for subscription "%s"', 'woocommerce-subscriptions'), $item['name']);
     }
     $order->add_order_note($order_note);
     do_action('processed_subscription_payment', $user_id, $subscription_key);
 }
 /**
  * Outputs the content for each column.
  *
  * @param array $item A singular item (one full row's worth of data)
  * @param array $column_name The name/slug of the column to be processed
  * @return string Text or HTML to be placed inside the column <td>
  * @since 1.0
  */
 public function column_default($item, $column_name)
 {
     global $woocommerce;
     $current_gmt_time = gmdate('U');
     $column_content = '';
     switch ($column_name) {
         case 'status':
             $actions = array();
             $action_url = add_query_arg(array('page' => $_REQUEST['page'], 'user' => $item['user_id'], 'subscription' => $item['subscription_key'], '_wpnonce' => wp_create_nonce($item['subscription_key'])));
             if (isset($_REQUEST['status'])) {
                 $action_url = add_query_arg(array('status' => $_REQUEST['status']), $action_url);
             }
             $order = new WC_Order($item['order_id']);
             $all_statuses = array('active' => __('Reactivate', 'woocommerce-subscriptions'), 'on-hold' => __('Suspend', 'woocommerce-subscriptions'), 'cancelled' => __('Cancel', 'woocommerce-subscriptions'), 'trash' => __('Trash', 'woocommerce-subscriptions'), 'deleted' => __('Delete Permanently', 'woocommerce-subscriptions'));
             foreach ($all_statuses as $status => $label) {
                 if (WC_Subscriptions_Manager::can_subscription_be_changed_to($status, $item['subscription_key'], $item['user_id'])) {
                     $action = 'deleted' == $status ? 'delete' : $status;
                     // For built in CSS
                     $actions[$action] = sprintf('<a href="%s">%s</a>', esc_url(add_query_arg('new_status', $status, $action_url)), $label);
                 }
             }
             if ($item['status'] == 'pending') {
                 unset($actions['active']);
                 unset($actions['trash']);
             } elseif (!in_array($item['status'], array('cancelled', 'expired', 'switched', 'suspended'))) {
                 unset($actions['trash']);
             }
             $actions = apply_filters('woocommerce_subscriptions_list_table_actions', $actions, $item);
             $column_content = sprintf('<mark class="%s">%s</mark> %s', sanitize_title($item[$column_name]), WC_Subscriptions_Manager::get_status_to_display($item[$column_name], $item['subscription_key'], $item['user_id']), $this->row_actions($actions));
             $column_content = apply_filters('woocommerce_subscriptions_list_table_column_status_content', $column_content, $item, $actions, $this);
             break;
         case 'title':
             //Return the title contents
             $column_content = sprintf('<a href="%s">%s</a>', get_edit_post_link($item['product_id']), WC_Subscriptions_Order::get_item_name($item['order_id'], $item['product_id']));
             $order = new WC_Order($item['order_id']);
             $order_item = WC_Subscriptions_Order::get_item_by_product_id($order, $item['product_id']);
             $product = $order->get_product_from_item($order_item);
             if (isset($product->variation_data)) {
                 $column_content .= '<br />' . woocommerce_get_formatted_variation($product->variation_data, true);
             }
             break;
         case 'order_id':
             $order = new WC_Order($item[$column_name]);
             $column_content = sprintf('<a href="%1$s">%2$s</a>', get_edit_post_link($item[$column_name]), sprintf(__('Order %s', 'woocommerce-subscriptions'), $order->get_order_number()));
             break;
         case 'user':
             $user = get_user_by('id', $item['user_id']);
             if (is_object($user)) {
                 $column_content = sprintf('<a href="%s">%s</a>', admin_url('user-edit.php?user_id=' . $user->ID), ucfirst($user->display_name));
             }
             break;
         case 'start_date':
         case 'expiry_date':
         case 'end_date':
             if ($column_name == 'expiry_date' && $item[$column_name] == 0) {
                 $column_content = __('Never', 'woocommerce-subscriptions');
             } else {
                 if ($column_name == 'end_date' && $item[$column_name] == 0) {
                     $column_content = __('Not yet ended', 'woocommerce-subscriptions');
                 } else {
                     $gmt_timestamp = strtotime($item[$column_name]);
                     $user_timestamp = $gmt_timestamp + get_option('gmt_offset') * 3600;
                     $column_content = sprintf('<time>%s</time>', date_i18n(woocommerce_date_format(), $user_timestamp));
                 }
             }
             break;
         case 'trial_expiry_date':
             $trial_expiration = WC_Subscriptions_Manager::get_trial_expiration_date($item['subscription_key'], $item['user_id'], 'timestamp');
             if (empty($trial_expiration)) {
                 $column_content = '-';
             } else {
                 $column_content = sprintf('<time title="%s">%s</time>', esc_attr($trial_expiration), date_i18n(woocommerce_date_format(), $trial_expiration + get_option('gmt_offset') * 3600));
             }
             break;
         case 'last_payment_date':
             // Although we record the sign-up date as a payment, if there is a free trial and no sign-up fee, no payment is actually charged
             if (0 == WC_Subscriptions_Order::get_total_initial_payment($item['order_id']) && 1 == count($item['completed_payments'])) {
                 $column_content = '-';
             } else {
                 $last_payment_timestamp = strtotime($item['last_payment_date']);
                 $time_diff = $current_gmt_time - $last_payment_timestamp;
                 if ($time_diff > 0 && $time_diff < 7 * 24 * 60 * 60) {
                     $last_payment = sprintf(__('%s ago', 'woocommerce-subscriptions'), human_time_diff($last_payment_timestamp, $current_gmt_time));
                 } else {
                     $last_payment = date_i18n(woocommerce_date_format(), $last_payment_timestamp + get_option('gmt_offset') * 3600);
                 }
                 $column_content = sprintf('<time title="%s">%s</time>', esc_attr($last_payment_timestamp), $last_payment);
             }
             break;
         case 'next_payment_date':
             $next_payment_timestamp_gmt = WC_Subscriptions_Manager::get_next_payment_date($item['subscription_key'], $item['user_id'], 'timestamp');
             $next_payment_timestamp = $next_payment_timestamp_gmt + get_option('gmt_offset') * 3600;
             if ($next_payment_timestamp_gmt == 0) {
                 $column_content = '-';
             } else {
                 // Convert to site time
                 $time_diff = $next_payment_timestamp_gmt - $current_gmt_time;
                 if ($time_diff > 0 && $time_diff < 7 * 24 * 60 * 60) {
                     $next_payment = sprintf(__('In %s', 'woocommerce-subscriptions'), human_time_diff($current_gmt_time, $next_payment_timestamp_gmt));
                 } else {
                     $next_payment = date_i18n(woocommerce_date_format(), $next_payment_timestamp);
                 }
                 $column_content = sprintf('<time class="next-payment-date" title="%s">%s</time>', esc_attr($next_payment_timestamp), $next_payment);
                 if (WC_Subscriptions_Manager::can_subscription_be_changed_to('new-payment-date', $item['subscription_key'], $item['user_id'])) {
                     $column_content .= '<div class="edit-date-div row-actions hide-if-no-js">';
                     $column_content .= '<img class="date-picker-icon" src="' . admin_url('images/date-button.gif') . '" title="' . __('Date Picker Icon', 'woocommerce-subscriptions') . '" />';
                     $column_content .= '<a href="#edit_timestamp" class="edit-timestamp" tabindex="4">' . __('Change', 'woocommerce-subscriptions') . '</a>';
                     $column_content .= '<div class="date-picker-div hide-if-js">';
                     $column_content .= WC_Subscriptions_Manager::touch_time(array('date' => date('Y-m-d', $next_payment_timestamp), 'echo' => false, 'multiple' => true, 'include_time' => false));
                     $column_content .= '</div>';
                     $column_content .= '</div>';
                 }
             }
             break;
         case 'renewal_order_count':
             $count = WC_Subscriptions_Renewal_Order::get_renewal_order_count($item['order_id']);
             $column_content = sprintf('<a href="%1$s">%2$d</a>', admin_url('edit.php?post_status=all&post_type=shop_order&_renewal_order_parent_id=' . absint($item['order_id'])), $count);
             break;
     }
     return apply_filters('woocommerce_subscriptions_list_table_column_content', $column_content, $item, $column_name);
 }
 /**
  * Adds subscriptions data to the order object
  *
  * @since 1.0
  * @see SV_WC_Payment_Gateway::get_order()
  * @param WC_Order $order the order
  * @return WC_Order the orders
  */
 public function subscriptions_get_order($order)
 {
     // bail if the gateway doesn't support subscriptions or the order doesn't contain a subscription
     if (!$this->supports_subscriptions() || !WC_Subscriptions_Order::order_contains_subscription($order->id)) {
         return $order;
     }
     // subscriptions total, ensuring that we have a decimal point, even if it's 1.00
     $order->payment_total = number_format((double) WC_Subscriptions_Order::get_total_initial_payment($order), 2, '.', '');
     // load any required members that we might not have
     if (!isset($order->payment->token) || !$order->payment->token) {
         $order->payment->token = get_post_meta($order->id, '_wc_' . $this->get_id() . '_payment_token', true);
     }
     if (!isset($order->customer_id) || !$order->customer_id) {
         $order->customer_id = get_post_meta($order->id, '_wc_' . $this->get_id() . '_customer_id', true);
     }
     // ensure the payment token is still valid
     if (!$this->has_payment_token($order->user_id, $order->payment->token)) {
         $order->payment->token = null;
     } else {
         // get the token object
         $token = $this->get_payment_token($order->user_id, $order->payment->token);
         if (!isset($order->payment->account_number) || !$order->payment->account_number) {
             $order->payment->account_number = $token->get_last_four();
         }
         if ($this->is_credit_card_gateway()) {
             // credit card token
             if (!isset($order->payment->card_type) || !$order->payment->card_type) {
                 $order->payment->card_type = $token->get_card_type();
             }
             if (!isset($order->payment->exp_month) || !$order->payment->exp_month) {
                 $order->payment->exp_month = $token->get_exp_month();
             }
             if (!isset($order->payment->exp_year) || !$order->payment->exp_year) {
                 $order->payment->exp_year = $token->get_exp_year();
             }
         } elseif ($this->is_echeck_gateway()) {
             // check token
             if (!isset($order->payment->account_type) || !$order->payment->account_type) {
                 $order->payment->account_type = $token->get_account_type();
             }
         }
     }
     return $order;
 }
 /**
  * Filters WC_Subscriptions_Order::get_sign_up_fee() to make sure the sign-up fee for a subscription product
  * that is synchronised is returned correctly.
  *
  * @param float The initial sign-up fee charged when the subscription product in the order was first purchased, if any.
  * @param mixed $order A WC_Order object or the ID of the order which the subscription was purchased in.
  * @param int $product_id The post ID of the subscription WC_Product object purchased in the order. Defaults to the ID of the first product purchased in the order.
  * @return float The initial sign-up fee charged when the subscription product in the order was first purchased, if any.
  * @since 1.5.3
  * @deprecated 2.0
  */
 public static function get_sign_up_fee($sign_up_fee, $order, $product_id, $non_subscription_total)
 {
     _deprecated_function(__METHOD__, '2.0', __CLASS__ . '::get_synced_sign_up_fee');
     if ('shop_order' == get_post_type($order) && self::order_contains_synced_subscription($order->id) && WC_Subscriptions_Order::get_subscription_trial_length($order) < 1) {
         $sign_up_fee = max(WC_Subscriptions_Order::get_total_initial_payment($order) - $non_subscription_total, 0);
     }
     return $sign_up_fee;
 }
 /**
  * Set up the charge that will be sent to Stripe
  *
  * @access      private
  * @return      void
  */
 private function charge_set_up()
 {
     global $s4wc;
     // Add a customer or retrieve an existing one
     $customer = $this->get_customer();
     $customer_info = get_user_meta($this->order->user_id, $s4wc->settings['stripe_db_location'], true);
     // Update default card
     if ($this->form_data['chosen_card'] !== 'new') {
         $default_card = $customer_info['cards'][intval($this->form_data['chosen_card'])]['id'];
         S4WC_DB::update_customer($this->order->user_id, array('default_card' => $default_card));
     }
     $initial_payment = WC_Subscriptions_Order::get_total_initial_payment($this->order);
     $charge = $this->process_subscription_payment($initial_payment);
     $this->charge = $charge;
     $this->transaction_id = $charge->id;
 }
 /**
  * Adds subscriptions data to the order object
  *
  * @since 4.1.0
  * @see SV_WC_Payment_Gateway::get_order()
  * @param WC_Order $order the order
  * @return WC_Order the orders
  */
 public function get_order_1_5($order)
 {
     // bail if the order doesn't contain a subscription
     if (!WC_Subscriptions_Order::order_contains_subscription($order->id)) {
         return $order;
     }
     // subscriptions total, ensuring that we have a decimal point, even if it's 1.00
     $order->payment_total = SV_WC_Helper::number_format(WC_Subscriptions_Order::get_total_initial_payment($order));
     // load any required members that we might not have
     if (!isset($order->payment->token) || !$order->payment->token) {
         $order->payment->token = $this->get_gateway()->get_order_meta($order->id, 'payment_token');
     }
     if (!isset($order->customer_id) || !$order->customer_id) {
         $order->customer_id = $this->get_gateway()->get_order_meta($order->id, 'customer_id');
     }
     // ensure the payment token is still valid
     if (!$this->get_gateway()->has_payment_token($order->get_user_id(), $order->payment->token)) {
         $order->payment->token = null;
     } else {
         // get the token object
         $token = $this->get_gateway()->get_payment_token($order->get_user_id(), $order->payment->token);
         if (!isset($order->payment->account_number) || !$order->payment->account_number) {
             $order->payment->account_number = $token->get_last_four();
         }
         if ($this->get_gateway()->is_credit_card_gateway()) {
             // credit card token
             if (!isset($order->payment->card_type) || !$order->payment->card_type) {
                 $order->payment->card_type = $token->get_card_type();
             }
             if (!isset($order->payment->exp_month) || !$order->payment->exp_month) {
                 $order->payment->exp_month = $token->get_exp_month();
             }
             if (!isset($order->payment->exp_year) || !$order->payment->exp_year) {
                 $order->payment->exp_year = $token->get_exp_year();
             }
         } elseif ($this->get_gateway()->is_echeck_gateway()) {
             // check token
             if (!isset($order->payment->account_type) || !$order->payment->account_type) {
                 $order->payment->account_type = $token->get_account_type();
             }
         }
     }
     return $order;
 }
 /**
  * Override the default PayPal standard args in WooCommerce for subscription purchases.
  *
  * Based on the HTML Variables documented here: https://developer.paypal.com/webapps/developer/docs/classic/paypal-payments-standard/integration-guide/Appx_websitestandard_htmlvariables/#id08A6HI00JQU
  *
  * @since 1.0
  */
 public static function paypal_standard_subscription_args($paypal_args)
 {
     extract(self::get_order_id_and_key($paypal_args));
     if (WC_Subscriptions_Order::order_contains_subscription($order_id) && 'yes' !== get_option(WC_Subscriptions_Admin::$option_prefix . '_turn_off_automatic_payments', 'no')) {
         $order = new WC_Order($order_id);
         $order_items = $order->get_items();
         // Only one subscription allowed in the cart when PayPal Standard is active
         $product = $order->get_product_from_item(array_pop($order_items));
         // It's a subscription
         $paypal_args['cmd'] = '_xclick-subscriptions';
         if (count($order->get_items()) > 1) {
             foreach ($order->get_items() as $item) {
                 if ($item['qty'] > 1) {
                     $item_names[] = $item['qty'] . ' x ' . $item['name'];
                 } else {
                     if ($item['qty'] > 0) {
                         $item_names[] = $item['name'];
                     }
                 }
             }
             $paypal_args['item_name'] = sprintf(__('Order %s', WC_Subscriptions::$text_domain), $order->get_order_number());
         } else {
             $paypal_args['item_name'] = $product->get_title();
         }
         $unconverted_periods = array('billing_period' => WC_Subscriptions_Order::get_subscription_period($order), 'trial_period' => WC_Subscriptions_Order::get_subscription_trial_period($order));
         $converted_periods = array();
         // Convert period strings into PayPay's format
         foreach ($unconverted_periods as $key => $period) {
             switch (strtolower($period)) {
                 case 'day':
                     $converted_periods[$key] = 'D';
                     break;
                 case 'week':
                     $converted_periods[$key] = 'W';
                     break;
                 case 'year':
                     $converted_periods[$key] = 'Y';
                     break;
                 case 'month':
                 default:
                     $converted_periods[$key] = 'M';
                     break;
             }
         }
         $price_per_period = WC_Subscriptions_Order::get_recurring_total($order);
         $subscription_interval = WC_Subscriptions_Order::get_subscription_interval($order);
         $subscription_length = WC_Subscriptions_Order::get_subscription_length($order);
         $subscription_installments = $subscription_length / $subscription_interval;
         $is_payment_change = WC_Subscriptions_Change_Payment_Gateway::$is_request_to_change_payment;
         $is_switch_order = WC_Subscriptions_Switcher::order_contains_subscription_switch($order->id);
         $sign_up_fee = $is_payment_change ? 0 : WC_Subscriptions_Order::get_sign_up_fee($order);
         $initial_payment = $is_payment_change ? 0 : WC_Subscriptions_Order::get_total_initial_payment($order);
         if ($is_payment_change) {
             // Add a nonce to the order ID to avoid "This invoice has already been paid" error when changing payment method to PayPal when it was previously PayPal
             $paypal_args['invoice'] = $paypal_args['invoice'] . '-wcscpm-' . wp_create_nonce();
             // Set a flag on the order if changing from PayPal *to* PayPal to prevent incorrectly cancelling the subscription
             if ('paypal' == $order->recurring_payment_method) {
                 add_post_meta($order_id, '_wcs_changing_payment_from_paypal_to_paypal', 'true', true);
             }
         }
         // If we're changing the payment date or switching subs, we need to set the trial period to the next payment date & installments to be the number of installments left
         if ($is_payment_change || $is_switch_order) {
             $subscription_key = WC_Subscriptions_Manager::get_subscription_key($order_id, $product->id);
             // Give a free trial until the next payment date
             $next_payment_timestamp = WC_Subscriptions_Manager::get_next_payment_date($subscription_key, $order->user_id, 'timestamp');
             // When the subscription is on hold
             if ($next_payment_timestamp != false) {
                 $trial_until = self::calculate_trial_periods_until($next_payment_timestamp);
                 $subscription_trial_length = $trial_until['first_trial_length'];
                 $converted_periods['trial_period'] = $trial_until['first_trial_period'];
                 $second_trial_length = $trial_until['second_trial_length'];
                 $second_trial_period = $trial_until['second_trial_period'];
             }
             // If is a payment change, we need to account for completed payments on the number of installments owing
             if ($is_payment_change && $subscription_length > 0) {
                 $subscription_installments -= WC_Subscriptions_Manager::get_subscriptions_completed_payment_count($subscription_key);
             }
         } else {
             $subscription_trial_length = WC_Subscriptions_Order::get_subscription_trial_length($order);
         }
         if ($subscription_trial_length > 0) {
             // Specify a free trial period
             if ($is_switch_order) {
                 $paypal_args['a1'] = $initial_payment > 0 ? $initial_payment : 0;
             } else {
                 $paypal_args['a1'] = $sign_up_fee > 0 ? $sign_up_fee : 0;
             }
             // Maybe add the sign up fee to the free trial period
             // Trial period length
             $paypal_args['p1'] = $subscription_trial_length;
             // Trial period
             $paypal_args['t1'] = $converted_periods['trial_period'];
             // We need to use a second trial period before we have more than 90 days until the next payment
             if (WC_Subscriptions_Change_Payment_Gateway::$is_request_to_change_payment && $second_trial_length > 0) {
                 $paypal_args['a2'] = 0;
                 $paypal_args['p2'] = $second_trial_length;
                 $paypal_args['t2'] = $second_trial_period;
             }
         } elseif ($sign_up_fee > 0 || $initial_payment !== $price_per_period) {
             // No trial period, so charge sign up fee and per period price for the first period
             if ($subscription_installments == 1) {
                 $param_number = 3;
             } else {
                 $param_number = 1;
             }
             $paypal_args['a' . $param_number] = $initial_payment;
             // Sign Up interval
             $paypal_args['p' . $param_number] = $subscription_interval;
             // Sign Up unit of duration
             $paypal_args['t' . $param_number] = $converted_periods['billing_period'];
         }
         // We have a recurring payment
         if (!isset($param_number) || $param_number == 1) {
             // Subscription price
             $paypal_args['a3'] = $price_per_period;
             // Subscription duration
             $paypal_args['p3'] = $subscription_interval;
             // Subscription period
             $paypal_args['t3'] = $converted_periods['billing_period'];
         }
         // Recurring payments
         if ($subscription_installments == 1 || $sign_up_fee > 0 && $subscription_trial_length == 0 && $subscription_installments == 2) {
             // Non-recurring payments
             $paypal_args['src'] = 0;
         } else {
             $paypal_args['src'] = 1;
             if ($subscription_installments > 0) {
                 if ($sign_up_fee > 0 && $subscription_trial_length == 0) {
                     // An initial period is being used to charge a sign-up fee
                     $subscription_installments--;
                 }
                 $paypal_args['srt'] = $subscription_installments;
             }
         }
         // Don't reattempt failed payments, instead let Subscriptions handle the failed payment
         $paypal_args['sra'] = 0;
         // Force return URL so that order description & instructions display
         $paypal_args['rm'] = 2;
     }
     return $paypal_args;
 }
Exemplo n.º 14
0
 /**
  * callback_handler function.
  *
  * Is called after a payment has been submitted in the QuickPay payment window.
  *
  * @access public 
  * @return void
  */
 public function callback_handler()
 {
     $request_body = file_get_contents("php://input");
     $json = json_decode($request_body);
     $payment = new WC_QuickPay_API_Payment($request_body);
     if ($payment->is_authorized_callback($request_body)) {
         // Fetch order number;
         $order_number = WC_QuickPay_Order::get_order_id_from_callback($json);
         // Instantiate order object
         $order = new WC_QuickPay_Order($order_number);
         // Get last transaction in operation history
         $transaction = end($json->operations);
         // Is the transaction accepted?
         if ($json->accepted) {
             // Add order transaction fee
             $order->add_transaction_fee($transaction->amount);
             // Perform action depending on the operation status type
             try {
                 switch ($transaction->type) {
                     //
                     // Cancel callbacks are currently not supported by the QuickPay API
                     //
                     case 'cancel':
                         if (WC_QuickPay_Helper::subscription_is_active()) {
                             if ($order->contains_subscription()) {
                                 WC_Subscriptions_Manager::cancel_subscriptions_for_order($order->id);
                             }
                         }
                         // Write a note to the order history
                         $order->note(__('Payment cancelled.', 'woo-quickpay'));
                         break;
                     case 'capture':
                         // Write a note to the order history
                         $order->note(__('Payment captured.', 'woo-quickpay'));
                         break;
                     case 'refund':
                         $order->note(sprintf(__('Refunded %s %s', 'woo-quickpay'), WC_QuickPay_Helper::price_normalize($transaction->amount), $json->currency));
                         break;
                     case 'authorize':
                         // Set the transaction ID
                         $order->set_transaction_id($json->id);
                         // Set the transaction order ID
                         $order->set_transaction_order_id($json->order_id);
                         // Remove payment link
                         $order->delete_payment_link();
                         // Remove payment ID, now we have the transaction ID
                         $order->delete_payment_id();
                         // Subscription authorization
                         if (isset($json->type) and strtolower($json->type) == 'subscription') {
                             // Create subscription instance
                             $subscription = new WC_QuickPay_API_Subscription($request_body);
                             // Write log
                             $order->note(sprintf(__('Subscription authorized. Transaction ID: %s', 'woo-quickpay'), $json->id));
                             // If 'capture first payment on subscription' is enabled
                             if (WC_QuickPay_Helper::option_is_enabled($this->s('quickpay_autodraw_subscription'))) {
                                 // Check if there is an initial payment on the subscription
                                 $subscription_initial_payment = WC_Subscriptions_Order::get_total_initial_payment($order);
                                 // Only make an instant payment if there is an initial payment
                                 if ($subscription_initial_payment > 0) {
                                     // New subscription instance
                                     $subscription = new WC_QuickPay_API_Subscription();
                                     // Perform API recurring payment request
                                     $recurring = $subscription->recurring($json->id, $order, $subscription_initial_payment);
                                     // Process the recurring response data
                                     WC_QuickPay_API_Subscription::process_recurring_response($recurring, $order);
                                 }
                             }
                         } else {
                             // Write a note to the order history
                             $order->note(sprintf(__('Payment authorized. Transaction ID: %s', 'woo-quickpay'), $json->id));
                         }
                         // Register the payment on the order
                         $order->payment_complete();
                         break;
                 }
             } catch (QuickPay_API_Exception $e) {
                 $e->write_to_logs();
             }
         } else {
             // Write debug information
             $this->log->separator();
             $this->log->add(sprintf(__('Transaction failed for #%s.', 'woo-quickpay'), $order_number));
             $this->log->add(sprintf(__('QuickPay status code: %s.', 'woo-quickpay'), $transaction->qp_status_code));
             $this->log->add(sprintf(__('QuickPay status message: %s.', 'woo-quickpay'), $transaction->qp_status_msg));
             $this->log->add(sprintf(__('Acquirer status code: %s', 'woo-quickpay'), $transaction->aq_status_code));
             $this->log->add(sprintf(__('Acquirer status message: %s', 'woo-quickpay'), $transaction->aq_status_msg));
             $this->log->separator();
             // Update the order statuses
             if ($transaction->type == 'subscribe' or $transaction->type == 'recurring') {
                 WC_Subscriptions_Manager::process_subscription_payment_failure_on_order($order);
             } else {
                 $order->update_status('failed');
             }
         }
     } else {
         $this->log->add(sprintf(__('Invalid callback body for order #%s.', 'woo-quickpay'), $order_number));
     }
 }
 /**
  * Override the default PayPal standard args in WooCommerce for subscription purchases when
  * automatic payments are enabled and when the recurring order totals is over $0.00 (because
  * PayPal doesn't support subscriptions with a $0 recurring total, we need to circumvent it and
  * manage it entirely ourselves.)
  *
  * Based on the HTML Variables documented here: https://developer.paypal.com/webapps/developer/docs/classic/paypal-payments-standard/integration-guide/Appx_websitestandard_htmlvariables/#id08A6HI00JQU
  *
  * @since 1.0
  */
 public static function paypal_standard_subscription_args($paypal_args)
 {
     extract(self::get_order_id_and_key($paypal_args));
     $order = new WC_Order($order_id);
     if ($cart_item = WC_Subscriptions_Cart::cart_contains_failed_renewal_order_payment() || false !== WC_Subscriptions_Renewal_Order::get_failed_order_replaced_by($order_id)) {
         $renewal_order = $order;
         $order = WC_Subscriptions_Renewal_Order::get_parent_order($renewal_order);
         $order_contains_failed_renewal = true;
     } else {
         $order_contains_failed_renewal = false;
     }
     if ($order_contains_failed_renewal || WC_Subscriptions_Order::order_contains_subscription($order) && WC_Subscriptions_Order::get_recurring_total($order) > 0 && 'yes' !== get_option(WC_Subscriptions_Admin::$option_prefix . '_turn_off_automatic_payments', 'no')) {
         // Only one subscription allowed in the cart when PayPal Standard is active
         $product = $order->get_product_from_item(array_pop(WC_Subscriptions_Order::get_recurring_items($order)));
         // It's a subscription
         $paypal_args['cmd'] = '_xclick-subscriptions';
         if (count($order->get_items()) > 1) {
             foreach ($order->get_items() as $item) {
                 if ($item['qty'] > 1) {
                     $item_names[] = $item['qty'] . ' x ' . self::paypal_item_name($item['name']);
                 } elseif ($item['qty'] > 0) {
                     $item_names[] = self::paypal_item_name($item['name']);
                 }
             }
             $paypal_args['item_name'] = self::paypal_item_name(sprintf(__('Order %s', 'woocommerce-subscriptions'), $order->get_order_number() . " - " . implode(', ', $item_names)));
         } else {
             $paypal_args['item_name'] = self::paypal_item_name($product->get_title());
         }
         $unconverted_periods = array('billing_period' => WC_Subscriptions_Order::get_subscription_period($order), 'trial_period' => WC_Subscriptions_Order::get_subscription_trial_period($order));
         $converted_periods = array();
         // Convert period strings into PayPay's format
         foreach ($unconverted_periods as $key => $period) {
             switch (strtolower($period)) {
                 case 'day':
                     $converted_periods[$key] = 'D';
                     break;
                 case 'week':
                     $converted_periods[$key] = 'W';
                     break;
                 case 'year':
                     $converted_periods[$key] = 'Y';
                     break;
                 case 'month':
                 default:
                     $converted_periods[$key] = 'M';
                     break;
             }
         }
         $price_per_period = WC_Subscriptions_Order::get_recurring_total($order);
         $subscription_interval = WC_Subscriptions_Order::get_subscription_interval($order);
         $subscription_length = WC_Subscriptions_Order::get_subscription_length($order);
         $subscription_installments = $subscription_length / $subscription_interval;
         $is_payment_change = WC_Subscriptions_Change_Payment_Gateway::$is_request_to_change_payment;
         $is_switch_order = WC_Subscriptions_Switcher::order_contains_subscription_switch($order->id);
         $is_synced_subscription = WC_Subscriptions_Synchroniser::order_contains_synced_subscription($order->id);
         $sign_up_fee = $is_payment_change ? 0 : WC_Subscriptions_Order::get_sign_up_fee($order);
         $initial_payment = $is_payment_change ? 0 : WC_Subscriptions_Order::get_total_initial_payment($order);
         if ($is_payment_change) {
             // Add a nonce to the order ID to avoid "This invoice has already been paid" error when changing payment method to PayPal when it was previously PayPal
             $paypal_args['invoice'] = $paypal_args['invoice'] . '-wcscpm-' . wp_create_nonce();
         } elseif ($order_contains_failed_renewal) {
             // Set the invoice details to the original order's invoice but also append a special string and this renewal orders ID so that we can match it up as a failed renewal order payment later
             $paypal_args['invoice'] = self::$invoice_prefix . ltrim($order->get_order_number(), '#') . '-wcsfrp-' . $renewal_order->id;
             $paypal_args['custom'] = serialize(array($order->id, $order->order_key));
         }
         if ($order_contains_failed_renewal) {
             $sign_up_fee = 0;
             $initial_payment = $renewal_order->get_total();
             // Initial payment can be left in case the customer is purchased other products with the payment
             $subscription_trial_length = 0;
             $subscription_installments = max($subscription_installments - WC_Subscriptions_Manager::get_subscriptions_completed_payment_count(WC_Subscriptions_Manager::get_subscription_key($order_id, $product->id)), 0);
             // If we're changing the payment date or switching subs, we need to set the trial period to the next payment date & installments to be the number of installments left
         } elseif ($is_payment_change || $is_switch_order || $is_synced_subscription) {
             $subscription_key = WC_Subscriptions_Manager::get_subscription_key($order_id, $product->id);
             // Give a free trial until the next payment date
             if ($is_switch_order) {
                 $next_payment_timestamp = get_post_meta($order->id, '_switched_subscription_first_payment_timestamp', true);
             } elseif ($is_synced_subscription) {
                 $next_payment_timestamp = WC_Subscriptions_Synchroniser::calculate_first_payment_date($product, 'timestamp');
             } else {
                 $next_payment_timestamp = WC_Subscriptions_Manager::get_next_payment_date($subscription_key, $order->user_id, 'timestamp');
             }
             // When the subscription is on hold
             if ($next_payment_timestamp != false && !empty($next_payment_timestamp)) {
                 $trial_until = self::calculate_trial_periods_until($next_payment_timestamp);
                 $subscription_trial_length = $trial_until['first_trial_length'];
                 $converted_periods['trial_period'] = $trial_until['first_trial_period'];
                 $second_trial_length = $trial_until['second_trial_length'];
                 $second_trial_period = $trial_until['second_trial_period'];
             } else {
                 $subscription_trial_length = 0;
             }
             // If is a payment change, we need to account for completed payments on the number of installments owing
             if ($is_payment_change && $subscription_length > 0) {
                 $subscription_installments -= WC_Subscriptions_Manager::get_subscriptions_completed_payment_count($subscription_key);
             }
         } else {
             $subscription_trial_length = WC_Subscriptions_Order::get_subscription_trial_length($order);
         }
         if ($subscription_trial_length > 0) {
             // Specify a free trial period
             if ($is_switch_order || $is_synced_subscription || $initial_payment != $sign_up_fee) {
                 $paypal_args['a1'] = $initial_payment > 0 ? $initial_payment : 0;
             } else {
                 $paypal_args['a1'] = $sign_up_fee > 0 ? $sign_up_fee : 0;
                 // Maybe add the sign up fee to the free trial period
             }
             // Trial period length
             $paypal_args['p1'] = $subscription_trial_length;
             // Trial period
             $paypal_args['t1'] = $converted_periods['trial_period'];
             // We need to use a second trial period before we have more than 90 days until the next payment
             if (isset($second_trial_length) && $second_trial_length > 0) {
                 $paypal_args['a2'] = 0.01;
                 // Alas, although it's undocumented, PayPal appears to require a non-zero value in order to allow a second trial period
                 $paypal_args['p2'] = $second_trial_length;
                 $paypal_args['t2'] = $second_trial_period;
             }
         } elseif ($sign_up_fee > 0 || $initial_payment != $price_per_period) {
             // No trial period, so charge sign up fee and per period price for the first period
             if ($subscription_installments == 1) {
                 $param_number = 3;
             } else {
                 $param_number = 1;
             }
             $paypal_args['a' . $param_number] = $initial_payment;
             // Sign Up interval
             $paypal_args['p' . $param_number] = $subscription_interval;
             // Sign Up unit of duration
             $paypal_args['t' . $param_number] = $converted_periods['billing_period'];
         }
         // We have a recurring payment
         if (!isset($param_number) || $param_number == 1) {
             // Subscription price
             $paypal_args['a3'] = $price_per_period;
             // Subscription duration
             $paypal_args['p3'] = $subscription_interval;
             // Subscription period
             $paypal_args['t3'] = $converted_periods['billing_period'];
         }
         // Recurring payments
         if ($subscription_installments == 1 || $sign_up_fee > 0 && $subscription_trial_length == 0 && $subscription_installments == 2) {
             // Non-recurring payments
             $paypal_args['src'] = 0;
         } else {
             $paypal_args['src'] = 1;
             if ($subscription_installments > 0) {
                 if ($sign_up_fee > 0 && $subscription_trial_length == 0) {
                     // An initial period is being used to charge a sign-up fee
                     $subscription_installments--;
                 }
                 $paypal_args['srt'] = $subscription_installments;
             }
         }
         // Don't reattempt failed payments, instead let Subscriptions handle the failed payment
         $paypal_args['sra'] = 0;
         // Force return URL so that order description & instructions display
         $paypal_args['rm'] = 2;
     }
     return $paypal_args;
 }
 /**
  * Process the subscription
  *
  * @param int $order_id
  * @return array
  */
 public function process_subscription($order_id, $retry = true)
 {
     $order = new WC_Order($order_id);
     $stripe_token = isset($_POST['stripe_token']) ? wc_clean($_POST['stripe_token']) : '';
     $card_id = isset($_POST['stripe_card_id']) ? wc_clean($_POST['stripe_card_id']) : '';
     $customer_id = is_user_logged_in() ? get_user_meta(get_current_user_id(), '_stripe_customer_id', true) : 0;
     if (!$customer_id || !is_string($customer_id)) {
         $customer_id = 0;
     }
     // Use Stripe CURL API for payment
     try {
         $post_data = array();
         // Pay using a saved card!
         if ($card_id !== 'new' && $card_id && $customer_id) {
             $post_data['customer'] = $customer_id;
             $post_data['card'] = $card_id;
         } elseif (empty($stripe_token)) {
             $error_msg = __('Please make sure your card details have been entered correctly and that your browser supports JavaScript.', 'woocommerce-gateway-stripe');
             if ($this->testmode) {
                 $error_msg .= ' ' . __('Developers: Please make sure that you are including jQuery and there are no JavaScript errors on the page.', 'woocommerce-gateway-stripe');
             }
             throw new Exception($error_msg);
         }
         // Save token
         if (!$customer_id) {
             $customer_id = $this->add_customer($order, $stripe_token);
             if (is_wp_error($customer_id)) {
                 throw new Exception($customer_id->get_error_message());
             }
             unset($post_data['card']);
             $post_data['customer'] = $customer_id;
         } elseif (!$card_id || $card_id === 'new') {
             $card_id = $this->add_card($customer_id, $stripe_token);
             if (is_wp_error($card_id)) {
                 // Customer param wrong? The user may have been deleted on stripe's end. Remove customer_id and retry.
                 if ('customer' === $card_id->get_error_code() && $retry) {
                     delete_user_meta(get_current_user_id(), '_stripe_customer_id');
                     return $this->process_subscription($order_id, false);
                     // false to prevent retry again (endless loop)
                 }
                 throw new Exception($card_id->get_error_message());
             }
             $post_data['card'] = $card_id;
             $post_data['customer'] = $customer_id;
         }
         // Store the ID in the order
         update_post_meta($order_id, '_stripe_customer_id', $customer_id);
         update_post_meta($order_id, '_stripe_card_id', $card_id);
         $initial_payment = WC_Subscriptions_Order::get_total_initial_payment($order);
         if ($initial_payment > 0) {
             $payment_response = $this->process_subscription_payment($order, $initial_payment);
         }
         if (isset($payment_response) && is_wp_error($payment_response)) {
             throw new Exception($payment_response->get_error_message());
         } else {
             if (isset($payment_response->balance_transaction) && isset($payment_response->balance_transaction->fee)) {
                 $fee = number_format($payment_response->balance_transaction->fee / 100, 2, '.', '');
                 update_post_meta($order->id, 'Stripe Fee', $fee);
                 update_post_meta($order->id, 'Net Revenue From Stripe', $order->order_total - $fee);
             }
             // Payment complete
             $order->payment_complete($payment_response->id);
             // Remove cart
             WC()->cart->empty_cart();
             // Activate subscriptions
             WC_Subscriptions_Manager::activate_subscriptions_for_order($order);
             // Return thank you page redirect
             return array('result' => 'success', 'redirect' => $this->get_return_url($order));
         }
     } catch (Exception $e) {
         wc_add_notice(__('Error:', 'woocommerce-gateway-stripe') . ' "' . $e->getMessage() . '"', 'error');
         return;
     }
 }
 /**
  * Process the payment and return the result
  **/
 function process_payment($order_id)
 {
     global $woocommerce;
     $order = new WC_Order($order_id);
     if (class_exists("WC_Subscriptions_Order") && WC_Subscriptions_Order::order_contains_subscription($order)) {
         // Charge sign up fee + first period here..
         // Periodic charging should happen via scheduled_subscription_payment_fatzebra
         $amount = (int) (WC_Subscriptions_Order::get_total_initial_payment($order) * 100);
     } else {
         $amount = (int) ($order->order_total * 100);
     }
     $page_url = $this->parent_settings["sandbox_mode"] == "yes" ? $this->sandbox_paynow_url : $this->live_paynow_url;
     $_SESSION['masterpass_order_id'] = $order_id;
     $username = $this->parent_settings["username"];
     $currency = $order->get_order_currency();
     $reference = (string) $order_id;
     $return_args = array('wc-api' => 'WC_FatZebra_MasterPass', "echo[order_id]" => $order_id);
     if ($amount === 0) {
         $return_args["echo[tokenize]"] = true;
     }
     $return_path = str_replace('https:', 'http:', add_query_arg($return_args, home_url('/')));
     $verification_string = implode(":", array($reference, $amount, $currency, $return_path));
     $verification_value = hash_hmac("md5", $verification_string, $this->settings["shared_secret"]);
     $redirect = "{$page_url}/{$username}/{$reference}/{$currency}/{$amount}/{$verification_value}?masterpass=true&iframe=true&return_path=" . urlencode($return_path);
     if ($amount === 0) {
         $redirect .= "&tokenize_only=true";
     }
     $result = array('result' => 'success', 'redirect' => $redirect);
     return $result;
 }
 /**
  * Calculate the maximum amount that can be charged throughout the life of a subscription. Amazon displays this
  * to the customer when they're authorizing their payment.
  *
  * @since 2.0
  * @param WC_Order $order the WC order object
  * @return float the maximum total amount that can be charged, rounded to the nearest whole number
  */
 private function calculate_lifetime_subscription_total(WC_Order $order)
 {
     // start with the total initial payment, which includes any sign up fee or one-off shipping/tax charge
     $total = WC_Subscriptions_Order::get_total_initial_payment($order);
     // add the total from all the recurring periods
     if (WC_Subscriptions_Order::get_subscription_length($order) > 0) {
         $total += WC_Subscriptions_Order::get_recurring_total($order) * WC_Subscriptions_Order::get_subscription_length($order);
         // If a subscription never ends, use 5 years worth of recurring charges as a sensible maximum
     } else {
         // first get the subscription period in year terms
         switch (WC_Subscriptions_Order::get_subscription_period($order)) {
             case 'day':
                 $period = 365;
                 break;
             case 'week':
                 $period = 52;
                 break;
             case 'month':
                 $period = 12;
                 break;
             case 'year':
                 $period = 1;
                 break;
             default:
                 $period = 1;
                 break;
         }
         // divide by the interval (e.g. recurs every Xth week)
         $period = $period / WC_Subscriptions_Order::get_subscription_interval($order);
         // multiply by recurring total per period by the number of periods in a year by 5 years to get the total
         $total += WC_Subscriptions_Order::get_recurring_total($order) * $period * 5;
     }
     // finally increase by 25% to account for price increases / upgrades
     $total *= 1.25;
     /**
      * Round to whole number and allow an entirely different total to be set
      *
      * @since 2.0
      * @param float $lifetime_subscription_total the total amount that may be charged, as shown to the customer during checkout @ Amazon
      * @param WC_Order $order the WC Order object
      */
     return apply_filters('wc_amazon_fps_lifetime_subscription_total', round($total, 0), $order);
 }
 /**
  * Process the payment and return the result
  **/
 function process_payment($order_id)
 {
     global $woocommerce;
     $this->params["customer_ip"] = $this->get_customer_real_ip();
     $defer_payment = $this->parent_settings["deferred_payments"] == "yes";
     $test_mode = $this->parent_settings["test_mode"] == "yes";
     $order = new WC_Order($order_id);
     $this->params["currency"] = $order->get_order_currency();
     if (class_exists("WC_Subscriptions_Order") && WC_Subscriptions_Order::order_contains_subscription($order)) {
         // No deferred payments for subscriptions.
         $defer_payment = false;
         // Charge sign up fee + first period here..
         // Periodic charging should happen via scheduled_subscription_payment_fatzebra
         $this->params["amount"] = (int) (WC_Subscriptions_Order::get_total_initial_payment($order) * 100);
     } else {
         $this->params["amount"] = (int) ($order->order_total * 100);
     }
     $this->params["reference"] = (string) $order_id;
     $this->params["test"] = $test_mode;
     $this->params["deferred"] = $defer_payment;
     $this->params["wallet"] = array("type" => "VISA", "callid" => $_POST['callid']);
     if (isset($_POST['token'])) {
         $this->params['card_token'] = $_POST['token'];
     }
     if ($this->parent_settings['fraud_data'] == 'yes') {
         $fz_base = new WC_FatZebra();
         $fraud_data = $fz_base->get_fraud_payload($order);
         $this->params['fraud'] = $fraud_data;
     }
     if ($this->params["amount"] === 0) {
         $result = $this->tokenize_card($this->params);
     } else {
         $result = $this->do_payment($this->params);
     }
     if (is_wp_error($result)) {
         switch ($result->get_error_code()) {
             case 1:
                 // Non-200 response, so failed... (e.g. 401, 403, 500 etc).
                 $order->add_order_note($result->get_error_message());
                 wc_add_notice($result->get_error_message(), 'error');
                 break;
             case 2:
                 // Gateway error (data etc)
                 $errors = $result->get_error_data();
                 foreach ($errors as $error) {
                     $order->add_order_note("Gateway Error: " . $error);
                 }
                 error_log("WooCommerce Fat Zebra - Gateway Error: " . print_r($errors, true));
                 wc_add_notice("Payment Failed: " . implode(", ", $errors), 'error');
                 break;
             case 3:
                 // Declined - error data is array with keys: message, id
                 $order->add_order_note(__("Payment Declined: " . $this->response_data->response->message . ". Reference: " . $this->response_data->response->transaction_id));
                 wc_add_notice("Payment declined: " . $this->response_data->response->message, 'error');
                 if (isset($this->response_data->response->fraud_result) && !empty($this->response_data->response->fraud_result)) {
                     if ($this->response_data->response->fraud_result == 'Accept') {
                         $order->add_order_note("Fraud Check Result: Accept");
                     } else {
                         $order->add_order_note("Fraud Check Result: " . $this->response_data->response->fraud_result . " - " . implode(", ", $this->response_data->response->fraud_messages));
                     }
                 }
                 break;
             case 4:
                 // Exception caught, something bad happened. Data is exception
             // Exception caught, something bad happened. Data is exception
             default:
                 wc_add_notice("Unknown error.", 'error');
                 $order->add_order_note(__("Unknown Error (exception): " . print_r($result->get_error_data(), true)));
                 break;
         }
         return;
     } else {
         // Success! Returned is an array with the transaction ID etc
         // For a deferred payment we set the status to on-hold and then add a detailed note for review.
         if ($defer_payment) {
             $date = new DateTime($result["card_expiry"], new DateTimeZone("Australia/Sydney"));
             $note = "Deferred Payment:<ul><li>Card Token: " . $result["card_token"] . "</li><li>Card Holder: " . $result["card_holder"] . "</li><li>Card Number: " . $result["card_number"] . "</li><li>Expiry: " . $date->format("m/Y") . "</li></ul>";
             $order->update_status("on-hold", $note);
             update_post_meta($order_id, "_fatzebra_card_token", $result["card_token"]);
             update_post_meta($order_id, "fatzebra_card_token", $result["card_token"]);
         } else {
             if ($this->params["amount"] === 0) {
                 $order->add_order_note(__("Fat Zebra payment complete - \$0 initial amount, card tokenized. Card token: " . $result["card_token"]));
             } else {
                 $order->add_order_note(__("Fat Zebra payment complete. Reference: " . $result["transaction_id"]));
             }
             if (isset($this->response_data->response->fraud_result) && !empty($this->response_data->response->fraud_result)) {
                 if ($this->response_data->response->fraud_result == 'Accept') {
                     $order->add_order_note("Fraud Check Result: Accept");
                 } else {
                     $order->add_order_note("Fraud Check Result: " . $this->response_data->response->fraud_result . " - " . implode(", ", $this->response_data->response->fraud_messages));
                 }
             }
             $order->payment_complete($result['transaction_id']);
             // Clear the session values
             $this->clear_visa_checkout_session_values();
             // Store the card token as post meta
             update_post_meta($order_id, "_fatzebra_card_token", $result["card_token"]);
             update_post_meta($order_id, "fatzebra_card_token", $result["card_token"]);
         }
         $woocommerce->cart->empty_cart();
         return array('result' => 'success', 'redirect' => $this->get_return_url($order));
     }
 }
 /**
  * Process initial payment for a subscription
  *
  * @since 2.0
  * @param \WC_Order $order the order object
  * @return array
  */
 private function process_subscription_payment($order)
 {
     // get subscription amount
     $order->braintree_order['amount'] = WC_Subscriptions_Order::get_total_initial_payment($order);
     // create new braintree customer if needed
     if (empty($order->braintree_order['customerId'])) {
         $order = $this->create_customer($order);
     }
     // save card in vault if customer is using new card
     if (empty($order->braintree_order['paymentMethodToken'])) {
         $order = $this->create_credit_card($order);
     } else {
         // save payment token to order when processing $0 total subscriptions (e.g. those with a free trial)
         if (0 == $order->braintree_order['amount']) {
             update_post_meta($order->id, '_wc_braintree_cc_token', $order->braintree_order['paymentMethodToken']);
         }
     }
     // process transaction (the order amount will be $0 if a free trial exists)
     // note that customer ID & credit card token are saved to order when create_customer() or create_credit_card() are called
     if (0 == $order->braintree_order['amount'] || $this->do_transaction($order)) {
         // mark order as having received payment
         $order->payment_complete();
         SV_WC_Plugin_Compatibility::WC()->cart->empty_cart();
         return array('result' => 'success', 'redirect' => $this->get_return_url($order));
     }
 }
 /**
  * Override the default PayPal standard args in WooCommerce for subscription purchases.
  *
  * @since 1.0
  */
 public static function paypal_standard_subscription_args($paypal_args)
 {
     extract(self::get_order_id_and_key($paypal_args));
     if (WC_Subscriptions_Order::order_contains_subscription($order_id) && 'yes' !== get_option(WC_Subscriptions_Admin::$option_prefix . '_turn_off_automatic_payments', 'no')) {
         $order = new WC_Order($order_id);
         $order_items = $order->get_items();
         // Only one subscription allowed in the cart when PayPal Standard is active
         $product = $order->get_product_from_item(array_pop($order_items));
         // It's a subscription
         $paypal_args['cmd'] = '_xclick-subscriptions';
         if (count($order->get_items()) > 1) {
             foreach ($order->get_items() as $item) {
                 if ($item['qty'] > 1) {
                     $item_names[] = $item['qty'] . ' x ' . $item['name'];
                 } else {
                     if ($item['qty'] > 0) {
                         $item_names[] = $item['name'];
                     }
                 }
             }
             $paypal_args['item_name'] = sprintf(__('Order %s', WC_Subscriptions::$text_domain), $order->get_order_number());
         } else {
             $paypal_args['item_name'] = $product->get_title();
         }
         $unconverted_periods = array('billing_period' => WC_Subscriptions_Order::get_subscription_period($order), 'trial_period' => WC_Subscriptions_Order::get_subscription_trial_period($order));
         $converted_periods = array();
         // Convert period strings into PayPay's format
         foreach ($unconverted_periods as $key => $period) {
             switch (strtolower($period)) {
                 case 'day':
                     $converted_periods[$key] = 'D';
                     break;
                 case 'week':
                     $converted_periods[$key] = 'W';
                     break;
                 case 'year':
                     $converted_periods[$key] = 'Y';
                     break;
                 case 'month':
                 default:
                     $converted_periods[$key] = 'M';
                     break;
             }
         }
         $sign_up_fee = WC_Subscriptions_Order::get_sign_up_fee($order);
         $initial_payment = WC_Subscriptions_Order::get_total_initial_payment($order);
         $price_per_period = WC_Subscriptions_Order::get_recurring_total($order);
         $subscription_interval = WC_Subscriptions_Order::get_subscription_interval($order);
         $subscription_installments = WC_Subscriptions_Order::get_subscription_length($order) / $subscription_interval;
         $subscription_trial_length = WC_Subscriptions_Order::get_subscription_trial_length($order);
         if ($subscription_trial_length > 0) {
             // Specify a free trial period
             $paypal_args['a1'] = $sign_up_fee > 0 ? $sign_up_fee : 0;
             // Maybe add the sign up fee to the free trial period
             // Trial period length
             $paypal_args['p1'] = $subscription_trial_length;
             // Trial period
             $paypal_args['t1'] = $converted_periods['trial_period'];
         } elseif ($sign_up_fee > 0 || $initial_payment !== $price_per_period) {
             // No trial period, so charge sign up fee and per period price for the first period
             if ($subscription_installments == 1) {
                 $param_number = 3;
             } else {
                 $param_number = 1;
             }
             $paypal_args['a' . $param_number] = $initial_payment;
             // Sign Up interval
             $paypal_args['p' . $param_number] = $subscription_interval;
             // Sign Up unit of duration
             $paypal_args['t' . $param_number] = $converted_periods['billing_period'];
         }
         // We have a recurring payment
         if (!isset($param_number) || $param_number == 1) {
             // Subscription price
             $paypal_args['a3'] = $price_per_period;
             // Subscription duration
             $paypal_args['p3'] = $subscription_interval;
             // Subscription period
             $paypal_args['t3'] = $converted_periods['billing_period'];
         }
         // Recurring payments
         if ($subscription_installments == 1 || $sign_up_fee > 0 && $subscription_trial_length == 0 && $subscription_installments == 2) {
             // Non-recurring payments
             $paypal_args['src'] = 0;
         } else {
             $paypal_args['src'] = 1;
             if ($subscription_installments > 0) {
                 if ($sign_up_fee > 0 && $subscription_trial_length == 0) {
                     // An initial period is being used to charge a sign-up fee
                     $subscription_installments--;
                 }
                 $paypal_args['srt'] = $subscription_installments;
             }
         }
         // Force return URL so that order description & instructions display
         $paypal_args['rm'] = 2;
     }
     return $paypal_args;
 }
Exemplo n.º 22
0
		/**
		 * Relay response - handles response from NAB Transact CRN
		 * At this stage we've just added a CRN record, and now we must process the payment to this CRN
		 * 
		 * @since 1.2.0
		 */
		function relay_response_crn() {
			global $woocommerce;

			// Process response
			$response = new stdClass;
			foreach ($_GET as $key => $value) {
				$response->$key = $value;
			}
		    foreach ($_POST as $key => $value) {
	            $response->$key = $value;
	        }

			if ( ! empty( $response->order ) ) {
		    
		        $order = new WC_Order( (int) $response->order );

				if ((!isset($response->afrescode) || $response->afrescode=='400' || $response->afrescode=='000') && ($response->rescode == '00' || $response->rescode == '08' || $response->rescode == '11')) { // Approved
					if ($order->key_is_valid( $response->key ) && $order->status != 'completed' && $order->status != 'processing') {

						// Save CRN to order meta also
						$this->save_subscription_meta( (int)$response->order , $response->CRN);

						// Add Order Note
						$order->add_order_note(__('Credit card details stored.','wc-nab'));

						if (!function_exists('wcs_get_subscriptions_for_order')) {
							$amount = WC_Subscriptions_Order::get_total_initial_payment($order);
						} else {
							$amount = $order->get_total();
						}

						if (isset($response->is_payment_change) && $response->is_payment_change == '1' && get_post_meta($order->id,'_is_mid_change_method',true)) {
							$amount = 0;
							delete_post_meta($order->id,'_is_mid_change_method',true);
						}

						if ($amount == 0) {
							$order->payment_complete();
						} else {
							// Now to process payment, but only if it hasn't already been done
							// (this url is used by result AND return)
							if ($order->status != 'completed') {
								$data = array(
									'crn'=>$response->CRN,
									'amountcents'=>($amount*100),
									'reference'=>substr(urlencode($response->order.'-'.$order->order_key),0,32),
									'currency'=>get_woocommerce_currency());
								$payment_xml = $this->generatePaymentXMLMessage($data);
								$payment_result = $this->send($payment_xml,$this->xmlapiurl,true);

								$result_object = simplexml_load_string($payment_result); 


								if ($result_object->Periodic->PeriodicList->PeriodicItem->responseCode == '00' || $result_object->Periodic->PeriodicList->PeriodicItem->responseCode == '08' || $result_object->Periodic->PeriodicList->PeriodicItem->responseCode == '11') {
									// Payment success!
									$order->add_order_note(sprintf(__("NAB Transaction id: %s\r\nNAB Settlement date: %s",'wc-nab'),$result_object->Periodic->PeriodicList->PeriodicItem->txnID,$result_object->Periodic->PeriodicList->PeriodicItem->settlementDate));

									$order->payment_complete((string)$result_object->Periodic->PeriodicList->PeriodicItem->txnID);
									// Remove cart
									$woocommerce->cart->empty_cart();

								} else {
									if ($order->status != 'completed' && $order->status != 'processing') {
										$order->update_status( 'failed', sprintf(__("NAB error whilst processing payment via XML API using CRN: code %s - %s.", 'wc-nab'), $result_object->Status->statusCode, $result_object->Status->statusDescription) );
									}
								}
							}
						}

					} else { // payment received but order key didn't match!

						// Key did not match order id
						$order->add_order_note( sprintf(__('Payment received, but order ID did not match key: code %s - %s.', 'wc-nab'), $response->response_code, $response->response_reason_text ) );

						// Put on hold if pending
						if ($order->status == 'pending' || $order->status == 'failed') {
							$order->update_status( 'on-hold' );
						}
					}
				} else { // Transaction failed
					if ($order->status != 'completed' && $order->status != 'processing') {
						$order->update_status( 'failed', sprintf(__("NAB error whilst adding CRN: code %s - %s. PAYMENT NOT PROCESSED!", 'wc-nab'), $response->rescode, $response->restext) );
					}
				}
				
				// It's possible we just processed a change of payment method, not a proper order
		        // so we might want to just go back to the My Account page
		        if (isset($_GET['is_payment_change']) && $_GET['is_payment_change'] == '1') {
		        	wp_redirect(get_permalink( woocommerce_get_page_id( 'myaccount' ) ));
		        } else {
		        	wp_redirect( $this->get_return_url( $order ) );
		        }
				exit;

			}
			wp_redirect( $this->get_return_url() );
			exit;
		}
 /**
  * Filters WC_Subscriptions_Order::get_sign_up_fee() to make sure the sign-up fee for a subscription product
  * that is synchronised is returned correctly.
  *
  * @param float The initial sign-up fee charged when the subscription product in the order was first purchased, if any.
  * @param mixed $order A WC_Order object or the ID of the order which the subscription was purchased in.
  * @param int $product_id The post ID of the subscription WC_Product object purchased in the order. Defaults to the ID of the first product purchased in the order.
  * @return float The initial sign-up fee charged when the subscription product in the order was first purchased, if any.
  * @since 1.5.3
  */
 public static function get_sign_up_fee($sign_up_fee, $order, $product_id, $non_subscription_total)
 {
     if (self::order_contains_synced_subscription($order->id) && WC_Subscriptions_Order::get_subscription_trial_length($order) < 1) {
         $sign_up_fee = max(WC_Subscriptions_Order::get_total_initial_payment($order) - $non_subscription_total, 0);
     }
     return $sign_up_fee;
 }
        /**
         * Generate the epay button link
         **/
        public function generate_epay_form($order_id)
        {
            global $woocommerce;
            $order = new WC_Order($order_id);
            $epay_args = array('merchantnumber' => $this->merchant, 'windowid' => $this->windowid, 'windowstate' => $this->windowstate, 'instantcallback' => 1, 'instantcapture' => $this->yesnotoint($this->instantcapture), 'group' => $this->group, 'mailreceipt' => $this->authmail, 'ownreceipt' => $this->yesnotoint($this->ownreceipt), 'amount' => class_exists('WC_Subscriptions_Order') ? WC_Subscriptions_Order::order_contains_subscription($order) ? WC_Subscriptions_Order::get_total_initial_payment($order) * 100 : $order->order_total * 100 : $order->order_total * 100, 'orderid' => str_replace(_x('#', 'hash before order number', 'woocommerce'), "", $order->get_order_number()), 'currency' => get_woocommerce_currency(), 'callbackurl' => $this->fix_url(add_query_arg('wooorderid', $order_id, add_query_arg('wc-api', 'WC_Gateway_EPayDk', $this->get_return_url($order)))), 'accepturl' => $this->fix_url($this->get_return_url($order)), 'cancelurl' => $this->fix_url($order->get_cancel_order_url()), 'language' => $this->get_language_code(get_locale()), 'subscription' => class_exists('WC_Subscriptions_Order') ? WC_Subscriptions_Order::order_contains_subscription($order) ? 1 : 0 : 0);
            if ($this->settings["enableinvoice"] == "yes") {
                $invoice = array();
                $invoice["customer"] = array("emailaddress" => $order->billing_email, "firstname" => $this->jsonValueRemoveSpecialCharacters($order->billing_first_name), "lastname" => $this->jsonValueRemoveSpecialCharacters($order->billing_last_name), "address" => $this->jsonValueRemoveSpecialCharacters($order->billing_address_1 . ($order->billing_address_2 != null) ? ' ' . $order->billing_address_2 : ''), "zip" => $order->billing_postcode, "city" => $order->billing_city, "country" => $order->billing_country);
                $invoice["shippingaddress"] = array("firstname" => $this->jsonValueRemoveSpecialCharacters($order->shipping_first_name), "lastname" => $this->jsonValueRemoveSpecialCharacters($order->shipping_last_name), "address" => $this->jsonValueRemoveSpecialCharacters($order->shipping_address_1 . ($order->shipping_address_2 != null) ? ' ' . $order->shipping_address_2 : ''), "zip" => $order->shipping_postcode, "city" => $order->shipping_city, "country" => $order->shipping_country);
                $items = $order->get_items();
                foreach ($items as $item) {
                    $invoice["lines"][] = array("id" => $item["product_id"], "description" => $this->jsonValueRemoveSpecialCharacters($item["name"]), "quantity" => $item["qty"], "price" => round($item["line_subtotal"] / $item["qty"] * 100), "vat" => round($item["line_subtotal_tax"] / $item["line_subtotal"] * 100));
                }
                $discount = $order->get_total_discount();
                if ($discount > 0) {
                    $invoice["lines"][] = array("id" => "discount", "description" => "discount", "quantity" => 1, "price" => -round($discount * 100), "vat" => round($order->get_total_tax() / ($order->get_total() - $order->get_total_tax()) * 100));
                }
                $shipping = $order->get_total_shipping();
                if ($shipping > 0) {
                    $invoice["lines"][] = array("id" => "shipping", "description" => "shipping", "quantity" => 1, "price" => round($shipping * 100), "vat" => round($order->get_shipping_tax() / $shipping * 100));
                }
                $epay_args['invoice'] = $this->jsonRemoveUnicodeSequences($invoice);
            }
            if (strlen($this->md5key) > 0) {
                $hash = "";
                foreach ($epay_args as $key => $value) {
                    $hash .= $value;
                }
                $epay_args["hash"] = md5($hash . $this->md5key);
            }
            $epay_args_array = array();
            foreach ($epay_args as $key => $value) {
                $epay_args_array[] = '\'' . esc_attr($key) . '\': \'' . $value . '\'';
            }
            return '<script type="text/javascript">
			function PaymentWindowReady() {
				paymentwindow = new PaymentWindow({					
					' . implode(',', $epay_args_array) . '
				});
				paymentwindow.open();
			}
			</script>
			<script type="text/javascript" src="https://ssl.ditonlinebetalingssystem.dk/integration/ewindow/paymentwindow.js" charset="UTF-8"></script>
			<a class="button" onclick="javascript: paymentwindow.open();" id="submit_epay_payment_form" />' . __('Pay via ePay', 'woocommerce-gateway-epay-dk') . '</a>
			<a class="button cancel" href="' . esc_url($order->get_cancel_order_url()) . '">' . __('Cancel order &amp; restore cart', 'woocommerce-gateway-epay-dk') . '</a>';
        }
 /**
  * Process an initial subscription payment if the order contains a
  * subscription, otherwise use the parent::process_payment() method
  *
  * @since  1.4
  * @param int $order_id the order identifier
  * @return array
  */
 public function process_payment($order_id)
 {
     require_once 'class-wc-realex-api.php';
     // processing subscription (which means we are ineligible for 3DSecure for now)
     if (SV_WC_Plugin_Compatibility::is_wc_subscriptions_version_gte_2_0() ? wcs_order_contains_subscription($order_id) : WC_Subscriptions_Order::order_contains_subscription($order_id)) {
         $order = wc_get_order($order_id);
         // redirect to payment page for payment if 3D secure is enabled
         if ($this->get_threedsecure()->is_3dsecure_available() && !SV_WC_Helper::get_post('woocommerce_pay_page')) {
             // empty cart before redirecting from Checkout page
             WC()->cart->empty_cart();
             // redirect to payment page to continue payment
             return array('result' => 'success', 'redirect' => $order->get_checkout_payment_url(true));
         }
         $order->payment_total = SV_WC_Helper::number_format(SV_WC_Plugin_Compatibility::is_wc_subscriptions_version_gte_2_0() ? $order->get_total() : WC_Subscriptions_Order::get_total_initial_payment($order));
         // create the realex api client
         $realex_client = new Realex_API($this->get_endpoint_url(), $this->get_realvault_endpoint_url(), $this->get_shared_secret());
         // create the customer/cc tokens, and authorize the initial payment amount, if any
         $result = $this->authorize($realex_client, $order);
         // subscription with initial payment, everything is now taken care of
         if (is_array($result)) {
             // for Subscriptions 2.0.x, save payment token to subscription object
             if (SV_WC_Plugin_Compatibility::is_wc_subscriptions_version_gte_2_0()) {
                 // a single order can contain multiple subscriptions
                 foreach (wcs_get_subscriptions_for_order($order->id) as $subscription) {
                     // payment token
                     update_post_meta($subscription->id, '_realex_cardref', get_post_meta($order->id, '_realex_cardref', true));
                 }
             }
             return $result;
         }
         // otherwise there was no initial payment, so we mark the order as complete, etc
         if ($order->payment_total == 0) {
             // mark order as having received payment
             $order->payment_complete();
             WC()->cart->empty_cart();
             return array('result' => 'success', 'redirect' => $this->get_return_url($order));
         }
     } else {
         // processing regular product
         return parent::process_payment($order_id);
     }
 }
 /**
  * Send subscription form data to Stripe
  * Handles sending the charge to an existing customer, a new customer (that's logged in), or a guest
  *
  * @access      protected
  * @return      bool
  */
 protected function subscription_to_stripe()
 {
     // Get the credit card details submitted by the form
     $form_data = $this->get_form_data();
     // If there are errors on the form, don't bother sending to Stripe.
     if ($form_data['errors'] == 1) {
         return;
     }
     // Set up the charge for Stripe's servers
     try {
         // Add a customer or retrieve an existing one
         $description = $this->current_user->user_login . ' (#' . $this->current_user_id . ' - ' . $this->current_user->user_email . ') ' . $form_data['customer']['name'];
         // username (user_id - user_email) Full Name
         $customer = $this->get_customer($description, $form_data);
         // Update default card
         if ($form_data['chosen_card'] !== 'new') {
             $default_card = $this->stripe_customer_info['cards'][(int) $form_data['chosen_card']]['id'];
             S4WC_DB::update_customer($this->current_user_id, array('default_card' => $default_card));
         }
         $initial_payment = WC_Subscriptions_Order::get_total_initial_payment($this->order);
         $charge = $this->process_subscription_payment($this->order, $initial_payment);
         $this->transaction_id = $charge->id;
         // Save data for the "Capture"
         update_post_meta($this->order->id, '_transaction_id', $this->transaction_id);
         update_post_meta($this->order->id, 'capture', strcmp($this->settings['charge_type'], 'authorize') == 0);
         // Save data for cross-reference between Stripe Dashboard and WooCommerce
         update_post_meta($this->order->id, 'customer_id', $customer['customer_id']);
         return true;
     } catch (Exception $e) {
         // Stop page reload if we have errors to show
         unset(WC()->session->reload_checkout);
         $message = $this->get_stripe_error_message($e);
         wc_add_notice(__('Subscription Error:', 'stripe-for-woocommerce') . ' ' . $message, 'error');
         return false;
     }
 }