微信小程序——微信支付——申請退款(PHP語言Laravel框架)

第一步:下載微信支付sdk

下載網址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

這是微信支付商戶平臺頁面“公衆號支付”模塊裏面的sdk,app支付的sdk是不能用的。

下載好sdk之後,真正需要的文件有5個,在lib文件夾內,複製lib文件夾到你項目的某個位置即可。


第二步:下載證書cert

微信官方要求退款需要使用證書,下載證書需要登錄微信支付商戶平臺安裝並下載,步驟很簡單,按照指導或百度搜索即可解決。

下載後複製cert文件夾到你項目的某個位置即可,我這裏放到了微信支付sdk目錄,位置不影響使用即可。


第三步:修改配置文件

找到微信支付配置文件WxPay.Config.php並進行如下修改:


第四步:退款功能實現

1.路由

Route::put('api/:version/refund/refund/:id', 'api/:version.Refund/doRefund',[], ['id'=>'\d+']);

2.控制器方法

在控制器的退款類中建立doRefund方法,驗證參數id是否滿足條件,實例化Refund模型類(這個類中的refund是執行退款的方法);

// 管理後臺點擊退款按鈕,執行退款操作
    public function doRefund($id){
        if(empty($id)){
            $id = $_GET['id'];
        }
        (new IDMustBePositiveInt())->goCheck();
        $refund = new Refund($id);
        return $refund->refund();
    }

3.模型方法

在模型的退款類中建立refund方法,並進行必要驗證,通過則執行退款操作。

<?php
/**
 * Created by PhpStorm.
 * User: Admin
 * Date: 2018-05-22
 * Time: 10:51
 */

namespace app\api\service;

use app\lib\enum\OrderStatusEnum;
use app\lib\exception\OrderException;
use app\lib\exception\RefundException;
use app\lib\exception\TokenException;
use think\Exception;
use app\api\model\Refund as RefundModel;
use app\api\model\Order as OrderModel;
use think\Loader;
use think\Log;
// 引入WxPayApi.php文件,下單、查詢、退款等api方法都在此文件,其他四個文件在WxPayApi.php文件中被引入
Loader::import('WxPay.WxPay', EXTEND_PATH, '.Api.php');

class Refund
{
    private $orderNo;
    private $orderID;
    private $refundNo;
    private $refundID;

    function __construct($refundID){
        if (!$refundID){
            throw new Exception('退款單號不允許爲NULL');
        }
        $this->refundID = $refundID;
    }

    public function refund(){
        $this->checkRefundValid();
        $refund = RefundModel::where('id', '=', $this->refundID)->find();
        $order = $refund->order()->where('id', '=', $refund->oid)->find();
        if($order->status != OrderStatusEnum::AUDIT_PASS){
            throw new RefundException([
                'msg' => '退款申請不是審覈通過狀態,出現異常',
                'errorCode' => 80004,
                'code' => 400
            ]);
        }
        return $this->makeWxRefund($order->total_price, $refund->money);
    }

    // 構建微信退款訂單信息
    private function makeWxRefund($order_money, $refund_money){
        $wxRefundData = new \WxPayRefund();
        $wxRefundData->SetOut_trade_no($this->orderNo);
        $wxRefundData->SetOut_refund_no($this->refundNo);
        $wxRefundData->SetTotal_fee($order_money * 100);
        $wxRefundData->SetRefund_fee($refund_money * 100);
        $wxRefundData->SetOp_user_id(\WxPayConfig::MCHID);

        $wxRefund = \WxPayApi::refund($wxRefundData);

        // 失敗時不會返回result_code
        if($wxRefund['return_code'] != 'SUCCESS' || $wxRefund['result_code'] !='SUCCESS'){
            Log::record($wxRefund,'error');
            Log::record('退款失敗','error');
            // throw new Exception('退款失敗');
        }elseif($wxRefund['return_code'] == 'SUCCESS' || $wxRefund['result_code'] =='SUCCESS'){
            $this->updateOrderStatus();
        }
        return  $wxRefund;
    }
    //退款成功,改變訂單狀態
    private function updateOrderStatus(){
        $status = OrderStatusEnum::HAVE_A_REFUND;
        OrderModel::where('id', '=', $this->orderID)->update(['status' => $status]);
    }
    //校驗訂單並進行參數賦值
    private function checkRefundValid(){
        $refund = RefundModel::where('id', '=', $this->refundID)->find();
        $order = $refund->order()->where('id', '=', $refund->oid)->find();
        if (!$refund){
            throw new RefundException();
        }
        if(!$order){
            throw new OrderException();
        }
        if($order->user_id != $refund->uid){
            throw new TokenException([
                'msg' => '訂單與或申請退款單用戶不匹配',
                'errorCode' => 10003
            ]);
        }
        if($order->status != OrderStatusEnum::AUDIT_PASS){
            throw new RefundException([
                'msg' => '退款申請未審覈或審覈拒絕',
                'errorCode' => 80009,
                'code' => 400
            ]);
        }
        $this->orderNo = $order->order_no;
        $this->orderID = $refund->oid;
        $this->refundNo = $refund->refund_no;

        return true;
    }

}

最重要的方法就是makeWxRefund,其他的方法都可以忽略不計,只要微信退款必要的參數能夠給到。


注意可能會出現的錯誤:curl錯誤:58,這是因爲證書路徑不是絕對路徑造成的,在服務器上應該從根目錄開始找到文件的絕對路徑,如:

    E:/wamp/www/medisum/extend/WxPay/cert/apiclient_cert.pem

退款功能至此完成,如有問題,評論留言。


****************************************只要思想不滑坡,辦法總比困難多******************************************


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章