先吐槽下微信的文檔和demo,重要的步驟信息沒有強調清楚,.net的demo就沒有跑成功過。php
1.微信掃碼登陸html
2.微信PC端支付api
幾經摸索才走通這個退款功能。下面介紹下微信支付退款功能的開發步驟:安全
1、下載證書並導入到系統微信
微信退款是須要證書的,這個證書不是官方demo中的證書,而是須要本身在微信商戶平臺中的api安全欄下載的證書,在官方的證書使用實例的一個word文檔看到下面話:C#有一點須要注意,除了在代碼中使用apiclient_cert.p12以外還須要將該證書導入操做系統才能使用,一、代碼中使用、;二、導入操做系統,兩者缺一不可。.NET版本須要大於2.0 以前就是不知道這兩步,浪費了太多時間。因此先下載證書:網絡
下載的時候須要手機驗證及登陸密碼。下載後找到apiclient_cert.p12這個證書,雙擊導入,導入的時候提示輸入密碼,這個密碼就是商戶ID,且必須是在本身的商戶平臺下載的證書。不然會出現密碼錯誤的提示:app
導入正確的提示:微信支付
2、代碼退款ui
這個地方能夠直接用官方demo中的代碼,demo下載url
須要修改WxPayConfig中的幾個參數:
public const string APPID = "wxf6dd794bcexxxx"; public const string MCHID = "xxxx"; public const string KEY = "xxxxx849ba56abbe56e05xxxxx"; public const string APPSECRET = "---"; //=======【證書路徑設置】===================================== /* 證書路徑,注意應該填寫絕對路徑(僅退款、撤銷訂單時須要) */ public const string SSLCERT_PATH = "/WxPayAPI/cert/apiclient_cert.p12"; public const string SSLCERT_PASSWORD = "131xxxx";
上面的SSLCERT_PASSWORD就是MCHID,也就是商戶ID,SSLCERT_PASSWORD錯誤會出現指定的網絡密碼不正確的提示:
接下來在控制器中增長一個退款方法,包含微信訂單號、商戶訂單號、總金額和退款金額。商戶訂單號和微信訂單號二選一。詳細參數
public ActionResult DoRefund() { string result = Refund.Run("","131667780120trade_no", "1", "1"); return Content(result); }
Refund類的Run方法:
/*** * 申請退款完整業務流程邏輯 * @param transaction_id 微信訂單號(優先使用) * @param out_trade_no 商戶訂單號 * @param total_fee 訂單總金額 * @param refund_fee 退款金額 * @return 退款結果(xml格式) */ public static string Run(string transaction_id, string out_trade_no, string total_fee, string refund_fee) { Logger.Info("Refund is processing..."); WxPayData data = new WxPayData(); if (!string.IsNullOrEmpty(transaction_id))//微信訂單號存在的條件下,則已微信訂單號爲準 { data.SetValue("transaction_id", transaction_id); } else//微信訂單號不存在,才根據商戶訂單號去退款 { data.SetValue("out_trade_no", out_trade_no); } data.SetValue("total_fee", int.Parse(total_fee));//訂單總金額 data.SetValue("refund_fee", int.Parse(refund_fee));//退款金額 data.SetValue("out_refund_no", out_trade_no);//隨機生成商戶退款單號 data.SetValue("op_user_id", WxPayConfig.MCHID);//操做員,默認爲商戶號 WxPayData result = WxPayApi.Refund(data);//提交退款申請給API,接收返回數據 Logger.Info("Refund process complete, result : " + result.ToXml()); return result.ToPrintStr(); }
Refund:方法
/** * * 申請退款 * @param WxPayData inputObj 提交給申請退款API的參數 * @param int timeOut 超時時間 * @throws WxPayException * @return 成功時返回接口調用結果,其餘拋異常 */ public static WxPayData Refund(WxPayData inputObj, int timeOut = 6) { string url = "https://api.mch.weixin.qq.com/secapi/pay/refund"; //檢測必填參數 if (!inputObj.IsSet("out_trade_no") && !inputObj.IsSet("transaction_id")) { throw new WxPayException("退款申請接口中,out_trade_no、transaction_id至少填一個!"); } else if (!inputObj.IsSet("out_refund_no")) { throw new WxPayException("退款申請接口中,缺乏必填參數out_refund_no!"); } else if (!inputObj.IsSet("total_fee")) { throw new WxPayException("退款申請接口中,缺乏必填參數total_fee!"); } else if (!inputObj.IsSet("refund_fee")) { throw new WxPayException("退款申請接口中,缺乏必填參數refund_fee!"); } else if (!inputObj.IsSet("op_user_id")) { throw new WxPayException("退款申請接口中,缺乏必填參數op_user_id!"); } inputObj.SetValue("appid", WxPayConfig.APPID);//公衆帳號ID inputObj.SetValue("mch_id", WxPayConfig.MCHID);//商戶號 inputObj.SetValue("nonce_str", Guid.NewGuid().ToString().Replace("-", ""));//隨機字符串 inputObj.SetValue("sign", inputObj.MakeSign());//簽名 string xml = inputObj.ToXml(); var start = DateTime.Now; Log.Debug("WxPayApi", "Refund request : " + xml); string response = HttpService.Post(xml, url, true, timeOut);//調用HTTP通訊接口提交數據到API Log.Debug("WxPayApi", "Refund response : " + response); var end = DateTime.Now; int timeCost = (int)((end - start).TotalMilliseconds);//得到接口耗時 //將xml格式的結果轉換爲對象以返回 WxPayData result = new WxPayData(); result.FromXml(response); ReportCostTime(url, timeCost, result);//測速上報 return result; }
生產環境中記得修改爲本身的參數。若是參數都正確,將會返回:
並且,微信立刻回收到退款通知:
小結:至此,退款功能已經走通,其實若是參數和流程對了,這個地方仍是很簡單的,微信的規定是能夠申請一年內交易的退款。可是又有個問題,虛擬空間中怎麼導入證書呢,仍是要換雲?