using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using OSS.Clients.Pay.Wechat;
using OSS.Clients.Pay.Wechat.Basic;
using StackExchange.Redis;
namespace New_College.Common.Helper
{
public static class WeChatPayV3
{
///
/// 扫码支付-Native下单API
///
///
public static async Task QrCodePay(string outorderNo, decimal Price, string title)
{
////使用 Native 支付,输出二维码并展示
byte[] fileStream = null;//输出图片的URL
var price = (int)(Price * 100);
var name = title + "-扫码支付";
WechatPayHelper.pay_config = new WechatPayConfig()
{
app_id = WeixinConfig.Appid,
mch_id = WeixinConfig.MCHID,
api_key = WeixinConfig.Secret,
api_v3_key = WeixinConfig.KEY,
cert_path = WeixinConfig.PrivateKey,
cert_password = WeixinConfig.MCHID
};
var nResp = await new WechatNativePayReq()
{
description = name,
out_trade_no = outorderNo,
notify_url = WeixinConfig.NotifyUrl,
amount = new WechatPayAmount() { currency = "CNY", total = price }
}
// .SetContextConfig(new WechatPayConfig(){}) // 可以设置当前上下文的配置信息,设置后本次请求将使用此配置,方便多应用的用户
//.AddOptionalBodyPara("attach","附加数据") // 添加可选参数
.SendAsync();//
//系统创建订单逻辑
//var result = await basePayApis.NativeAsync(requestData);
////进行安全签名验证
if (!string.IsNullOrEmpty(nResp.code_url))
{
fileStream = QrCodeHelper.GerQrCodeStream(nResp.code_url);
}
else
{
// fileStream = QrCodeHelper.GetTextImageStream("Native Pay 未能通过签名验证,无法显示二维码");
}
return fileStream;
}
/**
*
* 统一下单
* @param WxPaydata inputObj 提交给统一下单API的参数
* @param int timeOut 超时时间
* @throws WePayException
* @return 成功时返回,其他抛异常
*/
public static WxPayData UnifiedOrder(WxPayData inputObj, int timeOut = 60)
{
string url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
//检测必填参数
if (!inputObj.IsSet("out_trade_no"))
{
throw new Exception("缺少统一支付接口必填参数out_trade_no!");
}
else if (!inputObj.IsSet("body"))
{
throw new Exception("缺少统一支付接口必填参数body!");
}
else if (!inputObj.IsSet("total_fee"))
{
throw new Exception("缺少统一支付接口必填参数total_fee!");
}
else if (!inputObj.IsSet("trade_type"))
{
throw new Exception("缺少统一支付接口必填参数trade_type!");
}
//关联参数
if (inputObj.GetValue("trade_type").ToString() == "JSAPI" && !inputObj.IsSet("openid"))
{
throw new Exception("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!");
}
if (inputObj.GetValue("trade_type").ToString() == "NATIVE" && !inputObj.IsSet("product_id"))
{
throw new Exception("统一支付接口中,缺少必填参数product_id!trade_type为JSAPI时,product_id为必填参数!");
}
//异步通知url未设置,则使用配置文件中的url
if (!inputObj.IsSet("notify_url"))
{
inputObj.SetValue("notify_url", WeixinConfig.NotifyUrl);//异步通知url
}
inputObj.SetValue("appid", WeixinConfig.Appid);//公众账号ID
inputObj.SetValue("mch_id", WeixinConfig.MCHID);//商户号
inputObj.SetValue("spbill_create_ip", WePayConfig.IP);//终端ip
inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串
//签名
inputObj.SetValue("sign", inputObj.MakeSign());
string xml = inputObj.ToXml();
var start = DateTime.Now;
// Log.Info("XcxPayApi", "UnfiedOrder request : " + xml);
string response = HttpPost(xml, url, "application/xml", timeOut);
//Log.Info("XcxPayApi", "UnfiedOrder response : " + response);
// WebHookHelper.WebHookmarkdownSend(response);
var end = DateTime.Now;
int timeCost = (int)((end - start).TotalMilliseconds);
WxPayData result = new WxPayData();
result.FromXml(response);
// ReportCostTime(url, timeCost, result);//测速上报网络不好时使用
return result;
}
///
/// 生成随机数
///
///
public static string GenerateNonceStr()
{
return Guid.NewGuid().ToString().Replace("-", "");
}
///
/// POST请求
///
///
///
/// application/xml、application/json、application/text、application/x-www-form-urlencoded
///
///
///
public static string HttpPost(string postData, string url, string contentType = null, int timeOut = 30, Dictionary headers = null)
{
postData = postData ?? "";
var httpClientHandler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) => true
};
using (HttpClient httpClient = new HttpClient(httpClientHandler))
{
if (headers != null)
{
foreach (var header in headers)
httpClient.DefaultRequestHeaders.Add(header.Key, header.Value);
}
using (HttpContent client = new StringContent(postData, Encoding.UTF8))
{
if (contentType != null)
client.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
HttpResponseMessage response = httpClient.PostAsync(url, client).Result;
return response.Content.ReadAsStringAsync().Result;
}
}
}
}
///
///
///
public class WePayConfig
{
//=======【商户系统后台机器IP】=====================================
/* 此参数可手动配置也可在程序中自动获取
*/
public const string IP = "8.8.8.8";
//=======【代理服务器设置】===================================
/* 默认IP和端口号分别为0.0.0.0和0,此时不开启代理(如有需要才设置)
*/
public const string PROXY_URL = "";
//=======【上报信息配置】===================================
/* 测速上报等级,0.关闭上报; 1.仅错误时上报; 2.全量上报
*/
public const int REPORT_LEVENL = 1;
//=======【日志级别】===================================
/* 日志等级,0.不输出日志;1.只输出错误信息; 2.输出错误和正常信息; 3.输出错误信息、正常信息和调试信息
*/
public const int LOG_LEVENL = 3;
}
}