由于公司运营需要,需要在客户端(android/ios)增加微信以及支付宝支付,在调用微信app支付时遇到一些问题,也算是一些踩过的坑,记录下来

,希望能对.net开发者服务端网站更快的集成微信app支付。

1.开发所需资料:微信开放平台应用的appid以及appsecert,商户平台的商户号以及api安全里面里面设置的key,详见 微信支付账户相关信息;

2.微信开发者平台完善应用平台的相关信息,android应用签名必须用打包签名过的发布版本apk(这一步很重用),包名必须一致,可以用微信提供的签名工具获得,签名工具下载地址https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk

以下是交互时序图,统一下单API、支付结果通知API和查询订单API等都涉及签名过程,调用都必须在商户服务器端完成(来源微信支付开发文档):

商户系统和微信支付支付系统主要交互:

步骤1:用户在商户APP中选择商品,提交订单,选择微信支付。商户后台收到订单时需要调用微信的同意下单接口,生成预支付单;

C#大概代码如下(相关代码参考自JeffreySu/WeiXinMPSDK ):

  1. private WechatPayResult generatePayResult(string mchappid,string mchid
  2. ,string body,string orderno,int total,string ip,string notify,string mchkey,string nonce)
  3. {
  4. DateTime start = DateTime.Now,end= DateTime.Now.AddMinutes();
  5. var xmlDataInfo = new TenPayV3UnifiedorderRequestData(mchappid
  6. ,mchid, body, orderno, total
  7. ,ip,notify, TenPayV3Type.APP
  8. , null, mchkey, nonce, null,start,end);
  9. var result = TenPayV3.Unifiedorder(xmlDataInfo);//调用统一订单接口
  10. return new WechatPayResult
  11. {
  12. appid=mchappid,
  13. body=body,
  14. CreatedOn=DateTime.Now,
  15. mch_id=mchid,
  16. prepay_id=result.prepay_id,
  17. spbill_create_ip=ip,
  18. nonce_str=nonce,
  19. timeStamp= TenPayV3Util.GetTimestamp(),
  20. out_trade_no=orderno,
  21. time_start=start,
  22. time_expire=end,
  23. total_fee=total,
  24. trade_type=result.trade_type
  25. };
  26. }
  1. public class RequestHandler
  2. {
  3.  
  4. public RequestHandler()
  5. {
  6. Parameters = new Hashtable();
  7. }
  8.  
  9. public RequestHandler(HttpContext httpContext)
  10. {
  11. Parameters = new Hashtable();
  12.  
  13. this.HttpContext = httpContext ?? HttpContext.Current;
  14.  
  15. }
  16. /// <summary>
  17. /// 密钥
  18. /// </summary>
  19. private string Key;
  20.  
  21. protected HttpContext HttpContext;
  22.  
  23. /// <summary>
  24. /// 请求的参数
  25. /// </summary>
  26. protected Hashtable Parameters;
  27.  
  28. /// <summary>
  29. /// debug信息
  30. /// </summary>
  31. private string DebugInfo;
  32.  
  33. /// <summary>
  34. /// 初始化函数
  35. /// </summary>
  36. public virtual void Init()
  37. {
  38. }
  39. /// <summary>
  40. /// 获取debug信息
  41. /// </summary>
  42. /// <returns></returns>
  43. public String GetDebugInfo()
  44. {
  45. return DebugInfo;
  46. }
  47. /// <summary>
  48. /// 获取密钥
  49. /// </summary>
  50. /// <returns></returns>
  51. public string GetKey()
  52. {
  53. return Key;
  54. }
  55. /// <summary>
  56. /// 设置密钥
  57. /// </summary>
  58. /// <param name="key"></param>
  59. public void SetKey(string key)
  60. {
  61. this.Key = key;
  62. }
  63.  
  64. /// <summary>
  65. /// 设置参数值
  66. /// </summary>
  67. /// <param name="parameter"></param>
  68. /// <param name="parameterValue"></param>
  69. public void SetParameter(string parameter, string parameterValue)
  70. {
  71. if (parameter != null && parameter != "")
  72. {
  73. if (Parameters.Contains(parameter))
  74. {
  75. Parameters.Remove(parameter);
  76. }
  77.  
  78. Parameters.Add(parameter, parameterValue);
  79. }
  80. }
  81.  
  82. /// <summary>
  83. /// 当参数不为null或空字符串时,设置参数值
  84. /// </summary>
  85. /// <param name="parameter"></param>
  86. /// <param name="parameterValue"></param>
  87. public void SetParameterWhenNotNull(string parameter, string parameterValue)
  88. {
  89. if (!string.IsNullOrEmpty(parameterValue))
  90. {
  91. SetParameter(parameter, parameterValue);
  92. }
  93. }
  94.  
  95. /// <summary>
  96. /// 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名
  97. /// </summary>
  98. /// <param name="key">参数名</param>
  99. /// <param name="value">参数值</param>
  100. /// key和value通常用于填充最后一组参数
  101. /// <returns></returns>
  102. public virtual string CreateMd5Sign(string key, string value)
  103. {
  104. StringBuilder sb = new StringBuilder();
  105.  
  106. ArrayList akeys = new ArrayList(Parameters.Keys);
  107. akeys.Sort();
  108.  
  109. foreach (string k in akeys)
  110. {
  111. string v = (string)Parameters[k];
  112. if (null != v && "".CompareTo(v) !=
  113. && "sign".CompareTo(k) !=
  114. //&& "sign_type".CompareTo(k) != 0
  115. && "key".CompareTo(k) != )
  116. {
  117. sb.Append(k + "=" + v + "&");
  118. }
  119. }
  120.  
  121. sb.Append(key + "=" + value);
  122. string sign = EncryptHelper.GetMD5(sb.ToString(), GetCharset()).ToUpper();
  123. //string sign = MD5UtilHelper.GetMD5(sb.ToString(), GetCharset()).ToUpper();
  124. return sign;
  125. }
  126. public virtual string CreateMd5Sign()
  127. {
  128. StringBuilder sb = new StringBuilder();
  129.  
  130. ArrayList akeys = new ArrayList(Parameters.Keys);
  131. akeys.Sort();
  132.  
  133. foreach (string k in akeys)
  134. {
  135. string v = (string)Parameters[k];
  136. if (null != v && "".CompareTo(v) !=
  137. && "sign".CompareTo(k) !=
  138. //&& "sign_type".CompareTo(k) != 0
  139. && "key".CompareTo(k) != )
  140. {
  141. sb.Append(k + "=" + v + "&");
  142. }
  143. }
  144. string sign = EncryptHelper.GetMD5(sb.ToString().Substring(,sb.Length-), GetCharset()).ToUpper();
  145. return sign;
  146. }
  147. /// <summary>
  148. /// 输出XML
  149. /// </summary>
  150. /// <returns></returns>
  151. public string ParseXML()
  152. {
  153. StringBuilder sb = new StringBuilder();
  154. sb.Append("<xml>");
  155. foreach (string k in Parameters.Keys)
  156. {
  157. string v = (string)Parameters[k];
  158. if (v != null && Regex.IsMatch(v, @"^[0-9.]$"))
  159. {
  160.  
  161. sb.Append("<" + k + ">" + v + "</" + k + ">");
  162. }
  163. else
  164. {
  165. sb.Append("<" + k + "><![CDATA[" + v + "]]></" + k + ">");
  166. }
  167.  
  168. }
  169. sb.Append("</xml>");
  170. return sb.ToString();
  171. }
  172.  
  173. /// <summary>
  174. /// 设置debug信息
  175. /// </summary>
  176. /// <param name="debugInfo"></param>
  177. public void SetDebugInfo(String debugInfo)
  178. {
  179. this.DebugInfo = debugInfo;
  180. }
  181.  
  182. public Hashtable GetAllParameters()
  183. {
  184. return this.Parameters;
  185. }
  186.  
  187. protected virtual string GetCharset()
  188. {
  189. if (this.HttpContext == null)
  190. {
  191. return Encoding.UTF8.BodyName;
  192. }
  193.  
  194. return this.HttpContext.Request.ContentEncoding.BodyName;
  195. }
  196. }
  1. /// <summary>
  2. /// 微信支付提交的XML Data数据[统一下单]
  3. /// </summary>
  4. public class TenPayV3UnifiedorderRequestData
  5. {
  6. /// <summary>
  7. /// 公众账号ID
  8. /// </summary>
  9. public string AppId { get; set; }
  10. /// <summary>
  11. /// 商户号
  12. /// </summary>
  13. public string MchId { get; set; }
  14. /// <summary>
  15. /// 自定义参数,可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传"WEB",String(32)如:013467007045764
  16. /// </summary>
  17. public string DeviceInfo { get; set; }
  18. /// <summary>
  19. /// 随机字符串
  20. /// </summary>
  21. public string NonceStr { get; set; }
  22. /// <summary>
  23. /// 签名类型,默认为MD5,支持HMAC-SHA256和MD5。(使用默认)
  24. /// </summary>
  25. public string SignType { get; set; }
  26. /// <summary>
  27. /// 商品信息
  28. /// </summary>
  29. public string Body { get; set; }
  30. /// <summary>
  31. /// 商品详细列表,使用Json格式,传输签名前请务必使用CDATA标签将JSON文本串保护起来。
  32. ///cost_price Int 可选 32 订单原价,商户侧一张小票订单可能被分多次支付,订单原价用于记录整张小票的支付金额。当订单原价与支付金额不相等则被判定为拆单,无法享/受/优/惠。
  33. /// receipt_id String 可选 32 商家小票ID
  34. ///goods_detail 服务商必填[]:
  35. ///└ goods_id String 必填 32 商品的编号
  36. ///└ wxpay_goods_id String 可选 32 微信支付定义的统一商品编号
  37. ///└ goods_name String 可选 256 商品名称
  38. ///└ quantity Int 必填 32 商品数量
  39. ///└ price Int 必填 32 商品单价,如果商户有优惠,需传输商户优惠后的单价
  40. ///注意:单品总金额应&lt;=订单总金额total_fee,否则会无法享受优惠。
  41. /// String(6000)
  42. /// </summary>
  43. public string Detail { get; set; }
  44. /// <summary>
  45. /// 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用。String(127),如:深圳分店
  46. /// </summary>
  47. public string Attach { get; set; }
  48. /// <summary>
  49. /// 符合ISO 4217标准的三位字母代码,默认人民币:CNY,详细列表请参见货币类型。String(16),如:CNY
  50. /// </summary>
  51. public string FeeType { get; set; }
  52. /// <summary>
  53. /// 商家订单号
  54. /// </summary>
  55. public string OutTradeNo { get; set; }
  56. /// <summary>
  57. /// 商品金额,以分为单位(money * 100).ToString()
  58. /// </summary>
  59. public int TotalFee { get; set; }
  60. /// <summary>
  61. /// 用户的公网ip,不是商户服务器IP
  62. /// </summary>
  63. public string SpbillCreateIP { get; set; }
  64. /// <summary>
  65. /// 订单生成时间,最终生成格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则。
  66. /// 如果为空,则默认为当前服务器时间
  67. /// </summary>
  68. public string TimeStart { get; set; }
  69. /// <summary>
  70. /// 订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则
  71. /// 注意:最短失效时间间隔必须大于5分钟。
  72. /// 留空则不设置失效时间
  73. /// </summary>
  74. public string TimeExpire { get; set; }
  75. /// <summary>
  76. /// 商品标记,使用代金券或立减优惠功能时需要的参数,说明详见代金券或立减优惠。String(32),如:WXG
  77. /// </summary>
  78. public string GoodsTag { get; set; }
  79. /// <summary>
  80. /// 接收财付通通知的URL
  81. /// </summary>
  82. public string NotifyUrl { get; set; }
  83. /// <summary>
  84. /// 交易类型
  85. /// </summary>
  86. public TenPayV3Type TradeType { get; set; }
  87. /// <summary>
  88. /// trade_type=NATIVE时(即扫码支付),此参数必传。此参数为二维码中包含的商品ID,商户自行定义。
  89. /// String(32),如:12235413214070356458058
  90. /// </summary>
  91. public string ProductId { get; set; }
  92. /// <summary>
  93. /// 上传此参数no_credit--可限制用户不能使用信用卡支付
  94. /// </summary>
  95. public string LimitPay { get; set; }
  96. /// <summary>
  97. /// 用户的openId
  98. /// </summary>
  99. public string OpenId { get; set; }
  100.  
  101. /// <summary>
  102. ///
  103. /// </summary>
  104. public string Key { get; set; }
  105.  
  106. public readonly RequestHandler PackageRequestHandler;
  107. public readonly string Sign;
  108.  
  109. /// <summary>
  110. ///
  111. /// </summary>
  112. /// <param name="appId"></param>
  113. /// <param name="mchId"></param>
  114. /// <param name="body"></param>
  115. /// <param name="outTradeNo"></param>
  116. /// <param name="totalFee">单位:分</param>
  117. /// <param name="spbillCreateIp"></param>
  118. /// <param name="notifyUrl"></param>
  119. /// <param name="tradeType"></param>
  120. /// <param name="openid"></param>
  121. /// <param name="key"></param>
  122. /// <param name="nonceStr"></param>
  123. /// <param name="deviceInfo">自定义参数,可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传"WEB",String(32)如:013467007045764</param>
  124. /// <param name="timeStart">订单生成时间,如果为空,则默认为当前服务器时间</param>
  125. /// <param name="timeExpire">订单失效时间,留空则不设置失效时间</param>
  126. /// <param name="detail">商品详细列表</param>
  127. /// <param name="attach">附加数据</param>
  128. /// <param name="feeType">符合ISO 4217标准的三位字母代码,默认人民币:CNY</param>
  129. /// <param name="goodsTag">商品标记,使用代金券或立减优惠功能时需要的参数,说明详见代金券或立减优惠。String(32),如:WXG</param>
  130. /// <param name="productId">trade_type=NATIVE时(即扫码支付),此参数必传。此参数为二维码中包含的商品ID,商户自行定义。String(32),如:12235413214070356458058</param>
  131. /// <param name="limitPay">是否限制用户不能使用信用卡支付</param>
  132. public TenPayV3UnifiedorderRequestData(string appId, string mchId, string body, string outTradeNo, int totalFee, string spbillCreateIp,
  133. string notifyUrl, TenPayV3Type tradeType, string openid, string key, string nonceStr,
  134. string deviceInfo = null, DateTime? timeStart = null, DateTime? timeExpire = null,
  135. string detail = null, string attach = null, string feeType = "CNY", string goodsTag = null, string productId = null, bool limitPay = false)
  136. {
  137. AppId = appId;
  138. MchId = mchId;
  139. DeviceInfo = deviceInfo;
  140. NonceStr = nonceStr;
  141. SignType = "MD5";
  142. Body = body ?? "";
  143. Detail = detail;
  144. Attach = attach;
  145. OutTradeNo = outTradeNo;
  146. FeeType = feeType;
  147. TotalFee = totalFee;
  148. SpbillCreateIP = spbillCreateIp;
  149. TimeStart = (timeStart ?? DateTime.Now).ToString("yyyyMMddHHmmss");
  150. TimeExpire = timeExpire.HasValue ? timeExpire.Value.ToString("yyyyMMddHHmmss") : null;
  151. GoodsTag = goodsTag;
  152. NotifyUrl = notifyUrl;
  153. TradeType = tradeType;
  154. ProductId = productId;
  155. LimitPay = limitPay ? "no_credit" : null;
  156. OpenId = openid;
  157. Key = key;
  158.  
  159. #region 设置RequestHandler
  160.  
  161. //创建支付应答对象
  162. PackageRequestHandler = new RequestHandler(null);
  163. //初始化
  164. PackageRequestHandler.Init();
  165.  
  166. //设置package订单参数
  167. //以下设置顺序按照官方文档排序,方便维护:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
  168. PackageRequestHandler.SetParameter("appid", this.AppId); //公众账号ID
  169. PackageRequestHandler.SetParameter("mch_id", this.MchId); //商户号
  170. PackageRequestHandler.SetParameterWhenNotNull("device_info", this.DeviceInfo); //自定义参数
  171. PackageRequestHandler.SetParameter("nonce_str", this.NonceStr); //随机字符串
  172. PackageRequestHandler.SetParameterWhenNotNull("sign_type", this.SignType); //签名类型,默认为MD5
  173. PackageRequestHandler.SetParameter("body", this.Body); //商品信息
  174. PackageRequestHandler.SetParameterWhenNotNull("detail", this.Detail); //商品详细列表
  175. PackageRequestHandler.SetParameterWhenNotNull("attach", this.Attach); //附加数据
  176. PackageRequestHandler.SetParameter("out_trade_no", this.OutTradeNo); //商家订单号
  177. PackageRequestHandler.SetParameterWhenNotNull("fee_type", this.FeeType); //符合ISO 4217标准的三位字母代码,默认人民币:CNY
  178. PackageRequestHandler.SetParameter("total_fee", this.TotalFee.ToString()); //商品金额,以分为单位(money * 100).ToString()
  179. PackageRequestHandler.SetParameter("spbill_create_ip", this.SpbillCreateIP); //用户的公网ip,不是商户服务器IP
  180. PackageRequestHandler.SetParameterWhenNotNull("time_start", this.TimeStart); //订单生成时间
  181. PackageRequestHandler.SetParameterWhenNotNull("time_expire", this.TimeExpire); //订单失效时间
  182. PackageRequestHandler.SetParameterWhenNotNull("goods_tag", this.GoodsTag); //商品标记
  183. PackageRequestHandler.SetParameter("notify_url", this.NotifyUrl); //接收财付通通知的URL
  184. PackageRequestHandler.SetParameter("trade_type", this.TradeType.ToString()); //交易类型
  185. PackageRequestHandler.SetParameterWhenNotNull("product_id", this.ProductId); //trade_type=NATIVE时(即扫码支付),此参数必传。
  186. PackageRequestHandler.SetParameterWhenNotNull("limit_pay", this.LimitPay); //上传此参数no_credit--可限制用户不能使用信用卡支付
  187. PackageRequestHandler.SetParameter("openid", this.OpenId); //用户的openId,trade_type=JSAPI时(即公众号支付),此参数必传
  188. Sign = PackageRequestHandler.CreateMd5Sign("key", this.Key);
  189. PackageRequestHandler.SetParameter("sign", Sign); //签名
  190. #endregion
  191. }
  192. }

