微信小程序支付及退款流程詳解【下】 - 新聞資訊 - 雲南小程序開發|雲南軟件開發|雲南網站建設-昆明融晨信息技術有限公司

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不(bù)管是(shì)網站,軟件還是(shì)小程序,都要(yào / yāo)直接或間接能爲(wéi / wèi)您産生價值,我們在(zài)追求其視覺表現的(de)同時(shí),更側重于(yú)功能的(de)便捷,營銷的(de)便利,運營的(de)高效,讓網站成爲(wéi / wèi)營銷工具,讓軟件能切實提升企業内部管理水平和(hé / huò)效率。優秀的(de)程序爲(wéi / wèi)後期升級提供便捷的(de)支持!

您當前位置>首頁 » 新聞資訊 » 小程序相關 >

微信小程序支付及退款流程詳解【下】

發表時(shí)間:2021-3-31

發布人(rén):融晨科技

浏覽次數:140

微信小程序支付及退款流程詳解【上(shàng)】中講了(le/liǎo)微信支付的(de)相關流程。在(zài)理清思路後,流程還是(shì)比較清晰和(hé / huò)簡單的(de)。重點在(zài)于(yú)需要(yào / yāo)注意一些細節問題,例如數據格式,加密方法等。

下面說(shuō)一下微信小程序退款的(de)具體實現

二.退款

小程序退款的(de)流程和(hé / huò)付款相似,但有一些細節上(shàng)的(de)不(bù)同。

首先退款的(de)步驟通常如下:

  1. 用戶前端點擊退款按鈕後,後端接收到(dào)用戶的(de)退款請求通過商城後台呈現給商戶,商戶确定允許退款後,後端再發起向微信退款接口的(de)請求來(lái)請求退款。
  2. 後端向微信退款接口發送請求後,得到(dào)響應信息,确定退款是(shì)否完成,根據退款是(shì)否完成再去進行改變訂單狀态等業務邏輯。

退款的(de)步驟相對微信支付來(lái)說(shuō)比較簡單。

值得注意的(de)有以(yǐ)下兩點:
1.向微信退款接口請求退款後,根據得到(dào)的(de)響應是(shì)可以(yǐ)直接确定退款是(shì)否完成的(de)。不(bù)再需要(yào / yāo)設置專門的(de)回調接口等待微信通知。當然如果需要(yào / yāo)也(yě)是(shì)可以(yǐ)在(zài)微信商戶平台設置回調接口接受從而(ér)接受微信回調的(de),但并不(bù)是(shì)必須的(de)。
2.退款請求需要(yào / yāo)在(zài)請求服務器安裝微信提供的(de)安全證書,也(yě)就(jiù)是(shì)說(shuō),發起退款請求相比較支付請求在(zài)請求時(shí)請求方法不(bù)能複用,因爲(wéi / wèi)微信退款需要(yào / yāo)攜帶證書的(de)請求,此證書可在(zài)申請微信商戶号成功後從微信商戶平台自行下載,Linux下的(de)PHP開發環境的(de)證書隻需要(yào / yāo)放在(zài)網站根目錄的(de)cert文件夾中即可。其他(tā)開發環境可能需要(yào / yāo)導入操作。

下面講解一下退款的(de)具體步驟

一. 用戶發起退款請求

    用戶在(zài)前端發起退款請求,後端接收到(dào)退款請求,将相應訂單标記爲(wéi / wèi)申請退款,展示在(zài)後台.商戶查看後,如果同意退款再進行相應操作.此後才進入真正的(de)退款流程.

