.Net 微信开发与微信支付
.NET
https://github.com/JeffreySu/WeiXinMPSDK
JAVA
http://git.oschina.net/pyinjava/fastweixin
NodeJS
https://github.com/node-weixin/node-weixin-api
Python
http://git.oschina.net/jeffkit/wechat
微信消息配置
已.NET 为例子,WeiXinMPSDK支持公众号与企业号,实现起来也比较简单

/// <summary>
/// 微信控制器
/// </summary>
public class WeixinController : Controller
{
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
public readonly string token = DbSetting.getAppText("Token");
public readonly string appId = DbSetting.getAppText("AppID");
public readonly string encodingAESKey = DbSetting.getAppText("EncodingAESKey"); /// <summary>
/// 微信验签
/// </summary>
/// <param name="signature"></param>
/// <param name="timestamp"></param>
/// <param name="nonce"></param>
/// <param name="echostr"></param>
/// <returns></returns>
[HttpGet]
public async Task<ActionResult> Index(string signature, string timestamp, string nonce, string echostr)
{
return await Task.Run(() =>
{
if (!CheckSignature.Check(signature, timestamp, nonce, token))
{
return "failed:" + signature + "," + CheckSignature.GetSignature(timestamp, nonce, token) + "。如果你在浏览器中看到这句话,说明此地址可以被作为微信公众账号后台的Url,请注意保持Token一致。";
}
return echostr;
}).ContinueWith(task => Content(task.Result));
} /// <summary>
/// 处理微信消息
/// </summary>
/// <param name="postModel">参数</param>
/// <returns></returns>
[HttpPost]
public async Task<ActionResult> Index(PostModel postModel)
{
return await Task.Run<ActionResult>(() =>
{
if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, token))
{
return new WeixinResult("参数错误!");
}
postModel.Token = token;
postModel.EncodingAESKey = encodingAESKey;
postModel.AppId = appId;
var messageHandler = new MpWeixinMessageHandler(Request.InputStream, postModel);
messageHandler.Execute();
return new FixWeixinBugWeixinResult(messageHandler);
}).ContinueWith(task => task.Result);
}
}

消息重载

/// <summary>
/// 处理微信消息
/// </summary>
public class MpWeixinMessageHandler : MessageHandler<MessageContext<IRequestMessageBase, IResponseMessageBase>>
{
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
public readonly string appId = DbSetting.getAppText("AppID");
public readonly string appSecret = DbSetting.getAppText("AppSecret"); /// <summary>
/// 构造函数
/// </summary>
/// <param name="inputStream"></param>
/// <param name="postModel"></param>
public MpWeixinMessageHandler(Stream inputStream, PostModel postModel)
: base(inputStream, postModel)
{
WeixinContext.ExpireMinutes = 5;
} /// <summary>
/// 默认消息 [没有重写的OnXX方法,将默认返回DefaultResponseMessage中的结果]
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns> public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
{
//ResponseMessageText也可以是News等其他类型
var responseMessage = this.CreateResponseMessage<ResponseMessageText>();
responseMessage.Content = "这条消息来自DefaultResponseMessage。";
return responseMessage;
} /// <summary>
/// 关注微信公众号
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase OnEvent_SubscribeRequest(RequestMessageEvent_Subscribe requestMessage)
{
var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageText>(requestMessage);
var token = CommonApi.GetToken(appId, appSecret).access_token;
var user = CommonApi.GetUserInfo(token, requestMessage.FromUserName);
responseMessage.Content = "Hi " + user.nickname + " ,感谢您关注XXX!!!";
return responseMessage;
} /// <summary>
/// 取消关注公众号
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase OnEvent_UnsubscribeRequest(RequestMessageEvent_Unsubscribe requestMessage)
{
return base.OnEvent_UnsubscribeRequest(requestMessage);
} /// <summary>
/// 发送文本消息
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
{
var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageText>(requestMessage);
responseMessage.Content = "感谢您关注XXX!!! ";
return responseMessage;
}
}

