Gene_Braintree - Version 1.0.3

Version Notes

Connect your Magento store to Braintree to accept Credit Cards & PayPal using V.Zero SDK

Download this release

Release Info

Developer Dave Macaulay
Extension Gene_Braintree
Version 1.0.3
Comparing to
See all releases


Code changes from version 1.0.2 to 1.0.3

app/code/community/Gene/Braintree/Block/Creditcard/Info.php CHANGED
@@ -5,7 +5,7 @@
5
  *
6
  * @author Dave Macaulay <dave@gene.co.uk>
7
  */
8
- class Gene_Braintree_Block_Creditcard_Info extends Mage_Payment_Block_Info
9
  {
10
 
11
  /**
@@ -17,26 +17,6 @@ class Gene_Braintree_Block_Creditcard_Info extends Mage_Payment_Block_Info
17
  $this->setTemplate('gene/braintree/creditcard/info.phtml');
18
  }
19
 
20
- /**
21
- * Return the currently viewed order
22
- *
23
- * @return \Mage_Sales_Model_Order
24
- */
25
- protected function getOrder()
26
- {
27
- if(Mage::registry('current_order')) {
28
- return Mage::registry('current_order');
29
- } else if(Mage::registry('current_invoice')) {
30
- return Mage::registry('current_invoice')->getOrder();
31
- } else if(Mage::registry('current_shipment')) {
32
- return Mage::registry('current_shipment')->getOrder();
33
- } else if(Mage::registry('current_creditmemo')) {
34
- return Mage::registry('current_creditmemo')->getOrder();
35
- }
36
-
37
- return false;
38
- }
39
-
40
  /**
41
  * Prepare information specific to current payment method
42
  *
@@ -49,52 +29,50 @@ class Gene_Braintree_Block_Creditcard_Info extends Mage_Payment_Block_Info
49
  // Get the original transport data
50
  $transport = parent::_prepareSpecificInformation($transport);
51
 
52
- // Build up the data we wish to pass through
53
- $data = array(
54
- $this->__('Card Number (Last 4)') => $this->getInfo()->getCcLast4(),
55
- $this->__('Credit Card Type') => $this->getInfo()->getCcType()
56
- );
57
 
58
- // Check we're in the admin area
59
- if(Mage::app()->getStore()->isAdmin()) {
 
 
 
60
 
61
- // Transaction ID won't matter for customers
62
- $data[$this->__('Braintree Transaction ID')] = $this->getInfo()->getLastTransId();
63
 
64
- // Only display transaction if we can load the order
65
- if($this->getOrder()) {
 
 
 
 
66
 
67
- // Add in the current status
68
- try {
69
- $transaction = Mage::getModel('gene_braintree/wrapper_braintree')->init($this->getOrder()->getStoreId())->findTransaction($this->getInfo()->getLastTransId());
70
- if ($transaction) {
71
- $data[$this->__('Status')] = $this->convertStatus($transaction->status);
72
- } else {
73
- $data[$this->__('Status')] = $this->__('<span style="color:red;"><strong>Warning:</strong> Cannot load payment in Braintree.</span>');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  }
75
- } catch (Exception $e) {
76
- $data[$this->__('Status')] = $this->__('<span style="color:red;"><strong>Warning:</strong> Unable to connect to Braintree to load transaction.</span>');
77
  }
78
- }
79
-
80
- // What additional information should we show
81
- $additionalInfoHeadings = array(
82
- 'avsErrorResponseCode' => $this->__('AVS Error Response Code'),
83
- 'avsPostalCodeResponseCode' => $this->__('AVS Postal Response Code'),
84
- 'avsStreetAddressResponseCode' => $this->__('AVS Street Address Response Code'),
85
- 'cvvResponseCode' => $this->__('CVV Response Code'),
86
- 'gatewayRejectionReason' => $this->__('Gateway Rejection Reason'),
87
- 'processorAuthorizationCode' => $this->__('Processor Autorization Code'),
88
- 'processorResponseCode' => $this->__('Processor Response Code'),
89
- 'processorResponseText' => $this->__('Processor Response Text'),
90
- 'threeDSecure' => $this->__('3D Secure')
91
- );
92
 
93
- // Add any of the data that we've recorded into the view
94
- foreach($additionalInfoHeadings as $key => $heading) {
95
- if($infoData = $this->getInfo()->getAdditionalInformation($key)) {
96
- $data[$heading] = $infoData;
97
- }
98
  }
99
 
100
  }
@@ -107,31 +85,4 @@ class Gene_Braintree_Block_Creditcard_Info extends Mage_Payment_Block_Info
107
  return $transport;
108
  }
109
 
110
- /**
111
- * Make the status nicer to read
112
- *
113
- * @param $status
114
- *
115
- * @return string
116
- */
117
- private function convertStatus($status)
118
- {
119
- switch($status){
120
- case 'authorized':
121
- return '<span style="color: #40A500;"> ' . Mage::helper('gene_braintree')->__('Authorized') . '</span>';
122
- break;
123
- case 'submitted_for_settlement':
124
- return '<span style="color: #40A500;">' . Mage::helper('gene_braintree')->__('Submitted For Settlement') . '</span>';
125
- break;
126
- case 'settled':
127
- return '<span style="color: #40A500;">' . Mage::helper('gene_braintree')->__('Settled') . '</span>';
128
- break;
129
- case 'voided':
130
- return '<span style="color: #ed4737;">' . Mage::helper('gene_braintree')->__('Voided') . '</span>';
131
- break;
132
- }
133
-
134
- return ucwords($status);
135
- }
136
-
137
  }
5
  *
6
  * @author Dave Macaulay <dave@gene.co.uk>
7
  */
8
+ class Gene_Braintree_Block_Creditcard_Info extends Gene_Braintree_Block_Info
9
  {
10
 
11
  /**
17
  $this->setTemplate('gene/braintree/creditcard/info.phtml');
18
  }
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  /**
21
  * Prepare information specific to current payment method
22
  *
29
  // Get the original transport data
30
  $transport = parent::_prepareSpecificInformation($transport);
31
 
32
+ // Only display this information if it's a single invoice
33
+ if($this->isSingleInvoice()) {
 
 
 
34
 
35
+ // Build up the data we wish to pass through
36
+ $data = array(
37
+ $this->__('Card Number (Last 4)') => $this->getInfo()->getCcLast4(),
38
+ $this->__('Credit Card Type') => $this->getInfo()->getCcType()
39
+ );
40
 
41
+ } else {
 
42
 
43
+ // Never leave an empty array
44
+ $data = array();
45
+ }
46
+
47
+ // Check we're in the admin area
48
+ if(Mage::app()->getStore()->isAdmin()) {
49
 
50
+ // Include the transaction statuses
51
+ $this->includeLiveDetails($data);
52
+
53
+ // Only include extra information when viewing a single invoice
54
+ if($this->isSingleInvoice()) {
55
+
56
+ // What additional information should we show
57
+ $additionalInfoHeadings = array(
58
+ 'avsErrorResponseCode' => $this->__('AVS Error Response Code'),
59
+ 'avsPostalCodeResponseCode' => $this->__('AVS Postal Response Code'),
60
+ 'avsStreetAddressResponseCode' => $this->__('AVS Street Address Response Code'),
61
+ 'cvvResponseCode' => $this->__('CVV Response Code'),
62
+ 'gatewayRejectionReason' => $this->__('Gateway Rejection Reason'),
63
+ 'processorAuthorizationCode' => $this->__('Processor Autorization Code'),
64
+ 'processorResponseCode' => $this->__('Processor Response Code'),
65
+ 'processorResponseText' => $this->__('Processor Response Text'),
66
+ 'threeDSecure' => $this->__('3D Secure')
67
+ );
68
+
69
+ // Add any of the data that we've recorded into the view
70
+ foreach ($additionalInfoHeadings as $key => $heading) {
71
+ if ($infoData = $this->getInfo()->getAdditionalInformation($key)) {
72
+ $data[$heading] = $infoData;
73
  }
 
 
74
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
 
 
 
 
 
76
  }
77
 
78
  }
85
  return $transport;
86
  }
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  }
app/code/community/Gene/Braintree/Block/Info.php ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Gene_Braintree_Block_Info
5
+ *
6
+ * @author Dave Macaulay <dave@gene.co.uk>
7
+ */
8
+ class Gene_Braintree_Block_Info extends Mage_Payment_Block_Info
9
+ {
10
+ /**
11
+ * Store this within the model
12
+ */
13
+ private $_singleInvoice = null;
14
+
15
+ /**
16
+ * Return the currently viewed order
17
+ *
18
+ * @return \Mage_Sales_Model_Order|\Mage_Sales_Model_Order_Invoice|\Mage_Sales_Model_Order_Creditmemo
19
+ */
20
+ protected function getViewedObject()
21
+ {
22
+ // Return the invoice first
23
+ if(Mage::registry('current_invoice')) {
24
+ return Mage::registry('current_invoice');
25
+ } else if(Mage::registry('current_creditmemo')) {
26
+ return Mage::registry('current_creditmemo');
27
+ } else if(Mage::registry('current_order')) {
28
+ return Mage::registry('current_order');
29
+ } else if(Mage::registry('current_shipment')) {
30
+ return Mage::registry('current_shipment')->getOrder();
31
+ }
32
+
33
+ return false;
34
+ }
35
+
36
+ /**
37
+ * Include live details
38
+ *
39
+ * @param $data
40
+ */
41
+ protected function includeLiveDetails(&$data)
42
+ {
43
+ // Retrieve the order
44
+ $order = $this->getViewedObject();
45
+
46
+ // Sometimes orders may not have transaction Id's
47
+ $transactionIds = array();
48
+
49
+ // If we're viewing a single invoice change the response
50
+ if($this->isSingleInvoice()) {
51
+
52
+ // Transaction ID won't matter for customers
53
+ $data[$this->__('Braintree Transaction ID')] = $this->getTransactionId();
54
+
55
+ // Build an array of transaction ID's
56
+ $transactionIds = array($this->getTransactionId());
57
+
58
+ } else if($order) {
59
+
60
+ /* @var $invoices Mage_Sales_Model_Resource_Order_Invoice_Collection */
61
+ $invoices = $order->getInvoiceCollection();
62
+ if($invoices->getSize() > 1) {
63
+
64
+ // Build up our array
65
+ foreach($invoices as $invoice) {
66
+ $transactionIds[] = $invoice->getTransactionId();
67
+ }
68
+
69
+ } else {
70
+
71
+ // Transaction ID won't matter for customers
72
+ $data[$this->__('Braintree Transaction ID')] = $this->getTransactionId();
73
+ }
74
+
75
+ }
76
+
77
+ // Do we have any transaction ID's
78
+ if(!empty($transactionIds)) {
79
+
80
+ // Start a count
81
+ $count = 1;
82
+
83
+ // Iterate through transaction ID's
84
+ foreach ($transactionIds as $transactionId) {
85
+
86
+ // Add in another label
87
+ if(count($transactionIds) > 1) {
88
+ $data[$this->__('Braintree Transaction #%d', $count)] = '';
89
+ }
90
+
91
+ // If the order contains more than one transaction show all statuses
92
+ $label = $this->__('Status%s', (count($transactionIds) > 1 ? ' (' . $this->__('Transaction ID: ') . $transactionId . ')' : ''));
93
+
94
+ // Add in the current status
95
+ try {
96
+ $transaction = Mage::getModel('gene_braintree/wrapper_braintree')->init($this->getViewedObject()->getStoreId())->findTransaction($transactionId);
97
+ if ($transaction) {
98
+ $data[$label] = $this->convertStatus($transaction->status);
99
+ } else {
100
+ $data[$label] = $this->__('<span style="color:red;"><strong>Warning:</strong> Cannot load payment in Braintree.</span>');
101
+ }
102
+ } catch (Exception $e) {
103
+ $data[$label] = $this->__('<span style="color:red;"><strong>Warning:</strong> Unable to connect to Braintree to load transaction.</span>');
104
+ }
105
+
106
+ ++$count;
107
+
108
+ }
109
+ }
110
+
111
+ }
112
+
113
+ /**
114
+ * Are we viewing a single invoice?
115
+ *
116
+ * @return bool
117
+ */
118
+ protected function isSingleInvoice()
119
+ {
120
+ // Caching on the check
121
+ if($this->_singleInvoice === null) {
122
+ $this->_singleInvoice = $this->getViewedObject()
123
+ && ($this->getViewedObject() instanceof Mage_Sales_Model_Order
124
+ && $this->getViewedObject()->getInvoiceCollection()->getSize() <= 1)
125
+ || ($this->getViewedObject() instanceof Mage_Sales_Model_Order_Invoice)
126
+ || ($this->getViewedObject() instanceof Mage_Sales_Model_Order_Creditmemo);
127
+ }
128
+
129
+ return $this->_singleInvoice;
130
+ }
131
+
132
+ /**
133
+ * Return the transaction ID
134
+ *
135
+ * @return bool|string
136
+ */
137
+ protected function getTransactionId()
138
+ {
139
+ // If the viewed object is an order or it's an invoice but the order doesn't have any invoices
140
+ if($this->getViewedObject() && $this->getViewedObject() instanceof Mage_Sales_Model_Order
141
+ || ($this->getViewedObject() instanceof Mage_Sales_Model_Order_Invoice && !$this->getViewedObject()->getTransactionId()))
142
+ {
143
+
144
+ // Return the transaction ID from the info
145
+ return $this->_getWrapper()->getCleanTransactionId($this->getInfo()->getLastTransId());
146
+
147
+ // Else if we're viewing an invoice or a credit memo
148
+ } else if($this->getViewedObject() && ($this->getViewedObject() instanceof Mage_Sales_Model_Order_Invoice
149
+ || $this->getViewedObject() instanceof Mage_Sales_Model_Order_Creditmemo))
150
+ {
151
+
152
+ // If the creditmemo is being created it has no transaction ID
153
+ if($this->getViewedObject() instanceof Mage_Sales_Model_Order_Creditmemo && !$this->getViewedObject()->getTransactionId()) {
154
+
155
+ // If the creditmemo has an invoice use that transaction ID, otherwise we're viewing an order wide credit memo
156
+ if($this->getViewedObject()->getInvoice() && $this->getViewedObject()->getInvoice()->getTransactionId()) {
157
+ return $this->_getWrapper()->getCleanTransactionId($this->getViewedObject()->getInvoice()->getTransactionId());
158
+ } else {
159
+ return $this->_getWrapper()->getCleanTransactionId($this->getInfo()->getLastTransId());
160
+ }
161
+ }
162
+
163
+ return $this->_getWrapper()->getCleanTransactionId($this->getViewedObject()->getTransactionId());
164
+ }
165
+
166
+ return false;
167
+ }
168
+
169
+ /**
170
+ * Make the status nicer to read
171
+ *
172
+ * @param $status
173
+ *
174
+ * @return string
175
+ */
176
+ protected function convertStatus($status)
177
+ {
178
+ switch($status){
179
+ case 'authorized':
180
+ return '<span style="color: #40A500;"> ' . Mage::helper('gene_braintree')->__('Authorized') . '</span>';
181
+ break;
182
+ case 'submitted_for_settlement':
183
+ return '<span style="color: #40A500;">' . Mage::helper('gene_braintree')->__('Submitted For Settlement') . '</span>';
184
+ break;
185
+ case 'settling':
186
+ return '<span style="color: #40A500;">' . Mage::helper('gene_braintree')->__('Settling') . '</span>';
187
+ break;
188
+ case 'settled':
189
+ return '<span style="color: #40A500;">' . Mage::helper('gene_braintree')->__('Settled') . '</span>';
190
+ break;
191
+ case 'voided':
192
+ return '<span style="color: #ed4737;">' . Mage::helper('gene_braintree')->__('Voided') . '</span>';
193
+ break;
194
+ }
195
+
196
+ return ucwords($status);
197
+ }
198
+
199
+ /**
200
+ * Return the wrapper class
201
+ *
202
+ * @return Gene_Braintree_Model_Wrapper_Braintree
203
+ */
204
+ protected function _getWrapper()
205
+ {
206
+ return Mage::getSingleton('gene_braintree/wrapper_braintree');
207
+ }
208
+
209
+ }
app/code/community/Gene/Braintree/Block/Paypal/Info.php CHANGED
@@ -5,7 +5,7 @@
5
  *
6
  * @author Dave Macaulay <dave@gene.co.uk>
7
  */
8
- class Gene_Braintree_Block_Paypal_Info extends Mage_Payment_Block_Info
9
  {
10
 
11
  /**
@@ -37,14 +37,14 @@ class Gene_Braintree_Block_Paypal_Info extends Mage_Payment_Block_Info
37
  // Check we're in the admin area
38
  if(Mage::app()->getStore()->isAdmin()) {
39
 
 
 
 
40
  // Show these details to the admin only
41
  $data = array_merge(
42
  $data, array(
43
- $this->__('Braintree Transaction ID') => $this->getInfo()->getLastTransId(),
44
  $this->__('Payment ID') => $this->getInfo()->getAdditionalInformation('payment_id'),
45
- $this->__('Authorization ID') => $this->getInfo()->getAdditionalInformation(
46
- 'authorization_id'
47
- )
48
  )
49
  );
50
 
5
  *
6
  * @author Dave Macaulay <dave@gene.co.uk>
7
  */
8
+ class Gene_Braintree_Block_Paypal_Info extends Gene_Braintree_Block_Info
9
  {
10
 
11
  /**
37
  // Check we're in the admin area
38
  if(Mage::app()->getStore()->isAdmin()) {
39
 
40
+ // Include live details for this transaction
41
+ $this->includeLiveDetails($data);
42
+
43
  // Show these details to the admin only
44
  $data = array_merge(
45
  $data, array(
 
46
  $this->__('Payment ID') => $this->getInfo()->getAdditionalInformation('payment_id'),
47
+ $this->__('Authorization ID') => $this->getInfo()->getAdditionalInformation('authorization_id')
 
 
48
  )
49
  );
50
 
app/code/community/Gene/Braintree/Helper/Data.php CHANGED
@@ -30,4 +30,18 @@ class Gene_Braintree_Helper_Data extends Mage_Core_Helper_Abstract
30
  Braintree_Transaction::SETTLEMENT_PENDING => $this->__('Settlement Pending')
31
  );
32
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  }
30
  Braintree_Transaction::SETTLEMENT_PENDING => $this->__('Settlement Pending')
31
  );
32
  }
33
+
34
+ /**
35
+ * Force the prices to two decimal places
36
+ * Magento sometimes doesn't return certain totals in the correct format, yet Braintree requires them to always
37
+ * be in two decimal places, thus the need for this function
38
+ *
39
+ * @param $price
40
+ *
41
+ * @return string
42
+ */
43
+ public function formatPrice($price)
44
+ {
45
+ return number_format($price, 2, '.', '');
46
+ }
47
  }
app/code/community/Gene/Braintree/Model/Paymentmethod/Abstract.php CHANGED
@@ -106,4 +106,91 @@ abstract class Gene_Braintree_Model_Paymentmethod_Abstract extends Mage_Payment_
106
  return $this;
107
  }
108
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  }
106
  return $this;
