前面,我们完成了结算后,那么接下来就是退款和取消了。在braintree,退款和取消都有对应的方法。不像别的支付,退款和取消只能在支付的后台操作,操作完后通过回调来通知Magento。
Braintree提供了退款和取消的方法
退款和取消付款
什么时候可以取消,什么时候可以退款。这个判断的标准是通过订单的状态来完成的
编辑: app\code\local\Braintree\PaymentMethod\Model\Creditcard.php
添加方法:braintreeRefundOrVoid()
/**
* 退款
* https://developers.braintreepayments.com/reference/request/transaction/refund/php
* 取消
* https://developers.braintreepayments.com/reference/request/transaction/void/php
* $orderId int 订单编号id
* $transaction_Id int 订单在Braintree的id
* $manager string 名称,如果本方法是用于api调用,传api的名称,如果是magento后台调用,则不用传
* $money 退款的金额,用于部分退款,全额退款不需要此参数
* == 返回参数说明 ==
* Braintree 的退款,
* 1.会重新生成一个退款订单,所以会生成新的transaction_Id,返回的状态是Submitted For Settlement,退款完成的状态是Settled,
* 2.返回的订单的类型type是Credit,返回退款的具体金额。
* 3.新的订单会有refundedTransactionId参数作为关联旧订单。
* 4.发起退款旧的订单状态、类型、金额都不变,只是会新增一个退款详情信息。
* 5.部分退款每次发起退款都会生成一个新的订单!!!
* Braintree 的取消,
* 1.返回的状态是Voided,类型和金额不变,不会生成新的订单
*/
public function braintreeRefundOrVoid($orderId,$transaction_Id,$manager='',$money = 0){
$order = Mage::getSingleton('sales/order')->loadByIncrementId($orderId);
if(!$order->getId() || $transaction_Id != $order->getPayment()->getLastTransId()){
//不存在订单,订单transaction_id与提交过来的transaction_id不一致时,返回错误信息
return $this->_helper()->__('Incorrect order information');
}
//判断magento后台是否登录
if(Mage::getSingleton('admin/session')->isLoggedIn()){
$manager = Mage::getModel('admin/Session')->getUser()->getUsername();
}
try {
$transaction = $this->orderInquiry($transaction_Id);//查找交易
switch ($transaction->status) {//获取交易状态
case 'settling':
case 'settled':
if($transaction->type == 'credit'){//判断是否已经退款
return $this->_helper()->__('A refund request has been submitted for this order');
}
//如果交易已经结算:调用退款逻辑
if ($money) {
if ($money > $transaction->amount) {
//退款金额不能大于交易金额
return $this->_helper()->__('No more than the transaction amount allowed.');
}
//部分退款
$result = $this->getGateway()->transaction()->refund($transaction_Id, $money);
Mage::log('部分退款', null, "braintree_payment.log");
Mage::log(print_r($result, 1), null, "braintree_payment.log");
if ($result->success) {
//写入交易记录
$payment = $order->getPayment();
try {
$payment->setTransactionId($result->transaction->id)
->setParentTransactionId($result->transaction->refundedTransactionId)
->setIsTransactionClosed(true)//true
->registerRefundNotification($result->transaction->amount);
$order->save();
//部分退款不需要更改订单状态
//写入退款操作记录
$message = $this->_helper()->__('Manager:"%s" Partial Refunding... Brintree Status:"%s" Braintree Type:%s".', $manager, $result->transaction->status,$result->transaction->type);
$order->addStatusHistoryComment($message)
->setIsCustomerNotified(false)
->save();
} catch (Exception $e) {
Mage::log('partial err'.$order->getIncrementId().'===='.$result->transaction->refundedTransactionId.'#'.$e,null,'braintree_payment.log');
}
return 'refund';
} else {
// $result->errors;//官方写法,返回的是array,不适用
Mage::log($manager . ' Refund ' . $transaction_Id . ', Err:' . $result->message, null, "braintree_payment.log");
$message = $this->_helper()->__('Manager:"%s" Try Partial Refund amount %s. Brintree Err:"%s".', $manager, $result->transaction->amount, $result->message);
//写入退款操作记录
$order->addStatusHistoryComment($message, $order->getStatus())
->setIsCustomerNotified(false)
->save();
return $result->message;//测试后,用此方式,直接返回错误提示文字
}
} else {
//全额退款
$result = $this->getGateway()->transaction()->refund($transaction_Id);
Mage::log('退款', null, "braintree_payment.log");
Mage::log(print_r($result, 1), null, "braintree_payment.log");
if ($result->success) {
Mage::log('0', null, "braintree_payment.log");
Mage::log($manager . ' Refunded ' . $result->transaction->id . ', Parentid:' . $result->transaction->refundedTransactionId . ' Money:' . $result->transaction->amount, null, "braintree_payment.log");
Mage::log('1', null, "braintree_payment.log");
//写入交易记录
$payment = $order->getPayment();
try {
$payment->setTransactionId($result->transaction->id)
->setParentTransactionId($result->transaction->refundedTransactionId)
->setIsTransactionClosed(true)//true
->registerRefundNotification($result->transaction->amount);
//更改订单状态为退款
$order->setState(Hooya_Sales_Model_Order::STATE_REFUNDED, true);
$order->save();
Mage::log('4', null, "braintree_payment.log");
//写入退款操作记录
$message = $this->_helper()->__('Manager:"%s" Refunding... Brintree Status:"%s" Braintree Type:%s".', $manager, $result->transaction->status,$result->transaction->type);
$order->addStatusHistoryComment($message)
->setIsCustomerNotified(false)
->save();
} catch (Exception $e) {
Mage::log('full err'.$order->getIncrementId().'===='.$result->transaction->refundedTransactionId.'#'.$e,null,'braintree_payment.log');
}
Mage::log('2', null, "braintree_payment.log");
# Transaction successfully voided
return 'refund';
} else {
// $result->errors;//官方写法,返回的是array,不适用
Mage::log($manager . ' Refund ' . $transaction_Id . ', Err:' . $result->message, null, "braintree_payment.log");
$message = $this->_helper()->__('Manager:"%s" Try Refund amount %s. Brintree Err:"%s".', $manager, $result->transaction->amount, $result->message);
//写入退款操作记录
$order->addStatusHistoryComment($message, $order->getStatus())
->setIsCustomerNotified(false)
->save();
return $result->message;//测试后,用此方式,直接返回错误提示文字
}
}
break;
case 'authorized':
case 'submitted_for_settlement':
case 'settlement_pending':// (only for certain PayPal transactions)
//如果交易尚未开始结算:调用无效交易逻辑,无法设置退款金额,只能取消付款
$result = $this->getGateway()->transaction()->void($transaction_Id);
if ($result->success) {
Mage::log($manager . ' Refunded(void) ' . $result->transaction->id . ', Money:' . $result->transaction->amount, null, "braintree_payment.log");
# Transaction successfully voided
$message = $this->_helper()->__('Manager:"%s" Refunding... Brintree(void) Status:"%s".', $manager, $result->transaction->status);
$order->addStatusHistoryComment($message, $order->getStatus())
->setIsCustomerNotified(false)
->save();
//voided的交易,将订单状态更新为canceled
$order->setState(Mage_Sales_Model_Order::STATE_CANCELED, true);
$order->save();
return 'void';
} else {
// return $result->errors;//官方接口写法,可能是返回array的数据
return $result->message;//参见refund接口的数据,直接返回此值能显示错误提示,而非array格式
}
break;
default:
//其它情况返回不能处理结果
Mage::log($manager . ' Status:' . $transaction->status . $this->_helper()->__('transaction can not refunded'), null, "braintree_payment.log");//日志
$message = $this->_helper()->__('Manager:"%s", Brintree Status:"%s". Transaction:"%s" %s.', $manager, $transaction->status, $transaction_Id, $this->_helper()->__('can not canceled'));
$order->addStatusHistoryComment($message, $order->getStatus())
->setIsCustomerNotified(false)
->save();//后台写入退款操作记录
return $transaction->status . $this->_helper()->__('transaction can not canceled');
break;
}
} catch (Exception $e) {
}
}
到此,braintree的退款和取消付款的方法结束