Magento Braintree支付对接(八)取消和退款

前面,我们完成了结算后,那么接下来就是退款和取消了。在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的退款和取消付款的方法结束

赞(0)
微信
支付宝
微信二维码图片

微信扫描二维码打赏

支付宝二维码图片

支付宝扫描二维码打赏

相关文章

Please Login to comment