107
  }
108
 
109
+ /**
110
+ * Refund specified amount for payment
111
+ *
112
+ * @param \Varien_Object $payment
113
+ * @param float $amount
114
+ *
115
+ * @return $this
116
+ * @throws \Mage_Core_Exception
117
+ */
118
+ public function refund(Varien_Object $payment, $amount)
119
+ {
120
+ try {
121
+ // Attempt to load the invoice
122
+ /* @var $invoice Mage_Sales_Model_Order_Invoice */
123
+ $invoice = $payment->getCreditmemo()->getInvoice();
124
+ if(!$invoice) {
125
+ Mage::throwException('Unable to load invoice from credit memo.');
126
+ }
127
+
128
+ // Init the environment
129
+ $this->_getWrapper()->init($payment->getOrder()->getStoreId());
130
+
131
+ // Convert the refund amount
132
+ $refundAmount = $this->_getWrapper()->getCaptureAmount($payment->getOrder(), $amount);
133
+
134
+ // Retrieve the transaction ID
135
+ $transactionId = $this->_getWrapper()->getCleanTransactionId($invoice->getTransactionId());
136
+
137
+ // Load the transaction from Braintree
138
+ $transaction = Braintree_Transaction::find($transactionId);
139
+
140
+ // If the transaction hasn't yet settled we can't do partial refunds
141
+ if ($transaction->status === Braintree_Transaction::SUBMITTED_FOR_SETTLEMENT) {
142
+
143
+ // If we're doing a partial refund and it's not settled it's a no go
144
+ if ($transaction->amount != $refundAmount) {
145
+ Mage::throwException($this->_getHelper()->__('This transaction has not yet settled, please wait until the transaction has settled to process a partial refund.'));
146
+ }
147
+ }
148
+
149
+ // Swap between refund and void
150
+ $result = ($transaction->status === Braintree_Transaction::SETTLED || (isset($transaction->paypal) && isset($transaction->paypal['paymentId']) && !empty($transaction->paypal['paymentId'])))
151
+ ? Braintree_Transaction::refund($transactionId, $refundAmount)
152
+ : Braintree_Transaction::void($transactionId);
153
+
154
+ // If it's a success close the transaction
155
+ if ($result->success) {
156
+
157
+ // Pass over the transaction ID
158
+ $payment->getCreditmemo()->setRefundTransactionId($result->transaction->id);
159
+
160
+ // Only close the transaction once the
161
+ if($transaction->amount == $refundAmount) {
162
+
163
+ $payment->setIsTransactionClosed(1);
164
+
165
+ // Mark the invoice as canceled if the invoice was completely refunded
166
+ $invoice->setState(Mage_Sales_Model_Order_Invoice::STATE_CANCELED);
167
+ }
168
+
169
+ } else {
170
+ if($result->errors->deepSize() > 0) {
171
+ Mage::throwException($this->_getWrapper()->parseErrors($result->errors->deepAll()));
172
+ } else {
173
+ Mage::throwException('An unknown error has occurred whilst trying to process the transaction');
174
+ }
175
+ }
176
+
177
+ } catch (Exception $e) {
178
+ Mage::throwException($this->_getHelper()->__('An error occurred whilst trying to process the refund: ') . $e->getMessage());
179
+ }
180
+
181
+ return $this;
182
+ }
183
+
184
+ /**
185
+ * Set transaction ID into creditmemo for informational purposes
186
+ * @param Mage_Sales_Model_Order_Creditmemo $creditmemo
187
+ * @param Mage_Sales_Model_Order_Payment $payment
188
+ * @return Mage_Payment_Model_Method_Abstract
189
+ */
190
+ public function processCreditmemo($creditmemo, $payment)
191
+ {
192
+ // Copy the refund transaction ID from the credit memo
193
+ $creditmemo->setTransactionId($creditmemo->getRefundTransactionId());
194
+ return $this;
195
+ }
196
  }
app/code/community/Gene/Braintree/Model/Paymentmethod/Creditcard.php CHANGED
@@ -32,9 +32,9 @@ class Gene_Braintree_Model_Paymentmethod_Creditcard extends Gene_Braintree_Model
32
  protected $_canAuthorize = true;
33
  protected $_canCapture = true;
34
  protected $_canCapturePartial = true;
35
- protected $_canRefund = false;
36
- protected $_canRefundInvoicePartial = false;
37
- protected $_canVoid = false;
38
  protected $_canUseInternal = true;
39
  protected $_canUseCheckout = true;
40
  protected $_canUseForMultishipping = false;
@@ -102,31 +102,67 @@ class Gene_Braintree_Model_Paymentmethod_Creditcard extends Gene_Braintree_Model
102
  }
103
 
104
  /**
105
- * Psuedo _authorize function so we can pass in extra data
106
- * @param Varien_Object $payment
107
- * @param $amount
108
- * @param bool $shouldCapture
109
  *
110
- * @throws Mage_Core_Exception
111
  */
