微信小程序支付公用类。01

朋友写的,我还没测试

微信端 post 传4个参数过去
 

return {
"total_ fee: totalPrice,//订单金额
"device_info"; app.globalData.code,//设备号 (自定义参数为销售点编码)
"body":“睿冰信息 -扫码购",//商品描述
"detail": '{"goods_detal":" + JSON.strigfy(goods_detal) +'}' //高品详细
}

 

小程序端代码

 payOrder: function () {
    var that = this;
    wx.login({
      success: function (res) {
        if (res.code) {
          var payData = that.getPayRequestData();
          if (payData.total_fee > 0) {
            that.payPlaceOrder(res.code, payData);
          }
          else {
            wx.showToast({ title: '未选择任何商品', icon: 'none', duration: 2000 });
          }
        }
        else {
          wx.showToast({ title: '获取用户登录态失败', icon: 'none', duration: 2000 });
        }
      }
    })
  },
  payPlaceOrder:function (opencode, paydata) {
    var that = this;
    wx.request({
      url: "https://ssl.raybininfo.com/WeChatPay/OrderPay?opencode=" + opencode,
      method: 'POST',
      header: {'content-type': 'application/x-www-form-urlencoded'},
      data: paydata,
      success: function (res) {
        console.log(res);
        if (res.data.error == 0) {
          that.payRequest(res.data);
        }
        else {
          wx.showToast({ title: '支付请求失败', icon: 'none', duration: 2000 });
        }
      },
      fail: function () {
          console.log("支付统一下单失败");
      }
    })
  },
  getPayRequestData: function (){
    var that = this;
    var totalPrice = that.data.totalMoney * 100;
    var goodsDetail = [];
    for (var i = 0; i < that.data.carArray.length; i++) {
      var b = that.data.carArray[i].buynum;
      if (b > 0)
      {
        var g = that.data.carArray[i].goodsid;
        var t = that.data.carArray[i].title;
        var p = that.data.carArray[i].price;
        goodsDetail.push({ "goods_id":g, "goods_name":t, "quantity":b, "price":p * 100})
      }
    }
    return {
      "total_fee": totalPrice,             //订单金额
      "device_info": app.globalData.code,  //设备号 (自定义参数为 销售点编码)
      "body":  "睿冰信息-扫码购",           //商品描述
      "detail": '{"goods_detail":' + JSON.stringify(goodsDetail) + '}' //商品详细
    }
  },
  payRequest: function (param) {
    var that = this;
    wx.requestPayment({
      timeStamp: param.timeStamp,
      nonceStr: param.nonceStr,
      package: param.package,
      signType: param.signType,
      paySign: param.paySign,
      success: function (res) {
        console.log("支付成功");
      },
      fail: function () {
        console.log("支付失败");
      }
    })
  }

后端代码

using System;
using System.IO;
using System.Data;
using System.Text;
using System.Net.Http;
using System.Xml.Linq;
using System.Text.Json;
using System.Data.SqlClient;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using System.Security.Cryptography;
using Microsoft.Extensions.Configuration;

namespace WeChatPay
{
    [ApiController]
    [Route("[controller]/[action]")]
    public class WeChatPayController : ControllerBase
    {
        private readonly string appid = "你的小程序ID";
        private readonly string secret = "小程序密钥";
        private readonly string mch_id = "支付商户ID";
        private readonly string key = "支付商户密钥";

        [HttpPost]
        public async Task<IActionResult> OrderPay() 
        { 
            string opencode = Request.Query["opencode"];
            Code2SessionInfo csModel = await GetOpenId(opencode);
            if (csModel == null) { return new JsonResult(new { errcod = 1000, errmsg = "获取openid失败" });}
            int total_fee = int.Parse(Request.Form["total_fee"]);
            string device_info = Request.Form["device_info"];
            string body = Request.Form["body"];
            string detail = Request.Form["detail"];
            return await Unifiedorder(csModel.openid, body, total_fee, device_info, detail);
        }

        private async Task<Code2SessionInfo> GetOpenId(string jscode)
        {
            string code2SessionUrl = "https://api.weixin.qq.com/sns/jscode2session?";
            code2SessionUrl += $"appid={appid}&secret={secret}&js_code={jscode}&grant_type=authorization_code";
            using var httpclient = new HttpClient();
            HttpResponseMessage response = await httpclient.GetAsync(code2SessionUrl);
            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadAsStringAsync();
                Code2SessionInfo csModel = JsonSerializer.Deserialize<Code2SessionInfo>(result);
                return csModel;
            }
            return null;
        }

