微信app支付android客户端以及.net服务端实现
由于公司运营需要,需要在客户端(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 ):
- private WechatPayResult generatePayResult(string mchappid,string mchid
- ,string body,string orderno,int total,string ip,string notify,string mchkey,string nonce)
- {
- DateTime start = DateTime.Now,end= DateTime.Now.AddMinutes();
- var xmlDataInfo = new TenPayV3UnifiedorderRequestData(mchappid
- ,mchid, body, orderno, total
- ,ip,notify, TenPayV3Type.APP
- , null, mchkey, nonce, null,start,end);
- var result = TenPayV3.Unifiedorder(xmlDataInfo);//调用统一订单接口
- return new WechatPayResult
- {
- appid=mchappid,
- body=body,
- CreatedOn=DateTime.Now,
- mch_id=mchid,
- prepay_id=result.prepay_id,
- spbill_create_ip=ip,
- nonce_str=nonce,
- timeStamp= TenPayV3Util.GetTimestamp(),
- out_trade_no=orderno,
- time_start=start,
- time_expire=end,
- total_fee=total,
- trade_type=result.trade_type
- };
- }
- public class RequestHandler
- {
- public RequestHandler()
- {
- Parameters = new Hashtable();
- }
- public RequestHandler(HttpContext httpContext)
- {
- Parameters = new Hashtable();
- this.HttpContext = httpContext ?? HttpContext.Current;
- }
- /// <summary>
- /// 密钥
- /// </summary>
- private string Key;
- protected HttpContext HttpContext;
- /// <summary>
- /// 请求的参数
- /// </summary>
- protected Hashtable Parameters;
- /// <summary>
- /// debug信息
- /// </summary>
- private string DebugInfo;
- /// <summary>
- /// 初始化函数
- /// </summary>
- public virtual void Init()
- {
- }
- /// <summary>
- /// 获取debug信息
- /// </summary>
- /// <returns></returns>
- public String GetDebugInfo()
- {
- return DebugInfo;
- }
- /// <summary>
- /// 获取密钥
- /// </summary>
- /// <returns></returns>
- public string GetKey()
- {
- return Key;
- }
- /// <summary>
- /// 设置密钥
- /// </summary>
- /// <param name="key"></param>
- public void SetKey(string key)
- {
- this.Key = key;
- }
- /// <summary>
- /// 设置参数值
- /// </summary>
- /// <param name="parameter"></param>
- /// <param name="parameterValue"></param>
- public void SetParameter(string parameter, string parameterValue)
- {
- if (parameter != null && parameter != "")
- {
- if (Parameters.Contains(parameter))
- {
- Parameters.Remove(parameter);
- }
- Parameters.Add(parameter, parameterValue);
- }
- }
- /// <summary>
- /// 当参数不为null或空字符串时,设置参数值
- /// </summary>
- /// <param name="parameter"></param>
- /// <param name="parameterValue"></param>
- public void SetParameterWhenNotNull(string parameter, string parameterValue)
- {
- if (!string.IsNullOrEmpty(parameterValue))
- {
- SetParameter(parameter, parameterValue);
- }
- }
- /// <summary>
- /// 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名
- /// </summary>
- /// <param name="key">参数名</param>
- /// <param name="value">参数值</param>
- /// key和value通常用于填充最后一组参数
- /// <returns></returns>
- public virtual string CreateMd5Sign(string key, string value)
- {
- StringBuilder sb = new StringBuilder();
- ArrayList akeys = new ArrayList(Parameters.Keys);
- akeys.Sort();
- foreach (string k in akeys)
- {
- string v = (string)Parameters[k];
- if (null != v && "".CompareTo(v) !=
- && "sign".CompareTo(k) !=
- //&& "sign_type".CompareTo(k) != 0
- && "key".CompareTo(k) != )
- {
- sb.Append(k + "=" + v + "&");
- }
- }
- sb.Append(key + "=" + value);
- string sign = EncryptHelper.GetMD5(sb.ToString(), GetCharset()).ToUpper();
- //string sign = MD5UtilHelper.GetMD5(sb.ToString(), GetCharset()).ToUpper();
- return sign;
- }
- public virtual string CreateMd5Sign()
- {
- StringBuilder sb = new StringBuilder();
- ArrayList akeys = new ArrayList(Parameters.Keys);
- akeys.Sort();
- foreach (string k in akeys)
- {
- string v = (string)Parameters[k];
- if (null != v && "".CompareTo(v) !=
- && "sign".CompareTo(k) !=
- //&& "sign_type".CompareTo(k) != 0
- && "key".CompareTo(k) != )
- {
- sb.Append(k + "=" + v + "&");
- }
- }
- string sign = EncryptHelper.GetMD5(sb.ToString().Substring(,sb.Length-), GetCharset()).ToUpper();
- return sign;
- }
- /// <summary>
- /// 输出XML
- /// </summary>
- /// <returns></returns>
- public string ParseXML()
- {
- StringBuilder sb = new StringBuilder();
- sb.Append("<xml>");
- foreach (string k in Parameters.Keys)
- {
- string v = (string)Parameters[k];
- if (v != null && Regex.IsMatch(v, @"^[0-9.]$"))
- {
- sb.Append("<" + k + ">" + v + "</" + k + ">");
- }
- else
- {
- sb.Append("<" + k + "><![CDATA[" + v + "]]></" + k + ">");
- }
- }
- sb.Append("</xml>");
- return sb.ToString();
- }
- /// <summary>
- /// 设置debug信息
- /// </summary>
- /// <param name="debugInfo"></param>
- public void SetDebugInfo(String debugInfo)
- {
- this.DebugInfo = debugInfo;
- }
- public Hashtable GetAllParameters()
- {
- return this.Parameters;
- }
- protected virtual string GetCharset()
- {
- if (this.HttpContext == null)
- {
- return Encoding.UTF8.BodyName;
- }
- return this.HttpContext.Request.ContentEncoding.BodyName;
- }
- }
- /// <summary>
- /// 微信支付提交的XML Data数据[统一下单]
- /// </summary>
- public class TenPayV3UnifiedorderRequestData
- {
- /// <summary>
- /// 公众账号ID
- /// </summary>
- public string AppId { get; set; }
- /// <summary>
- /// 商户号
- /// </summary>
- public string MchId { get; set; }
- /// <summary>
- /// 自定义参数,可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传"WEB",String(32)如:013467007045764
- /// </summary>
- public string DeviceInfo { get; set; }
- /// <summary>
- /// 随机字符串
- /// </summary>
- public string NonceStr { get; set; }
- /// <summary>
- /// 签名类型,默认为MD5,支持HMAC-SHA256和MD5。(使用默认)
- /// </summary>
- public string SignType { get; set; }
- /// <summary>
- /// 商品信息
- /// </summary>
- public string Body { get; set; }
- /// <summary>
- /// 商品详细列表,使用Json格式,传输签名前请务必使用CDATA标签将JSON文本串保护起来。
- ///cost_price Int 可选 32 订单原价,商户侧一张小票订单可能被分多次支付,订单原价用于记录整张小票的支付金额。当订单原价与支付金额不相等则被判定为拆单,无法享/受/优/惠。
- /// receipt_id String 可选 32 商家小票ID
- ///goods_detail 服务商必填[]:
- ///└ goods_id String 必填 32 商品的编号
- ///└ wxpay_goods_id String 可选 32 微信支付定义的统一商品编号
- ///└ goods_name String 可选 256 商品名称
- ///└ quantity Int 必填 32 商品数量
- ///└ price Int 必填 32 商品单价,如果商户有优惠,需传输商户优惠后的单价
- ///注意:单品总金额应<=订单总金额total_fee,否则会无法享受优惠。
- /// String(6000)
- /// </summary>
- public string Detail { get; set; }
- /// <summary>
- /// 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用。String(127),如:深圳分店
- /// </summary>
- public string Attach { get; set; }
- /// <summary>
- /// 符合ISO 4217标准的三位字母代码,默认人民币:CNY,详细列表请参见货币类型。String(16),如:CNY
- /// </summary>
- public string FeeType { get; set; }
- /// <summary>
- /// 商家订单号
- /// </summary>
- public string OutTradeNo { get; set; }
- /// <summary>
- /// 商品金额,以分为单位(money * 100).ToString()
- /// </summary>
- public int TotalFee { get; set; }
- /// <summary>
- /// 用户的公网ip,不是商户服务器IP
- /// </summary>
- public string SpbillCreateIP { get; set; }
- /// <summary>
- /// 订单生成时间,最终生成格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则。
- /// 如果为空,则默认为当前服务器时间
- /// </summary>
- public string TimeStart { get; set; }
- /// <summary>
- /// 订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则
- /// 注意:最短失效时间间隔必须大于5分钟。
- /// 留空则不设置失效时间
- /// </summary>
- public string TimeExpire { get; set; }
- /// <summary>
- /// 商品标记,使用代金券或立减优惠功能时需要的参数,说明详见代金券或立减优惠。String(32),如:WXG
- /// </summary>
- public string GoodsTag { get; set; }
- /// <summary>
- /// 接收财付通通知的URL
- /// </summary>
- public string NotifyUrl { get; set; }
- /// <summary>
- /// 交易类型
- /// </summary>
- public TenPayV3Type TradeType { get; set; }
- /// <summary>
- /// trade_type=NATIVE时(即扫码支付),此参数必传。此参数为二维码中包含的商品ID,商户自行定义。
- /// String(32),如:12235413214070356458058
- /// </summary>
- public string ProductId { get; set; }
- /// <summary>
- /// 上传此参数no_credit--可限制用户不能使用信用卡支付
- /// </summary>
- public string LimitPay { get; set; }
- /// <summary>
- /// 用户的openId
- /// </summary>
- public string OpenId { get; set; }
- /// <summary>
- ///
- /// </summary>
- public string Key { get; set; }
- public readonly RequestHandler PackageRequestHandler;
- public readonly string Sign;
- /// <summary>
- ///
- /// </summary>
- /// <param name="appId"></param>
- /// <param name="mchId"></param>
- /// <param name="body"></param>
- /// <param name="outTradeNo"></param>
- /// <param name="totalFee">单位:分</param>
- /// <param name="spbillCreateIp"></param>
- /// <param name="notifyUrl"></param>
- /// <param name="tradeType"></param>
- /// <param name="openid"></param>
- /// <param name="key"></param>
- /// <param name="nonceStr"></param>
- /// <param name="deviceInfo">自定义参数,可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传"WEB",String(32)如:013467007045764</param>
- /// <param name="timeStart">订单生成时间,如果为空,则默认为当前服务器时间</param>
- /// <param name="timeExpire">订单失效时间,留空则不设置失效时间</param>
- /// <param name="detail">商品详细列表</param>
- /// <param name="attach">附加数据</param>
- /// <param name="feeType">符合ISO 4217标准的三位字母代码,默认人民币:CNY</param>
- /// <param name="goodsTag">商品标记,使用代金券或立减优惠功能时需要的参数,说明详见代金券或立减优惠。String(32),如:WXG</param>
- /// <param name="productId">trade_type=NATIVE时(即扫码支付),此参数必传。此参数为二维码中包含的商品ID,商户自行定义。String(32),如:12235413214070356458058</param>
- /// <param name="limitPay">是否限制用户不能使用信用卡支付</param>
- public TenPayV3UnifiedorderRequestData(string appId, string mchId, string body, string outTradeNo, int totalFee, string spbillCreateIp,
- string notifyUrl, TenPayV3Type tradeType, string openid, string key, string nonceStr,
- string deviceInfo = null, DateTime? timeStart = null, DateTime? timeExpire = null,
- string detail = null, string attach = null, string feeType = "CNY", string goodsTag = null, string productId = null, bool limitPay = false)
- {
- AppId = appId;
- MchId = mchId;
- DeviceInfo = deviceInfo;
- NonceStr = nonceStr;
- SignType = "MD5";
- Body = body ?? "";
- Detail = detail;
- Attach = attach;
- OutTradeNo = outTradeNo;
- FeeType = feeType;
- TotalFee = totalFee;
- SpbillCreateIP = spbillCreateIp;
- TimeStart = (timeStart ?? DateTime.Now).ToString("yyyyMMddHHmmss");
- TimeExpire = timeExpire.HasValue ? timeExpire.Value.ToString("yyyyMMddHHmmss") : null;
- GoodsTag = goodsTag;
- NotifyUrl = notifyUrl;
- TradeType = tradeType;
- ProductId = productId;
- LimitPay = limitPay ? "no_credit" : null;
- OpenId = openid;
- Key = key;
- #region 设置RequestHandler
- //创建支付应答对象
- PackageRequestHandler = new RequestHandler(null);
- //初始化
- PackageRequestHandler.Init();
- //设置package订单参数
- //以下设置顺序按照官方文档排序,方便维护:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
- PackageRequestHandler.SetParameter("appid", this.AppId); //公众账号ID
- PackageRequestHandler.SetParameter("mch_id", this.MchId); //商户号
- PackageRequestHandler.SetParameterWhenNotNull("device_info", this.DeviceInfo); //自定义参数
- PackageRequestHandler.SetParameter("nonce_str", this.NonceStr); //随机字符串
- PackageRequestHandler.SetParameterWhenNotNull("sign_type", this.SignType); //签名类型,默认为MD5
- PackageRequestHandler.SetParameter("body", this.Body); //商品信息
- PackageRequestHandler.SetParameterWhenNotNull("detail", this.Detail); //商品详细列表
- PackageRequestHandler.SetParameterWhenNotNull("attach", this.Attach); //附加数据
- PackageRequestHandler.SetParameter("out_trade_no", this.OutTradeNo); //商家订单号
- PackageRequestHandler.SetParameterWhenNotNull("fee_type", this.FeeType); //符合ISO 4217标准的三位字母代码,默认人民币:CNY
- PackageRequestHandler.SetParameter("total_fee", this.TotalFee.ToString()); //商品金额,以分为单位(money * 100).ToString()
- PackageRequestHandler.SetParameter("spbill_create_ip", this.SpbillCreateIP); //用户的公网ip,不是商户服务器IP
- PackageRequestHandler.SetParameterWhenNotNull("time_start", this.TimeStart); //订单生成时间
- PackageRequestHandler.SetParameterWhenNotNull("time_expire", this.TimeExpire); //订单失效时间
- PackageRequestHandler.SetParameterWhenNotNull("goods_tag", this.GoodsTag); //商品标记
- PackageRequestHandler.SetParameter("notify_url", this.NotifyUrl); //接收财付通通知的URL
- PackageRequestHandler.SetParameter("trade_type", this.TradeType.ToString()); //交易类型
- PackageRequestHandler.SetParameterWhenNotNull("product_id", this.ProductId); //trade_type=NATIVE时(即扫码支付),此参数必传。
- PackageRequestHandler.SetParameterWhenNotNull("limit_pay", this.LimitPay); //上传此参数no_credit--可限制用户不能使用信用卡支付
- PackageRequestHandler.SetParameter("openid", this.OpenId); //用户的openId,trade_type=JSAPI时(即公众号支付),此参数必传
- Sign = PackageRequestHandler.CreateMd5Sign("key", this.Key);
- PackageRequestHandler.SetParameter("sign", Sign); //签名
- #endregion
- }
- }
统一下单
- /// <summary>
- /// 统一支付接口
- /// 统一支付接口,可接受JSAPI/NATIVE/APP 下预支付订单,返回预支付订单号。NATIVE 支付返回二维码code_url。
- /// </summary>
- /// <param name="dataInfo">微信支付需要post的Data数据</param>
- /// <param name="timeOut"></param>
- /// <returns></returns>
- public static UnifiedorderResult Unifiedorder(TenPayV3UnifiedorderRequestData dataInfo, int timeOut = Config.TIME_OUT)
- {
- var urlFormat = "https://api.mch.weixin.qq.com/pay/unifiedorder";
- var data = dataInfo.PackageRequestHandler.ParseXML();//获取XML
- //throw new Exception(data.HtmlEncode());
- MemoryStream ms = new MemoryStream();
- var formDataBytes = data == null ? new byte[] : Encoding.UTF8.GetBytes(data);
- ms.Write(formDataBytes, , formDataBytes.Length);
- ms.Seek(, SeekOrigin.Begin);//设置指针读取位置
- var resultXml = RequestUtility.HttpPost(urlFormat, null, ms, timeOut: timeOut);
- return new UnifiedorderResult(resultXml);
- }
统一支付接口
步骤2:统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式为Sign=WXPay,签名的字段数量必须跟你app调起微信支付所传的参数一致:
- /// <summary>
- /// 生成微信app支付前面
- /// </summary>
- /// <param name="appId"></param>
- /// <param name="timeStamp"></param>
- /// <param name="nonceStr"></param>
- /// <param name="package"></param>
- /// <param name="key"></param>
- /// <param name="partnerid"></param>
- /// <param name="prepayid"></param>
- /// <param name="signType"></param>
- /// <returns></returns>
- public static string GetAppPaySign(string appId
- , string timeStamp, string nonceStr, string package,
- string key,string partnerid,string prepayid,string signType = "MD5"
- )
- {
- RequestHandler paySignReqHandler = new RequestHandler(null);
- paySignReqHandler.SetParameter("appid", appId.Trim());
- paySignReqHandler.SetParameter("timestamp", timeStamp.Trim());
- paySignReqHandler.SetParameter("noncestr", nonceStr.Trim());
- paySignReqHandler.SetParameter("partnerid", partnerid);
- paySignReqHandler.SetParameter("prepayid", prepayid);
- paySignReqHandler.SetParameter("package", package.Trim());
- //paySignReqHandler.SetParameter("signtype", "MD5");
- var paySign = paySignReqHandler.CreateMd5Sign("key", key);
- return paySign;
- }
生成微信app支付签名
步骤3:商户APP调起微信支付。详细介绍参见微信支付官方文档
关键代码如下:
- public static IWXAPI api;
- api= WXAPIFactory.createWXAPI(this, Constants.APP_ID,true);
- api.registerApp(Constants.APP_ID);
- Result result = JSON.parseObject(bytes, Result.class);
- if (null != result) {
- if (result.isSuccess()) {
- prepay prepay = JSON.parseObject(result.getData().toString(), prepay.class);
- PayReq request = new PayReq();
- request.appId = prepay.getAppid();
- request.partnerId =prepay.getPartnerid();
- request.prepayId= prepay.getPrepayid();
- request.packageValue = prepay.getPackages();
- request.nonceStr= prepay.getNoncestr();
- request.timeStamp=prepay.getTimestamp();
- request.sign= prepay.getSign();
- api.sendReq(request);
- }
- }
android调起支付相关代码
其中result.getData()表示服务端返回的预支付订单的相关参数,用这参数调用微信支付,该activity必须实现接口IWXAPIEventHandler,并实现
- @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)通知商户支付结果,商户后台校验相关信息
- [AllowAnonymous]
- public ActionResult PayResult()
- {
- ResponseHandler resHandler = new ResponseHandler(null);
- string return_code = resHandler.GetParameter("return_code");
- string return_msg = resHandler.GetParameter("return_msg");
- string res = null;
- EngineContext.Current.Resolve<ILogger>().Information("收到微信支付通知"+resHandler.ParseXML());
- //EngineContext.Current.Resolve<ILoggingService>().Write(LogType.Pay, resHandler.ParseXML());
- string orderno = resHandler.GetParameter("out_trade_no");
- string payno = resHandler.GetParameter("transaction_id");
- string nonce_str = resHandler.GetParameter("nonce_str");
- var order = _wechatService.GetWechatPayResult(orderno);
- if (order != null)
- {
- var first = order.FirstOrDefault(r => r.nonce_str == nonce_str);
- if (first != null)
- {
- var payProvider = _wechatService.GetWechatPayProvider(first.appid);
- resHandler.SetKey(payProvider.MchKey);
- if (resHandler.IsTenpaySign())
- {
- if (return_code == TenPayTypeResult.SUCCESS.ToString())
- {
- int totaled= int.Parse(resHandler.GetParameter("total_fee"));
- if (totaled == first.total_fee)
- {
- first.IsSuccess = true;
- first.time_end = DateTime.Now;
- first.total_fee_ed = int.Parse(resHandler.GetParameter("total_fee"));
- first.transaction_id = payno;
- first.Content = resHandler.ParseXML();
- _wechatService.UpdateWechatPayResult(first);
- EngineContext.Current.Resolve<IEventPublisher>().Publish(resultEvent);
- }else
- {
- EngineContext.Current.Resolve<ILogger>().Information("微信支付金额与订单金额不匹配" + resHandler.ParseXML());
- }
- }
- }
- }
- //验证请求是否从微信发过来(安全)
- string xml = string.Format(@"<xml>
- <return_code><![CDATA[{0}]]></return_code>
- <return_msg><![CDATA[{1}]]></return_msg>
- </xml>", return_code, return_msg);
- return Content(xml, "text/xml");
- }
微信回调通知参考代码
微信.NET集成可参考现有轮子 JeffreySu/WeiXinMPSDK
微信app支付android客户端以及.net服务端实现的更多相关文章
- 微信app支付(android端+java后台)
本文讲解使用微信支付接口完成在android开发的原生态app中完成微信支付功能, 文章具体讲解了前端android如何集成微信支付功能以及后台如何组装前端需要支付信息, 话不多话, 具体看文章内容吧 ...
- 微信移动支付V3开发详细教程服务端采用.net mvc webapi(C#)
转自:http://www.kwstu.com/ArticleView/netmvc_201511132050268716 最近开发手机app需要实现移动支付功能,由于考虑支付安全将微信支付生成签名写 ...
- Android客户端与PHP服务端交互(一)---框架概述
背景 作为一个普通上班族,总是想做一些自认为有意义的事情,于是乎准备成立一个工作室,尽管目前正在筹备阶段,但是之前有些朋友提出一些需求的时候,我发现自己的能力还是有限,直到最近和一些技术牛朋友聊起这事 ...
- Android客户端与PC服务端、android服务端通过WiFi通信
前期准备:我的是Linux Mint操作系统(总之折腾的过程中怀疑过是不是系统的问题),首先是要创建wifi热点给android手机使用,这个时候笔记本作为通信的服务器端,android手机作为客户端 ...
- android客户端向java服务端post发送json
android 端: private void HttpPostData() { try { HttpClient httpclient = new DefaultHttpClient( ...
- Android客户端转换php服务端获取的时间戳的转换
今天在用JSON获取后台的数据的时候,发现一个奇怪的现象就是返回来的时间戳都是1970年这样的,很是纠结,最后发现时php和Java中时间的格式不一样造成的,所以我们本地客户端要做一个转换: /** ...
- Android版-微信APP支付
首发地址: Android版-微信APP支付 欢迎留言.转发 微信极速开发系列文章(微信支付.授权获取用户信息等):点击这里 目录 1.注册账号.开发者认证 2.添加应用 3.申请微信支付 4.技术开 ...
- 微信支付-微信公众号支付,微信H5支付,微信APP支付,微信扫码支付
在支付前,如果使用第三方MVC框架,则使用重写模式,服务器也需要配置该项 if (!-e $request_filename){ rewrite ^/(.*)$ /index.php/$ last; ...
- asp.net core 微信APP支付(扫码支付,H5支付,公众号支付,app支付)之4
微信app支付需要以下参数,类封装如下 public class WxPayModel { /// <summary> /// 应用ID /// </summary> publ ...
随机推荐
- 微信小程序选项卡功能
首先看看微信小程序上的选项卡的效果 原理呢,就是先布局好(这就不必说了吧),然后在上面的每一个选项卡上都定义一个同样的点击事件,然后给每一个组件上绑定一个唯一的标识符,然后点击事件触发的时候,获取到绑 ...
- Android hook神器frida(一)
运行环境 ● Python – latest 3.x is highly recommended ● Windows, macOS, or Linux安装方法使用命令 sudo pip install ...
- HDU 2255 奔小康赚大钱(带权二分图最大匹配)
HDU 2255 奔小康赚大钱(带权二分图最大匹配) Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊 ...
- (转)示例化讲解RIP路由更新机制
目录(?)[+] 以下内容摘自最新上市的“四大金刚”图书之一<Cisco路由器配置与管理完全手册>(第二版)(其它三本分别为<Cisco交换机配置与管理完全手册>(第二 ...
- Cocoapods最新安装教程
一.CocoaPods简介 每种语言发展到一个阶段,就会出现相应的依赖管理工具,例如 Java 语言的 Maven,nodejs 的 npm.随着 iOS 开发者的增多,业界也出现了为 iOS 程序提 ...
- Spring源码情操陶冶-AbstractApplicationContext#invokeBeanFactoryPostProcessors
阅读源码有利于陶冶情操,承接前文Spring源码情操陶冶-AbstractApplicationContext#postProcessBeanFactory 约定:web.xml中配置的context ...
- 【css】盒子模型 之 概述
摘要 一些基本的概念以及常见使用问题 概述 BFC 是css 中布局的核心 - 盒模型,根据块级元素及行级元素可分为块级容器, 行级容器,但容器内部都遵循 BFC BFC 空间布局 备注: IE 的盒 ...
- mysql的并发处理机制_上篇
回来写博客,少年前端时间被django迷了心魄 如果转载,请注明博文来源: www.cnblogs.com/xinysu/ ,版权归 博客园 苏家小萝卜 所 ...
- SQL Server ---T-SQl基本语句
T-SQL 是 SQL-Server 的结构化查询语言. 基本数据操作语言. 基础语句 先创建表 我后面的列子都是用的这一个表,列名啥的 就大概看看吧~~ 纯粹为了学习语句,语法~~所以先创建个表吧~ ...
- H5微信通过百度地图API实现导航方式二
要有服务器才行哦 <!DOCTYPE html><html><head> <meta http-equiv="Content-Type&quo ...