Created
July 12, 2017 10:49
-
-
Save bubach/ed86611c634b401e5d66392cf32c2f6e to your computer and use it in GitHub Desktop.
Small module enabling refunds on Magento 1.x Paypal standard payments
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0"?> | |
<config> | |
<modules> | |
<Namespace_Modulename> | |
<version>0.0.1</version> | |
<depends> | |
<!-- <MageCoders_PaypalMulticurrency /> --> | |
<Mage_Paypal /> | |
<!-- <AW_Storecredit /> --> | |
</depends> | |
</Namespace_Modulename> | |
</modules> | |
<global> | |
<models> | |
<modulename> | |
<class>Namespace_Modulename_Model</class> | |
</modulename> | |
</models> | |
</global> | |
<adminhtml> | |
<events> | |
<sales_order_payment_refund> | |
<observers> | |
<modulename> | |
<type>singleton</type> | |
<class>Namespace_Modulename_Model_Model_Observer</class> | |
<method>creditMemo</method> | |
</modulename> | |
</observers> | |
</sales_order_payment_refund> | |
</events> | |
</adminhtml> | |
<!-- Left out config for module setting 'modulename/active', ACL and other crap. --> | |
</config> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* app/code/local/Namespace/Modulename/Model/Namespace_Modulename_Model_Observer.php | |
*/ | |
class Namespace_Modulename_Model_Model_Observer | |
{ | |
/** | |
* Observer for paypal standard payments refund | |
* | |
* @param Varien_Event_Observer $observer | |
* @throws Mage_Core_Exception | |
*/ | |
public function creditMemo(Varien_Event_Observer $observer) | |
{ | |
$payment = $observer->getEvent()->getPayment(); | |
$paymentCode = $payment->getMethod(); | |
$storeId = $payment->getOrder()->getStoreId(); | |
// check if we should handle paypal refunds | |
if (Mage::getStoreConfigFlag('modulename/paypal/active', storeId)) { | |
if ($paymentCode == "paypal_standard") { | |
$creditmemo = $observer->getEvent()->getCreditmemo(); | |
// instantiate our model directly instead of keeping rewrite in config (why not) | |
$paypal = Mage::getModel('modulename/paypal'); | |
//$paypal = Mage::getModel('paypal/pro'); | |
if ($paypal && method_exists($paypal, 'tryRefund')) { | |
$ares = $paypal->tryRefund($payment, $creditmemo->getGrandTotal()); | |
if ($ares[0] == 0) { | |
Mage::getSingleton('adminhtml/session')->addSuccess($ares[1]); | |
} elseif ($ares[0] > 1) { | |
throw new Mage_Core_Exception($ares[1]); | |
} elseif ($ares[0] < 0) { | |
throw new Mage_Core_Exception($ares[1]); | |
} | |
$payment | |
->getOrder() | |
->addStatusToHistory($payment | |
->getOrder() | |
->getStatus(), $ares[1]); | |
} | |
} | |
} | |
} | |
/** | |
* Observer for paypal standard payments cancel order | |
* | |
* @param Varien_Event_Observer $observer | |
* @throws Mage_Core_Exception | |
*/ | |
public function orderCancel(Varien_Event_Observer $observer) | |
{ | |
$payment = $observer->getEvent()->getPayment(); | |
$paymentCode = $payment->getMethod(); | |
$storeId = $payment->getOrder()->getStoreId(); | |
// check if we should handle paypal refunds | |
if (Mage::getStoreConfigFlag('paymentaddon/paypal/active', $storeId)) { | |
if ($paymentCode == "paypal_standard") { | |
// if payment is pending, then we have no money to return | |
$order = $payment->getOrder(); | |
if ($order && $order->getState() == 'pending_payment') { | |
return; | |
} | |
// instantiate our model directly instead of keeping rewrite in config (why not) | |
$paypal = Mage::getModel('paymentaddon/paypal'); | |
//$paypal = Mage::getModel('paypal/pro'); | |
if ($paypal && method_exists($paypal, 'tryCancel')) { | |
$ares = $paypal->tryCancel($payment); | |
if ($ares[0] == 0) { | |
if ($ares[1] != "") { | |
Mage::getSingleton('adminhtml/session')->addSuccess($ares[1]); | |
} | |
} elseif ($ares[0] > 1) { | |
throw new Mage_Core_Exception($ares[1]); | |
} elseif ($ares[0] < 0) { | |
throw new Mage_Core_Exception($ares[1]); | |
} | |
$payment | |
->getOrder() | |
->addStatusToHistory($payment | |
->getOrder() | |
->getStatus(), $ares[1]); | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* app/code/local/Namespace/Modulename/Model/Namespace_Modulename_Model_Paypal.php | |
*/ | |
class Namespace_Modulename_Model_Paypal extends Mage_Paypal_Model_Standard | |
{ | |
protected $_canRefund = true; | |
protected $_canRefundInvoicePartial = true; | |
protected $_canVoid = true; | |
/** | |
* https://developer.paypal.com/webapps/developer/docs/classic/api/merchant/RefundTransaction_API_Operation_NVP/ | |
*/ | |
public function tryRefund(Varien_Object $payment, $amount) | |
{ | |
$transactionId = $payment->getLastTransId(); | |
if ($transactionId) { | |
$order = $payment->getOrder(); | |
$storeId = $order->getStoreId(); | |
$refundType = "Partial"; | |
$invoiceFee = $payment->getMethodInstance()->getInfoInstance()->getAdditionalInformation('invoice_fee'); | |
$remaining = $order->getTotalInvoiced() - ($order->getTotalOfflineRefunded() + $order->getTotalOnlineRefunded()) - $invoiceFee; | |
if (abs($remaining - $amount) < 0.00001) { | |
$refundType = "Full"; | |
} | |
$currencyCode = $order->getBaseCurrencyCode(); | |
$invoiceId = $order->getIncrementId(); | |
$params = array( | |
"METHOD" => "RefundTransaction", | |
"VERSION" => "72.0", | |
"TRANSACTIONID" => $transactionId, | |
"INVOICEID" => $invoiceId, | |
"REFUNDTYPE" => $refundType, | |
"AMT" => $amount, | |
"CURRENCYCODE" => $currencyCode, | |
"USER" => Mage::getStoreConfig('paypal/wpp/api_username', $storeId), | |
"PWD" => Mage::getStoreConfig('paypal/wpp/api_password', $storeId), | |
"SIGNATURE" => Mage::getStoreConfig('paypal/wpp/api_signature', $storeId) | |
); | |
$ch = curl_init(); | |
curl_setopt($ch, CURLOPT_URL, "https://api-3t.paypal.com/nvp"); | |
curl_setopt($ch, CURLOPT_HEADER, false); | |
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); | |
curl_setopt($ch, CURLOPT_POST, true); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params)); | |
$response = curl_exec($ch); | |
if (curl_errno($ch)) { | |
curl_close($ch); | |
throw new Mage_Core_Exception('Impossible to issue a refund transaction because of cURL error.'); | |
} else { | |
curl_close($ch); | |
$responseArray = array(); | |
parse_str($response, $responseArray); // Break the NVP string to an array | |
if ($responseArray['ACK'] == "Success") { | |
return array(0, "Paypal refunded successfully"); | |
} else { | |
return array(-1, "Paypal refund failed!"); | |
} | |
} | |
} else { | |
Mage::throwException(Mage::helper('paypal')->__('Impossible to issue a refund transaction because the capture transaction does not exist.')); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment