最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于node.js實(shí)現(xiàn)微信支付退款功能

 更新時(shí)間:2017年12月19日 08:37:52   作者:Hello World 大神  
在微信開(kāi)發(fā)中有有付款就會(huì)有退款,這樣的功能非常常見(jiàn),這篇文章主要介紹了node.js實(shí)現(xiàn)微信支付退款功能,需要的朋友可以參考下

緣起

有付款就會(huì)有退款

注意,退款支持部分退款

左口袋的錢(qián)退到右口袋羅

 

這次發(fā)起的退款請(qǐng)求0.01元是實(shí)時(shí)到賬的,因此,用戶(hù)在小程序端發(fā)起的退款只是一個(gè)請(qǐng)求到后臺(tái),后臺(tái)審核人員審核無(wú)誤后才后微信發(fā)起退款操作。

引入第三方module

在package.json 中加入"weixin-pay": "^1.1.7"這一條

代碼目錄結(jié)構(gòu)

 

入?yún)?/strong>

{ transaction_id: '4200000005201712165508745023', // 交易
 out_trade_no: '5b97cba0ae164bd58dfe9e77891d3aaf', // 自己這頭的交易號(hào)
 out_refund_no: '6f3240c353934105be34eb9f2d364cec', // 退款訂單,自己生成
 total_fee: 1, // 退款總額
 nonce_str: '1xSZW0op0KcdKoMYxnyxhEuF1fAQefhU', // 隨機(jī)串
 appid: 'wxff154ce14ad59a55', // 小程序 appid
 mch_id: '1447716902', // 微信支付商戶(hù)id
 sign: '416FCB62F9B8F03C82E83052CC77524B' // 簽名,weixin-pay這個(gè)module幫助生成 }

然后由wxpay為我們生成其余字段,比如nonce_str,sign,當(dāng)然還少不了p12證書(shū),

這個(gè)早選在wxpay初始代碼里已經(jīng)配置了,pfx: fs.readFileSync(__dirname + '/../../../cert/apiclient_cert.p12'), //微信商戶(hù)平臺(tái)證書(shū)

lib/wechat/utils/wxpay.js的源碼

const WXPay = require('weixin-pay'); // 引入weixin-pay這個(gè)第三方模塊
const {weapp} = require('../../../utils/config'); // 我自己的全局配置文件,包括了appid key 等
const fs = require('fs');
const wxpay = WXPay({
 appid: weapp.APPID,
 mch_id: weapp.MCHID,
 partner_key: weapp.KEY, //微信商戶(hù)平臺(tái) API secret,非小程序 secret
 pfx: fs.readFileSync(__dirname + '/../../../cert/apiclient_cert.p12'), 
});

module.exports = wxpay;

另外還有一個(gè)util.js工具類(lèi)

用于驗(yàn)證與錯(cuò)誤回調(diào)

const wxpay = require('./wxpay');

const validateSign = results => {
 const sign = wxpay.sign(results);
 if (sign !== results.sign) {
 const error = new Error('微信返回參數(shù)簽名結(jié)果不正確');
 error.code = 'INVALID_RESULT_SIGN';
 throw error;
 };
 return results;
};

const handleError = results => {
 if (results.return_code === 'FAIL') {
 throw new Error(results.return_msg);
 }
 if (results.result_code !== 'SUCCESS') {
 const error = new Error(results.err_code_des);
 error.code = results.err_code;
 throw error;
 }
 return results;
};

module.exports = {
 validateSign,
 handleError,
};

發(fā)起退款請(qǐng)求

退款邏輯是這樣的,先從自己這邊的Order數(shù)據(jù)表中查出transaction_id/out_trade_no/total_fee,再拼上自己生成的out_refund_no退款單號(hào),本次退款部分金額refund_fee,最后由weixin-pay這個(gè)模塊下的wxpay.refund調(diào)起就可以了,成功就把訂單狀態(tài)改成"退款成功"

// 退款
router.post('/refund', function(req, res) {
 Order.findById(req.body._id, (err, order) => {
  if (err) {
   console.log(err);
  }
  console.log(order);
  // 生成微信設(shè)定的訂單格式
  var data = {
   transaction_id: order.transactionId,
   out_trade_no: order.tradeId,
   out_refund_no: uuid().replace(/-/g, ''),
   total_fee: order.amount,
   refund_fee: order.amount
  };
  console.log(data);
  // 先查詢(xún)訂單,再退訂單
  wxpay.refund(data, (err, result) => {
   if (err) {
    console.log(err);
    res.send(
     utils.json({
      code: 500,
      msg: '退款失敗'
     })
    );
   }
   // 返回退款請(qǐng)求成功后,要將訂單狀態(tài)改成REFUNDED
   if (result.result_code === 'SUCCESS') {
    console.log(result);
    order.status = 'REFUNDED';
    order.save((err, response) => {
     res.send(
      utils.json({
       msg: '退款成功'
      })
     );
    });
   } else {
    res.send(
     utils.json({
      code: 500,
      msg: result.err_code_des
     })
    );
   }

  });
 });
});

入?yún)⒌目?/strong>

