public function process_payment_start(EE_Line_Item $total_line_item, $transaction = null, $total_to_pay = NULL)
 {
     $paypal_settings = $this->_payment_settings;
     $paypal_id = $paypal_settings['paypal_id'];
     $paypal_cur = $paypal_settings['currency_format'];
     $no_shipping = $paypal_settings['no_shipping'];
     $item_num = 1;
     /* @var $transaction EE_Transaction */
     if (!$transaction) {
         $transaction = $total_line_item->transaction();
     }
     $primary_registrant = $transaction->primary_registration();
     if ($total_to_pay === NULL && $total_to_pay != $transaction->total() && !$transaction->paid()) {
         //and there have been no payments on the transaction yet anyways
         //so let's create a nice looking invoice including everything
         foreach ($total_line_item->get_items() as $line_item) {
             $this->addField('item_name_' . $item_num, substr(sprintf(__('%s for %s', 'event_espresso'), $line_item->name(), $line_item->ticket_event_name()), 0, 127));
             $this->addField('amount_' . $item_num, $line_item->unit_price());
             $this->addField('quantity_' . $item_num, $line_item->quantity());
             $item_num++;
         }
         foreach ($total_line_item->tax_descendants() as $tax_line_item) {
             $this->addField('item_name_' . $item_num, substr($tax_line_item->name(), 0, 127));
             $this->addField('amount_' . $item_num, $tax_line_item->total());
             $this->addField('quantity_' . $item_num, '1');
             $item_num++;
         }
     } else {
         //we're only charging for part of the transaction's total
         if ($total_to_pay) {
             //client code specified how much to charge
             $description = sprintf(__("Partial payment of %s", "event_espresso"), $total_to_pay);
         } elseif ($transaction->paid()) {
             //they didn't specify how much, but there has already been a payment, so let's just charge on what's left
             $total_to_pay = $transaction->remaining();
             $description = sprintf(__("Total paid to date: %s, and this charge is for the balance.", "event_espresso"), $transaction->get_pretty('TXN_paid'));
         } else {
             throw new EE_Error(sprintf(__("Thats impossible!!", "event_espresso")));
         }
         $this->addField('item_name_' . $item_num, sprintf(__("Amount owing for registration %s", 'event_espresso'), $primary_registrant->reg_code()));
         $this->addField('amount_' . $item_num, $total_to_pay);
         $this->addField('on0_' . $item_num, __("Amount Owing:", 'event_espresso'));
         $this->addField('os0_' . $item_num, $description);
         $item_num++;
     }
     if ($paypal_settings['use_sandbox']) {
         $this->addField('item_name_' . $item_num, 'DEBUG INFO (this item only added in sandbox mode)');
         $this->addField('amount_' . $item_num, 0);
         $this->addField('on0_' . $item_num, 'NOTIFY URL');
         $this->addField('os0_' . $item_num, $this->_get_notify_url($primary_registrant));
     }
     $this->addField('business', $paypal_id);
     $this->addField('return', $this->_get_return_url($primary_registrant));
     $this->addField('cancel_return', $this->_get_cancel_url());
     $this->addField('notify_url', $this->_get_notify_url($primary_registrant));
     $this->addField('cmd', '_cart');
     $this->addField('upload', '1');
     $this->addField('currency_code', $paypal_cur);
     $this->addField('image_url', empty($paypal_settings['image_url']) ? '' : $paypal_settings['image_url']);
     $this->addField('no_shipping ', $no_shipping);
     do_action('AHEE_log', __FILE__, __FUNCTION__, serialize(get_object_vars($this)));
     $this->_EEM_Gateways->set_off_site_form($this->submitPayment());
     $this->redirect_after_reg_step_3($transaction, $paypal_settings['use_sandbox']);
 }