朋友写的,我还没测试
微信端 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}¬ify_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
}
}