112
- protected function _authorize(Varien_Object $payment, $amount, $shouldCapture = false)
113
  {
 
 
 
114
  // Retrieve the post data from the request
115
  $paymentPost = Mage::app()->getRequest()->getPost('payment');
116
 
117
  // Confirm that we have a nonce from Braintree
118
- if(!isset($paymentPost['card_payment_method_token']) || (isset($paymentPost['card_payment_method_token']) && $paymentPost['card_payment_method_token'] == 'threedsecure')) {
119
  if ((!isset($paymentPost['payment_method_nonce']) || empty($paymentPost['payment_method_nonce']))) {
 
 
 
120
  Mage::throwException(
121
  $this->_getHelper()->__('Your card payment has failed, please try again.')
122
  );
123
  }
124
- } else if(isset($paymentPost['card_payment_method_token']) && empty($paymentPost['card_payment_method_token'])) {
 
 
 
125
  Mage::throwException(
126
  $this->_getHelper()->__('Your card payment has failed, please try again.')
127
  );
128
  }
129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  // Get the device data for fraud screening
131
  $deviceData = Mage::app()->getRequest()->getPost('device_data');
132
 
@@ -137,20 +173,8 @@ class Gene_Braintree_Model_Paymentmethod_Creditcard extends Gene_Braintree_Model
137
  try {
138
 
139
  // Pass over the CVV/CCV
140
- if($this->requireCcv() && isset($paymentPost['cc_cid'])) {
141
-
142
  $paymentArray['cvv'] = $paymentPost['cc_cid'];
143
-
144
- } else if($this->requireCcv() && !isset($paymentPost['cc_cid']) && empty($paymentPost['card_payment_method_token'])) {
145
-
146
- // Log it
147
- Gene_Braintree_Model_Debug::log('CVV required but not present in request');
148
-
149
- // Politely inform the user
150
- Mage::throwException(
151
- $this->_getHelper()->__('We require a CVV when creating card transactions.')
152
- );
153
-
154
  }
155
 
156
  // Check to see whether we're using a payment method token?
@@ -190,6 +214,16 @@ class Gene_Braintree_Model_Paymentmethod_Creditcard extends Gene_Braintree_Model
190
  $threeDSecure = false;
191
  }
192
 
 
 
 
 
 
 
 
 
 
 
193
  // Retrieve the amount we should capture
194
  $amount = $this->_getWrapper()->getCaptureAmount($payment->getOrder(), $amount);
195
 
@@ -308,16 +342,61 @@ class Gene_Braintree_Model_Paymentmethod_Creditcard extends Gene_Braintree_Model
308
  // Has the payment already been authorized?
309
  if ($payment->getCcTransId()) {
310
 
311
- // Init the environment
312
- $result = $this->_getWrapper()->init()->submitForSettlement($payment->getCcTransId(), $amount);
 
 
 
 
 
 
 
 
 
313
 
314
- // Log the result
315
- Gene_Braintree_Model_Debug::log(array('capture:submitForSettlement' => $result));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
 
317
  if($result->success) {
318
  $this->_processSuccessResult($payment, $result, $amount);
319
  } else if($result->errors->deepSize() > 0) {
320
- Mage::throwException($result->errors);
321
  } else {
322
  Mage::throwException($result->transaction->processorSettlementResponseCode.': '.$result->transaction->processorSettlementResponseText);
323
  }
@@ -330,6 +409,68 @@ class Gene_Braintree_Model_Paymentmethod_Creditcard extends Gene_Braintree_Model
330
  return $this;
331
  }
332
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333
  /**
334
  * Processes successful authorize/clone result
335
  *
32
  protected $_canAuthorize = true;
33
  protected $_canCapture = true;
34
  protected $_canCapturePartial = true;
35
+ protected $_canRefund = true;
36
+ protected $_canRefundInvoicePartial = true;
37
+ protected $_canVoid = true;
38
  protected $_canUseInternal = true;
39
  protected $_canUseCheckout = true;
40
  protected $_canUseForMultishipping = false;
102
  }
103
 
104
  /**
105
+ * Validate payment method information object
 
 
 
106
  *
107
+ * @return $this
108
  */
109
+ public function validate()
110
  {
111
+ // Run the built in Magento validation
112
+ parent::validate();
113
+
114
  // Retrieve the post data from the request
115
  $paymentPost = Mage::app()->getRequest()->getPost('payment');
116
 
117
  // Confirm that we have a nonce from Braintree
118
+ if (!isset($paymentPost['card_payment_method_token']) || (isset($paymentPost['card_payment_method_token']) && $paymentPost['card_payment_method_token'] == 'threedsecure')) {
119
  if ((!isset($paymentPost['payment_method_nonce']) || empty($paymentPost['payment_method_nonce']))) {
120
+
121
+ Gene_Braintree_Model_Debug::log('Card payment has failed, missing token/nonce');
122
+
123
  Mage::throwException(
124
  $this->_getHelper()->__('Your card payment has failed, please try again.')
125
  );
126
  }
127
+ } else if (isset($paymentPost['card_payment_method_token']) && empty($paymentPost['card_payment_method_token'])) {
128
+
129
+ Gene_Braintree_Model_Debug::log('No saved card token present');
130
+
131
  Mage::throwException(
132
  $this->_getHelper()->__('Your card payment has failed, please try again.')
133
  );
134
  }
135
 
136
+ // If the CVV is required and it's not been sent in the request throw an error
137
+ if ($this->requireCcv() && (!isset($paymentPost['cc_cid']) || empty($paymentPost['cc_cid'])) && empty($paymentPost['card_payment_method_token'])) {
138
+
139
+ // Log it
140
+ Gene_Braintree_Model_Debug::log('CVV required but not present in request');
141
+
142
+ // Politely inform the user
143
+ Mage::throwException(
144
+ $this->_getHelper()->__('We require a CVV when creating card transactions.')
145
+ );
146
+
147
+ }
148
+
149
+
150
+ return $this;
151
+ }
152
+
153
+ /**
154
+ * Psuedo _authorize function so we can pass in extra data
155
+ * @param Varien_Object $payment
156
+ * @param $amount
157
+ * @param bool $shouldCapture
158
+ *
159
+ * @throws Mage_Core_Exception
160
+ */
161
+ protected function _authorize(Varien_Object $payment, $amount, $shouldCapture = false, $token = false)
162
+ {
163
+ // Retrieve the post data from the request
164
+ $paymentPost = Mage::app()->getRequest()->getPost('payment');
165
+
166
  // Get the device data for fraud screening
167
  $deviceData = Mage::app()->getRequest()->getPost('device_data');
168
 
173
  try {
174
 
175
  // Pass over the CVV/CCV
176
+ if ($this->requireCcv() && isset($paymentPost['cc_cid'])) {
 
177
  $paymentArray['cvv'] = $paymentPost['cc_cid'];
 
 
 
 
 
 
 
 
 
 
 
178
  }
179
 
180
  // Check to see whether we're using a payment method token?
214
  $threeDSecure = false;
215
  }
216
 
217
+ // If a token is present in the request use that
218
+ if($token) {
219
+
220
+ // Remove this unneeded data
221
+ unset($paymentArray['paymentMethodNonce'], $paymentArray['cvv']);
222
+
223
+ // Send the token as the payment array
224
+ $paymentArray['paymentMethodToken'] = $token;
225
+ }
226
+
227
  // Retrieve the amount we should capture
228
  $amount = $this->_getWrapper()->getCaptureAmount($payment->getOrder(), $amount);
229
 
342
  // Has the payment already been authorized?
343
  if ($payment->getCcTransId()) {
344
 
345
+ // Convert the capture amount to the correct currency
346
+ $captureAmount = $this->_getWrapper()->getCaptureAmount($payment->getOrder(), $amount);
347
+
348
+ // Has the authorization already been settled? Partial invoicing
349
+ if($this->authorizationUsed($payment)) {
350
+
351
+ // Set the token as false
352
+ $token = false;
353
+
354
+ // Was the original payment created with a token?
355
+ if($additionalInfoToken = $payment->getAdditionalInformation('token')) {
356
 
357
+ try {
358
+ // Init the environment
359
+ $this->_getWrapper()->init($payment->getOrder()->getStoreId());
360
+
361
+ // Attempt to find the token
362
+ Braintree_PaymentMethod::find($additionalInfoToken);
363
+
364
+ // Set the token if a success
365
+ $token = $additionalInfoToken;
366
+
367
+ } catch (Exception $e) {
368
+ $token = false;
369
+ }
370
+
371
+ }
372
+
373
+ // If we managed to find a token use that for the capture
374
+ if($token) {
375
+
376
+ // Stop processing the rest of the method
377
+ // We pass $amount instead of $captureAmount as the authorize function contains the conversion
378
+ $this->_authorize($payment, $amount, true, $token);
379
+ return $this;
380
+
381
+ } else {
382
+
383
+ // Attempt to clone the transaction
384
+ $result = $this->_getWrapper()->init($payment->getOrder()->getStoreId())->cloneTransaction($payment->getLastTransId(), $captureAmount);
385
+ }
386
+
387
+ } else {
388
+
389
+ // Init the environment
390
+ $result = $this->_getWrapper()->init($payment->getOrder()->getStoreId())->submitForSettlement($payment->getCcTransId(), $captureAmount);
391
+
392
+ // Log the result
393
+ Gene_Braintree_Model_Debug::log(array('capture:submitForSettlement' => $result));
394
+ }
395
 
396
  if($result->success) {
397
  $this->_processSuccessResult($payment, $result, $amount);
398
  } else if($result->errors->deepSize() > 0) {
399
+ Mage::throwException($this->_getWrapper()->parseErrors($result->errors->deepAll()));
400
  } else {
401
  Mage::throwException($result->transaction->processorSettlementResponseCode.': '.$result->transaction->processorSettlementResponseText);
402
  }
409
  return $this;
410
  }
411
 
412
+ /**
413
+ * If we're doing authorize, has the payment already got more than one transaction?
414
+ *
415
+ * @param \Varien_Object $payment
416
+ *
417
+ * @return int
418
+ */
419
+ public function authorizationUsed(Varien_Object $payment)
420
+ {
421
+ $collection = Mage::getModel('sales/order_payment_transaction')
422
+ ->getCollection()
423
+ ->addFieldToFilter('payment_id', $payment->getId())
424
+ ->addFieldToFilter('txn_type', Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE);
425
+
426
+ return $collection->getSize();
427
+ }
428
+
429
+ /**
430
+ * Void payment abstract method
431
+ *
432
+ * @param Varien_Object $payment
433
+ *
434
+ * @return Mage_Payment_Model_Abstract
435
+ */
436
+ public function void(Varien_Object $payment)
437
+ {
438
+ try {
439
+ // Init the environment
440
+ $this->_getWrapper()->init($payment->getOrder()->getStoreId());
441
+
442
+ // Retrieve the transaction ID
443
+ $transactionId = $this->_getWrapper()->getCleanTransactionId($payment->getLastTransId());
444
+
445
+ // Load the transaction from Braintree
446
+ $transaction = Braintree_Transaction::find($transactionId);
447
+
448
+ // If the transaction hasn't yet settled we can't do partial refunds
449
+ if ($transaction->status !== Braintree_Transaction::AUTHORIZED || $transaction->status !== Braintree_Transaction::SUBMITTED_FOR_SETTLEMENT) {
450
+ Mage::throwException($this->_getHelper()->__('You can only void authorized/submitted for settlement payments, please setup a credit memo if you wish to refund this order.'));
451
+ }
452
+
453
+ // Swap between refund and void
454
+ $result = Braintree_Transaction::void($transactionId);
455
+
456
+ // If it's a success close the transaction
457
+ if ($result->success) {
458
+ $payment->setIsTransactionClosed(1);
459
+ } else {
460
+ if($result->errors->deepSize() > 0) {
461
+ Mage::throwException($this->_getWrapper()->parseErrors($result->errors->deepAll()));
462
+ } else {
463
+ Mage::throwException('Unknown');
464
+ }
465
+ }
466
+
467
+ } catch (Exception $e) {
468
+ Mage::throwException($this->_getHelper()->__('An error occurred whilst trying to void the transaction: ') . $e->getMessage());
469
+ }
470
+
471
+ return $this;
472
+ }
473
+
474
  /**
475
  * Processes successful authorize/clone result
476
  *
app/code/community/Gene/Braintree/Model/Paymentmethod/Paypal.php CHANGED
@@ -32,8 +32,8 @@ class Gene_Braintree_Model_Paymentmethod_Paypal extends Gene_Braintree_Model_Pay
32
  protected $_canAuthorize = false;
33
  protected $_canCapture = true;
34
  protected $_canCapturePartial = false;
35
- protected $_canRefund = false;
36
- protected $_canRefundInvoicePartial = false;
37
  protected $_canVoid = false;
38
  protected $_canUseInternal = false;
39
  protected $_canUseCheckout = true;
@@ -73,6 +73,7 @@ class Gene_Braintree_Model_Paymentmethod_Paypal extends Gene_Braintree_Model_Pay
73
  $paymentPost = Mage::app()->getRequest()->getPost('payment');
74
 
75
  // Confirm that we have a nonce from Braintree
 
76
  if(!isset($paymentPost['paypal_payment_method_token'])) {
77
  if ((!isset($paymentPost['payment_method_nonce']) || empty($paymentPost['payment_method_nonce']))) {
78
  Mage::throwException(
32
  protected $_canAuthorize = false;
33
  protected $_canCapture = true;
34
  protected $_canCapturePartial = false;
35
+ protected $_canRefund = true;
36
+ protected $_canRefundInvoicePartial = true;
37
  protected $_canVoid = false;
38
  protected $_canUseInternal = false;
39
  protected $_canUseCheckout = true;
73
  $paymentPost = Mage::app()->getRequest()->getPost('payment');
74
 
75
  // Confirm that we have a nonce from Braintree
76
+ // We cannot utilise the validate() function as these checks need to happen at the capture point
77
  if(!isset($paymentPost['paypal_payment_method_token'])) {
78
  if ((!isset($paymentPost['payment_method_nonce']) || empty($paymentPost['payment_method_nonce']))) {
79
  Mage::throwException(
app/code/community/Gene/Braintree/Model/Wrapper/Braintree.php CHANGED
@@ -248,6 +248,31 @@ class Gene_Braintree_Model_Wrapper_Braintree extends Mage_Core_Model_Abstract
248
  return $this->braintreeId;
249
  }
250
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
 
252
  /**
253
  * Validate the credentials within the admin area
@@ -262,10 +287,10 @@ class Gene_Braintree_Model_Wrapper_Braintree extends Mage_Core_Model_Abstract
262
 
263
  // If we're within the admin we want to grab these values from whichever store we're modifying
264
  if(Mage::app()->getStore()->isAdmin()) {
265
- Braintree_Configuration::environment(Mage::getSingleton('adminhtml/config_data')->getConfigDataValue(self::BRAINTREE_ENVIRONMENT_PATH));
266
- Braintree_Configuration::merchantId(Mage::getSingleton('adminhtml/config_data')->getConfigDataValue(self::BRAINTREE_MERCHANT_ID_PATH));
267
- Braintree_Configuration::publicKey(Mage::getSingleton('adminhtml/config_data')->getConfigDataValue(self::BRAINTREE_PUBLIC_KEY_PATH));
268
- Braintree_Configuration::privateKey(Mage::getSingleton('adminhtml/config_data')->getConfigDataValue(self::BRAINTREE_PRIVATE_KEY_PATH));
269
  } else {
270
  $this->init();
271
  }
@@ -293,7 +318,7 @@ class Gene_Braintree_Model_Wrapper_Braintree extends Mage_Core_Model_Abstract
293
  // Check to see if we've been passed the merchant account ID?
294
  if(!$merchantAccountId) {
295
  if(Mage::app()->getStore()->isAdmin()) {
296
- $merchantAccountId = Mage::getSingleton('adminhtml/config_data')->getConfigDataValue(self::BRAINTREE_MERCHANT_ACCOUNT_ID_PATH);
297
  } else {
298
  $merchantAccountId = $this->getMerchantAccountId();
299
  }
@@ -463,7 +488,7 @@ class Gene_Braintree_Model_Wrapper_Braintree extends Mage_Core_Model_Abstract
463
  $request = array(
464
  'amount' => $amount,
465
  'orderId' => $order->getIncrementId(),
466
- 'merchantAccountId' => $this->getMerchantAccountId(),
467
  'channel' => 'MagentoVZero',
468
  'options' => array(
469
  'submitForSettlement' => $submitForSettlement,
@@ -608,17 +633,17 @@ class Gene_Braintree_Model_Wrapper_Braintree extends Mage_Core_Model_Abstract
608
  *
609
  * @return mixed
610
  */
611
- public function getMerchantAccountId()
612
  {
613
  // If multi-currency is enabled use the mapped merchant account ID
614
- if($currencyCode = $this->hasMappedCurrencyCode()) {
615
 
616
  // Return the mapped currency code
617
  return $currencyCode;
618
  }
619
 
620
  // Otherwise return the one from the store
621
- return Mage::getStoreConfig(self::BRAINTREE_MERCHANT_ACCOUNT_ID_PATH);
622
  }
623
 
624
  /**
@@ -626,18 +651,19 @@ class Gene_Braintree_Model_Wrapper_Braintree extends Mage_Core_Model_Abstract
626
  *
627
  * @return bool
628
  */
629
- public function hasMappedCurrencyCode()
630
  {
631
  // If multi-currency is enabled use the mapped merchant account ID
632
- if($this->currencyMappingEnabled()) {
633
 
634
  // Retrieve the mapping from the config
635
- $mapping = Mage::helper('core')->jsonDecode(Mage::getStoreConfig(self::BRAINTREE_MULTI_CURRENCY_MAPPING));
636
 
637
  // Verify it decoded correctly
638
  if(is_array($mapping) && !empty($mapping)) {
639
 
640
- $currency = $this->getCurrencyCode();
 
641
 
642
  // Verify we have a mapping value for this currency
643
  if(isset($mapping[$currency]) && !empty($mapping[$currency])) {
@@ -652,73 +678,78 @@ class Gene_Braintree_Model_Wrapper_Braintree extends Mage_Core_Model_Abstract
652
  }
653
 
654
  /**
655
- * Return the users current currency code
656
  *
657
- * @return bool|string
658
  */
659
- public function getCurrencyCode()
660
  {
661
- // If we're in the admin get the currency code from the admin session quote
662
- if(Mage::app()->getStore()->isAdmin()) {
663
- return $this->getAdminCurrency();
664
- }
665
-
666
- // Retrieve the current from the session
667
- return Mage::app()->getStore()->getCurrentCurrencyCode();
668
  }
669
 
670
  /**
671
- * Do we have currency mapping enabled?
672
  *
673
- * @return bool
674
  */
675
- public function currencyMappingEnabled()
676
  {
677
- return Mage::getStoreConfigFlag(self::BRAINTREE_MULTI_CURRENCY)
678
- && Mage::getStoreConfig(self::BRAINTREE_MULTI_CURRENCY_MAPPING)
679
- && (Mage::app()->getStore()->getCurrentCurrencyCode() || (Mage::app()->getStore()->isAdmin() && $this->getAdminCurrency()));
 
 
 
680
  }
681
 
682
  /**
683
  * If we have a mapped currency code we need to convert the currency
684
  *
685
- * @param $amount
 
686
  *
687
- * @return mixed
 
688
  */
689
- public function getCaptureAmount(Mage_Sales_Model_Order $order, $amount)
690
  {
691
  // If we've got a mapped currency code the amount is going to change
692
- if($this->hasMappedCurrencyCode()) {
693
-
694
- // Convert the current
695
- $convertedCurrency = Mage::helper('directory')->currencyConvert($amount, $order->getBaseCurrencyCode(), $this->getCurrencyCode());
696
 
697
- // Format it to a precision of 2
698
- $options = array(
699
- 'currency' => $this->getCurrencyCode(),
700
- 'display' => ''
701
- );
702
 
703
- return Mage::app()->getLocale()->currency($this->getCurrencyCode())->toCurrency($convertedCurrency, $options);
 
704
  }
705
 
706
- return $amount;
 
707
  }
708
 
709
  /**
710
- * Retrieve the admin currency
711
  *
712
- * @return bool
 
713
  */
714
- private function getAdminCurrency()
715
  {
716
- $order = Mage::app()->getRequest()->getPost('order');
717
- if(isset($order['currency']) && !empty($order['currency'])) {
718
- return $order['currency'];
719
- }
720
 
721
- return false;
 
 
 
 
 
 
722
  }
723
 
724
  /**
@@ -756,4 +787,51 @@ class Gene_Braintree_Model_Wrapper_Braintree extends Mage_Core_Model_Abstract
756
  return $customer;
757
  }
758
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
759
  }
248
  return $this->braintreeId;
249
  }
250
 
251
+ /**
252
+ * Return the admin config value
253
+ **/
254
+ protected function getAdminConfigValue($path)
255
+ {
256
+ // If we have the getConfigDataValue use that
257
+ if(method_exists('Mage_Adminhtml_Model_Config_Data','getConfigDataValue')) {
258
+ return Mage::getSingleton('adminhtml/config_data')->getConfigDataValue($path);
259
+ }
260
+
261
+ // Otherwise use the default amazing getStoreConfig
262
+ return Mage::getStoreConfig($path);
263
+ }
264
+
265
+ /**
266
+ * If a transaction has been voided it's transaction ID can change
267
+ *
268
+ * @param $transactionId
269
+ *
270
+ * @return string
271
+ */
272
+ public function getCleanTransactionId($transactionId)
273
+ {
274
+ return strtok($transactionId, '-');
275
+ }
276
 
277
  /**
278
  * Validate the credentials within the admin area
287
 
288
  // If we're within the admin we want to grab these values from whichever store we're modifying
289
  if(Mage::app()->getStore()->isAdmin()) {
290
+ Braintree_Configuration::environment($this->getAdminConfigValue(self::BRAINTREE_ENVIRONMENT_PATH));
291
+ Braintree_Configuration::merchantId($this->getAdminConfigValue(self::BRAINTREE_MERCHANT_ID_PATH));
292
+ Braintree_Configuration::publicKey($this->getAdminConfigValue(self::BRAINTREE_PUBLIC_KEY_PATH));
293
+ Braintree_Configuration::privateKey($this->getAdminConfigValue(self::BRAINTREE_PRIVATE_KEY_PATH));
294
  } else {
295
  $this->init();
296
  }
318
  // Check to see if we've been passed the merchant account ID?
319
  if(!$merchantAccountId) {
320
  if(Mage::app()->getStore()->isAdmin()) {
321
+ $merchantAccountId = $this->getAdminConfigValue(self::BRAINTREE_MERCHANT_ACCOUNT_ID_PATH);
322
  } else {
323
  $merchantAccountId = $this->getMerchantAccountId();
324
  }
488
  $request = array(
489
  'amount' => $amount,
490
  'orderId' => $order->getIncrementId(),
491
+ 'merchantAccountId' => $this->getMerchantAccountId($order),
492
  'channel' => 'MagentoVZero',
493
  'options' => array(
494
  'submitForSettlement' => $submitForSettlement,
633
  *
634
  * @return mixed
635
  */
636
+ public function getMerchantAccountId(Mage_Sales_Model_Order $order = null)
637
  {
638
  // If multi-currency is enabled use the mapped merchant account ID
639
+ if($currencyCode = $this->hasMappedCurrencyCode($order)) {
640
 
641
  // Return the mapped currency code
642
  return $currencyCode;
643
  }
644
 
645
  // Otherwise return the one from the store
646
+ return Mage::getStoreConfig(self::BRAINTREE_MERCHANT_ACCOUNT_ID_PATH, ($order ? $order->getStoreId() : false));
647
  }
648
 
649
  /**
651
  *
652
  * @return bool
653
  */
654
+ public function hasMappedCurrencyCode(Mage_Sales_Model_Order $order = null)
655
  {
656
  // If multi-currency is enabled use the mapped merchant account ID
657
+ if($this->currencyMappingEnabled($order)) {
658
 
659
  // Retrieve the mapping from the config
660
+ $mapping = Mage::helper('core')->jsonDecode(Mage::getStoreConfig(self::BRAINTREE_MULTI_CURRENCY_MAPPING, ($order ? $order->getStoreId() : false)));
661
 
662
  // Verify it decoded correctly
663
  if(is_array($mapping) && !empty($mapping)) {
664
 
665
+ // If we haven't been given an order use the quote currency code
666
+ $currency = (!$order ? $this->getQuote()->getQuoteCurrencyCode() : $order->getOrderCurrencyCode());
667
 
668
  // Verify we have a mapping value for this currency
669
  if(isset($mapping[$currency]) && !empty($mapping[$currency])) {
678
  }
679
 
680
  /**
681
+ * Do we have currency mapping enabled?
682
  *
683
+ * @return bool
684
  */
685
+ public function currencyMappingEnabled(Mage_Sales_Model_Order $order = null)
686
  {
687
+ return Mage::getStoreConfigFlag(self::BRAINTREE_MULTI_CURRENCY)
688
+ && Mage::getStoreConfig(self::BRAINTREE_MULTI_CURRENCY_MAPPING)
689
+ && ((!$order ? $this->getQuote()->getQuoteCurrencyCode() : $order->getOrderCurrencyCode())
690
+ != (!$order ? $this->getQuote()->getBaseCurrencyCode() : $order->getBaseCurrencyCode()));
 
 
 
691
  }
692
 
693
  /**
694
+ * Get the current quote
695
  *
696
+ * @return \Mage_Sales_Model_Quote
697
  */
698
+ public function getQuote()
699
  {
700
+ // If we're within the admin return the admin quote
701
+ if(Mage::app()->getStore()->isAdmin()) {
702
+ return Mage::getSingleton('adminhtml/session_quote')->getQuote();
703
+ }
704
+
705
+ return Mage::helper('checkout')->getQuote();
706
  }
707
 
708
  /**
709
  * If we have a mapped currency code we need to convert the currency
710
  *
711
+ * @param \Mage_Sales_Model_Order $order
712
+ * @param $amount
713
  *
714
+ * @return string
715
+ * @throws \Zend_Currency_Exception
716
  */
717
+ public function getCaptureAmount(Mage_Sales_Model_Order $order = null, $amount)
718
  {
719
  // If we've got a mapped currency code the amount is going to change
720
+ if($this->hasMappedCurrencyCode($order)) {
 
 
 
721
 
722
+ // If we don't have an order yet get the quote capture amount
723
+ if($order === null) {
724
+ return $this->convertCaptureAmount($this->getQuote()->getBaseCurrencyCode(), $this->getQuote()->getQuoteCurrencyCode(), $amount);
725
+ }
 
726
 
727
+ // Convert the capture amount
728
+ return $this->convertCaptureAmount($order->getBaseCurrencyCode(), $order->getOrderCurrencyCode(), $amount);
729
  }
730
 
731
+ // Always make sure the number has two decimal places
732
+ return Mage::helper('gene_braintree')->formatPrice($amount);
733
  }
734
 
735
  /**
736
+ * @param $amount
737
  *
738
+ * @return string
739
+ * @throws \Zend_Currency_Exception
740
  */
741
+ public function convertCaptureAmount($baseCurrencyCode, $orderQuoteCurrencyCode, $amount)
742
  {
743
+ // Convert the current
744
+ $convertedCurrency = Mage::helper('directory')->currencyConvert($amount, $baseCurrencyCode, $orderQuoteCurrencyCode);
 
 
745
 
746
+ // Format it to a precision of 2
747
+ $options = array(
748
+ 'currency' => $orderQuoteCurrencyCode,
749
+ 'display' => ''
750
+ );
751
+
752
+ return Mage::app()->getLocale()->currency($orderQuoteCurrencyCode)->toCurrency($convertedCurrency, $options);
753
  }
754
 
755
  /**
787
  return $customer;
788
  }
789
 
790
+ /**
791
+ * Clone a transaction
792
+ *
793
+ * @param $transactionId
794
+ * @param $amount
795
+ *
796
+ * @return bool|mixed
797
+ */
798
+ public function cloneTransaction($transactionId, $amount, $submitForSettlement = true)
799
+ {
800
+ // Attempt to clone the transaction
801
+ try {
802
+ $result = Braintree_Transaction::cloneTransaction($transactionId, array(
803
+ 'amount' => $amount,
804
+ 'options' => array(
805
+ 'submitForSettlement' => $submitForSettlement
806
+ )
807
+ ));
808
+
809
+ return $result;
810
+
811
+ } catch (Exception $e) {
812
+
813
+ // Log the issue
814
+ Gene_Braintree_Model_Debug::log(array('cloneTransaction' => $e));
815
+
816
+ return false;
817
+ }
818
+ }
819
+
820
+ /**
821
+ * Parse Braintree errors as a string
822
+ *
823
+ * @param $braintreeErrors
824
+ *
825
+ * @return string
826
+ */
827
+ public function parseErrors($braintreeErrors)
828
+ {
829
+ $errors = array();
830
+ foreach($braintreeErrors as $error) {
831
+ $errors[] = $error->code . ': ' . $error->message;
832
+ }
833
+
834
+ return implode(', ', $errors);
835
+ }
836
+
837
  }
app/code/community/Gene/Braintree/controllers/CheckoutController.php CHANGED
@@ -40,7 +40,7 @@ class Gene_Braintree_CheckoutController extends Mage_Core_Controller_Front_Actio
40
  $jsonResponse = array(
41
  'billingName' => $billingName,
42
  'billingPostcode' => $billingPostcode,
43
- 'grandTotal' => number_format($quote->getGrandTotal(), 2),
44
  'currencyCode' => $quote->getQuoteCurrencyCode(),
45
  'threeDSecure' => Mage::getSingleton('gene_braintree/paymentmethod_creditcard')->is3DEnabled()
46
  );
40
  $jsonResponse = array(
41
  'billingName' => $billingName,
42
  'billingPostcode' => $billingPostcode,
43
+ 'grandTotal' => Mage::helper('gene_braintree')->formatPrice($quote->getGrandTotal()),
44
  'currencyCode' => $quote->getQuoteCurrencyCode(),
45
  'threeDSecure' => Mage::getSingleton('gene_braintree/paymentmethod_creditcard')->is3DEnabled()
46
  );
app/code/community/Gene/Braintree/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <Gene_Braintree>
5
- <version>1.0.2</version>
6
  </Gene_Braintree>
7
  </modules>
8
  <global>
2
  <config>
3
  <modules>
4
  <Gene_Braintree>
5
+ <version>1.0.3</version>
6
  </Gene_Braintree>
7
  </modules>
8
  <global>
app/design/adminhtml/default/default/template/gene/braintree/creditcard/info.phtml CHANGED
@@ -1,6 +1,6 @@
1
 
2
  <div id="braintree_creditcard_logo" style="padding-top: 5px;padding-left: 2px;">
3
- <img src="http://i.imgur.com/JR1BJTr.png" alt="<?php echo $this->__('PayPal - Braintree'); ?>" /> by <a href="http://gene.co.uk" target="_blank" style="text-decoration: none;">Gene Commerce</a>
4
  </div>
5
 
6
  <?php if ($_specificInfo = $this->getSpecificInformation()):?>
@@ -14,4 +14,8 @@
14
  </table>
15
  <?php endif;?>
16
 
 
 
 
 
17
  <?php echo $this->getChildHtml()?>
1
 
2
  <div id="braintree_creditcard_logo" style="padding-top: 5px;padding-left: 2px;">
3
+ <img src="//i.imgur.com/JR1BJTr.png" alt="<?php echo $this->__('PayPal - Braintree'); ?>" /> by <a href="http://gene.co.uk" target="_blank" style="text-decoration: none;">Gene Commerce</a>
4
  </div>
5
 
6
  <?php if ($_specificInfo = $this->getSpecificInformation()):?>
14
  </table>
15
  <?php endif;?>
16
 
17
+ <?php if(!$this->isSingleInvoice()): ?>
18
+ <p><?php echo $this->__('This order contains multiple Braintree transactions, to view more information on each transaction please view their corresponding invoice.'); ?></p>
19
+ <?php endif; ?>
20
+
21
  <?php echo $this->getChildHtml()?>
app/design/adminhtml/default/default/template/gene/braintree/paypal/info.phtml CHANGED
@@ -1,6 +1,6 @@
1
 
2
  <div id="braintree_paypal_logo" style="padding-top: 5px;padding-left: 2px;">
3
- <img src="http://i.imgur.com/sitDbHA.png" alt="<?php echo $this->__('PayPal - Braintree'); ?>" /> by <a href="http://gene.co.uk" target="_blank" style="text-decoration: none;">Gene Commerce</a>
4
  </div>
5
 
6
  <?php if ($_specificInfo = $this->getSpecificInformation()):?>
@@ -8,7 +8,7 @@
8
  <?php foreach ($_specificInfo as $_label => $_value):?>
9
  <tr>
10
  <th width="180"><?php echo $this->escapeHtml($_label)?>:</td>
11
- <td><?php echo nl2br(implode($this->getValueAsArray($_value, true), "\n"))?></td>
12
  </tr>
13
  <?php endforeach; ?>
14
  </table>
1
 
2
  <div id="braintree_paypal_logo" style="padding-top: 5px;padding-left: 2px;">
3
+ <img src="//i.imgur.com/sitDbHA.png" alt="<?php echo $this->__('PayPal - Braintree'); ?>" /> by <a href="http://gene.co.uk" target="_blank" style="text-decoration: none;">Gene Commerce</a>
4
  </div>
5
 
6
  <?php if ($_specificInfo = $this->getSpecificInformation()):?>
8
  <?php foreach ($_specificInfo as $_label => $_value):?>
9
  <tr>
10
  <th width="180"><?php echo $this->escapeHtml($_label)?>:</td>
11
+ <td><?php echo nl2br(implode($this->getValueAsArray($_value, false), "\n"))?></td>
12
  </tr>
13
  <?php endforeach; ?>
14
  </table>
app/design/frontend/base/default/template/gene/braintree/creditcard.phtml CHANGED
@@ -6,8 +6,8 @@ $_code = $this->getMethodCode()
6
 
7
  <?php if($this->hasSavedDetails() && $this->getMethod()->isVaultEnabled()): ?>
8
 
9
- <label><?php echo $this->__('Saved Cards'); ?></label>
10
- <p><?php echo $this->__('The following credit cards accounts are currently linked with your account.'); ?></p>
11
  <table cellspacing="0" cellpadding="0" id="creditcard-saved-accounts">
12
  <?php
13
  $count = 0;
@@ -22,7 +22,7 @@ $_code = $this->getMethodCode()
22
  <?php endif; ?>
23
  </td>
24
  <td valign="middle">
25
- <label for="<?php echo $savedDetail->token; ?>" style="line-height: 48px;">
26
  <img src="<?php echo $this->getSkinUrl('images/gene/braintree/' . $this->getCardIcon($savedDetail->cardType)) ?>" align="left" />&nbsp;&nbsp; xxxx - xxxx - xxxx - <?php echo $savedDetail->last4; ?> &nbsp;&nbsp;&nbsp; <em><?php echo $this->__('Expires:'); ?></em> <?php echo $savedDetail->expirationMonth; ?>/<?php echo $savedDetail->expirationYear; ?>
27
  </label>
28
  </td>
@@ -150,7 +150,7 @@ $_code = $this->getMethodCode()
150
  CreditCardInit = true;
151
 
152
  // Always set the amount as it's needed within 3D secure requests
153
- vzero.setAmount('<?php echo Mage::getSingleton('checkout/cart')->getQuote()->collectTotals()->getGrandTotal(); ?>');
154
 
155
  // We now need to set this information into the browser
156
  vzero.setBillingName("<?php echo $this->jsQuoteEscape(Mage::getSingleton('checkout/session')->getQuote()->getBillingAddress()->getName(), '"'); ?>");
6
 
7
  <?php if($this->hasSavedDetails() && $this->getMethod()->isVaultEnabled()): ?>
8
 
9
+ <label><?php echo $this->__('Saved Cards'); ?></label><br />
10
+ <p style="padding-left: 0;"><?php echo $this->__('The following credit cards accounts are currently linked with your account.'); ?></p>
11
  <table cellspacing="0" cellpadding="0" id="creditcard-saved-accounts">
12
  <?php
13
  $count = 0;
22
  <?php endif; ?>
23
  </td>
24
  <td valign="middle">
25
+ <label for="<?php echo $savedDetail->token; ?>" style="line-height: 48px;width: auto;">
26
  <img src="<?php echo $this->getSkinUrl('images/gene/braintree/' . $this->getCardIcon($savedDetail->cardType)) ?>" align="left" />&nbsp;&nbsp; xxxx - xxxx - xxxx - <?php echo $savedDetail->last4; ?> &nbsp;&nbsp;&nbsp; <em><?php echo $this->__('Expires:'); ?></em> <?php echo $savedDetail->expirationMonth; ?>/<?php echo $savedDetail->expirationYear; ?>
27
  </label>
28
  </td>
150
  CreditCardInit = true;
151
 
152
  // Always set the amount as it's needed within 3D secure requests
153
+ vzero.setAmount('<?php echo Mage::helper('gene_braintree')->formatPrice(Mage::getSingleton('checkout/cart')->getQuote()->collectTotals()->getGrandTotal()); ?>');
154
 
155
  // We now need to set this information into the browser
156
  vzero.setBillingName("<?php echo $this->jsQuoteEscape(Mage::getSingleton('checkout/session')->getQuote()->getBillingAddress()->getName(), '"'); ?>");
app/design/frontend/base/default/template/gene/braintree/paypal.phtml CHANGED
@@ -61,7 +61,7 @@
61
  PayPalInit = true;
62
 
63
  // Always set the amount as it's needed within 3D secure requests
64
- vzeroPaypal.setPricing('<?php echo Mage::getSingleton('checkout/cart')->getQuote()->collectTotals()->getGrandTotal(); ?>', '<?php echo Mage::getSingleton('checkout/cart')->getQuote()->getQuoteCurrencyCode(); ?>');
65
  }
66
 
67
  $$('#paypal-saved-accounts input[type="radio"]').each(function(elm) {
61
  PayPalInit = true;
62
 
63
  // Always set the amount as it's needed within 3D secure requests
64
+ vzeroPaypal.setPricing('<?php echo Mage::helper('gene_braintree')->formatPrice(Mage::getSingleton('checkout/cart')->getQuote()->collectTotals()->getGrandTotal()); ?>', '<?php echo Mage::getSingleton('checkout/cart')->getQuote()->getQuoteCurrencyCode(); ?>');
65
  }
66
 
67
  $$('#paypal-saved-accounts input[type="radio"]').each(function(elm) {
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Gene_Braintree</name>
4
- <version>1.0.2</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/mit-license.php">MIT License</license>
7
  <channel>community</channel>
@@ -36,9 +36,9 @@ Easily add PayPal to your checkout. We've built the best PayPal integration arou
36
  &lt;/ul&gt;</description>
37
  <notes>Connect your Magento store to Braintree to accept Credit Cards &amp;amp; PayPal using V.Zero SDK</notes>
38
  <authors><author><name>Dave Macaulay</name><user>dave</user><email>magento@gene.co.uk</email></author></authors>
39
- <date>2015-05-29</date>
40
- <time>08:44:09</time>
41
- <contents><target name="magecommunity"><dir name="Gene"><dir name="Braintree"><dir name="Block"><dir name="Adminhtml"><dir name="Report"><dir name="Transactions"><file name="Grid.php" hash="32b32086548f62ae4aca4baf456b9ed2"/><file name="Search.php" hash="81d57c3744530f36c37782ce9d0f3a70"/></dir><file name="Transactions.php" hash="7afe45b49353e52b432aa0392d76a08e"/></dir><dir name="System"><dir name="Config"><dir name="Braintree"><file name="Config.php" hash="eaaf6c74be4233a315d5aa5932f7c9ca"/><file name="Currency.php" hash="9ffa8a2ded53be75e88a60a024883b07"/><file name="Moduleversion.php" hash="fe3836bde24bb31c4c4585f2cd2f20ed"/><file name="Version.php" hash="ce58278a4faf965301cc2d8b2da4483c"/></dir></dir></dir></dir><dir name="Cart"><file name="Totals.php" hash="a03c441e8143896f92d02931a809f666"/></dir><dir name="Creditcard"><file name="Info.php" hash="adb06dab5fb625e4bf71e8cd62230f9c"/><file name="Threedsecure.php" hash="7848d4ecac743be985f328fa969318bf"/></dir><file name="Creditcard.php" hash="989678324ff3fcddcc99cbe4613019fa"/><file name="Js.php" hash="50cdd6d01eddfbdcc0061f4369cbeb58"/><dir name="Paypal"><file name="Info.php" hash="a0206fad8b91aa382c3ac16b9651c723"/></dir><file name="Paypal.php" hash="36294a461378cceee66e99d45753c6e1"/><file name="Saved.php" hash="74ed8e70a404a814b94f21f88c1ca737"/></dir><dir name="Helper"><file name="Data.php" hash="a5b64dd6760e881b1823adfaeb7c1501"/></dir><dir name="Model"><file name="Debug.php" hash="f3360f71e2346881f93424792ed9f209"/><file name="Observer.php" hash="176b48ac3b74bfaa3c28f4126093b49b"/><dir name="Paymentmethod"><file name="Abstract.php" hash="cebdcee57db8ed28760313b6078348c3"/><file name="Creditcard.php" hash="4c1256ff5aef5c958a5059e3a3d3a1b3"/><file name="Paypal.php" hash="f7802643b422628d09ae2b5ae03163fb"/></dir><file name="Saved.php" hash="3b235b454a3692d1c3d5343e2a1c91e9"/><dir name="Source"><file name="Cctype.php" hash="d76aa6c3a4bd798e3a47695f579d21d4"/><dir name="Creditcard"><file name="CaptureAction.php" hash="6444cfc430de44f06e85bd9c8b80d77b"/><file name="PaymentAction.php" hash="a2f3f3d36a98df4d12f76b6ab77f9c47"/></dir><file name="Environment.php" hash="02567d2ddba74d06ac000b4ddb12723a"/><dir name="Paypal"><file name="Locale.php" hash="8988ca77f9c2aa2d19ff0b614a4b7621"/><file name="Paymenttype.php" hash="fe1fe4ee89d5b7a87c7c28716bb2f1cb"/></dir></dir><dir name="System"><dir name="Config"><dir name="Backend"><file name="Currency.php" hash="73cb15b1de303e88c487db4c585ef94e"/></dir></dir></dir><dir name="Wrapper"><file name="Braintree.php" hash="203dbffc8be8e9827f92c971bdb15337"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="BraintreeController.php" hash="7c621fa1548c04e24bb1136bcbbe1d72"/></dir><file name="CheckoutController.php" hash="6c97fd8d9894cebcd1f5d839c0901dd5"/><file name="SavedController.php" hash="036e97703c853a5bae064dd7cf5030a8"/></dir><dir name="etc"><file name="adminhtml.xml" hash="c9c940beffa0ec19e4a1499a66f7fd12"/><file name="config.xml" hash="0394250964f9b7207d4e2d4f2c5e99d7"/><file name="system.xml" hash="01fc95e2c590d2fad81b007e361cfa63"/></dir><dir name="sql"><dir name="gene_braintree_setup"><file name="install-0.1.0.php" hash="7ef62b7c19b9da5990974da6edb3e77c"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><dir name="gene"><file name="braintree.xml" hash="1ded19331e4656bd31d052eb729ff7c2"/></dir></dir><dir name="template"><dir name="gene"><dir name="braintree"><dir name="creditcard"><file name="info.phtml" hash="2ae1e397b3a633dd305bc26c7b9c1065"/><file name="threedsecure.phtml" hash="ee8ad689afde041c39dd92ffa5274883"/></dir><file name="creditcard.phtml" hash="1d1795c1d29b37ac9cf090ad76f22bb5"/><dir name="customer"><file name="methods.phtml" hash="eb5e2d8f4a0f419fcf720c12062f808a"/><file name="saved.phtml" hash="691162b89ed085599f76072226ca2307"/></dir><dir name="js"><file name="amasty.phtml" hash="2f0601e50fc2fcf0ffe03a013737186c"/><file name="data.phtml" hash="7c77e2c13c9037ab993b7c7f8aa72d98"/><file name="default.phtml" hash="4fde57aa847f06bc02feaaf9097b1f57"/><file name="idev.phtml" hash="5fd739089dbe0191c1f44640f7ef2f76"/><file name="setup.phtml" hash="86a6da43f073b5fc75ce170a50af3bcd"/></dir><dir name="paypal"><file name="info.phtml" hash="5149b273730121e4dec3c3179820f747"/></dir><file name="paypal.phtml" hash="3c579ad7ba3290c15fcce027cdd66d16"/></dir></dir></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><dir name="gene"><file name="braintree.xml" hash="1995e85eb47b909120ce8b9b537bf5db"/></dir></dir><dir name="template"><dir name="gene"><dir name="braintree"><dir name="creditcard"><file name="info.phtml" hash="3c5f033eb99ab8d78517ae5eb45a3a1a"/></dir><file name="creditcard.phtml" hash="0c6b7806732c336ead14fab596f1b923"/><file name="js.phtml" hash="0a66005bfd1452be665299b11b6fbf8b"/><dir name="paypal"><file name="info.phtml" hash="53fae03530369f101f5eaed49508a1ee"/></dir><dir name="transactions"><file name="index.phtml" hash="1791b6393f319616dd79c0b46e391847"/><file name="search.phtml" hash="1682ce6200681681f0ce3c848e2e6694"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Gene_Braintree.xml" hash="8c0ffda8566dca2f0b98a999921e3e55"/></dir></target><target name="mageweb"><dir name="js"><dir name="gene"><dir name="braintree"><file name="braintree.js" hash="4a074b2952d6e3c0052f85442b284abc"/><file name="vzero.js" hash="0ea7d83df34c94eae8fa9d1c112d6824"/></dir></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="images"><dir name="gene"><dir name="braintree"><file name="AE.png" hash="6b6f405105413b0723a62ee498f88bf6"/><file name="DI.png" hash="d8e3c3022dda9e723f466b8976ae428f"/><file name="JCB.png" hash="3aa9a71ed8a1d6610bbe0dfe2040e29e"/><file name="MC.png" hash="1fcd14928245139962b72f9368bdbe32"/><file name="ME.png" hash="b9389913c47b9546a67f907fcca73706"/><file name="PP.png" hash="b4946bccba574e86c9716a4986e21c36"/><file name="VI.png" hash="c9f74d1d54e61ab2c748f45a4bdface0"/><file name="card.png" hash="66e16f8c573fad93bb0d62258dce28bb"/><file name=".DS_Store" hash="194577a7e20bdcc7afbb718f502c134c"/></dir></dir></dir></dir></dir></dir></target><target name="magelib"><dir name="Braintree"><file name="AddOn.php" hash="07bc690cf426276dfdd802c49cfd72a3"/><file name="AddOnGateway.php" hash="ed9a94155c1c13ba37910fd48bdad40a"/><file name="Address.php" hash="1d4e7f964ed208a381b352d21fc370b8"/><file name="AddressGateway.php" hash="11716dc4ede8b7455197d08b88c91568"/><file name="ApplePayCard.php" hash="6fdbe99722514408f613c417e0e48711"/><file name="ClientToken.php" hash="f606f4bbafaea470333290be52b0030d"/><file name="ClientTokenGateway.php" hash="ede93fa63f0e96d296f315180f5ff1ad"/><file name="CoinbaseAccount.php" hash="7a4992ed13c26ad3785cf7d3455ef5fb"/><file name="Collection.php" hash="0e7d31ffcbd9780fb554186bd2c194b0"/><file name="Configuration.php" hash="6414dae20a80d926c28bd681bb535934"/><file name="CreditCard.php" hash="cf0aab2bcdcc7c231ccedc05a0f853e4"/><file name="CreditCardGateway.php" hash="3c5c3d9cee27da71e338b51d42b685ee"/><file name="CreditCardVerification.php" hash="48d6ea546914278f4bea2fefb75e7836"/><file name="CreditCardVerificationGateway.php" hash="e020dd1c26cd8c3bd7eb55eed2f72346"/><file name="CreditCardVerificationSearch.php" hash="baa6ed22471ea1f142a4195d1e36f89a"/><file name="Customer.php" hash="69d834344b93277dbeadb4ee6a881a60"/><file name="CustomerGateway.php" hash="bde59d4c6d7418fcbd87d4484384705b"/><file name="CustomerSearch.php" hash="8aacc83dac341cd9afec5a3deab17593"/><file name="Descriptor.php" hash="3f5db5e817280ce7f2fa18a205281ad9"/><file name="Digest.php" hash="9d12d067770f55b123b8498fce4478fa"/><file name="Disbursement.php" hash="589534043e466d17fede916fd7986edc"/><file name="DisbursementDetails.php" hash="ae632207d0982e288a83aed401c880d9"/><file name="Discount.php" hash="763b3f9cde0ff3af3e8795cac4097595"/><file name="DiscountGateway.php" hash="42ca6f2f11074ec18eecd1506996a393"/><dir name="Dispute"><file name="TransactionDetails.php" hash="7fdea673a1295055508f42286ad57f4e"/></dir><file name="Dispute.php" hash="2ee0f4a77b7cfec4763b55627a57e348"/><file name="EqualityNode.php" hash="cfd6aa184186233b8d6d1ec0f0e79298"/><dir name="Error"><file name="Codes.php" hash="d0d1007255af20889a4874d028ebeab2"/><file name="ErrorCollection.php" hash="e28d638db56524f5bf3609fa725e6d55"/><file name="Validation.php" hash="bf4e2198300019c52ba56f16269d66ce"/><file name="ValidationErrorCollection.php" hash="9ef25d0126a0b4f6951da5334ae6f0dc"/></dir><dir name="Exception"><file name="Authentication.php" hash="f9e13654988452cca2ac5228a80adae4"/><file name="Authorization.php" hash="5f8c017c6e9fd79a556dade8e15a72e8"/><file name="Configuration.php" hash="b50f67e8ea36cff0d9f6ad718126c6fc"/><file name="DownForMaintenance.php" hash="7fd30b1f8976ed7e38b7e9fae5c20f03"/><file name="ForgedQueryString.php" hash="6884dbae1e86767834b77c821df2db62"/><file name="InvalidSignature.php" hash="b83f5b16735cb3a8e0a8111c4f32711e"/><file name="NotFound.php" hash="f832f771d20b381c2780eb2a572b9f44"/><file name="SSLCaFileNotFound.php" hash="e927c7307bf1761814dc8a755238070d"/><file name="SSLCertificate.php" hash="d509b6a6206bd7c5563ac142dfe3801f"/><file name="ServerError.php" hash="b4645290229ab228a257047d08ef63d7"/><file name="Unexpected.php" hash="01ea2800fb91995ec2a15aee5024611e"/><file name="UpgradeRequired.php" hash="7f40b174df891cc3b3e206d1be884a58"/><file name="ValidationsFailed.php" hash="cd2d30c69911f81b55279c3d6bf88c61"/></dir><file name="Exception.php" hash="f14c94bf67206184eb3e4e7aeb4a608a"/><file name="Gateway.php" hash="8b214a63ed50539e75031caff78d4560"/><file name="Http.php" hash="5f6a9990a14684c82b6952937889412b"/><file name="Instance.php" hash="f0603b3f9213b53687e079c5621ac8f3"/><file name="IsNode.php" hash="e4b1f7bbfcbd24b1d08b97f94df592be"/><file name="KeyValueNode.php" hash="255595ec01a16906dd0c49faf67d9efb"/><dir name="MerchantAccount"><file name="AddressDetails.php" hash="1d265d864a884ebcf2504f55207cc0dd"/><file name="BusinessDetails.php" hash="c9ae627c4a4b526c2ecb0c07d70b3017"/><file name="FundingDetails.php" hash="7368f653fcbcc3d87924447b1763e616"/><file name="IndividualDetails.php" hash="68daf00759335cde82f176f0844e0d9b"/></dir><file name="MerchantAccount.php" hash="489844cfd91dcc6a53024af97b85f3c7"/><file name="MerchantAccountGateway.php" hash="6a9033758b8c02501fd835a96fc385b7"/><file name="Modification.php" hash="fcce6784af2e658affe4a67ca75d8230"/><file name="MultipleValueNode.php" hash="92700fa03011eaa9561010b3a160449c"/><file name="MultipleValueOrTextNode.php" hash="ef06bac18e2bc40974bdc0bcb854890f"/><file name="PartialMatchNode.php" hash="370c7e0ab8a445cfeef6b19ef1755f4d"/><file name="PartnerMerchant.php" hash="20c87322d040eac1abcdf12b8838ec1c"/><file name="PayPalAccount.php" hash="1bbe86a33bbf3e3620364ba0c2e9b6fe"/><file name="PayPalAccountGateway.php" hash="bdf94548085765927368c49bcf028f47"/><file name="PaymentInstrumentType.php" hash="84e2d2fcfe45cf7cf188dc46f302fac8"/><file name="PaymentMethod.php" hash="8aca88278367fcbd5404a0abae848a45"/><file name="PaymentMethodGateway.php" hash="ed81d66dcb097021c4f6518b9ea5e5cf"/><file name="PaymentMethodNonce.php" hash="a72e8ed6506327cdac92d8b082e4dd74"/><file name="PaymentMethodNonceGateway.php" hash="e8ee61d15b73bd2ef9efef8a6b5f4132"/><file name="Plan.php" hash="f73f24fcc57cfeb2e6f0e6312e531073"/><file name="PlanGateway.php" hash="8392fc6b714b30d16fe0308a1e81db4f"/><file name="RangeNode.php" hash="4ad9a92547423b3d54d69097114c3daf"/><file name="ResourceCollection.php" hash="8f437cb5014148c0e2f6049347ae795c"/><dir name="Result"><file name="CreditCardVerification.php" hash="27b965f1e197b0392879e24cccf6dd9c"/><file name="Error.php" hash="81b616e25f182c0c571ad4e9e6fbc611"/><file name="Successful.php" hash="56c6f9a3e5996d18e01a8d382cc03cde"/></dir><file name="RiskData.php" hash="dd74658f351fe8af26cee3016a076fb9"/><file name="SettlementBatchSummary.php" hash="0dcc2b5dd7071d9037cf5970fafe8668"/><file name="SettlementBatchSummaryGateway.php" hash="4ec1a7a1c8875693123430aa51410b22"/><file name="SignatureService.php" hash="4b78d3e5897e715dcc877c5f65b3cfae"/><dir name="Subscription"><file name="StatusDetails.php" hash="29e375f02150bfd7147591f0eb27cb4f"/></dir><file name="Subscription.php" hash="96db82b5b67a72d4287d79b7c691b3d7"/><file name="SubscriptionGateway.php" hash="34118ee95b83d8904a47b388cbb8cfea"/><file name="SubscriptionSearch.php" hash="1874ebe5cb42d7d2836617810cced1af"/><dir name="Test"><file name="CreditCardNumbers.php" hash="676a9100354eb679e7ca1e0f0d67293f"/><file name="MerchantAccount.php" hash="612e7e30cca364c0d14cbff3b54ebf3f"/><file name="Nonces.php" hash="89bb29ef4552037973fe04d344f657ef"/><file name="TransactionAmounts.php" hash="ed9bf1f57d871542c32d11de9e031f05"/><file name="VenmoSdk.php" hash="6ce94deccd1f968596011487c7e69cc7"/></dir><file name="TextNode.php" hash="94c95ec9645de57acace2179fef7fb43"/><dir name="Transaction"><file name="AddressDetails.php" hash="ff52a4a48248085b7ea92e992160e413"/><file name="ApplePayCardDetails.php" hash="c4dd87cd46fe7269e1bd51c867adf7cb"/><file name="CoinbaseDetails.php" hash="d19a625f8de98698b8277c25660358f0"/><file name="CreditCardDetails.php" hash="aac5eb1f5804d4f979b9c71f7b98cb36"/><file name="CustomerDetails.php" hash="e137895c646127312be44292c84a2d81"/><file name="PayPalDetails.php" hash="ede299e376bce7714838d79ca3d40842"/><file name="StatusDetails.php" hash="7c6e719c51bf13bdfd07615030100ac6"/><file name="SubscriptionDetails.php" hash="1cf1f511d1545a2e27b8d3f4bee800ca"/></dir><file name="Transaction.php" hash="9970a0fa9d6af3e543703426da99a3c4"/><file name="TransactionGateway.php" hash="37500b8a181a18375c171d4a5a4938c6"/><file name="TransactionSearch.php" hash="41dd086066fa57582161032249b3d8ee"/><file name="TransparentRedirect.php" hash="154c9850be5175a5cd1b35bdf78ae939"/><file name="TransparentRedirectGateway.php" hash="89f002df5a2abafcaa9676a3e2935c75"/><file name="UnknownPaymentMethod.php" hash="811394ea4bee98a651dc5e1cba8223da"/><file name="Util.php" hash="2cf47c3acd49da4a6c2b0a9a55701d7b"/><file name="Version.php" hash="1ebf13fcec95da846f917f74e030714b"/><file name="WebhookNotification.php" hash="f58be59156e5728f491da4235a58e994"/><file name="WebhookTesting.php" hash="c40311458bb64e37b4c08eb88df37805"/><dir name="Xml"><file name="Generator.php" hash="f82af40e5759c3d46909f3dec2498d02"/><file name="Parser.php" hash="4e6df3327a04915715333460733df93c"/></dir><file name="Xml.php" hash="dc69e05bea21e3d1185d45d53e4747db"/></dir><dir name="."><file name="Braintree.php" hash="ee3e665877882e5b5076ff51dc8111bd"/></dir><dir name="ssl"><file name="api_braintreegateway_com.ca.crt" hash="04beb23c767547e980c76eb68c7eab15"/><file name="sandbox_braintreegateway_com.ca.crt" hash="f1b529883c7c2cbb4251658f5da7b4c9"/></dir></target><target name="magelocale"><dir><dir name="en_US"><file name="Gene_Braintree.csv" hash="00ae6dc359bc0d9c48bfc90a865232a3"/></dir></dir></target></contents>
42
  <compatible/>
43
  <dependencies><required><php><min>5.2.1</min><max>6.0.0</max></php><package><name/><channel>connect.magentocommerce.com/core</channel><min/><max/></package></required></dependencies>
44
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Gene_Braintree</name>
4
+ <version>1.0.3</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/mit-license.php">MIT License</license>
7
  <channel>community</channel>
36
  &lt;/ul&gt;</description>
37
  <notes>Connect your Magento store to Braintree to accept Credit Cards &amp;amp; PayPal using V.Zero SDK</notes>
38
  <authors><author><name>Dave Macaulay</name><user>dave</user><email>magento@gene.co.uk</email></author></authors>
39
+ <date>2015-06-08</date>
40
+ <time>13:19:19</time>
41
+ <contents><target name="magecommunity"><dir name="Gene"><dir name="Braintree"><dir name="Block"><dir name="Adminhtml"><dir name="Report"><dir name="Transactions"><file name="Grid.php" hash="32b32086548f62ae4aca4baf456b9ed2"/><file name="Search.php" hash="81d57c3744530f36c37782ce9d0f3a70"/></dir><file name="Transactions.php" hash="7afe45b49353e52b432aa0392d76a08e"/></dir><dir name="System"><dir name="Config"><dir name="Braintree"><file name="Config.php" hash="eaaf6c74be4233a315d5aa5932f7c9ca"/><file name="Currency.php" hash="9ffa8a2ded53be75e88a60a024883b07"/><file name="Moduleversion.php" hash="fe3836bde24bb31c4c4585f2cd2f20ed"/><file name="Version.php" hash="ce58278a4faf965301cc2d8b2da4483c"/></dir></dir></dir></dir><dir name="Cart"><file name="Totals.php" hash="a03c441e8143896f92d02931a809f666"/></dir><dir name="Creditcard"><file name="Info.php" hash="8050c4c5321535fe93e62b47eab97b82"/><file name="Threedsecure.php" hash="7848d4ecac743be985f328fa969318bf"/></dir><file name="Creditcard.php" hash="989678324ff3fcddcc99cbe4613019fa"/><file name="Info.php" hash="2a8367489959ba9c1de4fe4c9afa62e4"/><file name="Js.php" hash="50cdd6d01eddfbdcc0061f4369cbeb58"/><dir name="Paypal"><file name="Info.php" hash="0874c0839a27c14ec9be47fed152e880"/></dir><file name="Paypal.php" hash="36294a461378cceee66e99d45753c6e1"/><file name="Saved.php" hash="74ed8e70a404a814b94f21f88c1ca737"/></dir><dir name="Helper"><file name="Data.php" hash="7ab1dba0f90dc067f0293e3f34bdf387"/></dir><dir name="Model"><file name="Debug.php" hash="f3360f71e2346881f93424792ed9f209"/><file name="Observer.php" hash="176b48ac3b74bfaa3c28f4126093b49b"/><dir name="Paymentmethod"><file name="Abstract.php" hash="f6f818eb5720ceee4e43cff281209a88"/><file name="Creditcard.php" hash="c0c1307ada89f675ff97b96412205615"/><file name="Paypal.php" hash="6523279bdc21c8b047d85b99d251a26a"/></dir><file name="Saved.php" hash="3b235b454a3692d1c3d5343e2a1c91e9"/><dir name="Source"><file name="Cctype.php" hash="d76aa6c3a4bd798e3a47695f579d21d4"/><dir name="Creditcard"><file name="CaptureAction.php" hash="6444cfc430de44f06e85bd9c8b80d77b"/><file name="PaymentAction.php" hash="a2f3f3d36a98df4d12f76b6ab77f9c47"/></dir><file name="Environment.php" hash="02567d2ddba74d06ac000b4ddb12723a"/><dir name="Paypal"><file name="Locale.php" hash="8988ca77f9c2aa2d19ff0b614a4b7621"/><file name="Paymenttype.php" hash="fe1fe4ee89d5b7a87c7c28716bb2f1cb"/></dir></dir><dir name="System"><dir name="Config"><dir name="Backend"><file name="Currency.php" hash="73cb15b1de303e88c487db4c585ef94e"/></dir></dir></dir><dir name="Wrapper"><file name="Braintree.php" hash="3b59754d575df9960ad973102bd038e2"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="BraintreeController.php" hash="7c621fa1548c04e24bb1136bcbbe1d72"/></dir><file name="CheckoutController.php" hash="19551187f161f5df4e49a9a009c0adaf"/><file name="SavedController.php" hash="036e97703c853a5bae064dd7cf5030a8"/></dir><dir name="etc"><file name="adminhtml.xml" hash="c9c940beffa0ec19e4a1499a66f7fd12"/><file name="config.xml" hash="9527dee069d34f723f74ac97e658a626"/><file name="system.xml" hash="01fc95e2c590d2fad81b007e361cfa63"/></dir><dir name="sql"><dir name="gene_braintree_setup"><file name="install-0.1.0.php" hash="7ef62b7c19b9da5990974da6edb3e77c"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><dir name="gene"><file name="braintree.xml" hash="1ded19331e4656bd31d052eb729ff7c2"/></dir></dir><dir name="template"><dir name="gene"><dir name="braintree"><dir name="creditcard"><file name="info.phtml" hash="2ae1e397b3a633dd305bc26c7b9c1065"/><file name="threedsecure.phtml" hash="ee8ad689afde041c39dd92ffa5274883"/></dir><file name="creditcard.phtml" hash="e741bce943fe9dbed1b4170ead312ed8"/><dir name="customer"><file name="methods.phtml" hash="eb5e2d8f4a0f419fcf720c12062f808a"/><file name="saved.phtml" hash="691162b89ed085599f76072226ca2307"/></dir><dir name="js"><file name="amasty.phtml" hash="2f0601e50fc2fcf0ffe03a013737186c"/><file name="data.phtml" hash="7c77e2c13c9037ab993b7c7f8aa72d98"/><file name="default.phtml" hash="4fde57aa847f06bc02feaaf9097b1f57"/><file name="idev.phtml" hash="5fd739089dbe0191c1f44640f7ef2f76"/><file name="setup.phtml" hash="86a6da43f073b5fc75ce170a50af3bcd"/></dir><dir name="paypal"><file name="info.phtml" hash="5149b273730121e4dec3c3179820f747"/></dir><file name="paypal.phtml" hash="4280fcf89509eb959171f2214779de35"/></dir></dir></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><dir name="gene"><file name="braintree.xml" hash="1995e85eb47b909120ce8b9b537bf5db"/></dir></dir><dir name="template"><dir name="gene"><dir name="braintree"><dir name="creditcard"><file name="info.phtml" hash="24c67bab482ea7383ce57d9a06bb9d6f"/></dir><file name="creditcard.phtml" hash="0c6b7806732c336ead14fab596f1b923"/><file name="js.phtml" hash="0a66005bfd1452be665299b11b6fbf8b"/><dir name="paypal"><file name="info.phtml" hash="a8f92f312f8aa5a9463f1d5c2a38cd1b"/></dir><dir name="transactions"><file name="index.phtml" hash="1791b6393f319616dd79c0b46e391847"/><file name="search.phtml" hash="1682ce6200681681f0ce3c848e2e6694"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Gene_Braintree.xml" hash="8c0ffda8566dca2f0b98a999921e3e55"/></dir></target><target name="mageweb"><dir name="js"><dir name="gene"><dir name="braintree"><file name="braintree.js" hash="4a074b2952d6e3c0052f85442b284abc"/><file name="vzero.js" hash="0ea7d83df34c94eae8fa9d1c112d6824"/></dir></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="images"><dir name="gene"><dir name="braintree"><file name="AE.png" hash="6b6f405105413b0723a62ee498f88bf6"/><file name="DI.png" hash="d8e3c3022dda9e723f466b8976ae428f"/><file name="JCB.png" hash="3aa9a71ed8a1d6610bbe0dfe2040e29e"/><file name="MC.png" hash="1fcd14928245139962b72f9368bdbe32"/><file name="ME.png" hash="b9389913c47b9546a67f907fcca73706"/><file name="PP.png" hash="b4946bccba574e86c9716a4986e21c36"/><file name="VI.png" hash="c9f74d1d54e61ab2c748f45a4bdface0"/><file name="card.png" hash="66e16f8c573fad93bb0d62258dce28bb"/><file name=".DS_Store" hash="194577a7e20bdcc7afbb718f502c134c"/></dir></dir></dir></dir></dir></dir></target><target name="magelib"><dir name="Braintree"><file name="AddOn.php" hash="07bc690cf426276dfdd802c49cfd72a3"/><file name="AddOnGateway.php" hash="ed9a94155c1c13ba37910fd48bdad40a"/><file name="Address.php" hash="1d4e7f964ed208a381b352d21fc370b8"/><file name="AddressGateway.php" hash="11716dc4ede8b7455197d08b88c91568"/><file name="ApplePayCard.php" hash="6fdbe99722514408f613c417e0e48711"/><file name="ClientToken.php" hash="f606f4bbafaea470333290be52b0030d"/><file name="ClientTokenGateway.php" hash="ede93fa63f0e96d296f315180f5ff1ad"/><file name="CoinbaseAccount.php" hash="7a4992ed13c26ad3785cf7d3455ef5fb"/><file name="Collection.php" hash="0e7d31ffcbd9780fb554186bd2c194b0"/><file name="Configuration.php" hash="6414dae20a80d926c28bd681bb535934"/><file name="CreditCard.php" hash="cf0aab2bcdcc7c231ccedc05a0f853e4"/><file name="CreditCardGateway.php" hash="3c5c3d9cee27da71e338b51d42b685ee"/><file name="CreditCardVerification.php" hash="48d6ea546914278f4bea2fefb75e7836"/><file name="CreditCardVerificationGateway.php" hash="e020dd1c26cd8c3bd7eb55eed2f72346"/><file name="CreditCardVerificationSearch.php" hash="baa6ed22471ea1f142a4195d1e36f89a"/><file name="Customer.php" hash="69d834344b93277dbeadb4ee6a881a60"/><file name="CustomerGateway.php" hash="bde59d4c6d7418fcbd87d4484384705b"/><file name="CustomerSearch.php" hash="8aacc83dac341cd9afec5a3deab17593"/><file name="Descriptor.php" hash="3f5db5e817280ce7f2fa18a205281ad9"/><file name="Digest.php" hash="9d12d067770f55b123b8498fce4478fa"/><file name="Disbursement.php" hash="589534043e466d17fede916fd7986edc"/><file name="DisbursementDetails.php" hash="ae632207d0982e288a83aed401c880d9"/><file name="Discount.php" hash="763b3f9cde0ff3af3e8795cac4097595"/><file name="DiscountGateway.php" hash="42ca6f2f11074ec18eecd1506996a393"/><dir name="Dispute"><file name="TransactionDetails.php" hash="7fdea673a1295055508f42286ad57f4e"/></dir><file name="Dispute.php" hash="2ee0f4a77b7cfec4763b55627a57e348"/><file name="EqualityNode.php" hash="cfd6aa184186233b8d6d1ec0f0e79298"/><dir name="Error"><file name="Codes.php" hash="d0d1007255af20889a4874d028ebeab2"/><file name="ErrorCollection.php" hash="e28d638db56524f5bf3609fa725e6d55"/><file name="Validation.php" hash="bf4e2198300019c52ba56f16269d66ce"/><file name="ValidationErrorCollection.php" hash="9ef25d0126a0b4f6951da5334ae6f0dc"/></dir><dir name="Exception"><file name="Authentication.php" hash="f9e13654988452cca2ac5228a80adae4"/><file name="Authorization.php" hash="5f8c017c6e9fd79a556dade8e15a72e8"/><file name="Configuration.php" hash="b50f67e8ea36cff0d9f6ad718126c6fc"/><file name="DownForMaintenance.php" hash="7fd30b1f8976ed7e38b7e9fae5c20f03"/><file name="ForgedQueryString.php" hash="6884dbae1e86767834b77c821df2db62"/><file name="InvalidSignature.php" hash="b83f5b16735cb3a8e0a8111c4f32711e"/><file name="NotFound.php" hash="f832f771d20b381c2780eb2a572b9f44"/><file name="SSLCaFileNotFound.php" hash="e927c7307bf1761814dc8a755238070d"/><file name="SSLCertificate.php" hash="d509b6a6206bd7c5563ac142dfe3801f"/><file name="ServerError.php" hash="b4645290229ab228a257047d08ef63d7"/><file name="Unexpected.php" hash="01ea2800fb91995ec2a15aee5024611e"/><file name="UpgradeRequired.php" hash="7f40b174df891cc3b3e206d1be884a58"/><file name="ValidationsFailed.php" hash="cd2d30c69911f81b55279c3d6bf88c61"/></dir><file name="Exception.php" hash="f14c94bf67206184eb3e4e7aeb4a608a"/><file name="Gateway.php" hash="8b214a63ed50539e75031caff78d4560"/><file name="Http.php" hash="5f6a9990a14684c82b6952937889412b"/><file name="Instance.php" hash="f0603b3f9213b53687e079c5621ac8f3"/><file name="IsNode.php" hash="e4b1f7bbfcbd24b1d08b97f94df592be"/><file name="KeyValueNode.php" hash="255595ec01a16906dd0c49faf67d9efb"/><dir name="MerchantAccount"><file name="AddressDetails.php" hash="1d265d864a884ebcf2504f55207cc0dd"/><file name="BusinessDetails.php" hash="c9ae627c4a4b526c2ecb0c07d70b3017"/><file name="FundingDetails.php" hash="7368f653fcbcc3d87924447b1763e616"/><file name="IndividualDetails.php" hash="68daf00759335cde82f176f0844e0d9b"/></dir><file name="MerchantAccount.php" hash="489844cfd91dcc6a53024af97b85f3c7"/><file name="MerchantAccountGateway.php" hash="6a9033758b8c02501fd835a96fc385b7"/><file name="Modification.php" hash="fcce6784af2e658affe4a67ca75d8230"/><file name="MultipleValueNode.php" hash="92700fa03011eaa9561010b3a160449c"/><file name="MultipleValueOrTextNode.php" hash="ef06bac18e2bc40974bdc0bcb854890f"/><file name="PartialMatchNode.php" hash="370c7e0ab8a445cfeef6b19ef1755f4d"/><file name="PartnerMerchant.php" hash="20c87322d040eac1abcdf12b8838ec1c"/><file name="PayPalAccount.php" hash="1bbe86a33bbf3e3620364ba0c2e9b6fe"/><file name="PayPalAccountGateway.php" hash="bdf94548085765927368c49bcf028f47"/><file name="PaymentInstrumentType.php" hash="84e2d2fcfe45cf7cf188dc46f302fac8"/><file name="PaymentMethod.php" hash="8aca88278367fcbd5404a0abae848a45"/><file name="PaymentMethodGateway.php" hash="ed81d66dcb097021c4f6518b9ea5e5cf"/><file name="PaymentMethodNonce.php" hash="a72e8ed6506327cdac92d8b082e4dd74"/><file name="PaymentMethodNonceGateway.php" hash="e8ee61d15b73bd2ef9efef8a6b5f4132"/><file name="Plan.php" hash="f73f24fcc57cfeb2e6f0e6312e531073"/><file name="PlanGateway.php" hash="8392fc6b714b30d16fe0308a1e81db4f"/><file name="RangeNode.php" hash="4ad9a92547423b3d54d69097114c3daf"/><file name="ResourceCollection.php" hash="8f437cb5014148c0e2f6049347ae795c"/><dir name="Result"><file name="CreditCardVerification.php" hash="27b965f1e197b0392879e24cccf6dd9c"/><file name="Error.php" hash="81b616e25f182c0c571ad4e9e6fbc611"/><file name="Successful.php" hash="56c6f9a3e5996d18e01a8d382cc03cde"/></dir><file name="RiskData.php" hash="dd74658f351fe8af26cee3016a076fb9"/><file name="SettlementBatchSummary.php" hash="0dcc2b5dd7071d9037cf5970fafe8668"/><file name="SettlementBatchSummaryGateway.php" hash="4ec1a7a1c8875693123430aa51410b22"/><file name="SignatureService.php" hash="4b78d3e5897e715dcc877c5f65b3cfae"/><dir name="Subscription"><file name="StatusDetails.php" hash="29e375f02150bfd7147591f0eb27cb4f"/></dir><file name="Subscription.php" hash="96db82b5b67a72d4287d79b7c691b3d7"/><file name="SubscriptionGateway.php" hash="34118ee95b83d8904a47b388cbb8cfea"/><file name="SubscriptionSearch.php" hash="1874ebe5cb42d7d2836617810cced1af"/><dir name="Test"><file name="CreditCardNumbers.php" hash="676a9100354eb679e7ca1e0f0d67293f"/><file name="MerchantAccount.php" hash="612e7e30cca364c0d14cbff3b54ebf3f"/><file name="Nonces.php" hash="89bb29ef4552037973fe04d344f657ef"/><file name="TransactionAmounts.php" hash="ed9bf1f57d871542c32d11de9e031f05"/><file name="VenmoSdk.php" hash="6ce94deccd1f968596011487c7e69cc7"/></dir><file name="TextNode.php" hash="94c95ec9645de57acace2179fef7fb43"/><dir name="Transaction"><file name="AddressDetails.php" hash="ff52a4a48248085b7ea92e992160e413"/><file name="ApplePayCardDetails.php" hash="c4dd87cd46fe7269e1bd51c867adf7cb"/><file name="CoinbaseDetails.php" hash="d19a625f8de98698b8277c25660358f0"/><file name="CreditCardDetails.php" hash="aac5eb1f5804d4f979b9c71f7b98cb36"/><file name="CustomerDetails.php" hash="e137895c646127312be44292c84a2d81"/><file name="PayPalDetails.php" hash="ede299e376bce7714838d79ca3d40842"/><file name="StatusDetails.php" hash="7c6e719c51bf13bdfd07615030100ac6"/><file name="SubscriptionDetails.php" hash="1cf1f511d1545a2e27b8d3f4bee800ca"/></dir><file name="Transaction.php" hash="9970a0fa9d6af3e543703426da99a3c4"/><file name="TransactionGateway.php" hash="37500b8a181a18375c171d4a5a4938c6"/><file name="TransactionSearch.php" hash="41dd086066fa57582161032249b3d8ee"/><file name="TransparentRedirect.php" hash="154c9850be5175a5cd1b35bdf78ae939"/><file name="TransparentRedirectGateway.php" hash="89f002df5a2abafcaa9676a3e2935c75"/><file name="UnknownPaymentMethod.php" hash="811394ea4bee98a651dc5e1cba8223da"/><file name="Util.php" hash="2cf47c3acd49da4a6c2b0a9a55701d7b"/><file name="Version.php" hash="1ebf13fcec95da846f917f74e030714b"/><file name="WebhookNotification.php" hash="f58be59156e5728f491da4235a58e994"/><file name="WebhookTesting.php" hash="c40311458bb64e37b4c08eb88df37805"/><dir name="Xml"><file name="Generator.php" hash="f82af40e5759c3d46909f3dec2498d02"/><file name="Parser.php" hash="4e6df3327a04915715333460733df93c"/></dir><file name="Xml.php" hash="dc69e05bea21e3d1185d45d53e4747db"/></dir><dir name="."><file name="Braintree.php" hash="ee3e665877882e5b5076ff51dc8111bd"/></dir><dir name="ssl"><file name="api_braintreegateway_com.ca.crt" hash="04beb23c767547e980c76eb68c7eab15"/><file name="sandbox_braintreegateway_com.ca.crt" hash="f1b529883c7c2cbb4251658f5da7b4c9"/></dir></target><target name="magelocale"><dir><dir name="en_US"><file name="Gene_Braintree.csv" hash="00ae6dc359bc0d9c48bfc90a865232a3"/></dir></dir></target></contents>
42
  <compatible/>
43
  <dependencies><required><php><min>5.2.1</min><max>6.0.0</max></php><package><name/><channel>connect.magentocommerce.com/core</channel><min/><max/></package></required></dependencies>
44
  </package>