统一下单

  1. /// <summary>
  2. /// 统一支付接口
  3. /// 统一支付接口,可接受JSAPI/NATIVE/APP 下预支付订单,返回预支付订单号。NATIVE 支付返回二维码code_url。
  4. /// </summary>
  5. /// <param name="dataInfo">微信支付需要post的Data数据</param>
  6. /// <param name="timeOut"></param>
  7. /// <returns></returns>
  8. public static UnifiedorderResult Unifiedorder(TenPayV3UnifiedorderRequestData dataInfo, int timeOut = Config.TIME_OUT)
  9. {
  10. var urlFormat = "https://api.mch.weixin.qq.com/pay/unifiedorder";
  11. var data = dataInfo.PackageRequestHandler.ParseXML();//获取XML
  12. //throw new Exception(data.HtmlEncode());
  13. MemoryStream ms = new MemoryStream();
  14. var formDataBytes = data == null ? new byte[] : Encoding.UTF8.GetBytes(data);
  15. ms.Write(formDataBytes, , formDataBytes.Length);
  16. ms.Seek(, SeekOrigin.Begin);//设置指针读取位置
  17.  
  18. var resultXml = RequestUtility.HttpPost(urlFormat, null, ms, timeOut: timeOut);
  19. return new UnifiedorderResult(resultXml);
  20. }