1.這次遇到的坑是refund_fee忘記傳值,也就是說(shuō)微信退款是支持部分退款的,如果是全額退款,那么將它賦值為total_fee相同

2.網(wǎng)上說(shuō)的op_user_id: weapp.MCHID這個(gè)參數(shù)是非必選的

3.transaction_id 與 out_trade_no 二選一即可,這樣在沒(méi)有記錄transaction_id的情況(比如沒(méi)有寫(xiě)支付成功的callback)下,也能發(fā)起退款;其中優(yōu)先級(jí)前者大于后者,在我在分別前其一故意給錯(cuò)的過(guò)程中得到了驗(yàn)證。

4.報(bào)了一個(gè)appid與商戶(hù)號(hào)不匹配的報(bào)錯(cuò),return_code: 'FAIL', return_msg: '商戶(hù)號(hào)mch_id與appid不匹配'原來(lái)是小程序還沒(méi)綁定公眾號(hào)微信支付,這真是一個(gè)烏龍。

成功退款微信返回的數(shù)據(jù)

 appid:"wxff154ce14ad59a55"
 cash_fee:"1"
 cash_refund_fee:"1"
 coupon_refund_count:"0"
 coupon_refund_fee:"0"
 mch_id:"1447716902"
 nonce_str:"c44wOvB6a4bQJfRk"
 out_refund_no:"9ace1466432a4d548065dc8df95d904a"
 out_trade_no:"5b97cba0ae164bd58dfe9e77891d3aaf"
 refund_channel:""
 refund_fee:"1"
 refund_id:"50000705182017121702756172970"
 result_code:"SUCCESS"
 return_code:"SUCCESS"
 return_msg:"OK"
 sign:"5C2E67B3250054E8A665BF1AE2E9BDA3"
 total_fee:"1"
 transaction_id:”4200000005201712165508745023”

重復(fù)退款將返回如下

 appid:"wxff154ce14ad59a55"
 err_code:"ERROR"
 err_code_des:"訂單已全額退款"
 mch_id:"1447716902"
 nonce_str:"KP1YWlU7a5viZEgK"
 result_code:"FAIL"
 return_code:"SUCCESS"
 return_msg:"OK"
 sign:”C2A7DED787BEA644C325E37D96E9F41C”

 

最后

如果沒(méi)有寫(xiě)退款功能或者不想寫(xiě)退款功能怎么辦,其實(shí)可以從微信支付的后臺(tái)pay.weixin.qq.com,也是能退款出去的,只是不想忘記了要人工將訂單狀態(tài)置為退款狀態(tài)。

總結(jié)