        private async Task<IActionResult> Unifiedorder(string openid, string bodys, int totalfee, string deviceinfo, string detail)
        {
            //统一支付签名
            string attach = getAttach(deviceinfo, "睿冰旗舰店");
            string nonce_str = getRandomString();                                       //随机字符串,不长于32位。  
            string notify_url = "http://www.raybininfo.com/miniapp/callback.ashx";      //通知地址必填
            string out_trade_no = Guid.NewGuid().ToString("N");                         //自定义订单号必填
            string spbill_create_ip = getSpbillCreateIp();                              //终端IP
            //支付方式
            string payParameter = $"appid={appid}&attach={attach}&body={bodys}&detail={detail}&mch_id={mch_id}&nonce_str={nonce_str}&notify_url={notify_url}&openid={openid}&out_trade_no={out_trade_no}&spbill_create_ip={spbill_create_ip}&total_fee={totalfee}&trade_type=JSAPI&key={key}";
            string sign = getSign(payParameter);
            StringBuilder sbXml = new StringBuilder();
            sbXml.Append("<xml>");
            sbXml.Append($"<appid>{appid}</appid>");
            sbXml.Append($"<attach>{attach}</attach>");
            sbXml.Append($"<body>{bodys}</body>");
            sbXml.Append($"<detail>{detail}</detail>");
            sbXml.Append($"<mch_id>{mch_id}</mch_id>");
            sbXml.Append($"<nonce_str>{nonce_str}</nonce_str>");
            sbXml.Append($"<notify_url>{notify_url}</notify_url>");
            sbXml.Append($"<openid>{openid}</openid>");
            sbXml.Append($"<out_trade_no>{out_trade_no}</out_trade_no>");
            sbXml.Append($"<spbill_create_ip>{spbill_create_ip}</spbill_create_ip>");
            sbXml.Append($"<total_fee>{totalfee}</total_fee>");
            sbXml.Append($"<trade_type>JSAPI</trade_type>");
            sbXml.Append($"<sign>{sign}</sign>");
            sbXml.Append($"</xml>");
            string xml = sbXml.ToString();
            string unifiedorderUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
            var content = new StringContent(xml);
            using var httpclient = new HttpClient();
            HttpResponseMessage response = await httpclient.PostAsync(unifiedorderUrl, content);
            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadAsStringAsync();
                TextReader tr = new StringReader(result);
                XDocument xDoc = XDocument.Load(tr);
                XElement xEle = xDoc.Root.Element("return_code");               
                if (xEle.Value != "SUCCESS") { return new JsonResult (string.Empty); } 
                string prepay_id = xDoc.Root.Element("prepay_id").Value;
                TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0);
                string timestamp = Convert.ToInt64(ts.TotalSeconds).ToString();
                string paysign = $"appId={appid}&nonceStr={nonce_str}&package=prepay_id={prepay_id}&signType=MD5&timeStamp={timestamp}&key={key}";
                paysign = getSign(paysign);
                return new JsonResult ( new { error=0, timeStamp = timestamp, nonceStr = nonce_str, package = "prepay_id=" + prepay_id, signType = "MD5", paySign = paysign });
            }
            return new JsonResult(new { error=1 });
        }

        #region 获取各种参数
        private string getRandomString()
        {
            string[] text = new string[] { "A", "B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","1","2","3","4","5","6","7","8","9","0" };
            StringBuilder sb = new StringBuilder();
            Random rnd = new Random();
            for (int count = 0; count < 32; count++)
            {
                int i = rnd.Next(0, 35);
                sb.Append(text[i]);
            }
            return sb.ToString();
        }

        private string getAttach(string code, string defaultAttach) 
        {
            try
            {
                string connectionString = ConfigHelper.Configs.GetConnectionString("Connection");
                string sqlString = "SELECT [Name] FROM [SMT_Distributor] WHERE [Code]= @Code";
                using SqlConnection connection = new SqlConnection(connectionString);
                using SqlCommand command = new SqlCommand(sqlString, connection);
                SqlParameter parameter = new SqlParameter("@Code", SqlDbType.NVarChar, 10);
                parameter.Value = code;
                connection.Open();
                command.CommandType =  CommandType.Text;
                command.Parameters.Add(parameter);
                object retValue = command.ExecuteScalar();
                if (retValue == null) { return defaultAttach; }
                return retValue.ToString();
            }
            catch
            {
                return defaultAttach;
            }
        }

        private string getSpbillCreateIp()
        {
            string ip =  Request.HttpContext.Connection.RemoteIpAddress.ToString();
            return string.IsNullOrEmpty(ip) ? "127.0.0.1" : ip;
        }

        private string getSign(string parameter) 
        { 
            using var md5 = MD5.Create();
            var result = md5.ComputeHash(Encoding.UTF8.GetBytes(parameter));
            string sign = BitConverter.ToString(result).ToUpper();
            sign = sign.Replace("-", string.Empty);
            return sign;
        }
        #endregion
    }
}
posted @ 2022-03-23 08:45  离。  阅读(41)  评论(0编辑  收藏  举报