微信支付签名

#region 创建订单与生成微信支付 JSAPPI 签名
/// <summary>
/// 创建订单与生成微信支付 JSAPPI 签名
/// </summary>
/// <param name="create">订餐参数</param>
/// <returns></returns>
[HttpPost]
public async Task<ActionResult> Create(Create create)
{
try
{
logger.Info("orders create xml: " + create.ToXml());
if (!ModelState.IsValid)
return Json(new { IsError = true, ErrorMsg = "创建订单参数异常!!!", Data = string.Empty }, JsonRequestBehavior.AllowGet);
//取购物车缓存
var cart = CacheManger.Cache.Get<CartInfoModel>(create.OpenId);
if (cart.IsNull() || cart.ShopId.IsNullOrEmpty() || cart.OpenID.IsNullOrEmpty() || cart.OpenID != create.OpenId || cart.CartItemList.IsNull() || cart.CartItemList.Count == 0)
return Json(new { IsError = true, ErrorMsg = "创建订单参数异常!!!", Data = string.Empty }, JsonRequestBehavior.AllowGet);
//控制库存与订单事物
using (var conn = new SqlConnection(DbSetting.App))
{
await conn.OpenAsync();
var trans = conn.BeginTransaction(); //验证价格及库存[重要] //创建订单
string subject = @"xxx支付";
string orderNo = WxPayConfig.OutTradeNo;
//!!! 1分钱测试 !!!
decimal total_fee = 0.01m;
var executeNum = await conn.ExecuteAsync(@"INSERT INTO Orders
(
Origin,
ShopId,
OpenId,
Name,
PhoneNo,
[Subject],
OrderNo,
[Status],
TotalFee,
Coupon,
Memo,
CreateTime
)
VALUES
(
@Origin,
@ShopId,
@OpenId,
@Name,
@PhoneNo,
@Subject,
@OrderNo,
@Status,
@TotalFee,
@Coupon,
@Memo,
@CreateTime
)", new
{
Origin = AbpConstants.WEIXIN_ORIGIN,
OpenId = create.OpenId,
ShopId = Guid.Parse(cart.ShopId),
Name = create.UserName,
PhoneNo = create.Phone,
Subject = subject,
OrderNo = orderNo,
Status = "R",
TotalFee = cart.TotalPrice,
Coupon = "0",
Memo = string.Empty,
CreateTime = DateTime.Now
}, trans);
if (executeNum <= 0)
{
trans.Rollback();
return Json(new { IsError = true, ErrorMsg = "创建订单异常!!!", Data = string.Empty }, JsonRequestBehavior.AllowGet);
}
foreach (var item in cart.CartItemList.Where(t => t.CartNum != 0))
{
executeNum = conn.Execute(@"INSERT INTO OrderDetail
(
OrderId,
ItemId,
ItemName,
Num,
UnitPrice,
TotalFee
)
VALUES
(
@OrderId,
@ItemId,
@ItemName,
@Num,
@UnitPrice,
@TotalFee
)", new
{
OrderId = orderNo,
ItemId = item.ItemId,
ItemName = item.ItemName,
Num = item.CartNum,
UnitPrice = item.Price,
TotalFee = item.Price * item.CartNum
}, trans);
if (executeNum <= 0)
{
trans.Rollback();
return Json(new { IsError = true, ErrorMsg = "创建订单明细异常!!!", Data = string.Empty }, JsonRequestBehavior.AllowGet);
}
}
//提交事物
trans.Commit();
var wxpay = await Order(WxPayConfig.APPID, create.OpenId, WxPayConfig.MCHID, orderNo, total_fee, WxPayConfig.NonceStr, subject, "没有优惠券", "XXX");
if (wxpay.IsError)
{
return Redirect(DbSetting.getAppText("Domain") + @"/oauth/1");
}
var jsApiDict = new SortedDictionary<string, string>();
jsApiDict.Add("appId", appId);
jsApiDict.Add("timeStamp", WxPayConfig.TimeStamp);
jsApiDict.Add("nonceStr", WxPayConfig.NonceStr);
jsApiDict.Add("package", "prepay_id=" + (wxpay.Data as SortedDictionary<string, string>)["prepay_id"]);
jsApiDict.Add("signType", "MD5");
jsApiDict.Add("paySign", WxPayConfig.GenerateSign(jsApiDict));
return Json(new { IsError = false, ErrorMsg = string.Empty, Data = jsApiDict.ConvertDictionaryToJson() }, JsonRequestBehavior.AllowGet);
}
}
catch (Exception ex)
{
logger.Info("orders create xml: " + create.ToXml() + " exception message: " + ex.Message);
return Json(new
{
IsError = true,
ErrorMsg = "创建订单异常!!!",
Data = string.Empty
}, JsonRequestBehavior.AllowGet);
}
}
#endregion #region 微信支付签名
/// <summary>
/// 微信支付签名
/// </summary>
/// <param name="appid">公众账号ID</param>
/// <param name="openid">微信唯一标识</param>
/// <param name="mch_id">商户号</param>
/// <param name="out_trade_no">商户订单号</param>
/// <param name="total_fee">订单总金额,单位为分</param>
/// <param name="nonce_str">随机字符串</param>
/// <param name="body"></param>
/// <param name="goods_tag"></param>
/// <param name="attach"></param>
/// <returns></returns>
private async Task<WebAPIResponse> Order(string appid, string openid, string mch_id, string out_trade_no, decimal total_fee, string nonce_str, string body, string goods_tag, string attach)
{
try
{
//网页端调起支付API
//https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6
//统一下单
//https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
var dict = new SortedDictionary<string, string>();
dict.Add("appid", appid);
dict.Add("openid", openid);
dict.Add("mch_id", mch_id);
dict.Add("nonce_str", nonce_str);
dict.Add("out_trade_no", out_trade_no);
//订单总金额,单位为分
dict.Add("total_fee", Convert.ToInt32(total_fee * 100).ToString());
//附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
dict.Add("attach", attach);
dict.Add("body", body);
dict.Add("trade_type", WxPayConfig.TRADETYPE);
//终端IP
dict.Add("spbill_create_ip", AbpConstants.Ip());
dict.Add("notify_url", DbSetting.getAppText("NOTIFY_URL"));
//商品标记,代金券或立减优惠功能的参数
dict.Add("goods_tag", goods_tag);
dict.Add("time_expire", DateTime.Now.AddMinutes(30).ToString("yyyyMMddHHmmss"));
dict.Add("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));
dict.Add("sign", WxPayConfig.GenerateSign(dict));
string xml = "<xml>";
foreach (var pair in dict)
{
if (pair.Value.GetType() == typeof(int))
{
xml += "<" + pair.Key + ">" + pair.Value + "</" + pair.Key + ">";
}
else if (pair.Value.GetType() == typeof(string))
{
xml += "<" + pair.Key + ">" + "<![CDATA[" + pair.Value + "]]></" + pair.Key + ">";
}
}
xml += "</xml>";
logger.Info("OrdersController unifiedorder Req xml: " + xml);
var data = await @"https://api.mch.weixin.qq.com/pay/unifiedorder".PostStringAsync(xml).ReceiveString();
logger.Info("OrdersController unifiedorder Resp xml: " + data);
if (data.IsNotNullOrEmpty() && data.Contains("SUCCESS", StringComparison.OrdinalIgnoreCase))
{
return new WebAPIResponse { IsError = false, Msg = "签名成功", Data = data.ConvertWeixinXmlToSortedDictionary() };
}
return new WebAPIResponse { IsError = true, Msg = "微信支付签名失败" };
}
catch (Exception ex)
{
logger.Error("OrdersController unifiedorder Exception :" + ex.Message);
return new WebAPIResponse { IsError = true, Msg = "微信支付签名失败" };
}
}
#endregion #region 微信订单查询
/// <summary>
/// 微信订单查询
/// </summary>
/// <param name="appid">公众账号ID</param>
/// <param name="mch_id">商户号</param>
/// <param name="transaction_id">微信的订单号</param>
/// <param name="out_trade_no">商户订单号</param>
/// <param name="nonce_str">随机字符串</param>
/// <param name="sign">签名</param>
/// <returns></returns>
private async Task<WebAPIResponse> Query(string appid, string mch_id, string transaction_id, string out_trade_no, string nonce_str, string sign)
{
if (appid.IsEmpty() || mch_id.IsEmpty() || transaction_id.IsEmpty())
{
return new WebAPIResponse { IsError = true, Msg = "参数有误!!!" };
}
try
{
var dict = new Dictionary<string, string>();
dict.Add("appid", appid);
dict.Add("mch_id", mch_id);
dict.Add("transaction_id", transaction_id);
dict.Add("out_trade_no", out_trade_no);
dict.Add("nonce_str", nonce_str);
dict.Add("sign", sign);
string xml = "<xml>";
foreach (var pair in dict)
{
if (pair.Value.GetType() == typeof(int))
{
xml += "<" + pair.Key + ">" + pair.Value + "</" + pair.Key + ">";
}
else if (pair.Value.GetType() == typeof(string))
{
xml += "<" + pair.Key + ">" + "<![CDATA[" + pair.Value + "]]></" + pair.Key + ">";
}
}
xml += "</xml>";
logger.Info("OrdersController WeixinNotify Req xml: " + xml);
var data = await @"https://api.mch.weixin.qq.com/pay/orderquery".PostStringAsync(xml).ReceiveString();
logger.Info("OrdersController WeixinNotify Resp xml: " + data);
if (data.IsNotNullOrEmpty() && data.Contains("SUCCESS", StringComparison.OrdinalIgnoreCase))
{
return new WebAPIResponse { IsError = false, Data = "查询订单成功!!!" };
}
return new WebAPIResponse { IsError = true, Msg = "微信订单查询失败!!!" };
}
catch (Exception ex)
{
logger.Error("OrdersController Exception :" + ex.Message);
return new WebAPIResponse { IsError = true, Msg = ex.Message };
}
}
#endregion

JS签名调起支付窗口

<script type="text/javascript">
if (typeof WeixinJSBridge == "undefined") {
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
} else {
onBridgeReady();
}
@*@Html.Raw(Model.WeixinJsAPI)*@
function onBridgeReady() {
WeixinJSBridge.invoke(
'getBrandWCPayRequest', $.parseJSON(document.getElementById("WeixinJsAPI").value),
function (data) {
if (data.err_msg == 'get_brand_wcpay_request:ok') {
window.location.href = ' @Url.Content("~/oauth/orders")';
} else {
$('.confirmbtn').removeAttr('disabled').css('background-color', '#80D200');
}
}
);
}
</script>

微信异步回调消息

/// <summary>
/// 微信支付异步通知
/// </summary>
/// <returns></returns>
public async Task<ActionResult> Notify()
{
int intLen = Convert.ToInt32(Request.InputStream.Length);
if (intLen <= 0)
{
return Json(new { IsError = true, ErrorMsg = "没有微信支付异步参数!!! ", Data = string.Empty }, JsonRequestBehavior.AllowGet);
}
try
{
var dict = new SortedDictionary<string, string>();
//dict = @"appid=wx0ae16b319cd984cf&attach=XXX&bank_type=CFT&cash_fee=1&fee_type=CNY&is_subscribe=Y&mch_id=1287151001&nonce_str=40f11a82cdde44588ec7d6b6bf9cca9d&openid=oxf8ns9AW1IwSwskzglgMH69t38o&out_trade_no=2015121621484780479309&result_code=SUCCESS&return_code=SUCCESS&sign=21C2A8727668E030BF801AB5B701BF93&time_end=20151216214906&total_fee=1&trade_type=JSAPI&transaction_id=1002230068201512162126471549".ConvertStringToSortedDictionary();
var xmlDoc = new XmlDocument();
xmlDoc.Load(Request.InputStream);
var root = xmlDoc.SelectSingleNode("xml");
XmlNodeList xnl = root.ChildNodes;
foreach (XmlNode xnf in xnl)
{
dict.Add(xnf.Name, xnf.InnerText);
}
if (dict.Count <= 0)
{
return Json(new { IsError = true, ErrorMsg = "没有异步参数!!! ", Data = string.Empty }, JsonRequestBehavior.AllowGet);
}
logger.Info("【 WeixinController Notify SDKUtil.ConvertDictionaryToString : 请求报文=[" + dict.ConvertDictionaryToString() + "]\n");
//验证签名
string signK = WxPayConfig.GenerateSign(dict);
if (signK != dict["sign"])
{
logger.Info("WeixinController Notify Verify WxSign Error : 请求报文=[signK " + signK + " : dict['sign'] " + dict["sign"] + "]\n");
return Json(new { IsError = true, ErrorMsg = "验证签名失败 !!! ", Data = string.Empty }, JsonRequestBehavior.AllowGet);
}
//验证通信标识
string return_code = dict["return_code"];
if (!return_code.Equals("SUCCESS", StringComparison.OrdinalIgnoreCase))
{
string return_msg = dict["return_msg"];
logger.Info("WeixinController Notify return_code Error : 请求报文=[" + return_code + " : " + return_msg + "]\n");
return Json(new { IsError = true, ErrorMsg = "验证通信标识失败 !!! ", Data = string.Empty }, JsonRequestBehavior.AllowGet);
}
//验证交易标识[重要!!!]
string result_code = dict["result_code"];
if (!result_code.Equals("SUCCESS", StringComparison.OrdinalIgnoreCase))
{
string err_code = dict["err_code"];
string err_code_des = dict["err_code_des"];
logger.Info("WeixinController Notify return_code Error : 请求报文=[" + err_code + " : " + err_code_des + "]\n");
return Json(new { IsError = true, ErrorMsg = "验证交易标识失败 !!! ", Data = string.Empty }, JsonRequestBehavior.AllowGet);
}
//公众账号ID
string appid = dict["appid"];
//商户号
string mch_id = dict["mch_id"];
//随机字符串
string nonce_str = dict["nonce_str"];
//签名
string sign = dict["sign"];
//用户在商户appid 下的唯一标识
string openid = dict["openid"];
//用户是否关注公众账
string is_subscribe = dict["is_subscribe"];
//交易类型
string trade_type = dict["trade_type"];
//付款银行
string bank_type = dict["bank_type"];
//订单总金额[金额分转元]
string total_fee = (float.Parse(dict["total_fee"]) / 100).ToString();
//商户订单号
string out_trade_no = dict["out_trade_no"];
//微信支付订单号
string transaction_id = dict["transaction_id"];
//商家数据包
string attach = dict["attach"];
//支付完成时间
string time_end = dict["time_end"]; #region 微信订单查询【使用签名验证废弃】
//var wxorder = await _weixinService.Query(WxPayConfig.KEY, WxPayConfig.APPID, WxPayConfig.MCHID, transaction_id, out_trade_no);
#endregion //验证查询订单状态[R 预定状态 C 取消状态 P 支付完成 I 取单完成 D 送货状态]
var order = await new SqlConnection(DbSetting.App).QueryAsync<Orders>(@"SELECT *FROM Orders WHERE OrderNo=@OrderNo", new { OrderNo = out_trade_no }).ContinueWith(t => t.Result.SingleOrDefault());
if (order.IsNull() || order.Status.Trim() != "R" || order.TradeNO.IsNotNullOrEmpty() || order.PayFee.IsNotNullOrEmpty())
{
logger.Error("WeixinController Notify order Error xml : " + order.ToXml() + string.Format(" 订单: {0} 信息不正确,如有疑问请联系客服!", out_trade_no));
return Json(new { IsError = true, ErrorMsg = "验证查询订单状态失败 !!! ", Data = string.Empty }, JsonRequestBehavior.AllowGet);
}
using (var conn = new SqlConnection(DbSetting.App))
{
await conn.OpenAsync();
var trans = conn.BeginTransaction();
//记录微信异步信息
var executeNum = await conn.ExecuteAsync(@"INSERT INTO PayNotify
(
openid,
is_subscribe,
trade_type,
bank_type,
transaction_id,
out_trade_no,
total_fee,
coupon_fee,
attach,
memo,
time_end,
createtime
)
VALUES
(
@openid,
@is_subscribe,
@trade_type,
@bank_type,
@transaction_id,
@out_trade_no,
@total_fee,
@coupon_fee,
@attach,
@memo,
@time_end,
@createtime
)", new
{
openid = openid,
is_subscribe = is_subscribe,
trade_type = trade_type,
bank_type = bank_type,
transaction_id = transaction_id,
out_trade_no = out_trade_no,
total_fee = total_fee,
coupon_fee = 0.0m,
attach = attach,
memo = dict.ConvertDictionaryToJson(),
time_end = time_end,
createtime = DateTime.Now
}, trans);
if (executeNum <= 0)
{
trans.Rollback();
return Json(new { IsError = true, ErrorMsg = "记录微信异步信息异常!!!", Data = string.Empty }, JsonRequestBehavior.AllowGet);
}
//更新订单支付信息
executeNum = await conn.ExecuteAsync(@"UPDATE Orders SET Status = 'P', TradeNO = @TradeNO, PayFee = @PayFee, PayTime = GETDATE()", new
{
TradeNO = transaction_id,
PayFee = total_fee,
}, trans);
if (executeNum <= 0)
{
trans.Rollback();
return Json(new { IsError = true, ErrorMsg = "更新订单支付信息异常!!!", Data = string.Empty }, JsonRequestBehavior.AllowGet);
}
//!!! 扣菜品库存 trans.Commit();
}
//构造成功XML
var wxdict = new SortedDictionary<string, string>();
wxdict.Add("return_code", "SUCCESS");
wxdict.Add("return_msg", "PAY_SUCCESS");
string wxRXml = wxdict.ConvertWxDictToString();
logger.Info("WeixinController Notify Success wxRXml : " + wxRXml + " 】");
return Content(wxRXml,@"text/xml",System.Text.Encoding.UTF8);
}
catch (Exception ex)
{
logger.Fatal("WeixinController Notify Exception : " + ex.Message + " 】");
return Json(new { IsError = true, ErrorMsg = "微信支付异常失败 !!! ", Data = string.Empty }, JsonRequestBehavior.AllowGet);
}
}

!!!注意事项
- 支付授权目录与测试人的微信帐号白名单(出现access_denied或access_not_allow错误,请检查是否设置正确)
- 支付授权目录区分大小写
- 安全域名配置
.Net 微信开发与微信支付的更多相关文章
- php 微信开发之 微信支付 V3 开发 -CURLOP_TIMEOUT问题
如果不懂怎么配置的话请看文章 php 微信开发之 微信支付配置 基本配置后在继续本文章的开发 . 本文章就先继续基本的实现!也并不困难.我大概的思路的返回购买者的唯一id 和 订单号的唯一 id 就2 ...
- [微信开发利器]微信内移动前端开发抓包调试工具fiddler使用教程
[微信开发利器]微信内移动前端开发抓包调试工具fiddler使用教程 在朋友圈看到一款疯转的H5小游戏,想要copy,什么?只能在微信里打开?小样,图样图森破,限制了oauth.微信浏览器内打开, ...
- 微信开发_微信教程__微信通讯框架V1.0
做个广告先, PHP千人群(6848027) C++群 (1414577) 看雪汇编&反汇编群(15375777) 看雪汇编&反汇编2群(4915800) 转载不一定注明出处,只要推荐 ...
- 微信开发:微信js_sdk 分享,前端部分(二)
微信开发:微信js-sdk前端分享,代码如下: <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"> ...
- 使用delphi+intraweb进行微信开发4—微信消息加解密
示例代码已经放出!请移步使用delphi+intraweb进行微信开发1~4代码示例进行下载,虽为示例代码但是是从我项目中移出来的,封装很完备适于自行扩展和修改. 在上一讲当中我做了个简单的微信文本消 ...
- 使用delphi+intraweb进行微信开发3—微信消息处理
示例代码已经放出!请移步使用delphi+intraweb进行微信开发1~4代码示例进行下载,虽为示例代码但是是从我项目中移出来的,封装很完备适于自行扩展和修改. 在第二讲使用delphi+intra ...
- 微信开发(2)---微信小程序开发实战part1
微信开发现在来说,简单可以概括为两部分,微信公众号和微信小程序. 微信公众号的技术已经非常成熟.分为服务号和订阅号.简单的.可以弄一个个人订阅号,在编辑模式下就可以实现推送图文.自动回复.自定义菜单的 ...
- 微信开发系列——微信订阅号前端开发利器:WeUI
前言:年前的两个星期,学习了下微信公众号的开发.后端基本能够基于盛派的第三方sdk能搞定大部分事宜.剩下的就是前端了,关于手机端的浏览器的兼容性,一直是博主的一块心病,因为博主一直专注于bootstr ...
- 微信开发:微信js_sdk分享,使用场景,网页在微信app内部分享时的标题与描述,包括logo设置(一)
主要有下面几步.首先大家先分清楚 小程序的appid,appSecret 跟公众号的appid,appSecret是不一样的.因为这两个都能拿到token,且是不同的值. 准备开始: 1.准备好 公众 ...
随机推荐
- ubuntu为IDE(Eclipse WebStorm)添加桌面快捷方式
在ubuntu15.10环境配置webstorm和eclipse的时候会下载官网上编译好的包, bin目录下面会有一个.sh文件(linux版本), 那么一般情况下,执行 ./sh就会启动IDE, 但 ...
- ios8,xcode6 周边
NSBundle.mainBundle().infoDictionary iOS 8中带按钮的推送代码 ") ){ application.registerForRemoteNotifica ...
- Hash Table构建
get-item e:\test\* |format-table @{name="aa";expression={$_.name.tostring().split(".& ...
- 【M4】非必要不提供default 构造方法
1.default 构造方法意味着,没有外来信息的情况下,进行初始化,构造出一个对象.对于有些对象是很合理的,比如数值之类的对象,可以初始化为0:对于指针之类的对象,初始化为null:对于集合如vec ...
- uoj #139. 【UER #4】被删除的黑白树 dfs序 贪心
#139. [UER #4]被删除的黑白树 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/139 Descript ...
- Cache选型的一些思考
Cache对于减轻DB负载有非常关键的数据.以下对经常使用的memcached和redis做个总结,便于技术选型. 1 memcached (1) 支持的操作有限,支持经常使用的set,get,de ...
- 免费的天气预报API--谷歌,雅虎,中央气象台
Google Weather API 仅仅支持美国地区使用邮政编码进行查询,比如: http://www.google.com/ig/api?hl=zh-cn&weather=94043 ...
- javascript 实现htmlEncode htmlDecode
屌屌的写法..function htmlEncode(value){ //create a in-memory div, set it's inner text(which jQuery automa ...
- zend studio 函数不提醒 小黄图标 小黄标
在用 Zend Studio 编写 PHP 项目时发现调用系统函数时调试正常, 但是在编写代码时却提示函数未定义"Call to undefined function ", 在左侧 ...
- mysql索引详解,摘自《MySQL 5权威指南》
本文介绍了数据库索引,及其优.缺点.针对MySQL索引的特点.应用进行了详细的描述.分析了如何避免MySQL无法使用,如何使用EXPLAIN分析查询语句,如何优化MySQL索引的应用.本文摘自< ...