支付效果展示
1、獲取openid
方式一:可以通過wx.login方式獲取openid
官方文檔:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html
wx.login({ success: res => { // 發送 res.code 到后台換取 openId, sessionKey, unionId if (res.code) { console.log('臨時登錄憑證code:'+res.code); wx.request({ url: 'https://api.weixin.qq.com/sns/jscode2session', data: { //填上自己的小程序唯一標識 appid: 'wxdf1bb7bb7ba9XXXX', //填上自己的小程序的 app secret secret: '4b4f1a2b1ae40c01b29aa1e595d6XXXX', grant_type: 'authorization_code', js_code: res.code }, method: 'GET', header: { 'content-type': 'application/json' }, success: function (openIdRes) { console.info(openIdRes); console.info("登錄成功返回的openId:" + openIdRes.data.openid); console.info("登錄成功返回的session_key:" + openIdRes.data.session_key); }, fail: function (error) { console.info(error); } }) } } })
方式二:通過后台獲取openid,前台需要傳入code(臨時登錄憑證),這里我們講述支付代碼用的是方式二(appid、secret最好不要放在js文件里面)
private static string sendGet(string js_code) { string url = string.Format("https://api.weixin.qq.com/sns/jscode2session?appid=" + _appid + "&secret=" + _secret + "&grant_type=authorization_code&js_code=" + js_code + ""); WebClient wc = new WebClient(); Encoding enc = Encoding.GetEncoding("UTF-8"); Byte[] pageData = wc.DownloadData(url); string re = enc.GetString(pageData); return re; }
2、統一下單
官方文檔:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1
[Route("api/[controller]")] [ApiController] public class PaymentController : ControllerBase { //所需值 public readonly static string _appid = "wx76bf5470a329XXXX";//小程序ID public readonly static string _secret = "17ccaa4f1da1d23c248a25884c7bXXXX";//小程序App/Secret public readonly static string _mch_id = "150301XXXX";//商戶號 public readonly static string _key = "49992dd11dd54545bead167681abXXXX";//微信支付的Key/Secret /// <summary> /// 模擬wx統一下單 /// </summary> /// <param name="openid">前台獲取用戶標識</param> /// <returns></returns> [HttpGet] public string GetAll(string openid, decimal amount) { if (openid == null) { return ""; } return Getprepay_id(_appid, "支付測試", "JSAPI支付測試", _mch_id, GetRandomString(30), "http://www.weixin.qq.com/wxpay/pay.php", openid, getRandomTime(), Convert.ToInt32(amount * 100)); } [HttpGet("{js_code}")] public string GetOpenId(string js_code) { if (js_code == null) { return ""; } return sendGet(js_code); } //微信統一下單獲取prepay_id & 再次簽名返回數據 private static string Getprepay_id(string appid, string attach, string body, string mch_id, string nonce_str, string notify_url, string openid, string bookingNo, int total_fee) { var url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信統一下單請求地址 string strA = "appid=" + appid + "&attach=" + attach + "&body=" + body + "&mch_id=" + mch_id + "&nonce_str=" + nonce_str + "¬ify_url=" + notify_url + "&openid=" + openid + "&out_trade_no=" + bookingNo + "&spbill_create_ip=61.50.221.43&total_fee=" + total_fee + "&trade_type=JSAPI"; string strk = strA + "&key=" + _key; //key為商戶平台設置的密鑰key(假) string strMD5 = MD5(strk).ToUpper();//MD5簽名 //簽名 var formData = "<xml>"; formData += "<appid>" + appid + "</appid>";//appid formData += "<attach>" + attach + "</attach>"; //附加數據(描述) formData += "<body>" + body + "</body>";//商品描述 formData += "<mch_id>" + mch_id + "</mch_id>";//商戶號 formData += "<nonce_str>" + nonce_str + "</nonce_str>";//隨機字符串,不長於32位。 formData += "<notify_url>" + notify_url + "</notify_url>";//通知地址 formData += "<openid>" + openid + "</openid>";//openid formData += "<out_trade_no>" + bookingNo + "</out_trade_no>";//商戶訂單號 formData += "<spbill_create_ip>61.50.221.43</spbill_create_ip>";//終端IP formData += "<total_fee>" + total_fee + "</total_fee>";//支付金額單位為(分) formData += "<trade_type>JSAPI</trade_type>";//交易類型(JSAPI--公眾號支付) formData += "<sign>" + strMD5 + "</sign>"; //簽名 formData += "</xml>"; //請求數據 var getdata = sendPost(url, formData); //獲取xml數據 XmlDocument doc = new XmlDocument(); doc.LoadXml(getdata); //xml格式轉json string json = Newtonsoft.Json.JsonConvert.SerializeXmlNode(doc); JObject jo = (JObject)JsonConvert.DeserializeObject(json); string prepay_id = jo["xml"]["prepay_id"]["#cdata-section"].ToString(); //時間戳 string _time = getTime().ToString(); //再次簽名返回數據至小程序 string strB = "appId=" + appid + "&nonceStr=" + nonce_str + "&package=prepay_id=" + prepay_id + "&signType=MD5&timeStamp=" + _time + "&key=" + _key; //wx自己寫的一個類 PaymentEntity payment = new PaymentEntity(); payment.timeStamp = _time; payment.nonceStr = nonce_str; payment.package = "prepay_id=" + prepay_id; payment.paySign = MD5(strB).ToUpper(); payment.signType = "MD5"; //向小程序返回json數據 return JsonConvert.SerializeObject(payment); } /// <summary> /// 生成隨機串 /// </summary> /// <param name="length">字符串長度</param> /// <returns></returns> private static string GetRandomString(int length) { const string key = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"; if (length < 1) return string.Empty; Random rnd = new Random(); byte[] buffer = new byte[8]; ulong bit = 31; ulong result = 0; int index = 0; StringBuilder sb = new StringBuilder((length / 5 + 1) * 5); while (sb.Length < length) { rnd.NextBytes(buffer); buffer[5] = buffer[6] = buffer[7] = 0x00; result = BitConverter.ToUInt64(buffer, 0); while (result > 0 && sb.Length < length) { index = (int)(bit & result); sb.Append(key[index]); result = result >> 5; } } return sb.ToString(); } /// <summary> /// 生成訂單號 /// </summary> /// <returns></returns> private static string getRandomTime() { Random rd = new Random();//用於生成隨機數 string DateStr = DateTime.Now.ToString("yyyyMMddHHmmssMM");//日期 string str = DateStr + rd.Next(10000).ToString().PadLeft(4, '0');//帶日期的隨機數 return str; } /// <summary> /// MD5簽名方法 /// </summary> /// <param name="inputText">加密參數</param> /// <returns></returns> private static string MD5(string inputText) { MD5 md5 = new MD5CryptoServiceProvider(); byte[] fromData = System.Text.Encoding.UTF8.GetBytes(inputText); byte[] targetData = md5.ComputeHash(fromData); string byte2String = null; for (int i = 0; i < targetData.Length; i++) { byte2String += targetData[i].ToString("x2"); } return byte2String; } /// <summary> /// wx統一下單請求數據 /// </summary> /// <param name="URL">請求地址</param> /// <param name="urlArgs">參數</param> /// <returns></returns> private static string sendPost(string URL, string urlArgs) { WebClient wCient = new WebClient(); wCient.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); byte[] postData = System.Text.Encoding.UTF8.GetBytes(urlArgs); byte[] responseData = wCient.UploadData(URL, "POST", postData); string returnStr = System.Text.Encoding.UTF8.GetString(responseData);//返回接受的數據 return returnStr; } /// <summary> /// 獲取時間戳 /// </summary> /// <returns></returns> private static long getTime() { TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0); return Convert.ToInt64(ts.TotalSeconds); } private static string sendGet(string js_code) { string url = string.Format("https://api.weixin.qq.com/sns/jscode2session?appid=" + _appid + "&secret=" + _secret + "&grant_type=authorization_code&js_code=" + js_code + ""); WebClient wc = new WebClient(); Encoding enc = Encoding.GetEncoding("UTF-8"); Byte[] pageData = wc.DownloadData(url); string re = enc.GetString(pageData); return re; } }
3、發起微信支付
上面后台代碼會返回timeStamp、nonceStr、package、signType、paySign拿到數據后傳遞給wx.requestPayme(Object object)
官方文檔:https://developers.weixin.qq.com/miniprogram/dev/api/open-api/payment/wx.requestPayment.html
JS
// pages/home/home.js Page({ data: { amount: 0 }, inputvalue: function(e) { if (e.detail.value == "") { this.setData({ amount: 0, }) } else { this.setData({ amount: e.detail.value, }) } }, //得到openid payment: function() { console.log(this.data.amount); var that = this; wx.login({ success: res => { if (res.code) { //console.log('臨時登錄憑證code:' + res.code); wx.request({ url: 'https://localhost:44302/api/payment/' + res.code, method: 'GET', header: { 'content-type': 'application/json' }, success: function(openIdRes) { console.info(openIdRes); var openid = openIdRes.data.openid; console.info("登錄成功返回的openId:" + openid); that.generateOrder(openid) }, fail: function(error) { console.info(error); } }) } } }) }, //生成商戶訂單 generateOrder: function(openid) { var that = this; wx.request({ url: 'https://localhost:44302/api/payment', data: { openid: openid + '', amount: that.data.amount }, method: 'GET', header: { 'content-type': 'application/json' }, success: function (param) { that.zf(param); }, fail: function(error) { console.info(error); } }) }, //支付 zf: function (param) { var that = this; console.log("發起支付") console.log(param) wx.requestPayment({ timeStamp: param.data.timeStamp, nonceStr: param.data.nonceStr, package: param.data.package, signType: param.data.signType, paySign: param.data.paySign, success: function (res) { console.log("success"); console.log(res); }, fail: function (res) { console.log("fail") console.log(res); }, complete: function (res) { console.log("complete"); console.log(res) } }) } })
WXML
<!--pages/home/home.wxml--> <input class="weui-input" style="margin-left: 20px;margin-right:20px;" type="number" bindinput="inputvalue" placeholder="¥請輸入充值金額" /> <view class='add_btn'> <button style="width:100vw;margin-top:20px;" bindtap="payment" class="btn"> 支付 </button> </view>
WXSS
.add_btn { width: 100%; display: flex; } .btn { background: #0072c6; color: #fff; float: right; border-radius: 0px 4px 0px 0px; }
源代碼:
鏈接:https://pan.baidu.com/s/1m4feS-XvdQsHYlWql8zQAA
提取碼:da9l
后續會陸續更新其他資料,喜歡請關注哦!