最近挺忙的,没时间写东西。然后在弄微信APP支付,网上的搜索一趟,都比较凌乱,我也遇到一些坑,不过也算弄好了,记录分享一下。

1、准备各种调用接口需要的参数,配置app.config。

<!--AppID-->
<add key="AppID" value="" />
<!--AppSecret-->
<add key="AppSecret" value="" />
<!--商户号-->
<add key="MchID" value="" />
<!--APIKey-->
<add key="APIKey" value="" />

2、调用统一下单API,直接上代码了。

	/// <summary>
/// Builds the request.
/// </summary>
/// <returns></returns>
public static string BuildRequest()
{
var dicParam = CreateParam(); var signString = CreateURLParamString(dicParam);
var preString = signString + "&key=" + ConfigHelper.APIKey;
var sign = Sign(preString, "utf-8").ToUpper();
dicParam.Add("sign", sign); return BuildForm(dicParam);
} /// <summary>
/// Generates the out trade no.
/// </summary>
/// <returns></returns>
private static string GenerateOutTradeNo()
{
var ran = new Random();
return $"{ConfigHelper.MchID}{DateTime.Now:yyyyMMddHHmmss}{ran.Next(999)}";
} /// <summary>
/// Signs the specified prestr.
/// </summary>
/// <param name="prestr">The prestr.</param>
/// <param name="_input_charset">The input charset.</param>
/// <returns></returns>
private static string Sign(string prestr, string _input_charset)
{
var sb = new StringBuilder(32);
MD5 md5 = new MD5CryptoServiceProvider();
var t = md5.ComputeHash(Encoding.GetEncoding(_input_charset).GetBytes(prestr));
foreach (var t1 in t)
{
sb.Append(t1.ToString("x").PadLeft(2, '0'));
} return sb.ToString();
} /// <summary>
/// Creates the parameter.
/// </summary>
/// <returns></returns>
private static SortedDictionary<string, string> CreateParam()
{
const string amount = "1";
double dubamount;
double.TryParse(amount, out dubamount);
var notify_url = ConfigHelper.WebSiteUrl + "/api/v1/testWeiXin"; //支付完成后的回调处理页面
const string detail = "xxxx"; var dic = new SortedDictionary<string, string>
{
{"appid", ConfigHelper.AppID},//账号ID
{"mch_id", ConfigHelper.MchID},//商户号
{"nonce_str", Guid.NewGuid().ToString().Replace("-", "")},//随机字符串
{"body", detail}, //商品描述
{"out_trade_no", GenerateOutTradeNo()},//商户订单号
{"total_fee", (dubamount * 100).ToString(CultureInfo.InvariantCulture)},//总金额
{"spbill_create_ip", GeneralHelper.GetIP()},//终端IP
{"notify_url", notify_url},//通知地址
{"trade_type", "APP"}//交易类型
}; return dic;
} /// <summary>
/// Creates the URL parameter string.
/// </summary>
/// <param name="dicArray">The dic array.</param>
/// <returns></returns>
private static string CreateURLParamString(SortedDictionary<string, string> dicArray)
{
var prestr = new StringBuilder();
foreach (var temp in dicArray.OrderBy(o => o.Key))
{
prestr.Append(temp.Key + "=" + temp.Value + "&");
} var nLen = prestr.Length;
prestr.Remove(nLen - 1, 1);
return prestr.ToString();
} /// <summary>
/// Builds the form.
/// </summary>
/// <param name="dicParam">The dic parameter.</param>
/// <returns></returns>
private static string BuildForm(SortedDictionary<string, string> dicParam)
{
var sbXML = new StringBuilder();
sbXML.Append("<xml>");
foreach (var temp in dicParam)
{
sbXML.Append("<" + temp.Key + ">" + temp.Value + "</" + temp.Key + ">");
} sbXML.Append("</xml>");
return sbXML.ToString();
} /// <summary>
/// Froms the XML.
/// </summary>
/// <param name="xml">The XML.</param>
/// <returns></returns>
/// <exception cref="Exception">将空的xml串转换为WxPayData不合法!</exception>
public static SortedDictionary<string, string> FromXml(string xml)
{
var sortDic = new SortedDictionary<string, string>();
if (string.IsNullOrEmpty(xml))
{
throw new Exception("将空的xml串转换为WxPayData不合法!");
} var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
var xmlNode = xmlDoc.FirstChild;//获取到根节点<xml>
var nodes = xmlNode.ChildNodes;
foreach (XmlNode xn in nodes)
{
var xe = (XmlElement)xn; if (!sortDic.ContainsKey(xe.Name))
sortDic.Add(xe.Name, xe.InnerText);
}
return sortDic;
} /// <summary>
/// Posts the specified URL.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="content">The content.</param>
/// <param name="contentType">Type of the content.</param>
/// <returns></returns>
/// <exception cref="Exception">POST请求错误" + e</exception>
public static string Post(string url, string content, string contentType = "application/x-www-form-urlencoded")
{
string result;
try
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(contentType));
var stringContent = new StringContent(content, Encoding.UTF8);
var response = client.PostAsync(url, stringContent).Result;
result = response.Content.ReadAsStringAsync().Result;
}
}
catch (Exception e)
{
throw new Exception("POST请求错误" + e);
}
return result;
}