以上所述是小編給大家介紹的基于node.js實(shí)現(xiàn)微信支付退款功能,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Node.js中,在cmd界面,進(jìn)入退出Node.js運(yùn)行環(huán)境的方法

    Node.js中,在cmd界面,進(jìn)入退出Node.js運(yùn)行環(huán)境的方法

    今天小編就為大家分享一篇Node.js中,在cmd界面,進(jìn)入退出Node.js運(yùn)行環(huán)境的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • node基于puppeteer模擬登錄抓取頁(yè)面的實(shí)現(xiàn)

    node基于puppeteer模擬登錄抓取頁(yè)面的實(shí)現(xiàn)

    本篇文章主要介紹了node基于puppeteer模擬登錄抓取頁(yè)面的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • Node.js的cross-env工具包使用介紹

    Node.js的cross-env工具包使用介紹

    這篇文章主要為大家介紹了Node.js的cross-env工具包使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • 解決npm?install版本不匹配問(wèn)題:?npm?ERR!?code?ETARGET?npm?ERR!?notarget?No?matching?version?found?for

    解決npm?install版本不匹配問(wèn)題:?npm?ERR!?code?ETARGET?npm?ERR!?

    這篇文章主要介紹了如何解決npm?install版本不匹配問(wèn)題:?npm?ERR!?code?ETARGET?npm?ERR!?notarget?No?matching?version?found?for,文中給出了詳細(xì)的解決方法,需要的朋友可以參考下
    2024-02-02
  • koa2 數(shù)據(jù)api中間件設(shè)計(jì)模型的實(shí)現(xiàn)方法

    koa2 數(shù)據(jù)api中間件設(shè)計(jì)模型的實(shí)現(xiàn)方法

    這篇文章主要介紹了koa2 數(shù)據(jù)api中間件設(shè)計(jì)模型的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • node.js通過(guò)Sequelize 連接MySQL的方法

    node.js通過(guò)Sequelize 連接MySQL的方法

    這篇文章主要介紹了node.js通過(guò)Sequelize 連接MySQL的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Node.js中的child_process模塊詳解

    Node.js中的child_process模塊詳解

    這篇文章主要給大家介紹了關(guān)于Node.js中child_process模塊的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-06-06
  • Node.js接入DeepSeek實(shí)現(xiàn)流式對(duì)話功能

    Node.js接入DeepSeek實(shí)現(xiàn)流式對(duì)話功能

    隨著人工智能技術(shù)的發(fā)展,越來(lái)越多的服務(wù)和應(yīng)用開(kāi)始集成AI能力以提升用戶(hù)體驗(yàn),本文將介紹如何通過(guò)Node.js接入DeepSeek提供的API服務(wù),特別是其聊天完成(Chat?Completions)功能,為您的應(yīng)用增添智能對(duì)話能力,需要的朋友可以參考下
    2025-02-02
  • 詳解express + mock讓前后臺(tái)并行開(kāi)發(fā)

    詳解express + mock讓前后臺(tái)并行開(kāi)發(fā)

    這篇文章主要介紹了詳解express + mock讓前后臺(tái)并行開(kāi)發(fā),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • 從零開(kāi)始學(xué)習(xí)Node.js

    從零開(kāi)始學(xué)習(xí)Node.js

    這篇文章主要介紹了從零開(kāi)始學(xué)習(xí)Node.js結(jié)合具體實(shí)例形式分析了使用方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下,希望能夠給你帶來(lái)幫助
    2021-09-09

最新評(píng)論

定南县| 洪湖市| 浦城县| 温州市| 清新县| 呼伦贝尔市| 盘山县| 汝阳县| 攀枝花市| 东山县| 渝中区| 遂昌县| 隆回县| 南岸区| 云阳县| 大英县| 汨罗市| 闵行区| 芜湖市| 深州市| 神池县| 洛南县| 永靖县| 洛浦县| 资阳市| 铜鼓县| 盐山县| 壤塘县| 丰城市| 灵台县| 大英县| 松江区| 吴旗县| 徐州市| 都匀市| 滕州市| 闻喜县| 久治县| 海阳市| 蓝田县| 巍山|