统一支付接口

步骤2:统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式为Sign=WXPay,签名的字段数量必须跟你app调起微信支付所传的参数一致:

  1. /// <summary>
  2. /// 生成微信app支付前面
  3. /// </summary>
  4. /// <param name="appId"></param>
  5. /// <param name="timeStamp"></param>
  6. /// <param name="nonceStr"></param>
  7. /// <param name="package"></param>
  8. /// <param name="key"></param>
  9. /// <param name="partnerid"></param>
  10. /// <param name="prepayid"></param>
  11. /// <param name="signType"></param>
  12. /// <returns></returns>
  13. public static string GetAppPaySign(string appId
  14. , string timeStamp, string nonceStr, string package,
  15. string key,string partnerid,string prepayid,string signType = "MD5"
  16. )
  17. {
  18. RequestHandler paySignReqHandler = new RequestHandler(null);
  19. paySignReqHandler.SetParameter("appid", appId.Trim());
  20. paySignReqHandler.SetParameter("timestamp", timeStamp.Trim());
  21. paySignReqHandler.SetParameter("noncestr", nonceStr.Trim());
  22. paySignReqHandler.SetParameter("partnerid", partnerid);
  23. paySignReqHandler.SetParameter("prepayid", prepayid);
  24. paySignReqHandler.SetParameter("package", package.Trim());
  25. //paySignReqHandler.SetParameter("signtype", "MD5");
  26. var paySign = paySignReqHandler.CreateMd5Sign("key", key);
  27. return paySign;
  28. }

