flywebdesign_paypalfee - Version 1.0.2

Version Notes

Add additional payment fees to payment methods

Download this release

Release Info

Developer Fly Webservices
Extension flywebdesign_paypalfee
Version 1.0.2
Comparing to
See all releases


Code changes from version 0.1.3 to 1.0.2

Files changed (21) hide show
  1. app/code/local/FlyWebdesign/PaypalFee/Helper/Data.php +0 -47
  2. app/code/local/FlyWebdesign/PaypalFee/Model/Sales/Quote/Address/Total/Paymentcharge.php +0 -49
  3. app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Block/Adminhtml/Sales/Order/Creditmemo/Totals.php +3 -3
  4. app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Block/Adminhtml/Sales/Order/Invoice/Totals.php +3 -3
  5. app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Block/Adminhtml/Sales/Order/Totals.php +3 -3
  6. app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Block/Adminhtml/Sales/Totals.php +71 -70
  7. app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Block/Sales/Order/Creditmemo/Totals.php +3 -3
  8. app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Block/Sales/Order/Invoice/Totals.php +3 -3
  9. app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Block/Sales/Order/Totals.php +3 -3
  10. app/code/local/FlyWebservices/PaypalFee/Helper/Data.php +52 -0
  11. app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Model/Paypal/Cart.php +25 -9
  12. app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Model/Sales/Order/Creditmemo/Total/Paymentcharge.php +1 -1
  13. app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Model/Sales/Order/Invoice/Total/Paymentcharge.php +1 -1
  14. app/code/local/FlyWebservices/PaypalFee/Model/Sales/Quote/Address/Total/Paymentcharge.php +65 -0
  15. app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Model/System/Config/Source/Chargetype.php +3 -3
  16. app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/etc/config.xml +16 -15
  17. app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/etc/system.xml +0 -0
  18. app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/sql/paymentcharge_setup/mysql4-install-0.1.0.php +0 -0
  19. app/code/local/Mage/Paypal/Model/Api/Nvp.php +1494 -0
  20. app/etc/modules/{FlyWebdesign_PaypalFee.xml → FlyWebservices_PaypalFee.xml} +2 -2
  21. package.xml +5 -5
