微信支付
微信支付各种解决方案已经写了无数遍了,这次我们来点不一样的
如何不一样呢?
回调出现的XML字符串可以反序列化成对象进行处理
并且能让返回值序列化成对应的XML字符串返回给微信
本次,我们会依赖两个类库
类库 | 用途 |
---|---|
Newtonsoft.Json | 用来序列化和反序列化各种账号配置 |
Senparc.Weixin.TenPay | 用来生成微信支付签名,混淆,时间戳等 |
##抽离脚手架
XML字符串序列化和反序列化
/// <summary>
/// Xml帮助类
/// </summary>
public class XmlHelper
{
/// <summary>
/// 将Xml字符串反序列化成对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="xmlStr"></param>
/// <returns></returns>
public static T Deserialize<T>(string xmlStr) where T : new()
{
if (string.IsNullOrWhiteSpace(xmlStr)) return default(T);
using (MemoryStream ms1 = new MemoryStream(Encoding.UTF8.GetBytes(xmlStr)))
{
XmlSerializer xs = new XmlSerializer(typeof(T));
var obj = (T)xs.Deserialize(ms1);
return obj;
}
}
/// <summary>
/// 将对象序列化成Xml字符串
/// 特性配置注意参考以下两个类
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="data"></param>
/// <returns></returns>
public static string Serialize<T>(T data) where T : new()
{
XmlSerializer xs = new XmlSerializer(data.GetType());
var xml = string.Empty;
using (MemoryStream writer = new MemoryStream())
{
xs.Serialize(writer, data);
xml = Encoding.UTF8.GetString(writer.GetBuffer());
}
return xml;
}
}
Json字符串序列化和反序列化
public static class JsonHelper
{
private static readonly JsonConverter[] JavaScriptConverters = new JsonConverter[] { new DateTimeConverter() };
public static string Serialize(object data)
{
return JsonConvert.SerializeObject(data, JavaScriptConverters);
}
public static object Deserialize(string json, Type targetType)
{
return JsonConvert.DeserializeObject(json, targetType);
}
public static T Deserialize<T>(string json)
{
return !string.IsNullOrWhiteSpace(json) ? JsonConvert.DeserializeObject<T>(json) : default(T);
}
}
internal class DateTimeConverter : Newtonsoft.Json.Converters.DateTimeConverterBase
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(((DateTime)value).ToString("yyyy/MM/dd HH:mm:ss"));
}
}
JSAPI 统一下单 调起支付
/// <summary>
/// 微信支付下单
/// JsAPI下单部分
/// </summary>
/// <param name="reqmodel"></param>
/// <returns></returns>
public UnifiedOrderModelForJSAPI WxPayUnifiedOrderForJSAPI(RequestUnifiedOrder reqmodel)
{
try
{
var wxPayAcc = JsonHelper.Deserialize<WxPayAccVM>(AccStr);
var nonceStr = TenPayV3Util.GetNoncestr();
var timeStamp = TenPayV3Util.GetTimestamp();
//此处填入此支付附加信息
var attach = string.Empty;
var xmlDataInfo = new TenPayV3UnifiedorderRequestData(wxPayAcc.AppId, wxPayAcc.MchId, reqmodel.Body,
reqmodel.OutTradeNo, reqmodel.TotalFee, reqmodel.SpbillCreateIp, wxPayAcc.NotifyUrl, Senparc.Weixin.TenPay.TenPayV3Type.JSAPI,
reqmodel.OpenId, wxPayAcc.MchIdKey, nonceStr, null, null, null, null, attach);
var result = TenPayV3.Html5Order(xmlDataInfo);//调用统一订单接口
var package = string.Format("prepay_id={0}", result.prepay_id);
var paySign = TenPayV3.GetJsPaySign(wxPayAcc.AppId, timeStamp, nonceStr, package, wxPayAcc.MchIdKey);
var model = new UnifiedOrderModelForJSAPI
{
AppId = result.appid,
NonceStr = nonceStr,
TimeStamp = timeStamp,
Package = package,
SignType = "MD5",
PaySign = paySign
};
return model;
}
catch (Exception ex)
{
throw ex;
}
}
微信App支付调起
/// <summary>
/// 微信支付下单
/// APP下单部分
/// </summary>
/// <param name="reqmodel"></param>
/// <returns></returns>
public UnifiedOrderModelForApp WxPayUnifiedOrderByApp(RequestUnifiedOrder reqmodel)
{
try
{
var wxPayAcc = JsonHelper.Deserialize<WxPayAccVM>(AccStr);
var nonceStr = TenPayV3Util.GetNoncestr();
var timeStamp = TenPayV3Util.GetTimestamp();
//此处填入此支付附加信息
var attach = string.Empty;
var xmlDataInfo = new TenPayV3UnifiedorderRequestData(wxPayAcc.AppId, wxPayAcc.MchId, reqmodel.Body,
reqmodel.OutTradeNo, reqmodel.TotalFee,
reqmodel.SpbillCreateIp, wxPayAcc.NotifyUrl, Senparc.Weixin.TenPay.TenPayV3Type.APP,
null, wxPayAcc.MchIdKey, nonceStr, null, null, null, null, attach);
var response = TenPayV3.Unifiedorder(xmlDataInfo);//调用统一订单接口
if (response.result_code != Success || response.return_code != Success) throw new Exception("微信App统一下单失败,请检查参数是否配置正确");
//重新获取混淆信息以及时间戳
nonceStr = TenPayV3Util.GetNoncestr();
timeStamp = TenPayV3Util.GetTimestamp();
var signData = new UnifiedOrderModelForApp
{
AppId = wxPayAcc.AppId,
PartnerId = wxPayAcc.MchId,
PrepayId = response.prepay_id,
Package = "Sign=WXPay",
NonceStr = nonceStr,
TimeStamp = timeStamp
};
//构建签名词典
var sParams = new SortedDictionary<string, string>{
{ "appid", wxPayAcc.AppId },
{ "partnerid", wxPayAcc.MchId },
{ "prepayid", response.prepay_id },
{ "package", "Sign=WXPay" },
{ "noncestr",nonceStr },
{ "timestamp",timeStamp}
};
var li = new List<string>();
//拼接部分
foreach (KeyValuePair<string, string> temp in sParams) li.Add(temp.Key + "=" + temp.Value);
//在最后追加支付密钥
li.Add("key=" + wxPayAcc.MchIdKey.Trim());
//MD5处理部分
MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider();
var inputBye = Encoding.UTF8.GetBytes(string.Join("&", li));
var outputBye = m5.ComputeHash(inputBye);
signData.Sign = BitConverter.ToString(outputBye).Replace("-", "").ToUpper();
return signData;
}
catch (Exception ex)
{
throw ex;
}
}
微信支付回调部分
/// <summary>
/// 微信支付回调
/// XML字符串封装进对象
///调用示例:
/// var stringData = new StreamReader(System.Web.HttpContext.Current.Request.InputStream).ReadToEnd();
/// var para= XmlHelper.Deserialize<WxNotifyVM>(stringData);
/// var rr = WxPayCalBack(para.CmpCode, para);
/// </summary>
/// <param name="cmpCode"></param>
/// <param name="para"></param>
/// <returns></returns>
public WxNotifyResultVM WxPayCalBack(string cmpCode, WxNotifyVM para)
{
try
{
if (string.Compare(para.ResultCode, Success) == 0)
{
if (true)//微信正常回调商户系统处理逻辑
{
return new WxNotifyResultVM()
{
ReturnCode = "SUCCESS",
ReturnMsg = "OK"
};
}
}
}
catch (Exception ex)
{
return new WxNotifyResultVM()
{
ReturnCode = "FAIL",
ReturnMsg = ex.Message
};
}
return new WxNotifyResultVM();
}