3、生成预付订单,获取prepay_id。

	/// <summary>
/// Gets the value from dic.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dic">The dic.</param>
/// <param name="key">The key.</param>
/// <returns></returns>
public static T GetValueFromDic<T>(IDictionary<string, string> dic, string key)
{
string val;
dic.TryGetValue(key, out val); var returnVal = default(T);
if (val != null)
returnVal = (T)Convert.ChangeType(val, typeof(T)); return returnVal;
} /// <summary>
/// Builds the application pay.
/// </summary>
/// <param name="prepayid">The prepayid.</param>
/// <returns></returns>
public static string BuildAppPay(string prepayid)
{
var dicParam = CreateWapAndAppPayParam(prepayid);
var signString = CreateURLParamString(dicParam);
var preString = signString + "&key=" + ConfigHelper.APIKey; var sign = Sign(preString, "utf-8").ToUpper();
dicParam.Add("sign", sign); return JsonConvert.SerializeObject(
new
{
appid = dicParam["appid"],
partnerid = dicParam["partnerid"],
prepayid = dicParam["prepayid"],
package = dicParam["package"],
noncestr = dicParam["noncestr"],
timestamp = dicParam["timestamp"],
sign = dicParam["sign"]
});
} /// <summary>
/// Creates the wap and application pay parameter.
/// </summary>
/// <param name="prepayId">The prepay identifier.</param>
/// <returns></returns>
private static SortedDictionary<string, string> CreateWapAndAppPayParam(string prepayId)
{
var dic = new SortedDictionary<string, string>
{
{"appid", ConfigHelper.AppID},//公众账号ID
{"partnerid", ConfigHelper.MchID},//商户号
{"prepayid", prepayId},//预支付交易会话ID
{"package", "Sign=WXPay"},//扩展字段
{"noncestr", Guid.NewGuid().ToString().Replace("-", "")},//随机字符串
{
"timestamp",
(Convert.ToInt32((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds)).ToString()
}//时间戳
}; return dic;
} /// <summary>
/// Validatons the query result.
/// </summary>
/// <param name="dic">The dic.</param>
/// <returns></returns>
public static bool ValidatonQueryResult(SortedDictionary<string, string> dic)
{
var result = false; if (dic.ContainsKey("return_code") && dic.ContainsKey("return_code"))
{
if (dic["return_code"] == "SUCCESS" && dic["result_code"] == "SUCCESS")
result = true;
} if (result) return true; var sb = new StringBuilder();
foreach (var item in dic.Keys)
{
sb.Append(item + ":" + dic[item] + "|");
} return false;
}

4、调用获取支付信息,给到APP发起支付操作。

		var requestXml = WeiXinUtil.BuildRequest();
var resultXml = WeiXinUtil.Post("https://api.mch.weixin.qq.com/pay/unifiedorder", requestXml); var dic = WeiXinUtil.FromXml(resultXml); string returnCode;
dic.TryGetValue("return_code", out returnCode); if (returnCode == "SUCCESS")
{
var prepay_id = WeiXinUtil.GetValueFromDic<string>(dic, "prepay_id");
if (!string.IsNullOrEmpty(prepay_id))
{
var payInfo = JsonConvert.DeserializeObject<WeiXinUtil.WxPayModel>(WeiXinUtil.BuildAppPay(prepay_id)); json.Add(new JProperty("appid", payInfo.appid));
json.Add(new JProperty("partnerid", payInfo.partnerid));
json.Add(new JProperty("prepayid", payInfo.prepayid));
json.Add(new JProperty("package", payInfo.package));
json.Add(new JProperty("noncestr", payInfo.noncestr));
json.Add(new JProperty("timestamp", payInfo.timestamp));
json.Add(new JProperty("sign", payInfo.sign));
json.Add(new JProperty("code", 0));
json.Add(new JProperty("msg", "成功"));
return this.Jsonp(json.ToString());
}
else
{
json.Add(new JProperty("code", 40028));
json.Add(new JProperty("msg", "支付错误:" + WeiXinUtil.GetValueFromDic<string>(dic, "err_code_des")));
return this.Jsonp(json.ToString());
}
}
else
{
return this.Jsonp(ApiException.OrderFailed());
}

5、APP支付完成,获得回调信息,就OK了。

		var context = this.HttpContext;
var request = context.Request;
var verifyResult = false;
var requestXml = WeiXinUtil.GetRequestXmlData(request);
var dic = WeiXinUtil.FromXml(requestXml);
var returnCode = WeiXinUtil.GetValueFromDic<string>(dic, "return_code"); if (!string.IsNullOrEmpty(returnCode) && returnCode == "SUCCESS")//通讯成功
{
var result = WeiXinUtil.WePayNotifyValidation(dic);
if (result)
{
var transactionid = WeiXinUtil.GetValueFromDic<string>(dic, "transaction_id"); if (!string.IsNullOrEmpty(transactionid))
{
var queryXml = WeiXinUtil.BuildQueryRequest(transactionid, dic);
var queryResult = WeiXinUtil.Post("https://api.mch.weixin.qq.com/pay/orderquery", queryXml);
var queryReturnDic = WeiXinUtil.FromXml(queryResult); if (WeiXinUtil.ValidatonQueryResult(queryReturnDic))//查询成功
{
verifyResult = true;
var status = WeiXinUtil.GetValueFromDic<string>(dic, "result_code"); if (!string.IsNullOrEmpty(status) && status == "SUCCESS")
{
var order = new Order()
{
OrderNumber = WeiXinUtil.GetValueFromDic<string>(dic, "out_trade_no"),
TransactionId = transactionid,
ProductPrice = WeiXinUtil.GetValueFromDic<decimal>(dic, "total_fee") / 100,
TradeType = WeiXinUtil.GetValueFromDic<string>(dic, "trade_type"),
BankType = WeiXinUtil.GetValueFromDic<string>(dic, "bank_type"),
PayDate = DateTime.Parse(WeiXinUtil.GetValueFromDic<string>(dic, "time_end")),
StatusId = 1,
IsPresent = false,
AddDate = DateTime.Now,
IsDelete = false
}; CURD.Add(order, ConfigHelper.WriteDB); WeiXinUtil.BuildReturnXml("OK", "成功");
}
}
else
WeiXinUtil.BuildReturnXml("FAIL", "订单查询失败");
}
else
WeiXinUtil.BuildReturnXml("FAIL", "支付结果中微信订单号不存在");
}
else
WeiXinUtil.BuildReturnXml("FAIL", "签名失败");
}
else
{
string returnmsg;
dic.TryGetValue("return_msg", out returnmsg);
throw new Exception("异步通知错误:" + returnmsg);
} return verifyResult; /// <summary>
/// Gets the request XML data.
/// </summary>
/// <param name="request">The request.</param>
/// <returns></returns>
public static string GetRequestXmlData(HttpRequestBase request)
{
var stream = request.InputStream;
int count;
var buffer = new byte[1024];
var builder = new StringBuilder();
while ((count = stream.Read(buffer, 0, 1024)) > 0)
{
builder.Append(Encoding.UTF8.GetString(buffer, 0, count));
}
stream.Flush();
stream.Close(); return builder.ToString();
} /// <summary>
/// Wes the pay notify validation.
/// </summary>
/// <param name="dic">The dic.</param>
/// <returns></returns>
public static bool WePayNotifyValidation(SortedDictionary<string, string> dic)
{
var sign = GetValueFromDic<string>(dic, "sign");
if (dic.ContainsKey("sign"))
{
dic.Remove("sign");
} var tradeType = GetValueFromDic<string>(dic, "trade_type");
var preString = CreateURLParamString(dic); if (string.IsNullOrEmpty(tradeType))
{
var preSignString = preString + "&key=" + ConfigHelper.APIKey;
var signString = Sign(preSignString, "utf-8").ToUpper();
return signString == sign;
}
else
return false;
} /// <summary>
/// Builds the query request.
/// </summary>
/// <param name="transactionId">The transaction identifier.</param>
/// <param name="dic">The dic.</param>
/// <returns></returns>
public static string BuildQueryRequest(string transactionId, SortedDictionary<string, string> dic)
{
var dicParam = CreateQueryParam(transactionId);
var signString = CreateURLParamString(dicParam);
var key = ConfigHelper.APIKey;
var preString = signString + "&key=" + key;
var sign = Sign(preString, "utf-8").ToUpper();
dicParam.Add("sign", sign); return BuildForm(dicParam);
} /// <summary>
/// Creates the query parameter.
/// </summary>
/// <param name="transactionId">The transaction identifier.</param>
/// <returns></returns>
private static SortedDictionary<string, string> CreateQueryParam(string transactionId)
{
var dic = new SortedDictionary<string, string>
{
{"appid", ConfigHelper.AppID},//公众账号ID
{"mch_id", ConfigHelper.MchID},//商户号
{"nonce_str", Guid.NewGuid().ToString().Replace("-", "")},//随机字符串
{"transaction_id", transactionId}//微信订单号
};
return dic;
} /// <summary>
/// Builds the return XML.
/// </summary>
/// <param name="code">The code.</param>
/// <param name="returnMsg">The return MSG.</param>
/// <returns></returns>
public static string BuildReturnXml(string code, string returnMsg)
{
return
$"<xml><return_code><![CDATA[{code}]]></return_code><return_msg><![CDATA[{returnMsg}]]></return_msg></xml>";
}

6、总结:这个可以直接拿来用了,反反复复测试了很多遍,遇到的问题有关于钱,还有签名的问题,调试都解决了。继续解决问题,积累经验。

微信APP支付 - C#的更多相关文章

  1. 微信app支付 ci框架做的

    /**     * 组合微信app支付  获得prepayid     * @param int $order_num     */    private function _wxpay_reques ...

  2. .net 微信APP支付接口的开发流程以及坑

    流程 申请APP的微信支付 申请成功之后得到APPID 商户号 以及自己设置商户号的支付密码 这时就可以开发接口了 微信APP支付API:https://pay.weixin.qq.com/wiki/ ...

  3. 微信app支付android客户端以及.net服务端实现

    由于公司运营需要,需要在客户端(android/ios)增加微信以及支付宝支付,在调用微信app支付时遇到一些问题,也算是一些踩过的坑,记录下来 ,希望能对.net开发者服务端网站更快的集成微信app ...

  4. php开发微信APP支付接口

    之前在开发APP中用到了微信支付,因为是第一次用,所以中途也遇到了好多问题,通过查看文档和搜集资料,终于完成了该功能的实现.在这里简单分享一下后台php接口的开发实例. 原文地址:代码汇个人博客 ht ...

  5. H5使用codovar插件实现微信支付(微信APP支付模式,前端)

    H5打包的app实现微信支付及支付宝支付,本章主要详解微信支付,支付宝支付请查看另一篇“H5使用codovar插件实现支付宝支付(支付宝APP支付模式,前端)” ps:本文只试用H5开发的,微信 AP ...

  6. nodejs+koa2微信app支付,小程序支付

    企业付款到零钱文档:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2 1,搞微信支付,先看流程图 https: ...

  7. asp.net core 微信APP支付(扫码支付,H5支付,公众号支付,app支付)之4

    微信app支付需要以下参数,类封装如下 public class WxPayModel { /// <summary> /// 应用ID /// </summary> publ ...

  8. 微信支付-微信公众号支付,微信H5支付,微信APP支付,微信扫码支付

    在支付前,如果使用第三方MVC框架,则使用重写模式,服务器也需要配置该项 if (!-e $request_filename){ rewrite ^/(.*)$ /index.php/$ last; ...

  9. Android版-微信APP支付

    首发地址: Android版-微信APP支付 欢迎留言.转发 微信极速开发系列文章(微信支付.授权获取用户信息等):点击这里 目录 1.注册账号.开发者认证 2.添加应用 3.申请微信支付 4.技术开 ...

随机推荐

  1. 如何用 js 递归输出树型

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  2. GMM高斯混合模型 学习(2)

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHpxMjAwODExMjExMDc=/font/5a6L5L2T/fontsize/400/fill/I0 ...

  3. Java之开发工具(1) - Eclipse 如何设置注释的模板

    最常用的注释就是对类的说明和方法的说明,关于这类代码的注释方式,在Eclipse中可以这样进行设置: windows---preferences...---java--code style--code ...

  4. 每日算法之二十三:Reverse Nodes in k-Group

    Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. If ...

  5. 铁通网络没有一个真实的公网IP,NAT转换能不能解决?

    铁通网络没有一个真实的公网IP,NAT转换能不能解决?     我的是铁通宽带,现在想用自己的机子做一个动态主机,可是因为铁通垃圾网络的NAT转发问题,使用cn99qdns手动更新动态域名IP后公网能 ...

  6. Sphinx全文检索引擎测试

    数据表 1.documents CREATE TABLE `documents` ( `id` int(13) NOT NULL auto_increment, `group_id` int(11) ...

  7. 常用/常见Java Web 服务器/应用服务器Logo图文介绍

    常用/常见应用服务器介绍:自己总结.整理一些常见的应用服务器,资料主要来源于网上.     常用Java Web 服务器Java Web应用程序需要部署在Java web服务器中运行,常用的Java ...

  8. mysql优化一

    1.show global status      可以列出MySQL服务器运行各种状态值 2.show variables            查询MySQL服务器配置信息 一.慢查询 mysql ...

  9. SQLServer 2008中SQL增强之三 Merge(在一条语句中使用

    SQLServer 2008中SQL增强之三 Merge(在一条语句中使用Insert,Update,Delete)   SQL Server 2008提供了一个增强的SQL命令Merge,用法参看M ...

  10. jQuery knowledge

    I have used jquery for many years, but didn't list the problem I ever meeting, so here is a list of ...