/**
  * Process capturing of a payment
  *
  * @param Varien_Object $payment
  * @param float         $amount
  *
  * @return Mage_Payment_Model_Abstract|void
  */
 public function capture(Varien_Object $payment, $amount)
 {
     // Has the payment already been authorized?
     if ($payment->getCcTransId()) {
         // Convert the capture amount to the correct currency
         $captureAmount = $this->_getWrapper()->getCaptureAmount($payment->getOrder(), $amount);
         // Has the authorization already been settled? Partial invoicing
         if ($this->authorizationUsed($payment)) {
             // Set the token as false
             $token = false;
             // Was the original payment created with a token?
             if ($additionalInfoToken = $payment->getAdditionalInformation('token')) {
                 try {
                     // Init the environment
                     $this->_getWrapper()->init($payment->getOrder()->getStoreId());
                     // Attempt to find the token
                     Braintree_PaymentMethod::find($additionalInfoToken);
                     // Set the token if a success
                     $token = $additionalInfoToken;
                 } catch (Exception $e) {
                     $token = false;
                 }
             }
             // If we managed to find a token use that for the capture
             if ($token) {
                 // Stop processing the rest of the method
                 // We pass $amount instead of $captureAmount as the authorize function contains the conversion
                 $this->_authorize($payment, $amount, true, $token);
                 return $this;
             } else {
                 // Attempt to clone the transaction
                 $result = $this->_getWrapper()->init($payment->getOrder()->getStoreId())->cloneTransaction($payment->getLastTransId(), $captureAmount);
             }
         } else {
             // Init the environment
             $result = $this->_getWrapper()->init($payment->getOrder()->getStoreId())->submitForSettlement($payment->getCcTransId(), $captureAmount);
             // Log the result
             Gene_Braintree_Model_Debug::log(array('capture:submitForSettlement' => $result));
         }
         if ($result->success) {
             $this->_processSuccessResult($payment, $result, $amount);
         } else {
             if ($result->errors->deepSize() > 0) {
                 // Clean up
                 Gene_Braintree_Model_Wrapper_Braintree::cleanUp();
                 Mage::throwException($this->_getWrapper()->parseErrors($result->errors->deepAll()));
             } else {
                 // Clean up
                 Gene_Braintree_Model_Wrapper_Braintree::cleanUp();
                 Mage::throwException($result->transaction->processorSettlementResponseCode . ': ' . $result->transaction->processorSettlementResponseText);
             }
         }
     } else {
         // Otherwise we need to do an auth & capture at once
         $this->_authorize($payment, $amount, true);
     }
     return $this;
 }
 /**
  * Clone a transaction
  *
  * @param $transactionId
  * @param $amount
  *
  * @return bool|mixed
  */
 public function cloneTransaction($transactionId, $amount, $submitForSettlement = true)
 {
     // Attempt to clone the transaction
     try {
         $result = Braintree_Transaction::cloneTransaction($transactionId, array('amount' => $amount, 'options' => array('submitForSettlement' => $submitForSettlement)));
         return $result;
     } catch (Exception $e) {
         // Log the issue
         Gene_Braintree_Model_Debug::log(array('cloneTransaction' => $e));
         return false;
     }
 }
 /**
  * Capture the payment on the checkout page
  *
  * @param Varien_Object $payment
  * @param float         $amount
  *
  * @return Mage_Payment_Model_Abstract
  */
 public function capture(Varien_Object $payment, $amount)
 {
     // Retrieve the payment data from the request
     $paymentPost = Mage::app()->getRequest()->getPost('payment');
     // Confirm that we have a nonce from Braintree
     // We cannot utilise the validate() function as these checks need to happen at the capture point
     if (!isset($paymentPost['paypal_payment_method_token'])) {
         if (!isset($paymentPost['payment_method_nonce']) || empty($paymentPost['payment_method_nonce'])) {
             Mage::throwException($this->_getHelper()->__('There has been an issue processing your PayPal payment, please try again.'));
         }
     } else {
         if (isset($paymentPost['paypal_payment_method_token']) && empty($paymentPost['paypal_payment_method_token'])) {
             Mage::throwException($this->_getHelper()->__('There has been an issue processing your PayPal payment, please try again.'));
         }
     }
     // Get the device data for fraud screening
     $deviceData = Mage::app()->getRequest()->getPost('device_data');
     // Init the environment
     $this->_getWrapper()->init();
     if (isset($paymentPost['paypal_payment_method_token']) && !empty($paymentPost['paypal_payment_method_token']) && $paymentPost['paypal_payment_method_token'] != 'other') {
         $paymentArray = array('paymentMethodToken' => $paymentPost['paypal_payment_method_token']);
     } else {
         $paymentArray = array('paymentMethodNonce' => $paymentPost['payment_method_nonce']);
     }
     // Retrieve the amount we should capture
     $amount = $this->_getWrapper()->getCaptureAmount($payment->getOrder(), $amount);
     // Attempt to create the sale
     try {
         // Build the array for the sale
         $saleArray = $this->_getWrapper()->buildSale($amount, $paymentArray, $payment->getOrder(), true, $deviceData, $this->shouldSaveMethod($payment, $paymentPost));
         // Pass the sale array into a varien object
         $request = new Varien_Object();
         $request->setData('sale_array', $saleArray);
         // Dispatch event for modifying the sale array
         Mage::dispatchEvent('gene_braintree_paypal_sale_array', array('payment' => $payment, 'request' => $request));
         // Pull the saleArray back out
         $saleArray = $request->getData('sale_array');
         // Log the initial sale array, no protected data is included
         Gene_Braintree_Model_Debug::log(array('saleArray' => $saleArray));
         // Attempt to create the sale
         $result = $this->_getWrapper()->makeSale($saleArray);
     } catch (Exception $e) {
         // Dispatch an event for when a payment fails
         Mage::dispatchEvent('gene_braintree_paypal_failed_exception', array('payment' => $payment, 'exception' => $e));
         // If there's an error
         Gene_Braintree_Model_Debug::log($e);
         Mage::throwException($this->_getHelper()->__('We were unable to complete your purchase through PayPal, please try again or an alternative payment method.'));
     }
     // Log the result
     Gene_Braintree_Model_Debug::log(array('result' => $result));
     // If the sale has failed
     if ($result->success != true) {
         // Dispatch an event for when a payment fails
         Mage::dispatchEvent('gene_braintree_paypal_failed', array('payment' => $payment, 'result' => $result));
         Mage::throwException($this->_getHelper()->__('%s. Please try again or attempt refreshing the page.', $result->message));
     }
     // Finish of the order
     $this->_processSuccessResult($payment, $result, $amount);
     return $this;
 }