生成微信app支付签名

步骤3:商户APP调起微信支付。详细介绍参见微信支付官方文档

关键代码如下:

  1. public static IWXAPI api;
  2. api= WXAPIFactory.createWXAPI(this, Constants.APP_ID,true);
  3. api.registerApp(Constants.APP_ID);
  4. Result result = JSON.parseObject(bytes, Result.class);
  5. if (null != result) {
  6. if (result.isSuccess()) {
  7. prepay prepay = JSON.parseObject(result.getData().toString(), prepay.class);
  8. PayReq request = new PayReq();
  9. request.appId = prepay.getAppid();
  10. request.partnerId =prepay.getPartnerid();
  11. request.prepayId= prepay.getPrepayid();
  12. request.packageValue = prepay.getPackages();
  13. request.nonceStr= prepay.getNoncestr();
  14. request.timeStamp=prepay.getTimestamp();
  15. request.sign= prepay.getSign();
  16. api.sendReq(request);
  17. }
  18. }

android调起支付相关代码

其中result.getData()表示服务端返回的预支付订单的相关参数,用这参数调用微信支付,该activity必须实现接口IWXAPIEventHandler,并实现

  1. @Override
    public void onResp(BaseResp baseResp) {
    if(baseResp.getType()== ConstantsAPI.COMMAND_PAY_BY_WX){
    Log.d("dd","onPayFinish,errCode="+baseResp.errCode);
    }
    }
    用于判断微信支付结果,安全起见,建议微信app回调后请求商户api相关接口确定支付结果
    支付成功时微信后台会请求生成预支付单时传递的通知url(即payProvider.TenpayNotify)通知商户支付结果,商户后台校验相关信息
  1. [AllowAnonymous]
  2. public ActionResult PayResult()
  3. {
  4. ResponseHandler resHandler = new ResponseHandler(null);
  5. string return_code = resHandler.GetParameter("return_code");
  6. string return_msg = resHandler.GetParameter("return_msg");
  7. string res = null;
  8. EngineContext.Current.Resolve<ILogger>().Information("收到微信支付通知"+resHandler.ParseXML());
  9. //EngineContext.Current.Resolve<ILoggingService>().Write(LogType.Pay, resHandler.ParseXML());
  10. string orderno = resHandler.GetParameter("out_trade_no");
  11. string payno = resHandler.GetParameter("transaction_id");
  12. string nonce_str = resHandler.GetParameter("nonce_str");
  13. var order = _wechatService.GetWechatPayResult(orderno);
  14. if (order != null)
  15. {
  16. var first = order.FirstOrDefault(r => r.nonce_str == nonce_str);
  17. if (first != null)
  18. {
  19. var payProvider = _wechatService.GetWechatPayProvider(first.appid);
  20. resHandler.SetKey(payProvider.MchKey);
  21. if (resHandler.IsTenpaySign())
  22. {
  23. if (return_code == TenPayTypeResult.SUCCESS.ToString())
  24. {
  25. int totaled= int.Parse(resHandler.GetParameter("total_fee"));
  26. if (totaled == first.total_fee)
  27. {
  28. first.IsSuccess = true;
  29. first.time_end = DateTime.Now;
  30. first.total_fee_ed = int.Parse(resHandler.GetParameter("total_fee"));
  31. first.transaction_id = payno;
  32. first.Content = resHandler.ParseXML();
  33. _wechatService.UpdateWechatPayResult(first);
  34. EngineContext.Current.Resolve<IEventPublisher>().Publish(resultEvent);
  35. }else
  36. {
  37. EngineContext.Current.Resolve<ILogger>().Information("微信支付金额与订单金额不匹配" + resHandler.ParseXML());
  38. }
  39.  
  40. }
  41. }
  42. }
  43.  
  44. //验证请求是否从微信发过来(安全)
  45. string xml = string.Format(@"<xml>
  46. <return_code><![CDATA[{0}]]></return_code>
  47. <return_msg><![CDATA[{1}]]></return_msg>
  48. </xml>", return_code, return_msg);
  49. return Content(xml, "text/xml");
  50. }

微信回调通知参考代码

微信支付官方文档

微信.NET集成可参考现有轮子 JeffreySu/WeiXinMPSDK

微信app支付android客户端以及.net服务端实现的更多相关文章

  1. 微信app支付(android端+java后台)

    本文讲解使用微信支付接口完成在android开发的原生态app中完成微信支付功能, 文章具体讲解了前端android如何集成微信支付功能以及后台如何组装前端需要支付信息, 话不多话, 具体看文章内容吧 ...

  2. 微信移动支付V3开发详细教程服务端采用.net mvc webapi(C#)

    转自:http://www.kwstu.com/ArticleView/netmvc_201511132050268716 最近开发手机app需要实现移动支付功能,由于考虑支付安全将微信支付生成签名写 ...

  3. Android客户端与PHP服务端交互(一)---框架概述

    背景 作为一个普通上班族,总是想做一些自认为有意义的事情,于是乎准备成立一个工作室,尽管目前正在筹备阶段,但是之前有些朋友提出一些需求的时候,我发现自己的能力还是有限,直到最近和一些技术牛朋友聊起这事 ...

  4. Android客户端与PC服务端、android服务端通过WiFi通信

    前期准备:我的是Linux Mint操作系统(总之折腾的过程中怀疑过是不是系统的问题),首先是要创建wifi热点给android手机使用,这个时候笔记本作为通信的服务器端,android手机作为客户端 ...

  5. android客户端向java服务端post发送json

    android 端: private void HttpPostData() {        try { HttpClient httpclient = new DefaultHttpClient( ...

  6. Android客户端转换php服务端获取的时间戳的转换

    今天在用JSON获取后台的数据的时候,发现一个奇怪的现象就是返回来的时间戳都是1970年这样的,很是纠结,最后发现时php和Java中时间的格式不一样造成的,所以我们本地客户端要做一个转换: /** ...

  7. Android版-微信APP支付

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

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

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

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

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

随机推荐

  1. 微信小程序选项卡功能

    首先看看微信小程序上的选项卡的效果 原理呢,就是先布局好(这就不必说了吧),然后在上面的每一个选项卡上都定义一个同样的点击事件,然后给每一个组件上绑定一个唯一的标识符,然后点击事件触发的时候,获取到绑 ...

  2. Android hook神器frida(一)

    运行环境 ● Python – latest 3.x is highly recommended ● Windows, macOS, or Linux安装方法使用命令 sudo pip install ...

  3. HDU 2255 奔小康赚大钱(带权二分图最大匹配)

    HDU 2255 奔小康赚大钱(带权二分图最大匹配) Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊 ...

  4. (转)示例化讲解RIP路由更新机制

      目录(?)[+]   以下内容摘自最新上市的“四大金刚”图书之一<Cisco路由器配置与管理完全手册>(第二版)(其它三本分别为<Cisco交换机配置与管理完全手册>(第二 ...

  5. Cocoapods最新安装教程

    一.CocoaPods简介 每种语言发展到一个阶段,就会出现相应的依赖管理工具,例如 Java 语言的 Maven,nodejs 的 npm.随着 iOS 开发者的增多,业界也出现了为 iOS 程序提 ...

  6. Spring源码情操陶冶-AbstractApplicationContext#invokeBeanFactoryPostProcessors

    阅读源码有利于陶冶情操,承接前文Spring源码情操陶冶-AbstractApplicationContext#postProcessBeanFactory 约定:web.xml中配置的context ...

  7. 【css】盒子模型 之 概述

    摘要 一些基本的概念以及常见使用问题 概述 BFC 是css 中布局的核心 - 盒模型,根据块级元素及行级元素可分为块级容器, 行级容器,但容器内部都遵循 BFC BFC 空间布局 备注: IE 的盒 ...

  8. mysql的并发处理机制_上篇

              回来写博客,少年前端时间被django迷了心魄           如果转载,请注明博文来源: www.cnblogs.com/xinysu/   ,版权归 博客园 苏家小萝卜 所 ...

  9. SQL Server ---T-SQl基本语句

    T-SQL 是 SQL-Server 的结构化查询语言. 基本数据操作语言. 基础语句 先创建表 我后面的列子都是用的这一个表,列名啥的 就大概看看吧~~ 纯粹为了学习语句,语法~~所以先创建个表吧~ ...

  10. H5微信通过百度地图API实现导航方式二

    要有服务器才行哦 <!DOCTYPE html><html><head>    <meta http-equiv="Content-Type&quo ...