二. 商戶發起退款請求

    商戶同意退款後,後端即向微信提供的(de)退款 API 發起請求.
    同請求微信支付API一樣.退款請求也(yě)需要(yào / yāo)将需要(yào / yāo)的(de)參數進行簽名後以(yǐ)XML發送到(dào)微信的(de)退款API [https://api.mch.weixin.qq.com/pay/refund](https://api.mch.weixin.qq.com/pay/refund)

退款請求需要(yào / yāo)的(de)參數如下(多個(gè)參數在(zài)支付API請求時(shí)也(yě)有使用):

  1. 小程序 appid。
  2. 商戶号 mch_id 。申請開通微信支付商戶認證成功後微信發給你的(de)郵件裏有
  3. 商戶訂單号 out_trade_no 。退款訂單在(zài)支付時(shí)生成的(de)訂單号
  4. 退款訂單号 out_refund_no 。由後端生成的(de)退款單号,需要(yào / yāo)保證唯一,因爲(wéi / wèi)多個(gè)同樣的(de)退款單号隻會退款一次。
  5. 總金額 total_fee 。訂單總金額,單位爲(wéi / wèi)分。
  6. 退款金額 refund_fee 需要(yào / yāo)退款的(de)金額,單位同樣爲(wéi / wèi)分
  7. 操作員 op_user_id .與商戶号相同即可
  8. 随機字符串 nonce_str 。同支付請求
  9. 簽名 sign 。使用上(shàng)面的(de)所有參數進行相應處理加密生成簽名。(具體處理方式與支付相同,可直接複用。)

三. 退款完成

    在(zài)發起退款請求後,就(jiù)可以(yǐ)直接根據請求的(de)響應XML中的(de)  result_code字段來(lái)判斷退款是(shì)否成功,從而(ér)對訂單狀态進行處理和(hé / huò)後續操作。不(bù)需要(yào / yāo)像支付那樣等待另一個(gè)接口的(de)通知來(lái)确定請求狀态。當然如上(shàng)文所說(shuō),如果需要(yào / yāo)微信服務器發送通知到(dào)後端的(de)話,可以(yǐ)到(dào)微信商戶平台進行設置。
    

退款因爲(wéi / wèi)流程與支付大(dà)同小異,因此退款的(de)PHP類我選擇了(le/liǎo)直接繼承支付類,
代碼如下,注意區分退款請求方法postXmlSSLCurl和(hé / huò)支付請求方法postXmlCurl的(de)區别,這(zhè)也(yě)就(jiù)是(shì)上(shàng)文提到(dào)的(de)退款需要(yào / yāo)的(de)雙向證書的(de)使用。
````

 class WinXinRefund extends WeiXinPay{
    protected \$SSLCERT_PATH = 'cert/apiclient_cert.pem';//證書路徑
    protected \$SSLKEY_PATH =  'cert/apiclient_key.pem';//證書路徑
    protected \$opUserId = '1234567899';//商戶号
    
function __construct($openid,$outTradeNo,$totalFee,$outRefundNo,$refundFee){
    //初始化退款類需要(yào / yāo)的(de)變量
    $this->openid = $openid;
    $this->outTradeNo = $outTradeNo;
    $this->totalFee = $totalFee;
    $this->outRefundNo = $outRefundNo;
    $this->refundFee = $refundFee;
} 

public function refund(){
    //對外暴露的(de)退款接口
    $result = $this->wxrefundapi();
    return $result;
}

private function wxrefundapi(){
    //通過微信api進行退款流程
    $parma = array(
        'appid'=> $this->APPID,
        'mch_id'=> $this->MCHID,
        'nonce_str'=> $this->createNoncestr(),
        'out_refund_no'=> $this->outRefundNo,
        'out_trade_no'=> $this->outTradeNo,
        'total_fee'=> $this->totalFee,
        'refund_fee'=> $this->refundFee,
        'op_user_id' => $this->opUserId,
    );
    $parma['sign'] = $this->getSign($parma);
    $xmldata = https://www.wxapp-union.com/$this->arrayToXml($parma);
    $xmlresult = $this->postXmlSSLCurl($xmldata,'https://api.mch.weixin.qq.com/secapi/pay/refund');
    $result = $this->xmlToArray($xmlresult);
    return $result;
}

//需要(yào / yāo)使用證書的(de)請求
function postXmlSSLCurl($xml,$url,$second=30)
{
    $ch = curl_init();
    //超時(shí)時(shí)間
    curl_setopt($ch,CURLOPT_TIMEOUT,$second);
    //這(zhè)裏設置代理,如果有的(de)話
    //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
    //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
    curl_setopt($ch,CURLOPT_URL, $url);
    curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
    curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
    //設置header
    curl_setopt($ch,CURLOPT_HEADER,FALSE);
    //要(yào / yāo)求結果爲(wéi / wèi)字符串且輸出(chū)到(dào)屏幕上(shàng)
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
    //設置證書
    //使用證書:cert 與 key 分别屬于(yú)兩個(gè).pem文件
    //默認格式爲(wéi / wèi)PEM,可以(yǐ)注釋
    curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
    curl_setopt($ch,CURLOPT_SSLCERT, $this->SSLCERT_PATH);
    //默認格式爲(wéi / wèi)PEM,可以(yǐ)注釋
    curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
    curl_setopt($ch,CURLOPT_SSLKEY, $this->SSLKEY_PATH);
    //post提交方式
    curl_setopt($ch,CURLOPT_POST, true);
    curl_setopt($ch,CURLOPT_POSTFIELDS,$xml);
    $data = https://www.wxapp-union.com/curl_exec($ch);
    //返回結果
    if($data){
        curl_close($ch);
        return $data;
    }
    else {
        $error = curl_errno($ch);
        echo "curl出(chū)錯,錯誤碼:$error"."<br>";
        curl_close($ch);
        return false;
    }
}}

三. 總結

以(yǐ)上(shàng)就(jiù)是(shì)關于(yú)微信支付和(hé / huò)退款的(de)流程及相關知識的(de)介紹。文中的(de) PHP類 均封裝直接可用。
因爲(wéi / wèi)微信支付和(hé / huò)退款涉及的(de)東西較爲(wéi / wèi)繁雜,很多人(rén)直接看官方文檔可能會一頭霧水,所以(yǐ)看過此文了(le/liǎo)解流程和(hé / huò)要(yào / yāo)點後,再去看微信官方文檔。一方面可以(yǐ)更清晰的(de)了(le/liǎo)解小程序的(de)支付和(hé / huò)退款流程。另一方面,本文因爲(wéi / wèi)篇幅有限及作者能力有限,肯定有無暇顧及或有所纰漏之(zhī)處。爲(wéi / wèi)求穩妥,還是(shì)需要(yào / yāo)多看看官方開發文檔。畢竟事涉支付,出(chū)個(gè)BUG可不(bù)是(shì)小事。
最後扯點閑話吧。這(zhè)篇博客本來(lái)應該在(zài)三個(gè)月前就(jiù)發表的(de),也(yě)算當時(shí)我從一無所知到(dào)獨立完成微信小程序商城前後端的(de)總結系列的(de)第一篇。但是(shì)公司突然出(chū)現人(rén)員和(hé / huò)項目的(de)變動,導緻管理和(hé / huò)項目上(shàng)都混亂不(bù)堪,再加上(shàng)個(gè)人(rén)的(de)惰性,導緻此篇博客一直拖到(dào)三個(gè)月後的(de)今天才斷斷續續寫完。這(zhè)三個(gè)月我的(de)心态因爲(wéi / wèi)各種事起起伏伏,也(yě)頗有一番風味。
借用李志的(de)一句歌詞結束這(zhè)篇博客吧。下一篇是(shì)什麽時(shí)候也(yě)說(shuō)不(bù)定了(le/liǎo),我苦笑。

我再也(yě)不(bù)會把自己,愚蠢的(de)交給過去。我的(de)生活和(hé / huò)我的(de)想法,從此相隔萬裏。

相關案例查看更多