app/code/local/FlyWebdesign/PaypalFee/Helper/Data.php DELETED
@@ -1,47 +0,0 @@
1
- <?php
2
-
3
- class FlyWebdesign_PaypalFee_Helper_Data extends Mage_Core_Helper_Abstract
4
- {
5
- /**
6
- * Get payment charge
7
- * @param string $code
8
- * @param Mage_Sales_Model_Quote $quote
9
- * @return float
10
- */
11
- public function getPaymentCharge($code, $quote=null)
12
- {
13
- if (is_null($quote)) {
14
- $quote = Mage::getSingleton('checkout/session')->getQuote();
15
- }
16
- $amount = 0;
17
- $address = $quote->isVirtual() ? $quote->getBillingAddress() : $quote->getShippingAddress();
18
-
19
- if (preg_match("/paypal/i", strval($code))) {
20
- if(Mage::getStoreConfig('payment/paypal_payment_solutions/charge_type')){
21
- // Magento 1.7.0.2 and higher
22
- $chargeType = Mage::getStoreConfig('payment/paypal_payment_solutions/charge_type');
23
- $chargeValue = Mage::getStoreConfig('payment/paypal_payment_solutions/charge_value');
24
- } else {
25
- $chargeType = Mage::getStoreConfig('paypal/account/charge_type');
26
- $chargeValue = Mage::getStoreConfig('paypal/account/charge_value');
27
- }
28
- }
29
- else {
30
- $chargeType = Mage::getStoreConfig('payment/'.strval($code).'/charge_type');
31
- $chargeValue = Mage::getStoreConfig('payment/'.strval($code).'/charge_value');
32
- }
33
-
34
- if ($chargeValue ) {
35
- if ($chargeType=="percentage") {
36
- $subTotal = $address->getSubtotal();
37
- $tax = $address->getBaseTaxAmount();
38
- $amount = ($subTotal + $tax) * floatval($chargeValue) / 100;
39
- }
40
- else {
41
- $amount = floatval($chargeValue);
42
- }
43
- }
44
- //return Mage::helper('core')->formatPrice($amount);
45
- return $amount;
46
- }
47
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/FlyWebdesign/PaypalFee/Model/Sales/Quote/Address/Total/Paymentcharge.php DELETED
@@ -1,49 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * @category FlyWebdesign
5
- * @package FlyWebdesign_PaypalFee
6
- */
7
- class FlyWebdesign_PaypalFee_Model_Sales_Quote_Address_Total_Paymentcharge extends Mage_Sales_Model_Quote_Address_Total_Abstract
8
- {
9
- public function __construct()
10
- {
11
- $this->setCode('payment_charge');
12
- }
13
-
14
- public function collect(Mage_Sales_Model_Quote_Address $address)
15
- {
16
- $address->setPaymentCharge(0);
17
- $address->setBasePaymentCharge(0);
18
-
19
- $items = $address->getAllItems();
20
- if (!count($items)) {
21
- return $this;
22
- }
23
-
24
- $paymentMethod = $address->getQuote()->getPayment()->getMethod();
25
- if ($paymentMethod) {
26
- $amount = Mage::helper('paymentcharge')->getPaymentCharge($paymentMethod, $address->getQuote());
27
- $address->setPaymentCharge($amount);
28
- $address->setBasePaymentCharge($amount);
29
- }
30
-
31
- $address->setGrandTotal($address->getGrandTotal() + $address->getPaymentCharge());
32
- $address->setBaseGrandTotal($address->getBaseGrandTotal() + $address->getBasePaymentCharge());
33
- return $this;
34
- }
35
-
36
- public function fetch(Mage_Sales_Model_Quote_Address $address)
37
- {
38
- $amount = $address->getPaymentCharge();
39
- if (($amount!=0)) {
40
- $address->addTotal(array(
41
- 'code' => $this->getCode(),
42
- 'title' => Mage::helper('sales')->__('Payment Charge'),
43
- 'full_info' => array(),
44
- 'value' => $amount
45
- ));
46
- }
47
- return $this;
48
- }
49
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Block/Adminhtml/Sales/Order/Creditmemo/Totals.php RENAMED
@@ -3,10 +3,10 @@
3
  /**
4
  * Adminhtml order creditmemo totals block
5
  *
6
- * @category FlyWebdesign
7
- * @package FlyWebdesign_PaypalFee
8
  */
9
- class FlyWebdesign_PaypalFee_Block_Adminhtml_Sales_order_Creditmemo_Totals extends FlyWebdesign_PaypalFee_Block_Adminhtml_Sales_Totals
10
  {
11
  protected $_creditmemo;
12
 
3
  /**
4
  * Adminhtml order creditmemo totals block
5
  *
6
+ * @category FlyWebservices
7
+ * @package FlyWebservices_PaypalFee
8
  */
9
+ class FlyWebservices_PaypalFee_Block_Adminhtml_Sales_order_Creditmemo_Totals extends FlyWebservices_PaypalFee_Block_Adminhtml_Sales_Totals
10
  {
11
  protected $_creditmemo;
12
 
app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Block/Adminhtml/Sales/Order/Invoice/Totals.php RENAMED
@@ -3,10 +3,10 @@
3
  /**
4
  * Adminhtml order invoice totals block
5
  *
6
- * @category FlyWebdesign
7
- * @package FlyWebdesign_PaypalFee
8
  */
9
- class FlyWebdesign_PaypalFee_Block_Adminhtml_Sales_order_Invoice_Totals extends FlyWebdesign_PaypalFee_Block_Adminhtml_Sales_Totals
10
  {
11
  protected $_invoice = null;
12
 
3
  /**
4
  * Adminhtml order invoice totals block
5
  *
6
+ * @category FlyWebservices
7
+ * @package FlyWebservices_PaypalFee
8
  */
9
+ class FlyWebservices_PaypalFee_Block_Adminhtml_Sales_order_Invoice_Totals extends FlyWebservices_PaypalFee_Block_Adminhtml_Sales_Totals
10
  {
11
  protected $_invoice = null;
12
 
app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Block/Adminhtml/Sales/Order/Totals.php RENAMED
@@ -3,10 +3,10 @@
3
  /**
4
  * Adminhtml order totals block
5
  *
6
- * @category FlyWebdesign
7
- * @package FlyWebdesign_PaypalFee
8
  */
9
- class FlyWebdesign_PaypalFee_Block_Adminhtml_Sales_Order_Totals extends FlyWebdesign_PaypalFee_Block_Adminhtml_Sales_Totals
10
  {
11
  /**
12
  * Initialize order totals array
3
  /**
4
  * Adminhtml order totals block
5
  *
6
+ * @category FlyWebservices
7
+ * @package FlyWebservices_PaypalFee
8
  */
9
+ class FlyWebservices_PaypalFee_Block_Adminhtml_Sales_Order_Totals extends FlyWebservices_PaypalFee_Block_Adminhtml_Sales_Totals
10
  {
11
  /**
12
  * Initialize order totals array
app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Block/Adminhtml/Sales/Totals.php RENAMED
@@ -1,70 +1,71 @@
1
- <?php
2
-
3
- /**
4
- * @category FlyWebdesign
5
- * @package FlyWebdesign_PaypalFee
6
- */
7
- class FlyWebdesign_PaypalFee_Block_Adminhtml_Sales_Totals extends Mage_Adminhtml_Block_Sales_Totals
8
- {
9
- /**
10
- * Initialize order totals array
11
- *
12
- * @return Mage_Sales_Block_Order_Totals
13
- */
14
- protected function _initTotals()
15
- {
16
- parent::_initTotals();
17
-
18
- $source = $this->getSource();
19
-
20
- $this->_totals['paid'] = new Varien_Object(array(
21
- 'code' => 'paid',
22
- 'strong' => true,
23
- 'value' => $this->getSource()->getTotalPaid(),
24
- 'base_value'=> $this->getSource()->getBaseTotalPaid(),
25
- 'label' => $this->helper('sales')->__('Total Paid'),
26
- 'area' => 'footer'
27
- ));
28
- $this->_totals['refunded'] = new Varien_Object(array(
29
- 'code' => 'refunded',
30
- 'strong' => true,
31
- 'value' => $this->getSource()->getTotalRefunded(),
32
- 'base_value'=> $this->getSource()->getBaseTotalRefunded(),
33
- 'label' => $this->helper('sales')->__('Total Refunded'),
34
- 'area' => 'footer'
35
- ));
36
- $this->_totals['due'] = new Varien_Object(array(
37
- 'code' => 'due',
38
- 'strong' => true,
39
- 'value' => $this->getSource()->getTotalDue(),
40
- 'base_value'=> $this->getSource()->getBaseTotalDue(),
41
- 'label' => $this->helper('sales')->__('Total Due'),
42
- 'area' => 'footer'
43
- ));
44
-
45
- /**
46
- * Add store rewards
47
- */
48
- $totals = $this->_totals;
49
- $newTotals = array();
50
- if (count($totals)>0) {
51
- foreach ($totals as $index=>$arr) {
52
- if ($index == "grand_total") {
53
- if (((float)$this->getSource()->getPaymentCharge()) != 0) {
54
- $label = $this->__('Payment Charge');
55
- $newTotals['payment_charge'] = new Varien_Object(array(
56
- 'code' => 'payment_charge',
57
- 'field' => 'payment_charge',
58
- 'value' => $source->getPaymentCharge(),
59
- 'label' => $label
60
- ));
61
- }
62
- }
63
- $newTotals[$index] = $arr;
64
- }
65
- $this->_totals = $newTotals;
66
- }
67
-
68
- return $this;
69
- }
70
- }
 
1
+ <?php
2
+
3
+ /**
4
+ * @category FlyWebservices
5
+ * @package FlyWebservices_PaypalFee
6
+ */
7
+ class FlyWebservices_PaypalFee_Block_Adminhtml_Sales_Totals extends Mage_Adminhtml_Block_Sales_Totals
8
+ {
9
+ /**
10
+ * Initialize order totals array
11
+ *
12
+ * @return Mage_Sales_Block_Order_Totals
13
+ */
14
+ protected function _initTotals()
15
+ {
16
+ parent::_initTotals();
17
+
18
+ $source = $this->getSource();
19
+
20
+ $this->_totals['paid'] = new Varien_Object(array(
21
+ 'code' => 'paid',
22
+ 'strong' => true,
23
+ 'value' => $this->getSource()->getTotalPaid(),
24
+ 'base_value'=> $this->getSource()->getBaseTotalPaid(),
25
+ 'label' => $this->helper('sales')->__('Total Paid'),
26
+ 'area' => 'footer'
27
+ ));
28
+ $this->_totals['refunded'] = new Varien_Object(array(
29
+ 'code' => 'refunded',
30
+ 'strong' => true,
31
+ 'value' => $this->getSource()->getTotalRefunded(),
32
+ 'base_value'=> $this->getSource()->getBaseTotalRefunded(),
33
+ 'label' => $this->helper('sales')->__('Total Refunded'),
34
+ 'area' => 'footer'
35
+ ));
36
+ $this->_totals['due'] = new Varien_Object(array(
37
+ 'code' => 'due',
38
+ 'strong' => true,
39
+ 'value' => $this->getSource()->getTotalDue(),
40
+ 'base_value'=> $this->getSource()->getBaseTotalDue(),
41
+ 'label' => $this->helper('sales')->__('Total Due'),
42
+ 'area' => 'footer'
43
+ ));
44
+
45
+ /**
46
+ * Add store rewards
47
+ */
48
+ $totals = $this->_totals;
49
+ $newTotals = array();
50
+ if (count($totals)>0) {
51
+ foreach ($totals as $index=>$arr) {
52
+ if ($index == "grand_total") {
53
+ if (((float)$this->getSource()->getPaymentCharge()) != 0) {
54
+ $label = $this->__('Payment Charge');
55
+ $newTotals['payment_charge'] = new Varien_Object(array(
56
+ 'code' => 'payment_charge',
57
+ 'field' => 'payment_charge',
58
+ 'base_value' => $source->getBasePaymentCharge(),
59
+ 'value' => $source->getPaymentCharge(),
60
+ 'label' => $label
61
+ ));
62
+ }
63
+ }
64
+ $newTotals[$index] = $arr;
65
+ }
66
+ $this->_totals = $newTotals;
67
+ }
68
+
69
+ return $this;
70
+ }
71
+ }
app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Block/Sales/Order/Creditmemo/Totals.php RENAMED
@@ -1,10 +1,10 @@
1
  <?php
2
 
3
  /**
4
- * @category FlyWebdesign
5
- * @package FlyWebdesign_PaypalFee
6
  */
7
- class FlyWebdesign_PaypalFee_Block_Sales_order_Creditmemo_Totals extends FlyWebdesign_PaypalFee_Block_Sales_Order_Totals
8
  {
9
  protected $_creditmemo = null;
10
 
1
  <?php
2
 
3
  /**
4
+ * @category FlyWebservices
5
+ * @package FlyWebservices_PaypalFee
6
  */
7
+ class FlyWebservices_PaypalFee_Block_Sales_order_Creditmemo_Totals extends FlyWebservices_PaypalFee_Block_Sales_Order_Totals
8
  {
9
  protected $_creditmemo = null;
10
 
app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Block/Sales/Order/Invoice/Totals.php RENAMED
@@ -1,10 +1,10 @@
1
  <?php
2
 
3
  /**
4
- * @category FlyWebdesign
5
- * @package FlyWebdesign_PaypalFee
6
  */
7
- class FlyWebdesign_PaypalFee_Block_Sales_order_Invoice_Totals extends FlyWebdesign_PaypalFee_Block_Sales_Order_Totals
8
  {
9
  protected $_invoice = null;
10
 
1
  <?php
2
 
3
  /**
4
+ * @category FlyWebservices
5
+ * @package FlyWebservices_PaypalFee
6
  */
7
+ class FlyWebservices_PaypalFee_Block_Sales_order_Invoice_Totals extends FlyWebservices_PaypalFee_Block_Sales_Order_Totals
8
  {
9
  protected $_invoice = null;
10
 
app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Block/Sales/Order/Totals.php RENAMED
@@ -1,10 +1,10 @@
1
  <?php
2
 
3
  /**
4
- * @category FlyWebdesign
5
- * @package FlyWebdesign_PaypalFee
6
  */
7
- class FlyWebdesign_PaypalFee_Block_Sales_Order_Totals extends Mage_Sales_Block_Order_Totals
8
  {
9
  /**
10
  * Initialize order totals array
1
  <?php
2
 
3
  /**
4
+ * @category FlyWebservices
5
+ * @package FlyWebservices_PaypalFee
6
  */
7
+ class FlyWebservices_PaypalFee_Block_Sales_Order_Totals extends Mage_Sales_Block_Order_Totals
8
  {
9
  /**
10
  * Initialize order totals array
app/code/local/FlyWebservices/PaypalFee/Helper/Data.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class FlyWebservices_PaypalFee_Helper_Data extends Mage_Core_Helper_Abstract
4
+ {
5
+ /**
6
+ * Get payment charge
7
+ * @param string $code
8
+ * @param Mage_Sales_Model_Quote $quote
9
+ * @return float
10
+ */
11
+ public function getPaymentCharge($code, $quote=null)
12
+ {
13
+ if (is_null($quote)) {
14
+ $quote = Mage::getSingleton('checkout/session')->getQuote();
15
+ }
16
+ $amount = 0;
17
+ $address = $quote->isVirtual() ? $quote->getBillingAddress() : $quote->getShippingAddress();
18
+
19
+ $tax=$address->getBaseTaxAmount();
20
+
21
+ if (preg_match("/paypal/i", strval($code))) {
22
+ if(Mage::getStoreConfig('payment/paypal_payment_solutions/charge_type')){
23
+ // Magento 1.7.0.2 and higher
24
+ $chargeType = Mage::getStoreConfig('payment/paypal_payment_solutions/charge_type');
25
+ $chargeValue = Mage::getStoreConfig('payment/paypal_payment_solutions/charge_value');
26
+ //$chargeValue = Mage::helper('directory')->currencyConvert(Mage::getStoreConfig('payment/paypal_payment_solutions/charge_value'), Mage::app()->getWebsite()->getConfig('currency/options/default'), Mage::app()->getStore()->getCurrentCurrencyCode());
27
+ } else {
28
+ $chargeType = Mage::getStoreConfig('paypal/account/charge_type');
29
+ $chargeValue = Mage::getStoreConfig('paypal/account/charge_value');
30
+ //$chargeValue = Mage::helper('directory')->currencyConvert(Mage::getStoreConfig('paypal/account/charge_value'), Mage::app()->getWebsite()->getConfig('currency/options/default'), Mage::app()->getStore()->getCurrentCurrencyCode());
31
+ }
32
+ }
33
+ else {
34
+ $chargeType = Mage::getStoreConfig('payment/'.strval($code).'/charge_type');
35
+ $chargeValue = Mage::getStoreConfig('payment/'.strval($code).'/charge_value');
36
+ //$chargeValue = Mage::helper('directory')->currencyConvert( strval($code), Mage::app()->getWebsite()->getConfig('currency/options/default'), Mage::app()->getStore()->getCurrentCurrencyCode());
37
+ }
38
+
39
+ if ($chargeValue) {
40
+ if ($chargeType=="percentage") {
41
+ $subTotal = $address->getBaseSubtotal();
42
+ $amount = ($subTotal+ $tax) * floatval($chargeValue) / 100;
43
+ } else {
44
+ $amount = floatval($chargeValue);
45
+ }
46
+ }
47
+ ////echo $amount;
48
+ //return Mage::helper('core')->formatPrice($amount);
49
+ return $amount;
50
+ }
51
+
52
+ }
app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Model/Paypal/Cart.php RENAMED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- class FlyWebdesign_PaypalFee_Model_Paypal_Cart extends Mage_Paypal_Model_Cart
4
  {
5
  protected function _render()
6
  {
@@ -22,10 +22,12 @@ class FlyWebdesign_PaypalFee_Model_Paypal_Cart extends Mage_Paypal_Model_Cart
22
  // Magento 1.7.0.2 and higher
23
  $chargeType = Mage::getStoreConfig('payment/paypal_payment_solutions/charge_type');
24
  $chargeValue = Mage::getStoreConfig('payment/paypal_payment_solutions/charge_value');
 
25
  } else {
26
  // Extra fee - added 21-4-12
27
  $chargeType = Mage::getStoreConfig('paypal/account/charge_type');
28
  $chargeValue = Mage::getStoreConfig('paypal/account/charge_value');
 
29
  }
30
 
31
  // regular totals
@@ -39,10 +41,13 @@ class FlyWebdesign_PaypalFee_Model_Paypal_Cart extends Mage_Paypal_Model_Cart
39
  self::TOTAL_DISCOUNT => abs($this->_salesEntity->getBaseDiscountAmount()),
40
  );
41
  if ($chargeType=="percentage") {
42
- $this->_totals[self::TOTAL_SUBTOTAL] += ($this->_totals[self::TOTAL_SUBTOTAL]+$this->_totals[self::TOTAL_TAX]) * floatval($chargeValue) / 100;
 
 
 
43
  }
44
  else {
45
- $this->_totals[self::TOTAL_SUBTOTAL] += floatval($chargeValue);
46
  }
47
  $this->_applyHiddenTaxWorkaround($this->_salesEntity);
48
  } else {
@@ -56,10 +61,13 @@ class FlyWebdesign_PaypalFee_Model_Paypal_Cart extends Mage_Paypal_Model_Cart
56
  self::TOTAL_DISCOUNT => abs($address->getBaseDiscountAmount()),
57
  );
58
  if ($chargeType=="percentage") {
59
- $this->_totals[self::TOTAL_SUBTOTAL] += ($this->_totals[self::TOTAL_SUBTOTAL]+$this->_totals[self::TOTAL_TAX]) * floatval($chargeValue) / 100;
 
 
 
60
  }
61
  else {
62
- $this->_totals[self::TOTAL_SUBTOTAL] += floatval($chargeValue);
63
  }
64
  $this->_applyHiddenTaxWorkaround($address);
65
  }
@@ -73,14 +81,22 @@ class FlyWebdesign_PaypalFee_Model_Paypal_Cart extends Mage_Paypal_Model_Cart
73
  $this->_totalLineItemDescriptions[self::TOTAL_DISCOUNT][] = Mage::helper('sales')->__('Discount (%s)', Mage::app()->getStore()->convertPrice($originalDiscount, true, false));
74
  }
75
 
76
- // discount, shipping as items
77
  if ($this->_isDiscountAsItem && $this->_totals[self::TOTAL_DISCOUNT]) {
78
  $this->addItem(Mage::helper('paypal')->__('Discount'), 1, -1.00 * $this->_totals[self::TOTAL_DISCOUNT],
79
  $this->_renderTotalLineItemDescriptions(self::TOTAL_DISCOUNT)
80
  );
81
  }
 
 
 
 
 
 
 
 
82
  $shippingItemId = $this->_renderTotalLineItemDescriptions(self::TOTAL_SHIPPING, $shippingDescription);
83
- if ($this->_isDiscountAsItem && $this->_isShippingAsItem && (float)$this->_totals[self::TOTAL_SHIPPING]) {
84
  $this->addItem(Mage::helper('paypal')->__('Shipping'), 1, (float)$this->_totals[self::TOTAL_SHIPPING],
85
  $shippingItemId
86
  );
@@ -101,10 +117,10 @@ class FlyWebdesign_PaypalFee_Model_Paypal_Cart extends Mage_Paypal_Model_Cart
101
 
102
  $this->_shouldRender = false;
103
 
104
- return parent::_render();
105
  }
106
 
107
- private function _applyHiddenTaxWorkaround($salesEntity)
108
  {
109
  $this->_totals[self::TOTAL_TAX] += (float)$salesEntity->getBaseHiddenTaxAmount();
110
  $this->_totals[self::TOTAL_TAX] += (float)$salesEntity->getBaseShippingHiddenTaxAmount();
1
  <?php
2
 
3
+ class FlyWebservices_PaypalFee_Model_Paypal_Cart extends Mage_Paypal_Model_Cart
4
  {
5
  protected function _render()
6
  {
22
  // Magento 1.7.0.2 and higher
23
  $chargeType = Mage::getStoreConfig('payment/paypal_payment_solutions/charge_type');
24
  $chargeValue = Mage::getStoreConfig('payment/paypal_payment_solutions/charge_value');
25
+ //$chargeValue = Mage::helper('directory')->currencyConvert(Mage::getStoreConfig('payment/paypal_payment_solutions/charge_value'), Mage::app()->getWebsite()->getConfig('currency/options/default'), Mage::app()->getStore()->getCurrentCurrencyCode());
26
  } else {
27
  // Extra fee - added 21-4-12
28
  $chargeType = Mage::getStoreConfig('paypal/account/charge_type');
29
  $chargeValue = Mage::getStoreConfig('paypal/account/charge_value');
30
+ //$chargeValue = Mage::helper('directory')->currencyConvert(Mage::getStoreConfig('paypal/account/charge_value'), Mage::app()->getWebsite()->getConfig('currency/options/default'), Mage::app()->getStore()->getCurrentCurrencyCode());
31
  }
32
 
33
  // regular totals
41
  self::TOTAL_DISCOUNT => abs($this->_salesEntity->getBaseDiscountAmount()),
42
  );
43
  if ($chargeType=="percentage") {
44
+ if(Mage::getStoreConfig('tax/calculation/price_includes_tax')!=1)
45
+ $total_fee = ($this->_totals[self::TOTAL_SUBTOTAL]+$this->_totals[self::TOTAL_TAX]) * floatval($chargeValue) / 100;
46
+ else
47
+ $total_fee = ($this->_totals[self::TOTAL_SUBTOTAL]) * floatval($chargeValue) / 100;
48
  }
49
  else {
50
+ $total_fee = floatval($chargeValue);
51
  }
52
  $this->_applyHiddenTaxWorkaround($this->_salesEntity);
53
  } else {
61
  self::TOTAL_DISCOUNT => abs($address->getBaseDiscountAmount()),
62
  );
63
  if ($chargeType=="percentage") {
64
+ if(Mage::getStoreConfig('tax/calculation/price_includes_tax')!=1)
65
+ $total_fee = ($this->_totals[self::TOTAL_SUBTOTAL]+$this->_totals[self::TOTAL_TAX]) * floatval($chargeValue) / 100;
66
+ else
67
+ $total_fee = ($this->_totals[self::TOTAL_SUBTOTAL]) * floatval($chargeValue) / 100;
68
  }
69
  else {
70
+ $total_fee = floatval($chargeValue);
71
  }
72
  $this->_applyHiddenTaxWorkaround($address);
73
  }
81
  $this->_totalLineItemDescriptions[self::TOTAL_DISCOUNT][] = Mage::helper('sales')->__('Discount (%s)', Mage::app()->getStore()->convertPrice($originalDiscount, true, false));
82
  }
83
 
84
+ // discount as item
85
  if ($this->_isDiscountAsItem && $this->_totals[self::TOTAL_DISCOUNT]) {
86
  $this->addItem(Mage::helper('paypal')->__('Discount'), 1, -1.00 * $this->_totals[self::TOTAL_DISCOUNT],
87
  $this->_renderTotalLineItemDescriptions(self::TOTAL_DISCOUNT)
88
  );
89
  }
90
+
91
+ // payment fee as item
92
+ if(Mage::getStoreConfig('tax/calculation/price_includes_tax')!=1||$chargeType=="percentage"){
93
+ $this->_totals[self::TOTAL_TAX]+=($total_fee/100*21);
94
+ }
95
+ $this->addItem(Mage::helper('paypal')->__('Payment Charge'), 1, (float)$total_fee,'fee');
96
+
97
+ // shipping as item
98
  $shippingItemId = $this->_renderTotalLineItemDescriptions(self::TOTAL_SHIPPING, $shippingDescription);
99
+ if ($this->_isShippingAsItem && (float)$this->_totals[self::TOTAL_SHIPPING]) {
100
  $this->addItem(Mage::helper('paypal')->__('Shipping'), 1, (float)$this->_totals[self::TOTAL_SHIPPING],
101
  $shippingItemId
102
  );
117
 
118
  $this->_shouldRender = false;
119
 
120
+ //return parent::_render();
121
  }
122
 
123
+ private function _applyHiddenTaxWorkaround($salesEntity)
124
  {
125
  $this->_totals[self::TOTAL_TAX] += (float)$salesEntity->getBaseHiddenTaxAmount();
126
  $this->_totals[self::TOTAL_TAX] += (float)$salesEntity->getBaseShippingHiddenTaxAmount();
app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Model/Sales/Order/Creditmemo/Total/Paymentcharge.php RENAMED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- class FlyWebdesign_PaypalFee_Model_Sales_Order_Creditmemo_Total_Paymentcharge extends Mage_Sales_Model_Order_Creditmemo_Total_Abstract
4
  {
5
  public function collect(Mage_Sales_Model_Order_Creditmemo $creditmemo)
6
  {
1
  <?php
2
 
3
+ class FlyWebservices_PaypalFee_Model_Sales_Order_Creditmemo_Total_Paymentcharge extends Mage_Sales_Model_Order_Creditmemo_Total_Abstract
4
  {
5
  public function collect(Mage_Sales_Model_Order_Creditmemo $creditmemo)
6
  {
app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Model/Sales/Order/Invoice/Total/Paymentcharge.php RENAMED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- class FlyWebdesign_PaypalFee_Model_Sales_Order_Invoice_Total_Paymentcharge extends Mage_Sales_Model_Order_Invoice_Total_Abstract
4
  {
5
  public function collect(Mage_Sales_Model_Order_Invoice $invoice)
6
  {
1
  <?php
2
 
3
+ class FlyWebservices_PaypalFee_Model_Sales_Order_Invoice_Total_Paymentcharge extends Mage_Sales_Model_Order_Invoice_Total_Abstract
4
  {
5
  public function collect(Mage_Sales_Model_Order_Invoice $invoice)
6
  {
app/code/local/FlyWebservices/PaypalFee/Model/Sales/Quote/Address/Total/Paymentcharge.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category FlyWebservices
5
+ * @package FlyWebservices_PaypalFee
6
+ */
7
+ class FlyWebservices_PaypalFee_Model_Sales_Quote_Address_Total_Paymentcharge extends Mage_Sales_Model_Quote_Address_Total_Abstract
8
+ {
9
+ public function __construct()
10
+ {
11
+ $this->setCode('payment_charge');
12
+ }
13
+
14
+ public function collect(Mage_Sales_Model_Quote_Address $address)
15
+ {
16
+ $address->setPaymentCharge(0);
17
+ $address->setBasePaymentCharge(0);
18
+
19
+ $items = $address->getAllItems();
20
+ if (!count($items)) {
21
+ return $this;
22
+ }
23
+
24
+ $paymentMethod = $address->getQuote()->getPayment()->getMethod();
25
+
26
+ if(Mage::getStoreConfig('tax/calculation/price_includes_tax')!=1)
27
+ $tax=$address->getTaxAmount();
28
+
29
+ if ($paymentMethod) {
30
+ $amount1 = Mage::helper('paymentcharge')->getPaymentCharge($paymentMethod, $address->getQuote());
31
+ $amount = Mage::helper('directory')->currencyConvert( $amount1, Mage::app()->getWebsite()->getConfig('currency/options/default'), Mage::app()->getStore()->getCurrentCurrencyCode());
32
+
33
+ // if(Mage::getStoreConfig('payment/paypal_payment_solutions/charge_type')!="percentage"){
34
+ $address->setPaymentCharge($amount);
35
+ $address->setBasePaymentCharge($amount1);
36
+ /* } else {
37
+ $address->setPaymentCharge($amount);
38
+
39
+ $subTotal = $address->getBaseSubtotal();
40
+ $amount12 = ($subTotal+ $tax) * floatval(Mage::getStoreConfig('payment/paypal_payment_solutions/charge_value')) / 100;
41
+ $address->setBasePaymentCharge($amount12);
42
+ }*/
43
+ }
44
+
45
+ $address->setGrandTotal($address->getGrandTotal() + $tax + $address->getPaymentCharge());
46
+ $address->setBaseGrandTotal($address->getBaseGrandTotal()+ $address->getBasePaymentCharge());
47
+
48
+ return $this;
49
+ }
50
+
51
+ public function fetch(Mage_Sales_Model_Quote_Address $address)
52
+ {
53
+ if (($address->getBasePaymentCharge() != 0)) {
54
+ $address->addTotal(array(
55
+ 'code' => $this->getCode(),
56
+ 'title' => Mage::helper('sales')->__('Payment Charge'),
57
+ 'full_info' => array(),
58
+ 'value' => $address->getPaymentCharge(),
59
+ 'base_value'=> $address->getBasePaymentCharge()
60
+
61
+ ));
62
+ }
63
+ return $address->getBasePaymentCharge();
64
+ }
65
+ }
app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/Model/System/Config/Source/Chargetype.php RENAMED
@@ -1,10 +1,10 @@
1
  <?php
2
 
3
  /**
4
- * @category FlyWebdesign
5
- * @package FlyWebdesign_PaypalFee
6
  */
7
- class FlyWebdesign_PaypalFee_Model_System_Config_Source_Chargetype extends Varien_Object
8
  {
9
  public function toOptionArray()
10
  {
1
  <?php
2
 
3
  /**
4
+ * @category FlyWebservices
5
+ * @package FlyWebservices_PaypalFee
6
  */
7
+ class FlyWebservices_PaypalFee_Model_System_Config_Source_Chargetype extends Varien_Object
8
  {
9
  public function toOptionArray()
10
  {
app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/etc/config.xml RENAMED
@@ -1,29 +1,29 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <config>
3
  <modules>
4
- <FlyWebdesign_PaypalFee>
5
  <version>0.1.0</version>
6
- </FlyWebdesign_PaypalFee>
7
  </modules>
8
 
9
  <global>
10
  <blocks>
11
  <paymentcharge>
12
- <class>FlyWebdesign_PaypalFee_Block</class>
13
  </paymentcharge>
14
  <sales>
15
  <rewrite>
16
- <order_totals>FlyWebdesign_PaypalFee_Block_Sales_Order_Totals</order_totals>
17
- <order_invoice_totals>FlyWebdesign_PaypalFee_Block_Sales_order_Invoice_Totals</order_invoice_totals>
18
- <order_creditmemo_totals>FlyWebdesign_PaypalFee_Block_Sales_order_Creditmemo_Totals</order_creditmemo_totals>
19
  </rewrite>
20
  </sales>
21
  <adminhtml>
22
  <rewrite>
23
- <sales_totals>FlyWebdesign_PaypalFee_Block_Adminhtml_Sales_Totals</sales_totals>
24
- <sales_order_totals>FlyWebdesign_PaypalFee_Block_Adminhtml_Sales_order_Totals</sales_order_totals>
25
- <sales_order_invoice_totals>FlyWebdesign_PaypalFee_Block_Adminhtml_Sales_order_Invoice_Totals</sales_order_invoice_totals>
26
- <sales_order_creditmemo_totals>FlyWebdesign_PaypalFee_Block_Adminhtml_Sales_order_Creditmemo_Totals</sales_order_creditmemo_totals>
27
  </rewrite>
28
  </adminhtml>
29
  </blocks>
@@ -35,23 +35,23 @@
35
  </fieldsets>
36
  <helpers>
37
  <paymentcharge>
38
- <class>FlyWebdesign_PaypalFee_Helper</class>
39
  </paymentcharge>
40
  </helpers>
41
  <models>
42
  <paymentcharge>
43
- <class>FlyWebdesign_PaypalFee_Model</class>
44
  </paymentcharge>
45
  <paypal>
46
  <rewrite>
47
- <cart>FlyWebdesign_PaypalFee_Model_Paypal_Cart</cart>
48
  </rewrite>
49
  </paypal>
50
  </models>
51
  <resources>
52
  <paymentcharge_setup>
53
  <setup>
54
- <module>FlyWebdesign_PaypalFee</module>
55
  <class>Mage_Sales_Model_Mysql4_Setup</class>
56
  </setup>
57
  <connection>
@@ -105,7 +105,8 @@
105
  <sort_order>200</sort_order>
106
  </payment_charge>
107
  </totals>
108
- </pdf>
 
109
  </global>
110
  <default>
111
  <sales>
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <config>
3
  <modules>
4
+ <FlyWebservices_PaypalFee>
5
  <version>0.1.0</version>
6
+ </FlyWebservices_PaypalFee>
7
  </modules>
8
 
9
  <global>
10
  <blocks>
11
  <paymentcharge>
12
+ <class>FlyWebservices_PaypalFee_Block</class>
13
  </paymentcharge>
14
  <sales>
15
  <rewrite>
16
+ <order_totals>FlyWebservices_PaypalFee_Block_Sales_Order_Totals</order_totals>
17
+ <order_invoice_totals>FlyWebservices_PaypalFee_Block_Sales_Order_Invoice_Totals</order_invoice_totals>
18
+ <order_creditmemo_totals>FlyWebservices_PaypalFee_Block_Sales_Order_Creditmemo_Totals</order_creditmemo_totals>
19
  </rewrite>
20
  </sales>
21
  <adminhtml>
22
  <rewrite>
23
+ <sales_totals>FlyWebservices_PaypalFee_Block_Adminhtml_Sales_Totals</sales_totals>
24
+ <sales_order_totals>FlyWebservices_PaypalFee_Block_Adminhtml_Sales_Order_Totals</sales_order_totals>
25
+ <sales_order_invoice_totals>FlyWebservices_PaypalFee_Block_Adminhtml_Sales_Order_Invoice_Totals</sales_order_invoice_totals>
26
+ <sales_order_creditmemo_totals>FlyWebservices_PaypalFee_Block_Adminhtml_Sales_Order_Creditmemo_Totals</sales_order_creditmemo_totals>
27
  </rewrite>
28
  </adminhtml>
29
  </blocks>
35
  </fieldsets>
36
  <helpers>
37
  <paymentcharge>
38
+ <class>FlyWebservices_PaypalFee_Helper</class>
39
  </paymentcharge>
40
  </helpers>
41
  <models>
42
  <paymentcharge>
43
+ <class>FlyWebservices_PaypalFee_Model</class>
44
  </paymentcharge>
45
  <paypal>
46
  <rewrite>
47
+ <cart>FlyWebservices_PaypalFee_Model_Paypal_Cart</cart>
48
  </rewrite>
49
  </paypal>
50
  </models>
51
  <resources>
52
  <paymentcharge_setup>
53
  <setup>
54
+ <module>FlyWebservices_PaypalFee</module>
55
  <class>Mage_Sales_Model_Mysql4_Setup</class>
56
  </setup>
57
  <connection>
105
  <sort_order>200</sort_order>
106
  </payment_charge>
107
  </totals>
108
+ </pdf>
109
+
110
  </global>
111
  <default>
112
  <sales>
app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/etc/system.xml RENAMED
File without changes
app/code/local/{FlyWebdesign → FlyWebservices}/PaypalFee/sql/paymentcharge_setup/mysql4-install-0.1.0.php RENAMED
File without changes
app/code/local/Mage/Paypal/Model/Api/Nvp.php ADDED
@@ -0,0 +1,1494 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Paypal
23
+ * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * NVP API wrappers model
29
+ * @TODO: move some parts to abstract, don't hesitate to throw exceptions on api calls
30
+ */
31
+ class Mage_Paypal_Model_Api_Nvp extends Mage_Paypal_Model_Api_Abstract
32
+ {
33
+ /**
34
+ * Paypal methods definition
35
+ */
36
+ const DO_DIRECT_PAYMENT = 'DoDirectPayment';
37
+ const DO_CAPTURE = 'DoCapture';
38
+ const DO_AUTHORIZATION = 'DoAuthorization';
39
+ const DO_VOID = 'DoVoid';
40
+ const REFUND_TRANSACTION = 'RefundTransaction';
41
+ const SET_EXPRESS_CHECKOUT = 'SetExpressCheckout';
42
+ const GET_EXPRESS_CHECKOUT_DETAILS = 'GetExpressCheckoutDetails';
43
+ const DO_EXPRESS_CHECKOUT_PAYMENT = 'DoExpressCheckoutPayment';
44
+ const CALLBACK_RESPONSE = 'CallbackResponse';
45
+
46
+ /**
47
+ * Paypal ManagePendingTransactionStatus actions
48
+ */
49
+ const PENDING_TRANSACTION_ACCEPT = 'Accept';
50
+ const PENDING_TRANSACTION_DENY = 'Deny';
51
+
52
+ /**
53
+ * Capture types (make authorization close or remain open)
54
+ * @var string
55
+ */
56
+ protected $_captureTypeComplete = 'Complete';
57
+ protected $_captureTypeNotcomplete = 'NotComplete';
58
+
59
+ /**
60
+ * Global public interface map
61
+ * @var array
62
+ */
63
+ protected $_globalMap = array(
64
+ // each call
65
+ 'VERSION' => 'version',
66
+ 'USER' => 'api_username',
67
+ 'PWD' => 'api_password',
68
+ 'SIGNATURE' => 'api_signature',
69
+ 'BUTTONSOURCE' => 'build_notation_code',
70
+
71
+ // for Unilateral payments
72
+ 'SUBJECT' => 'business_account',
73
+
74
+ // commands
75
+ 'PAYMENTACTION' => 'payment_action',
76
+ 'RETURNURL' => 'return_url',
77
+ 'CANCELURL' => 'cancel_url',
78
+ 'INVNUM' => 'inv_num',
79
+ 'TOKEN' => 'token',
80
+ 'CORRELATIONID' => 'correlation_id',
81
+ 'SOLUTIONTYPE' => 'solution_type',
82
+ 'GIROPAYCANCELURL' => 'giropay_cancel_url',
83
+ 'GIROPAYSUCCESSURL' => 'giropay_success_url',
84
+ 'BANKTXNPENDINGURL' => 'giropay_bank_txn_pending_url',
85
+ 'IPADDRESS' => 'ip_address',
86
+ 'NOTIFYURL' => 'notify_url',
87
+ 'RETURNFMFDETAILS' => 'fraud_management_filters_enabled',
88
+ 'NOTE' => 'note',
89
+ 'REFUNDTYPE' => 'refund_type',
90
+ 'ACTION' => 'action',
91
+ 'REDIRECTREQUIRED' => 'redirect_required',
92
+ 'SUCCESSPAGEREDIRECTREQUESTED' => 'redirect_requested',
93
+ 'REQBILLINGADDRESS' => 'require_billing_address',
94
+ // style settings
95
+ 'PAGESTYLE' => 'page_style',
96
+ 'HDRIMG' => 'hdrimg',
97
+ 'HDRBORDERCOLOR' => 'hdrbordercolor',
98
+ 'HDRBACKCOLOR' => 'hdrbackcolor',
99
+ 'PAYFLOWCOLOR' => 'payflowcolor',
100
+ 'LOCALECODE' => 'locale_code',
101
+ 'PAL' => 'pal',
102
+
103
+ // transaction info
104
+ 'TRANSACTIONID' => 'transaction_id',
105
+ 'AUTHORIZATIONID' => 'authorization_id',
106
+ 'REFUNDTRANSACTIONID' => 'refund_transaction_id',
107
+ 'COMPLETETYPE' => 'complete_type',
108
+ 'AMT' => 'amount',
109
+ 'ITEMAMT' => 'subtotal_amount',
110
+ 'GROSSREFUNDAMT' => 'refunded_amount', // possible mistake, check with API reference
111
+
112
+ // payment/billing info
113
+ 'CURRENCYCODE' => 'currency_code',
114
+ 'PAYMENTSTATUS' => 'payment_status',
115
+ 'PENDINGREASON' => 'pending_reason',
116
+ 'PROTECTIONELIGIBILITY' => 'protection_eligibility',
117
+ 'PAYERID' => 'payer_id',
118
+ 'PAYERSTATUS' => 'payer_status',
119
+ 'ADDRESSID' => 'address_id',
120
+ 'ADDRESSSTATUS' => 'address_status',
121
+ 'EMAIL' => 'email',
122
+ // backwards compatibility
123
+ 'FIRSTNAME' => 'firstname',
124
+ 'LASTNAME' => 'lastname',
125
+
126
+ // shipping rate
127
+ 'SHIPPINGOPTIONNAME' => 'shipping_rate_code',
128
+ 'NOSHIPPING' => 'suppress_shipping',
129
+
130
+ // paypal direct credit card information
131
+ 'CREDITCARDTYPE' => 'credit_card_type',
132
+ 'ACCT' => 'credit_card_number',
133
+ 'EXPDATE' => 'credit_card_expiration_date',
134
+ 'CVV2' => 'credit_card_cvv2',
135
+ 'STARTDATE' => 'maestro_solo_issue_date', // MMYYYY, always six chars, including leading zero
136
+ 'ISSUENUMBER' => 'maestro_solo_issue_number',
137
+ 'CVV2MATCH' => 'cvv2_check_result',
138
+ 'AVSCODE' => 'avs_result',
139
+ // cardinal centinel
140
+ 'AUTHSTATUS3DS' => 'centinel_authstatus',
141
+ 'MPIVENDOR3DS' => 'centinel_mpivendor',
142
+ 'CAVV' => 'centinel_cavv',
143
+ 'ECI3DS' => 'centinel_eci',
144
+ 'XID' => 'centinel_xid',
145
+ 'VPAS' => 'centinel_vpas_result',
146
+ 'ECISUBMITTED3DS' => 'centinel_eci_result',
147
+
148
+ // recurring payment profiles
149
+ //'TOKEN' => 'token',
150
+ 'SUBSCRIBERNAME' =>'subscriber_name',
151
+ 'PROFILESTARTDATE' => 'start_datetime',
152
+ 'PROFILEREFERENCE' => 'internal_reference_id',
153
+ 'DESC' => 'schedule_description',
154
+ 'MAXFAILEDPAYMENTS' => 'suspension_threshold',
155
+ 'AUTOBILLAMT' => 'bill_failed_later',
156
+ 'BILLINGPERIOD' => 'period_unit',
157
+ 'BILLINGFREQUENCY' => 'period_frequency',
158
+ 'TOTALBILLINGCYCLES' => 'period_max_cycles',
159
+ //'AMT' => 'billing_amount', // have to use 'amount', see above
160
+ 'TRIALBILLINGPERIOD' => 'trial_period_unit',
161
+ 'TRIALBILLINGFREQUENCY' => 'trial_period_frequency',
162
+ 'TRIALTOTALBILLINGCYCLES' => 'trial_period_max_cycles',
163
+ 'TRIALAMT' => 'trial_billing_amount',
164
+ // 'CURRENCYCODE' => 'currency_code',
165
+ 'SHIPPINGAMT' => 'shipping_amount',
166
+ 'TAXAMT' => 'tax_amount',
167
+ 'INITAMT' => 'init_amount',
168
+ 'FAILEDINITAMTACTION' => 'init_may_fail',
169
+ 'PROFILEID' => 'recurring_profile_id',
170
+ 'PROFILESTATUS' => 'recurring_profile_status',
171
+ 'STATUS' => 'status',
172
+
173
+ //Next two fields are used for Brazil only
174
+ 'TAXID' => 'buyer_tax_id',
175
+ 'TAXIDTYPE' => 'buyer_tax_id_type',
176
+
177
+ 'BILLINGAGREEMENTID' => 'billing_agreement_id',
178
+ 'REFERENCEID' => 'reference_id',
179
+ 'BILLINGAGREEMENTSTATUS' => 'billing_agreement_status',
180
+ 'BILLINGTYPE' => 'billing_type',
181
+ 'SREET' => 'street',
182
+ 'CITY' => 'city',
183
+ 'STATE' => 'state',
184
+ 'COUNTRYCODE' => 'countrycode',
185
+ 'ZIP' => 'zip',
186
+ 'PAYERBUSINESS' => 'payer_business',
187
+ );
188
+
189
+ /**
190
+ * Filter callbacks for preparing internal amounts to NVP request
191
+ *
192
+ * @var array
193
+ */
194
+ protected $_exportToRequestFilters = array(
195
+ 'AMT' => '_filterAmount',
196
+ 'ITEMAMT' => '_filterAmount',
197
+ 'TRIALAMT' => '_filterAmount',
198
+ 'SHIPPINGAMT' => '_filterAmount',
199
+ 'TAXAMT' => '_filterAmount',
200
+ 'INITAMT' => '_filterAmount',
201
+ 'CREDITCARDTYPE' => '_filterCcType',
202
+ // 'PROFILESTARTDATE' => '_filterToPaypalDate',
203
+ 'AUTOBILLAMT' => '_filterBillFailedLater',
204
+ 'BILLINGPERIOD' => '_filterPeriodUnit',
205
+ 'TRIALBILLINGPERIOD' => '_filterPeriodUnit',
206
+ 'FAILEDINITAMTACTION' => '_filterInitialAmountMayFail',
207
+ 'BILLINGAGREEMENTSTATUS' => '_filterBillingAgreementStatus',
208
+ 'NOSHIPPING' => '_filterInt',
209
+ );
210
+
211
+ protected $_importFromRequestFilters = array(
212
+ 'REDIRECTREQUIRED' => '_filterToBool',
213
+ 'SUCCESSPAGEREDIRECTREQUESTED' => '_filterToBool',
214
+ 'PAYMENTSTATUS' => '_filterPaymentStatusFromNvpToInfo',
215
+ );
216
+
217
+ /**
218
+ * Request map for each API call
219
+ * @var array
220
+ */
221
+ protected $_eachCallRequest = array('VERSION', 'USER', 'PWD', 'SIGNATURE', 'BUTTONSOURCE',);
222
+
223
+ /**
224
+ * SetExpressCheckout request/response map
225
+ * @var array
226
+ */
227
+ protected $_setExpressCheckoutRequest = array(
228
+ 'PAYMENTACTION', 'AMT', 'CURRENCYCODE', 'RETURNURL', 'CANCELURL', 'INVNUM', 'SOLUTIONTYPE', 'NOSHIPPING',
229
+ 'GIROPAYCANCELURL', 'GIROPAYSUCCESSURL', 'BANKTXNPENDINGURL',
230
+ 'PAGESTYLE', 'HDRIMG', 'HDRBORDERCOLOR', 'HDRBACKCOLOR', 'PAYFLOWCOLOR', 'LOCALECODE',
231
+ 'BILLINGTYPE', 'SUBJECT', 'ITEMAMT', 'SHIPPINGAMT', 'TAXAMT', 'REQBILLINGADDRESS',
232
+ );
233
+ protected $_setExpressCheckoutResponse = array('TOKEN');
234
+
235
+ /**
236
+ * GetExpressCheckoutDetails request/response map
237
+ * @var array
238
+ */
239
+ protected $_getExpressCheckoutDetailsRequest = array('TOKEN', 'SUBJECT',);
240
+
241
+ /**
242
+ * DoExpressCheckoutPayment request/response map
243
+ * @var array
244
+ */
245
+ protected $_doExpressCheckoutPaymentRequest = array(
246
+ 'TOKEN', 'PAYERID', 'PAYMENTACTION', 'AMT', 'CURRENCYCODE', 'IPADDRESS', 'BUTTONSOURCE', 'NOTIFYURL',
247
+ 'RETURNFMFDETAILS', 'SUBJECT', 'ITEMAMT', 'SHIPPINGAMT', 'TAXAMT',
248
+ );
249
+ protected $_doExpressCheckoutPaymentResponse = array(
250
+ 'TRANSACTIONID', 'AMT', 'PAYMENTSTATUS', 'PENDINGREASON', 'REDIRECTREQUIRED'
251
+ );
252
+
253
+ /**
254
+ * DoDirectPayment request/response map
255
+ * @var array
256
+ */
257
+ protected $_doDirectPaymentRequest = array(
258
+ 'PAYMENTACTION', 'IPADDRESS', 'RETURNFMFDETAILS',
259
+ 'AMT', 'CURRENCYCODE', 'INVNUM', 'NOTIFYURL', 'EMAIL', 'ITEMAMT', 'SHIPPINGAMT', 'TAXAMT',
260
+ 'CREDITCARDTYPE', 'ACCT', 'EXPDATE', 'CVV2', 'STARTDATE', 'ISSUENUMBER',
261
+ 'AUTHSTATUS3DS', 'MPIVENDOR3DS', 'CAVV', 'ECI3DS', 'XID',
262
+ );
263
+ protected $_doDirectPaymentResponse = array(
264
+ 'TRANSACTIONID', 'AMT', 'AVSCODE', 'CVV2MATCH', 'VPAS', 'ECISUBMITTED3DS'
265
+ );
266
+
267
+ /**
268
+ * DoReauthorization request/response map
269
+ * @var array
270
+ */
271
+ protected $_doReauthorizationRequest = array('AUTHORIZATIONID', 'AMT', 'CURRENCYCODE');
272
+ protected $_doReauthorizationResponse = array(
273
+ 'AUTHORIZATIONID', 'PAYMENTSTATUS', 'PENDINGREASON', 'PROTECTIONELIGIBILITY'
274
+ );
275
+
276
+ /**
277
+ * DoCapture request/response map
278
+ * @var array
279
+ */
280
+ protected $_doCaptureRequest = array('AUTHORIZATIONID', 'COMPLETETYPE', 'AMT', 'CURRENCYCODE', 'NOTE', 'INVNUM',);
281
+ protected $_doCaptureResponse = array('TRANSACTIONID', 'CURRENCYCODE', 'AMT', 'PAYMENTSTATUS', 'PENDINGREASON',);
282
+
283
+
284
+ /**
285
+ * DoAuthorization request/response map
286
+ * @var array
287
+ */
288
+ protected $_doAuthorizationRequest = array('TRANSACTIONID', 'AMT', 'CURRENCYCODE');
289
+ protected $_doAuthorizationResponse = array('TRANSACTIONID', 'AMT');
290
+
291
+ /**
292
+ * DoVoid request map
293
+ * @var array
294
+ */
295
+ protected $_doVoidRequest = array('AUTHORIZATIONID', 'NOTE',);
296
+
297
+ /**
298
+ * GetTransactionDetailsRequest
299
+ * @var array
300
+ */
301
+ protected $_getTransactionDetailsRequest = array('TRANSACTIONID');
302
+ protected $_getTransactionDetailsResponse = array(
303
+ 'PAYERID', 'FIRSTNAME', 'LASTNAME', 'TRANSACTIONID', 'PARENTTRANSACTIONID', 'CURRENCYCODE', 'AMT',
304
+ 'PAYMENTSTATUS', 'PENDINGREASON',
305
+ );
306
+
307
+ /**
308
+ * RefundTransaction request/response map
309
+ * @var array
310
+ */
311
+ protected $_refundTransactionRequest = array('TRANSACTIONID', 'REFUNDTYPE', 'CURRENCYCODE', 'NOTE',);
312
+ protected $_refundTransactionResponse = array('REFUNDTRANSACTIONID', 'GROSSREFUNDAMT',);
313
+
314
+ /**
315
+ * ManagePendingTransactionStatus request/response map
316
+ */
317
+ protected $_managePendingTransactionStatusRequest = array('TRANSACTIONID', 'ACTION');
318
+ protected $_managePendingTransactionStatusResponse = array('TRANSACTIONID', 'STATUS');
319
+
320
+ /**
321
+ * GetPalDetails response map
322
+ * @var array
323
+ */
324
+ protected $_getPalDetailsResponse = array('PAL');
325
+
326
+ /**
327
+ * CreateRecurringPaymentsProfile request/response map
328
+ *
329
+ * @var array
330
+ */
331
+ protected $_createRecurringPaymentsProfileRequest = array(
332
+ 'TOKEN', 'SUBSCRIBERNAME', 'PROFILESTARTDATE', 'PROFILEREFERENCE', 'DESC', 'MAXFAILEDPAYMENTS', 'AUTOBILLAMT',
333
+ 'BILLINGPERIOD', 'BILLINGFREQUENCY', 'TOTALBILLINGCYCLES', 'AMT', 'TRIALBILLINGPERIOD', 'TRIALBILLINGFREQUENCY',
334
+ 'TRIALTOTALBILLINGCYCLES', 'TRIALAMT', 'CURRENCYCODE', 'SHIPPINGAMT', 'TAXAMT', 'INITAMT', 'FAILEDINITAMTACTION'
335
+ );
336
+ protected $_createRecurringPaymentsProfileResponse = array(
337
+ 'PROFILEID', 'PROFILESTATUS'
338
+ );
339
+
340
+ /**
341
+ * Request/response for ManageRecurringPaymentsProfileStatus map
342
+ *
343
+ * @var array
344
+ */
345
+ protected $_manageRecurringPaymentsProfileStatusRequest = array('PROFILEID', 'ACTION');
346
+ // protected $_manageRecurringPaymentsProfileStatusResponse = array('PROFILEID');
347
+
348
+ /**
349
+ * Request/response for GetRecurringPaymentsProfileDetails
350
+ *
351
+ * @var array
352
+ */
353
+ protected $_getRecurringPaymentsProfileDetailsRequest = array('PROFILEID');
354
+ protected $_getRecurringPaymentsProfileDetailsResponse = array('STATUS', /* TODO: lot of other stuff */);
355
+
356
+ /**
357
+ * Map for billing address import/export
358
+ * @var array
359
+ */
360
+ protected $_billingAddressMap = array (
361
+ 'BUSINESS' => 'company',
362
+ 'NOTETEXT' => 'customer_notes',
363
+ 'EMAIL' => 'email',
364
+ 'FIRSTNAME' => 'firstname',
365
+ 'LASTNAME' => 'lastname',
366
+ 'MIDDLENAME' => 'middlename',
367
+ 'SALUTATION' => 'prefix',
368
+ 'SUFFIX' => 'suffix',
369
+
370
+ 'COUNTRYCODE' => 'country_id', // iso-3166 two-character code
371
+ 'STATE' => 'region',
372
+ 'CITY' => 'city',
373
+ 'STREET' => 'street',
374
+ 'STREET2' => 'street2',
375
+ 'ZIP' => 'postcode',
376
+ 'PHONENUM' => 'telephone',
377
+ );
378
+
379
+ /**
380
+ * Map for billing address to do request (not response)
381
+ * Merging with $_billingAddressMap
382
+ *
383
+ * @var array
384
+ */
385
+ protected $_billingAddressMapRequest = array ();
386
+
387
+ /**
388
+ * Map for shipping address import/export (extends billing address mapper)
389
+ * @var array
390
+ */
391
+ protected $_shippingAddressMap = array(
392
+ 'SHIPTOCOUNTRYCODE' => 'country_id',
393
+ 'SHIPTOSTATE' => 'region',
394
+ 'SHIPTOCITY' => 'city',
395
+ 'SHIPTOSTREET' => 'street',
396
+ 'SHIPTOSTREET2' => 'street2',
397
+ 'SHIPTOZIP' => 'postcode',
398
+ 'SHIPTOPHONENUM' => 'telephone',
399
+ // 'SHIPTONAME' will be treated manually in address import/export methods
400
+ );
401
+
402
+ /**
403
+ * Map for callback request
404
+ * @var array
405
+ */
406
+ protected $_callbackRequestMap = array(
407
+ 'SHIPTOCOUNTRY' => 'country_id',
408
+ 'SHIPTOSTATE' => 'region',
409
+ 'SHIPTOCITY' => 'city',
410
+ 'SHIPTOSTREET' => 'street',
411
+ 'SHIPTOSTREET2' => 'street2',
412
+ 'SHIPTOZIP' => 'postcode'
413
+ );
414
+
415
+ /**
416
+ * Payment information response specifically to be collected after some requests
417
+ * @var array
418
+ */
419
+ protected $_paymentInformationResponse = array(
420
+ 'PAYERID', 'PAYERSTATUS', 'CORRELATIONID', 'ADDRESSID', 'ADDRESSSTATUS',
421
+ 'PAYMENTSTATUS', 'PENDINGREASON', 'PROTECTIONELIGIBILITY', 'EMAIL', 'SHIPPINGOPTIONNAME', 'TAXID', 'TAXIDTYPE'
422
+ );
423
+
424
+ /**
425
+ * Line items export mapping settings
426
+ * @var array
427
+ */
428
+ protected $_lineItemTotalExportMap = array(
429
+ Mage_Paypal_Model_Cart::TOTAL_SUBTOTAL => 'ITEMAMT',
430
+ Mage_Paypal_Model_Cart::TOTAL_TAX => 'TAXAMT',
431
+ Mage_Paypal_Model_Cart::TOTAL_SHIPPING => 'SHIPPINGAMT',
432
+ );
433
+ protected $_lineItemExportItemsFormat = array(
434
+ 'id' => 'L_NUMBER%d',
435
+ 'name' => 'L_NAME%d',
436
+ 'qty' => 'L_QTY%d',
437
+ 'amount' => 'L_AMT%d',
438
+ );
439
+
440
+ /**
441
+ * Shipping options export to request mapping settings
442
+ * @var array
443
+ */
444
+ protected $_shippingOptionsExportItemsFormat = array(
445
+ 'is_default' => 'L_SHIPPINGOPTIONISDEFAULT%d',
446
+ 'amount' => 'L_SHIPPINGOPTIONAMOUNT%d',
447
+ 'code' => 'L_SHIPPINGOPTIONNAME%d',
448
+ 'name' => 'L_SHIPPINGOPTIONLABEL%d',
449
+ 'tax_amount' => 'L_TAXAMT%d',
450
+ );
451
+
452
+ /**
453
+ * init Billing Agreement request/response map
454
+ * @var array
455
+ */
456
+ protected $_customerBillingAgreementRequest = array('RETURNURL', 'CANCELURL', 'BILLINGTYPE');
457
+ protected $_customerBillingAgreementResponse = array('TOKEN');
458
+
459
+ /**
460
+ * Billing Agreement details request/response map
461
+ * @var array
462
+ */
463
+ protected $_billingAgreementCustomerDetailsRequest = array('TOKEN');
464
+ protected $_billingAgreementCustomerDetailsResponse = array('EMAIL', 'PAYERID', 'PAYERSTATUS', 'SHIPTOCOUNTRYCODE',
465
+ 'PAYERBUSINESS'
466
+ );
467
+
468
+ /**
469
+ * Create Billing Agreement request/response map
470
+ * @var array
471
+ */
472
+ protected $_createBillingAgreementRequest = array('TOKEN');
473
+ protected $_createBillingAgreementResponse = array('BILLINGAGREEMENTID');
474
+
475
+ /**
476
+ * Update Billing Agreement request/response map
477
+ * @var array
478
+ */
479
+ protected $_updateBillingAgreementRequest = array(
480
+ 'REFERENCEID', 'BILLINGAGREEMENTDESCRIPTION', 'BILLINGAGREEMENTSTATUS', 'BILLINGAGREEMENTCUSTOM'
481
+ );
482
+ protected $_updateBillingAgreementResponse = array(
483
+ 'REFERENCEID', 'BILLINGAGREEMENTDESCRIPTION', 'BILLINGAGREEMENTSTATUS', 'BILLINGAGREEMENTCUSTOM'
484
+ );
485
+
486
+ /**
487
+ * Do Reference Transaction request/response map
488
+ *
489
+ * @var array
490
+ */
491
+ protected $_doReferenceTransactionRequest = array('REFERENCEID', 'PAYMENTACTION', 'AMT', 'ITEMAMT', 'SHIPPINGAMT',
492
+ 'TAXAMT', 'INVNUM', 'NOTIFYURL'
493
+ );
494
+
495
+ protected $_doReferenceTransactionResponse = array('BILLINGAGREEMENTID', 'TRANSACTIONID');
496
+
497
+ /**
498
+ * Fields that should be replaced in debug with '***'
499
+ *
500
+ * @var array
501
+ */
502
+ protected $_debugReplacePrivateDataKeys = array(
503
+
504
+ 'ACCT', 'EXPDATE', 'CVV2', 'CARDISSUE', 'CARDSTART', 'CREDITCARDTYPE', 'USER', 'PWD', 'SIGNATURE'
505
+
506
+ );
507
+
508
+ /**
509
+ * Map of credit card types supported by this API
510
+ * @var array
511
+ */
512
+ protected $_supportedCcTypes = array(
513
+ 'VI' => 'Visa', 'MC' => 'MasterCard', 'DI' => 'Discover', 'AE' => 'Amex', 'SM' => 'Maestro', 'SO' => 'Solo');
514
+
515
+ /**
516
+ * Required fields in the response
517
+ *
518
+ * @var array
519
+ */
520
+ protected $_requiredResponseParams = array(
521
+ self::DO_DIRECT_PAYMENT => array('ACK', 'CORRELATIONID', 'AMT')
522
+ );
523
+
524
+ /**
525
+ * Warning codes recollected after each API call
526
+ *
527
+ * @var array
528
+ */
529
+ protected $_callWarnings = array();
530
+
531
+ /**
532
+ * Error codes recollected after each API call
533
+ *
534
+ * @var array
535
+ */
536
+ protected $_callErrors = array();
537
+
538
+ /**
539
+ * Whether to return raw response information after each call
540
+ *
541
+ * @var bool
542
+ */
543
+ protected $_rawResponseNeeded = false;
544
+
545
+ /**
546
+ * API endpoint getter
547
+ *
548
+ * @return string
549
+ */
550
+ public function getApiEndpoint()
551
+ {
552
+ $url = $this->getUseCertAuthentication() ? 'https://api%s.paypal.com/nvp' : 'https://api-3t%s.paypal.com/nvp';
553
+ return sprintf($url, $this->_config->sandboxFlag ? '.sandbox' : '');
554
+ }
555
+
556
+ /**
557
+ * Return Paypal Api version
558
+ *
559
+ * @return string
560
+ */
561
+ public function getVersion()
562
+ {
563
+ return '72.0';
564
+ }
565
+
566
+ /**
567
+ * Retrieve billing agreement type
568
+ *
569
+ * @return string
570
+ */
571
+ public function getBillingAgreementType()
572
+ {
573
+ return 'MerchantInitiatedBilling';
574
+ }
575
+
576
+ /**
577
+ * SetExpressCheckout call
578
+ * @link https://cms.paypal.com/us/cgi-bin/?&cmd=_render-content&content_ID=developer/e_howto_api_nvp_r_SetExpressCheckout
579
+ * TODO: put together style and giropay settings
580
+ */
581
+ public function callSetExpressCheckout()
582
+ {
583
+ $this->_prepareExpressCheckoutCallRequest($this->_setExpressCheckoutRequest);
584
+ $request = $this->_exportToRequest($this->_setExpressCheckoutRequest);
585
+ $this->_exportLineItems($request);
586
+
587
+ // import/suppress shipping address, if any
588
+ $options = $this->getShippingOptions();
589
+ if ($this->getAddress()) {
590
+ $request = $this->_importAddresses($request);
591
+ $request['ADDROVERRIDE'] = 1;
592
+ } elseif ($options && (count($options) <= 10)) { // doesn't support more than 10 shipping options
593
+ $request['CALLBACK'] = $this->getShippingOptionsCallbackUrl();
594
+ $request['CALLBACKTIMEOUT'] = 6; // max value
595
+ $request['MAXAMT'] = $request['AMT'] + 999.00; // it is impossible to calculate max amount
596
+ $this->_exportShippingOptions($request);
597
+ }
598
+
599
+ // add recurring profiles information
600
+ $i = 0;
601
+ foreach ($this->_recurringPaymentProfiles as $profile) {
602
+ $request["L_BILLINGTYPE{$i}"] = 'RecurringPayments';
603
+ $request["L_BILLINGAGREEMENTDESCRIPTION{$i}"] = $profile->getScheduleDescription();
604
+ $i++;
605
+ }
606
+
607
+ // Check discount
608
+ $lineAmt = 0;
609
+ $discount = 0;
610
+ $line = 0;
611
+ $discountIndex = 0;
612
+ while(isset($request["L_AMT{$line}"])) {
613
+ if($request["L_NAME{$line}"] == 'Discount') {
614
+ $discount += $request["L_AMT{$line}"];
615
+ $discountIndex = $line;
616
+ }
617
+ else {
618
+ $lineAmt += $request["L_AMT{$line}"];
619
+ }
620
+ $line++;
621
+ }
622
+
623
+ if($discount) {
624
+ if($discount + $lineAmt != $request['ITEMAMT']) {
625
+ // Do correction
626
+ $request["L_AMT{$discountIndex}"] = ($request['ITEMAMT'] - $lineAmt);
627
+ }
628
+ } else {
629
+ // Check item amount adds up
630
+ $correctItemAmt = $request['AMT'] - $request['SHIPPINGAMT'] - $request['TAXAMT'];
631
+ if($correctItemAmt != $request['ITEMAMT']) {
632
+ $request['ITEMAMT'] = $correctItemAmt;
633
+ }
634
+ }
635
+
636
+ $response = $this->call(self::SET_EXPRESS_CHECKOUT, $request);
637
+ $this->_importFromResponse($this->_setExpressCheckoutResponse, $response);
638
+ }
639
+
640
+ /**
641
+ * GetExpressCheckoutDetails call
642
+ * @link https://cms.paypal.com/us/cgi-bin/?&cmd=_render-content&content_ID=developer/e_howto_api_nvp_r_GetExpressCheckoutDetails
643
+ */
644
+ function callGetExpressCheckoutDetails()
645
+ {
646
+ $this->_prepareExpressCheckoutCallRequest($this->_getExpressCheckoutDetailsRequest);
647
+ $request = $this->_exportToRequest($this->_getExpressCheckoutDetailsRequest);
648
+ $response = $this->call(self::GET_EXPRESS_CHECKOUT_DETAILS, $request);
649
+ $this->_importFromResponse($this->_paymentInformationResponse, $response);
650
+ $this->_exportAddressses($response);
651
+ }
652
+
653
+ /**
654
+ * DoExpressCheckout call
655
+ * @link https://cms.paypal.com/us/cgi-bin/?&cmd=_render-content&content_ID=developer/e_howto_api_nvp_r_DoExpressCheckoutPayment
656
+ */
657
+ public function callDoExpressCheckoutPayment()
658
+ {
659
+ $this->_prepareExpressCheckoutCallRequest($this->_doExpressCheckoutPaymentRequest);
660
+ $request = $this->_exportToRequest($this->_doExpressCheckoutPaymentRequest);
661
+ $this->_exportLineItems($request);
662
+
663
+ if ($this->getAddress()) {
664
+ $request = $this->_importAddresses($request);
665
+ $request['ADDROVERRIDE'] = 1;
666
+ }
667
+
668
+ $response = $this->call(self::DO_EXPRESS_CHECKOUT_PAYMENT, $request);
669
+ $this->_importFromResponse($this->_paymentInformationResponse, $response);
670
+ $this->_importFromResponse($this->_doExpressCheckoutPaymentResponse, $response);
671
+ $this->_importFromResponse($this->_createBillingAgreementResponse, $response);
672
+ }
673
+
674
+ /**
675
+ * Process a credit card payment
676
+ */
677
+ public function callDoDirectPayment()
678
+ {
679
+ $request = $this->_exportToRequest($this->_doDirectPaymentRequest);
680
+ $this->_exportLineItems($request);
681
+ if ($this->getAddress()) {
682
+ $request = $this->_importAddresses($request);
683
+ }
684
+ $response = $this->call(self::DO_DIRECT_PAYMENT, $request);
685
+ $this->_importFromResponse($this->_doDirectPaymentResponse, $response);
686
+ }
687
+
688
+ /**
689
+ * Do Reference Transaction call
690
+ * @link https://cms.paypal.com/us/cgi-bin/?&cmd=_render-content&content_ID=developer/e_howto_api_nvp_r_DoReferenceTransaction
691
+ */
692
+ public function callDoReferenceTransaction()
693
+ {
694
+ $request = $this->_exportToRequest($this->_doReferenceTransactionRequest);
695
+ $this->_exportLineItems($request);
696
+ $response = $this->call('DoReferenceTransaction', $request);
697
+ $this->_importFromResponse($this->_doReferenceTransactionResponse, $response);
698
+ }
699
+
700
+ /**
701
+ * Check whether the last call was returned with fraud warning
702
+ *
703
+ * @return bool
704
+ */
705
+ public function getIsFraudDetected()
706
+ {
707
+ return in_array(11610, $this->_callWarnings);
708
+ }
709
+
710
+ /**
711
+ * Made additional request to paypal to get autharization id
712
+ */
713
+ public function callDoReauthorization()
714
+ {
715
+ $request = $this->_export($this->_doReauthorizationRequest);
716
+ $response = $this->call('DoReauthorization', $request);
717
+ $this->_import($response, $this->_doReauthorizationResponse);
718
+ }
719
+
720
+ /**
721
+ * DoCapture call
722
+ * @link https://cms.paypal.com/us/cgi-bin/?&cmd=_render-content&content_ID=developer/e_howto_api_nvp_r_DoCapture
723
+ */
724
+ public function callDoCapture()
725
+ {
726
+ $this->setCompleteType($this->_getCaptureCompleteType());
727
+ $request = $this->_exportToRequest($this->_doCaptureRequest);
728
+ $response = $this->call(self::DO_CAPTURE, $request);
729
+ $this->_importFromResponse($this->_paymentInformationResponse, $response);
730
+ $this->_importFromResponse($this->_doCaptureResponse, $response);
731
+ }
732
+
733
+ /**
734
+ * DoAuthorization call
735
+ *
736
+ * @link https://cms.paypal.com/us/cgi-bin/?&cmd=_render-content&content_ID=developer/e_howto_api_nvp_r_DoAuthorization
737
+ * @return Mage_Paypal_Model_Api_Nvp
738
+ */
739
+ public function callDoAuthorization()
740
+ {
741
+ $request = $this->_exportToRequest($this->_doAuthorizationRequest);
742
+ $response = $this->call(self::DO_AUTHORIZATION, $request);
743
+ $this->_importFromResponse($this->_paymentInformationResponse, $response);
744
+ $this->_importFromResponse($this->_doAuthorizationResponse, $response);
745
+
746
+ return $this;
747
+ }
748
+
749
+
750
+ /**
751
+ * DoVoid call
752
+ * @link https://cms.paypal.com/us/cgi-bin/?&cmd=_render-content&content_ID=developer/e_howto_api_nvp_r_DoVoid
753
+ */
754
+ public function callDoVoid()
755
+ {
756
+ $request = $this->_exportToRequest($this->_doVoidRequest);
757
+ $this->call(self::DO_VOID, $request);
758
+ }
759
+
760
+ /**
761
+ * GetTransactionDetails
762
+ * @link https://cms.paypal.com/us/cgi-bin/?&cmd=_render-content&content_ID=developer/e_howto_api_nvp_r_GetTransactionDetails
763
+ */
764
+ public function callGetTransactionDetails()
765
+ {
766
+ $request = $this->_exportToRequest($this->_getTransactionDetailsRequest);
767
+ $response = $this->call('GetTransactionDetails', $request);
768
+ $this->_importFromResponse($this->_getTransactionDetailsResponse, $response);
769
+ }
770
+
771
+ /**
772
+ * RefundTransaction call
773
+ * @link https://cms.paypal.com/us/cgi-bin/?&cmd=_render-content&content_ID=developer/e_howto_api_nvp_r_RefundTransaction
774
+ */
775
+ public function callRefundTransaction()
776
+ {
777
+ $request = $this->_exportToRequest($this->_refundTransactionRequest);
778
+ if ($this->getRefundType() === Mage_Paypal_Model_Config::REFUND_TYPE_PARTIAL) {
779
+ $request['AMT'] = $this->getAmount();
780
+ }
781
+ $response = $this->call(self::REFUND_TRANSACTION, $request);
782
+ $this->_importFromResponse($this->_refundTransactionResponse, $response);
783
+ }
784
+
785
+ /**
786
+ * ManagePendingTransactionStatus
787
+ * @link https://cms.paypal.com/us/cgi-bin/?&cmd=_render-content&content_ID=developer/e_howto_api_nvp_r_ManagePendingTransactionStatus
788
+ */
789
+ public function callManagePendingTransactionStatus()
790
+ {
791
+ $request = $this->_exportToRequest($this->_managePendingTransactionStatusRequest);
792
+ if (isset($request['ACTION'])) {
793
+ $request['ACTION'] = $this->_filterPaymentReviewAction($request['ACTION']);
794
+ }
795
+ $response = $this->call('ManagePendingTransactionStatus', $request);
796
+ $this->_importFromResponse($this->_managePendingTransactionStatusResponse, $response);
797
+ }
798
+
799
+ /**
800
+ * getPalDetails call
801
+ * @link https://www.x.com/docs/DOC-1300
802
+ * @link https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_ECButtonIntegration
803
+ */
804
+ public function callGetPalDetails()
805
+ {
806
+ $response = $this->call('getPalDetails', array());
807
+ $this->_importFromResponse($this->_getPalDetailsResponse, $response);
808
+ }
809
+
810
+ /**
811
+ * Set Customer BillingA greement call
812
+ *
813
+ * @link https://cms.paypal.com/us/cgi-bin/?&cmd=_render-content&content_ID=developer/e_howto_api_nvp_r_SetCustomerBillingAgreement
814
+ */
815
+ public function callSetCustomerBillingAgreement()
816
+ {
817
+ $request = $this->_exportToRequest($this->_customerBillingAgreementRequest);
818
+ $response = $this->call('SetCustomerBillingAgreement', $request);
819
+ $this->_importFromResponse($this->_customerBillingAgreementResponse, $response);
820
+ }
821
+
822
+ /**
823
+ * Get Billing Agreement Customer Details call
824
+ *
825
+ * @link https://cms.paypal.com/us/cgi-bin/?&cmd=_render-content&content_ID=developer/e_howto_api_nvp_r_GetBillingAgreementCustomerDetails
826
+ */
827
+ public function callGetBillingAgreementCustomerDetails()
828
+ {
829
+ $request = $this->_exportToRequest($this->_billingAgreementCustomerDetailsRequest);
830
+ $response = $this->call('GetBillingAgreementCustomerDetails', $request);
831
+ $this->_importFromResponse($this->_billingAgreementCustomerDetailsResponse, $response);
832
+ }
833
+
834
+ /**
835
+ * Create Billing Agreement call
836
+ *
837
+ */
838
+ public function callCreateBillingAgreement()
839
+ {
840
+ $request = $this->_exportToRequest($this->_createBillingAgreementRequest);
841
+ $response = $this->call('CreateBillingAgreement', $request);
842
+ $this->_importFromResponse($this->_createBillingAgreementResponse, $response);
843
+ }
844
+
845
+ /**
846
+ * Billing Agreement Update call
847
+ *
848
+ */
849
+ public function callUpdateBillingAgreement()
850
+ {
851
+ $request = $this->_exportToRequest($this->_updateBillingAgreementRequest);
852
+ try {
853
+ $response = $this->call('BillAgreementUpdate', $request);
854
+ } catch (Mage_Core_Exception $e) {
855
+ if (in_array(10201, $this->_callErrors)) {
856
+ $this->setIsBillingAgreementAlreadyCancelled(true);
857
+ }
858
+ throw $e;
859
+ }
860
+ $this->_importFromResponse($this->_updateBillingAgreementResponse, $response);
861
+ }
862
+
863
+ /**
864
+ * CreateRecurringPaymentsProfile call
865
+ */
866
+ public function callCreateRecurringPaymentsProfile()
867
+ {
868
+ $request = $this->_exportToRequest($this->_createRecurringPaymentsProfileRequest);
869
+ $response = $this->call('CreateRecurringPaymentsProfile', $request);
870
+ $this->_importFromResponse($this->_createRecurringPaymentsProfileResponse, $response);
871
+ $this->_analyzeRecurringProfileStatus($this->getRecurringProfileStatus(), $this);
872
+ }
873
+
874
+ /**
875
+ * ManageRecurringPaymentsProfileStatus call
876
+ */
877
+ public function callManageRecurringPaymentsProfileStatus()
878
+ {
879
+ $request = $this->_exportToRequest($this->_manageRecurringPaymentsProfileStatusRequest);
880
+ if (isset($request['ACTION'])) {
881
+ $request['ACTION'] = $this->_filterRecurringProfileActionToNvp($request['ACTION']);
882
+ }
883
+ try {
884
+ $response = $this->call('ManageRecurringPaymentsProfileStatus', $request);
885
+ } catch (Mage_Core_Exception $e) {
886
+ if ((in_array(11556, $this->_callErrors) && 'Cancel' === $request['ACTION'])
887
+ || (in_array(11557, $this->_callErrors) && 'Suspend' === $request['ACTION'])
888
+ || (in_array(11558, $this->_callErrors) && 'Reactivate' === $request['ACTION'])
889
+ ) {
890
+ Mage::throwException(Mage::helper('paypal')->__('Unable to change status. Current status is not correspond to real status.'));
891
+ }
892
+ throw $e;
893
+ }
894
+ }
895
+
896
+ /**
897
+ * GetRecurringPaymentsProfileDetails call
898
+ */
899
+ public function callGetRecurringPaymentsProfileDetails(Varien_Object $result)
900
+ {
901
+ $request = $this->_exportToRequest($this->_getRecurringPaymentsProfileDetailsRequest);
902
+ $response = $this->call('GetRecurringPaymentsProfileDetails', $request);
903
+ $this->_importFromResponse($this->_getRecurringPaymentsProfileDetailsResponse, $response);
904
+ $this->_analyzeRecurringProfileStatus($this->getStatus(), $result);
905
+ }
906
+
907
+ /**
908
+ * Import callback request array into $this public data
909
+ *
910
+ * @param array $request
911
+ * @return Varien_Object
912
+ */
913
+ public function prepareShippingOptionsCallbackAddress(array $request)
914
+ {
915
+ $address = new Varien_Object();
916
+ Varien_Object_Mapper::accumulateByMap($request, $address, $this->_callbackRequestMap);
917
+ $address->setExportedKeys(array_values($this->_callbackRequestMap));
918
+ $this->_applyStreetAndRegionWorkarounds($address);
919
+ return $address;
920
+ }
921
+
922
+ /**
923
+ * Prepare response for shipping options callback
924
+ *
925
+ * @return string
926
+ */
927
+ public function formatShippingOptionsCallback()
928
+ {
929
+ $response = array();
930
+ if (!$this->_exportShippingOptions($response)) {
931
+ $response['NO_SHIPPING_OPTION_DETAILS'] = '1';
932
+ }
933
+ $response = $this->_addMethodToRequest(self::CALLBACK_RESPONSE, $response);
934
+ return $this->_buildQuery($response);
935
+ }
936
+
937
+ /**
938
+ * Add method to request array
939
+ *
940
+ * @param string $methodName
941
+ * @param array $request
942
+ * @return array
943
+ */
944
+ protected function _addMethodToRequest($methodName, $request)
945
+ {
946
+ $request['METHOD'] = $methodName;
947
+ return $request;
948
+ }
949
+
950
+ /**
951
+ * Do the API call
952
+ *
953
+ * @param string $methodName
954
+ * @param array $request
955
+ * @return array
956
+ * @throws Mage_Core_Exception
957
+ */
958
+ public function call($methodName, array $request)
959
+ {
960
+ $request = $this->_addMethodToRequest($methodName, $request);
961
+ $eachCallRequest = $this->_prepareEachCallRequest($methodName);
962
+ if ($this->getUseCertAuthentication()) {
963
+ if ($key = array_search('SIGNATURE', $eachCallRequest)) {
964
+ unset($eachCallRequest[$key]);
965
+ }
966
+ }
967
+ $request = $this->_exportToRequest($eachCallRequest, $request);
968
+ $debugData = array('url' => $this->getApiEndpoint(), $methodName => $request);
969
+
970
+ try {
971
+ $http = new Varien_Http_Adapter_Curl();
972
+ $config = array(
973
+ 'timeout' => 30,
974
+ 'verifypeer' => $this->_config->verifyPeer
975
+ );
976
+
977
+ if ($this->getUseProxy()) {
978
+ $config['proxy'] = $this->getProxyHost(). ':' . $this->getProxyPort();
979
+ }
980
+ if ($this->getUseCertAuthentication()) {
981
+ $config['ssl_cert'] = $this->getApiCertificate();
982
+ }
983
+ $http->setConfig($config);
984
+ $http->write(Zend_Http_Client::POST, $this->getApiEndpoint(), '1.1', array(), $this->_buildQuery($request));
985
+ $response = $http->read();
986
+ } catch (Exception $e) {
987
+ $debugData['http_error'] = array('error' => $e->getMessage(), 'code' => $e->getCode());
988
+ $this->_debug($debugData);
989
+ throw $e;
990
+ }
991
+
992
+ $response = preg_split('/^\r?$/m', $response, 2);
993
+ $response = trim($response[1]);
994
+ $response = $this->_deformatNVP($response);
995
+
996
+ $debugData['response'] = $response;
997
+ $this->_debug($debugData);
998
+
999
+ // handle transport error
1000
+ if ($http->getErrno()) {
1001
+ Mage::logException(new Exception(
1002
+ sprintf('PayPal NVP CURL connection error #%s: %s', $http->getErrno(), $http->getError())
1003
+ ));
1004
+ $http->close();
1005
+
1006
+ Mage::throwException(Mage::helper('paypal')->__('Unable to communicate with the PayPal gateway.'));
1007
+ }
1008
+
1009
+ // cUrl resource must be closed after checking it for errors
1010
+ $http->close();
1011
+
1012
+ if (!$this->_validateResponse($methodName, $response)) {
1013
+ Mage::logException(new Exception(
1014
+ Mage::helper('paypal')->__("PayPal response hasn't required fields.")
1015
+ ));
1016
+ Mage::throwException(Mage::helper('paypal')->__('There was an error processing your order. Please contact us or try again later.'));
1017
+ }
1018
+
1019
+ $this->_callErrors = array();
1020
+ if ($this->_isCallSuccessful($response)) {
1021
+ if ($this->_rawResponseNeeded) {
1022
+ $this->setRawSuccessResponseData($response);
1023
+ }
1024
+ return $response;
1025
+ }
1026
+ $this->_handleCallErrors($response);
1027
+ return $response;
1028
+ }
1029
+
1030
+ /**
1031
+ * Setter for 'raw response needed' flag
1032
+ *
1033
+ * @param bool $flag
1034
+ * @return Mage_Paypal_Model_Api_Nvp
1035
+ */
1036
+ public function setRawResponseNeeded($flag)
1037
+ {
1038
+ $this->_rawResponseNeeded = $flag;
1039
+ return $this;
1040
+ }
1041
+
1042
+ /**
1043
+ * Handle logical errors
1044
+ *
1045
+ * @param array
1046
+ */
1047
+ protected function _handleCallErrors($response)
1048
+ {
1049
+ $errors = array();
1050
+ for ($i = 0; isset($response["L_ERRORCODE{$i}"]); $i++) {
1051
+ $longMessage = isset($response["L_LONGMESSAGE{$i}"])
1052
+ ? preg_replace('/\.$/', '', $response["L_LONGMESSAGE{$i}"]) : '';
1053
+ $shortMessage = preg_replace('/\.$/', '', $response["L_SHORTMESSAGE{$i}"]);
1054
+ $errors[] = $longMessage
1055
+ ? sprintf('%s (#%s: %s).', $longMessage, $response["L_ERRORCODE{$i}"], $shortMessage)
1056
+ : sprintf('#%s: %s.', $response["L_ERRORCODE{$i}"], $shortMessage);
1057
+ $this->_callErrors[] = $response["L_ERRORCODE{$i}"];
1058
+ }
1059
+ if ($errors) {
1060
+ $errors = implode(' ', $errors);
1061
+ $e = Mage::exception('Mage_Core', sprintf('PayPal NVP gateway errors: %s Correlation ID: %s. Version: %s.',
1062
+ $errors,
1063
+ isset($response['CORRELATIONID']) ? $response['CORRELATIONID'] : '',
1064
+ isset($response['VERSION']) ? $response['VERSION'] : ''
1065
+ ));
1066
+ Mage::logException($e);
1067
+ $e->setMessage(Mage::helper('paypal')->__('PayPal gateway has rejected request. %s', $errors));
1068
+ throw $e;
1069
+ }
1070
+ }
1071
+
1072
+ /**
1073
+ * Catch success calls and collect warnings
1074
+ *
1075
+ * @param array
1076
+ * @return bool| success flag
1077
+ */
1078
+ protected function _isCallSuccessful($response)
1079
+ {
1080
+ if (!isset($response['ACK'])) {
1081
+ return false;
1082
+ }
1083
+
1084
+ $ack = strtoupper($response['ACK']);
1085
+ $this->_callWarnings = array();
1086
+ if ($ack == 'SUCCESS' || $ack == 'SUCCESSWITHWARNING') {
1087
+ // collect warnings
1088
+ if ($ack == 'SUCCESSWITHWARNING') {
1089
+ for ($i = 0; isset($response["L_ERRORCODE{$i}"]); $i++) {
1090
+ $this->_callWarnings[] = $response["L_ERRORCODE{$i}"];
1091
+ }
1092
+ }
1093
+ return true;
1094
+ }
1095
+ return false;
1096
+ }
1097
+
1098
+ /**
1099
+ * Validate response array.
1100
+ *
1101
+ * @param string $method
1102
+ * @param array $response
1103
+ * @return bool
1104
+ */
1105
+ protected function _validateResponse($method, $response)
1106
+ {
1107
+ if (isset($this->_requiredResponseParams[$method])) {
1108
+ foreach ($this->_requiredResponseParams[$method] as $param) {
1109
+ if (!isset($response[$param])) {
1110
+ return false;
1111
+ }
1112
+ }
1113
+ }
1114
+ return true;
1115
+ }
1116
+
1117
+ /**
1118
+ * Parse an NVP response string into an associative array
1119
+ * @param string $nvpstr
1120
+ * @return array
1121
+ */
1122
+ protected function _deformatNVP($nvpstr)
1123
+ {
1124
+ $intial=0;
1125
+ $nvpArray = array();
1126
+
1127
+ $nvpstr = strpos($nvpstr, "\r\n\r\n")!==false ? substr($nvpstr, strpos($nvpstr, "\r\n\r\n")+4) : $nvpstr;
1128
+
1129
+ while(strlen($nvpstr)) {
1130
+ //postion of Key
1131
+ $keypos= strpos($nvpstr,'=');
1132
+ //position of value
1133
+ $valuepos = strpos($nvpstr,'&') ? strpos($nvpstr,'&'): strlen($nvpstr);
1134
+
1135
+ /*getting the Key and Value values and storing in a Associative Array*/
1136
+ $keyval=substr($nvpstr,$intial,$keypos);
1137
+ $valval=substr($nvpstr,$keypos+1,$valuepos-$keypos-1);
1138
+ //decoding the respose
1139
+ $nvpArray[urldecode($keyval)] =urldecode( $valval);
1140
+ $nvpstr=substr($nvpstr,$valuepos+1,strlen($nvpstr));
1141
+ }
1142
+ return $nvpArray;
1143
+ }
1144
+
1145
+ /**
1146
+ * NVP doesn't support passing discount total as a separate amount - add it as a line item
1147
+ *
1148
+ * @param array $request
1149
+ * @param int $i
1150
+ * @return true|null
1151
+ */
1152
+ protected function _exportLineItems(array &$request, $i = 0)
1153
+ {
1154
+ if (!$this->_cart) {
1155
+ return;
1156
+ }
1157
+ $this->_cart->isDiscountAsItem(true);
1158
+ return parent::_exportLineItems($request, $i);
1159
+ }
1160
+
1161
+ /**
1162
+ * Create billing and shipping addresses basing on response data
1163
+ * @param array $data
1164
+ */
1165
+ protected function _exportAddressses($data)
1166
+ {
1167
+ $address = new Varien_Object();
1168
+ Varien_Object_Mapper::accumulateByMap($data, $address, $this->_billingAddressMap);
1169
+ $address->setExportedKeys(array_values($this->_billingAddressMap));
1170
+ $this->_applyStreetAndRegionWorkarounds($address);
1171
+ $this->setExportedBillingAddress($address);
1172
+ // assume there is shipping address if there is at least one field specific to shipping
1173
+ if (isset($data['SHIPTONAME'])) {
1174
+ $shippingAddress = clone $address;
1175
+ Varien_Object_Mapper::accumulateByMap($data, $shippingAddress, $this->_shippingAddressMap);
1176
+ $this->_applyStreetAndRegionWorkarounds($shippingAddress);
1177
+ // PayPal doesn't provide detailed shipping name fields, so the name will be overwritten
1178
+ $firstName = $data['SHIPTONAME'];
1179
+ $lastName = null;
1180
+ if (isset($data['FIRSTNAME']) && $data['LASTNAME']) {
1181
+ $firstName = $data['FIRSTNAME'];
1182
+ $lastName = $data['LASTNAME'];
1183
+ }
1184
+ $shippingAddress->addData(array(
1185
+ 'prefix' => null,
1186
+ 'firstname' => $firstName,
1187
+ 'middlename' => null,
1188
+ 'lastname' => $lastName,
1189
+ 'suffix' => null,
1190
+ ));
1191
+ $this->setExportedShippingAddress($shippingAddress);
1192
+ }
1193
+ }
1194
+
1195
+ /**
1196
+ * Adopt specified address object to be compatible with Magento
1197
+ *
1198
+ * @param Varien_Object $address
1199
+ */
1200
+ protected function _applyStreetAndRegionWorkarounds(Varien_Object $address)
1201
+ {
1202
+ // merge street addresses into 1
1203
+ if ($address->hasStreet2()) {
1204
+ $address->setStreet(implode("\n", array($address->getStreet(), $address->getStreet2())));
1205
+ $address->unsStreet2();
1206
+ }
1207
+ // attempt to fetch region_id from directory
1208
+ if ($address->getCountryId() && $address->getRegion()) {
1209
+ $regions = Mage::getModel('directory/country')->loadByCode($address->getCountryId())->getRegionCollection()
1210
+ ->addRegionCodeOrNameFilter($address->getRegion())
1211
+ ->setPageSize(1);
1212
+ foreach ($regions as $region) {
1213
+ $address->setRegionId($region->getId());
1214
+ $address->setExportedKeys(array_merge($address->getExportedKeys(), array('region_id')));
1215
+ break;
1216
+ }
1217
+ }
1218
+ }
1219
+
1220
+ /**
1221
+ * Adopt specified request array to be compatible with Paypal
1222
+ * Puerto Rico should be as state of USA and not as a country
1223
+ *
1224
+ * @param array $request
1225
+ */
1226
+ protected function _applyCountryWorkarounds(&$request)
1227
+ {
1228
+ if (isset($request['SHIPTOCOUNTRYCODE']) && $request['SHIPTOCOUNTRYCODE'] == 'PR') {
1229
+ $request['SHIPTOCOUNTRYCODE'] = 'US';
1230
+ $request['SHIPTOSTATE'] = 'PR';
1231
+ }
1232
+ }
1233
+
1234
+ /**
1235
+ * Prepare request data basing on provided address
1236
+ *
1237
+ * @deprecated after 1.4.2.0-beta1, use _importAddresses() instead
1238
+ *
1239
+ * @param Varien_Object $address
1240
+ * @param array $to
1241
+ * @return array
1242
+ */
1243
+ protected function _importAddress(Varien_Object $address, array $to)
1244
+ {
1245
+ $this->setAddress($address);
1246
+ return $this->_importAddresses($to);
1247
+ }
1248
+
1249
+ /**
1250
+ * Prepare request data basing on provided addresses
1251
+ *
1252
+ * @param array $to
1253
+ * @return array
1254
+ */
1255
+ protected function _importAddresses(array $to)
1256
+ {
1257
+ $billingAddress = ($this->getBillingAddress()) ? $this->getBillingAddress() : $this->getAddress();
1258
+ $shippingAddress = $this->getAddress();
1259
+
1260
+ $to = Varien_Object_Mapper::accumulateByMap(
1261
+ $billingAddress,
1262
+ $to,
1263
+ array_merge(array_flip($this->_billingAddressMap), $this->_billingAddressMapRequest)
1264
+ );
1265
+ if ($regionCode = $this->_lookupRegionCodeFromAddress($billingAddress)) {
1266
+ $to['STATE'] = $regionCode;
1267
+ }
1268
+ if (!$this->getSuppressShipping()) {
1269
+ $to = Varien_Object_Mapper::accumulateByMap($shippingAddress, $to, array_flip($this->_shippingAddressMap));
1270
+ if ($regionCode = $this->_lookupRegionCodeFromAddress($shippingAddress)) {
1271
+ $to['SHIPTOSTATE'] = $regionCode;
1272
+ }
1273
+ $this->_importStreetFromAddress($shippingAddress, $to, 'SHIPTOSTREET', 'SHIPTOSTREET2');
1274
+ $this->_importStreetFromAddress($billingAddress, $to, 'STREET', 'STREET2');
1275
+ $to['SHIPTONAME'] = $shippingAddress->getName();
1276
+ }
1277
+ $this->_applyCountryWorkarounds($to);
1278
+ return $to;
1279
+ }
1280
+
1281
+ /**
1282
+ * Filter for credit card type
1283
+ *
1284
+ * @param string $value
1285
+ * @return string
1286
+ */
1287
+ protected function _filterCcType($value)
1288
+ {
1289
+ if (isset($this->_supportedCcTypes[$value])) {
1290
+ return $this->_supportedCcTypes[$value];
1291
+ }
1292
+ return '';
1293
+ }
1294
+
1295
+ /**
1296
+ * Filter for true/false values (converts to boolean)
1297
+ *
1298
+ * @param mixed $value
1299
+ * @return mixed
1300
+ */
1301
+ protected function _filterToBool($value)
1302
+ {
1303
+ if ('false' === $value || '0' === $value) {
1304
+ return false;
1305
+ } elseif ('true' === $value || '1' === $value) {
1306
+ return true;
1307
+ }
1308
+ return $value;
1309
+ }
1310
+
1311
+ /**
1312
+ * Filter for 'AUTOBILLAMT'
1313
+ *
1314
+ * @param string $value
1315
+ * @return string
1316
+ */
1317
+ protected function _filterBillFailedLater($value)
1318
+ {
1319
+ return $value ? 'AddToNextBilling' : 'NoAutoBill';
1320
+ }
1321
+
1322
+ /**
1323
+ * Filter for 'BILLINGPERIOD' and 'TRIALBILLINGPERIOD'
1324
+ *
1325
+ * @param string $value
1326
+ * @return string
1327
+ */
1328
+ protected function _filterPeriodUnit($value)
1329
+ {
1330
+ switch ($value) {
1331
+ case 'day': return 'Day';
1332
+ case 'week': return 'Week';
1333
+ case 'semi_month': return 'SemiMonth';
1334
+ case 'month': return 'Month';
1335
+ case 'year': return 'Year';
1336
+ }
1337
+ }
1338
+
1339
+ /**
1340
+ * Filter for 'FAILEDINITAMTACTION'
1341
+ *
1342
+ * @param string $value
1343
+ * @return string
1344
+ */
1345
+ protected function _filterInitialAmountMayFail($value)
1346
+ {
1347
+ return $value ? 'ContinueOnFailure' : 'CancelOnFailure';
1348
+ }
1349
+
1350
+ /**
1351
+ * Filter for billing agreement status
1352
+ *
1353
+ * @param string $value
1354
+ * @return string
1355
+ */
1356
+ protected function _filterBillingAgreementStatus($value)
1357
+ {
1358
+ switch ($value) {
1359
+ case 'canceled': return 'Canceled';
1360
+ case 'active': return 'Active';
1361
+ }
1362
+ }
1363
+
1364
+ /**
1365
+ * Convert payment status from NVP format to paypal/info model format
1366
+ *
1367
+ * @param string $value
1368
+ * @return string|null
1369
+ */
1370
+ protected function _filterPaymentStatusFromNvpToInfo($value)
1371
+ {
1372
+ switch ($value) {
1373
+ case 'None': return Mage_Paypal_Model_Info::PAYMENTSTATUS_NONE;
1374
+ case 'Completed': return Mage_Paypal_Model_Info::PAYMENTSTATUS_COMPLETED;
1375
+ case 'Denied': return Mage_Paypal_Model_Info::PAYMENTSTATUS_DENIED;
1376
+ case 'Expired': return Mage_Paypal_Model_Info::PAYMENTSTATUS_EXPIRED;
1377
+ case 'Failed': return Mage_Paypal_Model_Info::PAYMENTSTATUS_FAILED;
1378
+ case 'In-Progress': return Mage_Paypal_Model_Info::PAYMENTSTATUS_INPROGRESS;
1379
+ case 'Pending': return Mage_Paypal_Model_Info::PAYMENTSTATUS_PENDING;
1380
+ case 'Refunded': return Mage_Paypal_Model_Info::PAYMENTSTATUS_REFUNDED;
1381
+ case 'Partially-Refunded': return Mage_Paypal_Model_Info::PAYMENTSTATUS_REFUNDEDPART;
1382
+ case 'Reversed': return Mage_Paypal_Model_Info::PAYMENTSTATUS_REVERSED;
1383
+ case 'Canceled-Reversal': return Mage_Paypal_Model_Info::PAYMENTSTATUS_UNREVERSED;
1384
+ case 'Processed': return Mage_Paypal_Model_Info::PAYMENTSTATUS_PROCESSED;
1385
+ case 'Voided': return Mage_Paypal_Model_Info::PAYMENTSTATUS_VOIDED;
1386
+ }
1387
+ }
1388
+
1389
+ /**
1390
+ * Convert payment review action to NVP-compatible value
1391
+ *
1392
+ * @param string $value
1393
+ * @return string|null
1394
+ */
1395
+ protected function _filterPaymentReviewAction($value)
1396
+ {
1397
+ switch ($value) {
1398
+ case Mage_Paypal_Model_Pro::PAYMENT_REVIEW_ACCEPT:
1399
+ return 'Accept';
1400
+ case Mage_Paypal_Model_Pro::PAYMENT_REVIEW_DENY:
1401
+ return 'Deny';
1402
+ }
1403
+ }
1404
+
1405
+ /**
1406
+ * Convert RP management action to NVP format
1407
+ *
1408
+ * @param string $value
1409
+ * @return string|null
1410
+ */
1411
+ protected function _filterRecurringProfileActionToNvp($value)
1412
+ {
1413
+ switch ($value) {
1414
+ case 'cancel': return 'Cancel';
1415
+ case 'suspend': return 'Suspend';
1416
+ case 'activate': return 'Reactivate';
1417
+ }
1418
+ }
1419
+
1420
+ /**
1421
+ * Check the obtained RP status in NVP format and specify the profile state
1422
+ *
1423
+ * @param string $value
1424
+ * @param Varien_Object $result
1425
+ */
1426
+ protected function _analyzeRecurringProfileStatus($value, Varien_Object $result)
1427
+ {
1428
+ switch ($value) {
1429
+ case 'ActiveProfile':
1430
+ case 'Active':
1431
+ $result->setIsProfileActive(true);
1432
+ break;
1433
+ case 'PendingProfile':
1434
+ $result->setIsProfilePending(true);
1435
+ break;
1436
+ case 'CancelledProfile':
1437
+ case 'Cancelled':
1438
+ $result->setIsProfileCanceled(true);
1439
+ break;
1440
+ case 'SuspendedProfile':
1441
+ case 'Suspended':
1442
+ $result->setIsProfileSuspended(true);
1443
+ break;
1444
+ case 'ExpiredProfile':
1445
+ case 'Expired': // ??
1446
+ $result->setIsProfileExpired(true);
1447
+ break;
1448
+ }
1449
+ }
1450
+
1451
+ /**
1452
+ * Return capture type
1453
+ *
1454
+ * @param Varien_Object $payment
1455
+ * @return string
1456
+ */
1457
+ protected function _getCaptureCompleteType()
1458
+ {
1459
+ return ($this->getIsCaptureComplete())
1460
+ ? $this->_captureTypeComplete
1461
+ : $this->_captureTypeNotcomplete;
1462
+ }
1463
+
1464
+ /**
1465
+ * Return each call request without unused fields in case of Express Checkout Unilateral payments
1466
+ *
1467
+ * @param string $methodName Current method name
1468
+ * @return array
1469
+ */
1470
+ protected function _prepareEachCallRequest($methodName)
1471
+ {
1472
+ $expressCheckooutMetods = array(
1473
+ self::SET_EXPRESS_CHECKOUT, self::GET_EXPRESS_CHECKOUT_DETAILS, self::DO_EXPRESS_CHECKOUT_PAYMENT
1474
+ );
1475
+ if (!in_array($methodName, $expressCheckooutMetods) || !$this->_config->shouldUseUnilateralPayments()) {
1476
+ return $this->_eachCallRequest;
1477
+ }
1478
+ return array_diff($this->_eachCallRequest, array('USER', 'PWD', 'SIGNATURE'));
1479
+ }
1480
+
1481
+ /**
1482
+ * Check the EC request against unilateral payments mode and remove the SUBJECT if needed
1483
+ *
1484
+ * @param &array $requestFields
1485
+ */
1486
+ protected function _prepareExpressCheckoutCallRequest(&$requestFields)
1487
+ {
1488
+ if (!$this->_config->shouldUseUnilateralPayments()) {
1489
+ if ($key = array_search('SUBJECT', $requestFields)) {
1490
+ unset($requestFields[$key]);
1491
+ }
1492
+ }
1493
+ }
1494
+ }
app/etc/modules/{FlyWebdesign_PaypalFee.xml → FlyWebservices_PaypalFee.xml} RENAMED
@@ -1,9 +1,9 @@
1
  <?xml version="1.0"?>
2
  <config>
3
  <modules>
4
- <FlyWebdesign_PaypalFee>
5
  <active>true</active>
6
  <codePool>local</codePool>
7
- </FlyWebdesign_PaypalFee>
8
  </modules>
9
  </config>
1
  <?xml version="1.0"?>
2
  <config>
3
  <modules>
4
+ <FlyWebservices_PaypalFee>
5
  <active>true</active>
6
  <codePool>local</codePool>
7
+ </FlyWebservices_PaypalFee>
8
  </modules>
9
  </config>
package.xml CHANGED
@@ -1,9 +1,9 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>flywebdesign_paypalfee</name>
4
- <version>0.1.3</version>
5
  <stability>stable</stability>
6
- <license uri="http://opensource.org/licenses/osl-3.0.php">Open Software License (OSL)</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Add a customer fee to payment methods, like PayPal.</summary>
@@ -14,9 +14,9 @@ It provides the functionality to set different payment fee/charge for all paymen
14
  In the backend you can fill in a fixed price or percentage of the subtotal to add to the amount the customer has to pay.</description>
15
  <notes>Add additional payment fees to payment methods</notes>
16
  <authors><author><name>Fly Webservices</name><user>flyweb</user><email>info@flywebservices.nl</email></author></authors>
17
- <date>2013-10-30</date>
18
- <time>08:59:11</time>
19
- <contents><target name="mageetc"><dir name="modules"><file name="FlyWebdesign_PaypalFee.xml" hash="c07031f7f9da066befc127abc8c766f8"/></dir></target><target name="magelocal"><dir name="FlyWebdesign"><dir name="PaypalFee"><dir name="Block"><dir name="Adminhtml"><dir name="Sales"><dir name="Order"><dir name="Creditmemo"><file name="Totals.php" hash="99ccd5759d9070540bfba617f637b2d8"/></dir><dir name="Invoice"><file name="Totals.php" hash="2b0e3ee138df4503062e3a6645cd8bc1"/></dir><file name="Totals.php" hash="3abb380bb023ccf4126f4e63f179b54b"/></dir><file name="Totals.php" hash="53a4995e883a29be6d1a0155e279f063"/></dir></dir><dir name="Sales"><dir name="Order"><dir name="Creditmemo"><file name="Totals.php" hash="e37228644674a2f0950b34bd61dcc675"/></dir><dir name="Invoice"><file name="Totals.php" hash="4d81572c4b68ba0b7ee1c4f38e59022e"/></dir><file name="Totals.php" hash="f2a13692a95ca921af9cd1f090731835"/></dir></dir></dir><dir name="etc"><file name="config.xml" hash="85b056439185da114fa582b92c212b1e"/><file name="system.xml" hash="cf05881d5a1dfe470ecbe5394738fc8d"/></dir><dir name="Helper"><file name="Data.php" hash="779a54809ee04904be5baedeca294524"/></dir><dir name="Model"><dir name="Paypal"><file name="Cart.php" hash="a4272d68f9c8c018e5e13bc1a6e45a21"/></dir><dir name="Sales"><dir name="Order"><dir name="Creditmemo"><dir name="Total"><file name="Paymentcharge.php" hash="5e8be36c3c91891dd5b9d3a4ebeef1c8"/></dir></dir><dir name="Invoice"><dir name="Total"><file name="Paymentcharge.php" hash="dce4cb36f08cb7e1146d25d9dcb5f7f5"/></dir></dir></dir><dir name="Quote"><dir name="Address"><dir name="Total"><file name="Paymentcharge.php" hash="517eee927f1ac8ca4f082f14e52e46f4"/></dir></dir></dir></dir><dir name="System"><dir name="Config"><dir name="Source"><file name="Chargetype.php" hash="4c281a3c37d64567946829cbadf1d905"/></dir></dir></dir></dir><dir name="sql"><dir name="paymentcharge_setup"><file name="mysql4-install-0.1.0.php" hash="8135c131114d352519c92b44b10dfb45"/></dir></dir></dir></dir></target></contents>
20
  <compatible/>
21
  <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
22
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>flywebdesign_paypalfee</name>
4
+ <version>1.0.2</version>
5
  <stability>stable</stability>
6
+ <license>Commercial Software License</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Add a customer fee to payment methods, like PayPal.</summary>
14
  In the backend you can fill in a fixed price or percentage of the subtotal to add to the amount the customer has to pay.</description>
15
  <notes>Add additional payment fees to payment methods</notes>
16
  <authors><author><name>Fly Webservices</name><user>flyweb</user><email>info@flywebservices.nl</email></author></authors>
17
+ <date>2015-08-19</date>
18
+ <time>13:33:21</time>
19
+ <contents><target name="mageetc"><dir name="modules"><file name="FlyWebservices_PaypalFee.xml" hash="607aec02ddad0dd7617ff1549d924d03"/></dir></target><target name="magelocal"><dir name="FlyWebservices"><dir name="PaypalFee"><dir name="Block"><dir name="Adminhtml"><dir name="Sales"><dir name="Order"><dir name="Creditmemo"><file name="Totals.php" hash="e9e7ed9cab7837d11596695fb0646306"/></dir><dir name="Invoice"><file name="Totals.php" hash="660a63c5f284b70f5b02dc32a49a2b9c"/></dir><file name="Totals.php" hash="bc7a964aa8e38684d0f2f27ea09ad9b4"/></dir><file name="Totals.php" hash="284b30b3d02530352faadd23b36887b4"/></dir></dir><dir name="Sales"><dir name="Order"><dir name="Creditmemo"><file name="Totals.php" hash="e4be15d2fc229866659c3061598ec8c2"/></dir><dir name="Invoice"><file name="Totals.php" hash="45661ce603d1e6fa66b27e4581c7cf66"/></dir><file name="Totals.php" hash="67c37c2b38edaa0a7c9e204d2789232b"/></dir></dir></dir><dir name="etc"><file name="config.xml" hash="ae6d62caa91b2845ffb7931fe2d25088"/><file name="system.xml" hash="cf05881d5a1dfe470ecbe5394738fc8d"/></dir><dir name="Helper"><file name="Data.php" hash="4bae5ba1d7d97aefb841c78fe58236d6"/></dir><dir name="Model"><dir name="Paypal"><file name="Cart.php" hash="852b84388dc1b54f77e9b70e02bd43a0"/></dir><dir name="Sales"><dir name="Order"><dir name="Creditmemo"><dir name="Total"><file name="Paymentcharge.php" hash="c39277d48b51ba17ca15c9a32de3ded4"/></dir></dir><dir name="Invoice"><dir name="Total"><file name="Paymentcharge.php" hash="e089b7081954613119c8e7388d581c06"/></dir></dir></dir><dir name="Quote"><dir name="Address"><dir name="Total"><file name="Paymentcharge.php" hash="edb08a84b2701430efd7d78b22fcccd6"/></dir></dir></dir></dir><dir name="System"><dir name="Config"><dir name="Source"><file name="Chargetype.php" hash="b07a8ccce0961874e4d465a64f958f4e"/></dir></dir></dir></dir><dir name="sql"><dir name="paymentcharge_setup"><file name="mysql4-install-0.1.0.php" hash="8135c131114d352519c92b44b10dfb45"/></dir></dir></dir></dir><dir name="Mage"><dir name="Paypal"><dir name="Model"><dir name="Api"><file name="Nvp.php" hash="f06c82f8d892174eb7d5ddedb931cde2"/></dir></dir></dir></dir></target></contents>
20
  <compatible/>
21
  <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
22
  </package>