微信开放平台API
Add this line to your application’s Gemfile:
gem 'wechatruby'
And then execute:
$ bundle
Or install it yourself as:
$ gem install wechatruby
wechat = Wechatruby::Client.new(
id: ENV.fetch('AppID'),
secret: ENV.fetch('AppSecret')
)
# 通过openid获取用户信息
user_info = wechat.get_user_by_id('osip61TslXFOq134R4pc2tI9qQrk')
# =>
# {
# "openid":" OPENID",
# "nickname": NICKNAME,
# "sex":"1",
# "province":"PROVINCE",
# "city":"CITY",
# "country":"COUNTRY",
# "headimgurl": "http://thirdwx.qlogo.cn/mmopen/xxjx/46",
# "privilege":[ "PRIVILEGE1" "PRIVILEGE2" ],
# "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
# }
公众号和网页登录机制不同, 公众号登录需要认证过的服务号appid, 而网页登录需要在开放平台注册一个webapp, 并获取appid. 具体方法参考: https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
个人比较倾向的解决方案是使用公众号生成的临时二维码功能, 结合websocket来做pc网页端登录, 这样的好处是不用再申请开放平台, 而且可以强制用户登录前关注公众号.
callback_url = 'https://exmple.com/wechat/signup'
if request.headers['HTTP_USER_AGENT'].include?('MicroMessenger')
redirect_to wechat.code_request_url(callback_url)
return
end
# 处理回调
# 微信服务器 get 访问指定的回调地址, 并传入code参数
# 获取用户信息和openid
user_info = wechat.get_user_info(params[:code])
callback_url = 'https://exmple.com/wechat/signup'
redirect_to wechat.qr_code_url(callback_url)
# 处理回调
# 微信服务器 get 访问指定的回调地址, 并传入code参数
# 获取用户信息和openid
user_info = wechat.get_user_info(params[:code])
# 发送模板信息
params =
{
touser: 'sip61TslXFOq134R4pc2tI9qQrk',
template_id: 'tWRq3Qm-qcEUWw79sSADu6axa38reZUqTWJE2tsos0',
data: {
first: {
value: 'Welcome'
},
orderno: {
value: '123456789'
},
amount: {
value: 123
},
remark: {
value: 'Thanks'
}
}
}
result = wechat.messages.send_template(params)
# 发送图片
result = wechat.assets.tmp_add('image', '/FILE_PATH/a.png')
media_id = result['media_id']
wechat.messages.send_image('sip61TslXFOq134R4pc2tI9qQrk', media_id)
# 用户是否关注公众号
wechat.cgi.subscribed?("oY98t6BQs0wbmSgcpn2lseEV9N4k")
#=> false or true
# 短连接
short_url = wechat.cgi.short_url('http://long.url')
# 临时二维码
wechat.cgi.scene_qrcode('message', expire_seconds: 9999)
# 微信回调服务器白名单
ip_array = wechat.ip_list
xml = request.body.read
result = Wechatruby::Xml.parse(xml)
result.event
#=> 'CLICK'
# 触发点击的用户openid
result.openid
# 获取点击事件绑定的值
result.get_value('EventKey')
事件文档 https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_event_pushes.html
Name | Event | Values |
---|---|---|
关注公众号 | subscribe | |
扫码 | SCAN | EventKey |
上报地理位置 | LOCATION | Latitude Longitude |
菜单点击 | CLICK | EventKey |
带网址的菜单 | VIEW | EventKey |
公众号文本回复 | text | Content |
图片回复 | image | PicUrl MediaId |
从菜单选择地址 | location_select | Location_X Location_Y |
获取签名和配置
$(function(){
$.ajax({
method: "GET",
url: '<%= fetch_config_url %>',
data: { url: location.href.split('#')[0],
apis: [ 'scanQRCode', 'getLocation', 'openLocation' ]
}
}).done(function( res ) {
console.log(res)
wx.config(res)
});
$("#trigger").click(function(){
wx.scanQRCode({
needResult: 1,
scanType: ["qrCode","barCode"],
success: function (res) {
// barcode => CODE_128,xxxxx
}
});
});
$("#open-location").click(function(){
wx.openLocation({
latitude: 31.27850914001465, // 纬度,浮点数,范围为90 ~ -90
longitude: 121.42569732666016, // 经度,浮点数,范围为180 ~ -18 。
name: 'Home', // 位置名
address: '', // 地址详情说明
scale: 1, // 地图缩放级别 整形值 范围从1~2 。默认为最大
infoUrl: 'www.web-site.com.cn' // 在查看位置界面底部显示的超链接 可点击跳转
});
});
})
访问的页面先加载好, 获取当前url, 传入需要的功能(扫码, 地图..), 异步获取签名. js-sdk 具体使用方法请查看微信文档 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
# WechatController#fetch_config
def fetch_config
@jsapi_params = wechat.web_jsapi_params(
params[:url],
# Rails.env.development?,
false,
*params[:apis]
)
render json: @jsapi_params
end
# 获取订单。
begin_time = Time.now.to_i
end_time = begin_time - 24*3600
orders = wechat.shop.orders(end_time, begin_time, :paid)
# 关闭订单。
result = wechat.shop.close_order 'ORDER_ID'
首先设置微信支付功能, 参考: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_3
# WechatController#pay
def pay
@order = Order.find params[:id]
# 需要预先获取用户openid
@jsapi_params = wechat.prepay_params(
current_user.openid,
ip: request.ip,
fee: @order.fee,
redirect_url: wechat_call_back_url(id: @order.id)
)
end
def call_back
Order.find_by(id: params[:id], status: :waitting_pay)
# 处理订单状态
...
render xml: Wechatruby::Xml.pay_success
end
<script type="text/javascript">
//调用微信JS api 支付
function jsApiCall()
{
WeixinJSBridge.invoke(
'getBrandWCPayRequest',
<%= @jsapi_params.to_json.html_safe %>,
function(res){
WeixinJSBridge.log(res.err_msg);
if(res.err_msg == "get_brand_wcpay_request:ok" ){
window.location = '<%= pay_success_url %>'
}
}
);
}
function callpay()
{
if (typeof WeixinJSBridge == "undefined"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', jsApiCall);
document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
}
}else{
jsApiCall();
}
}
</script>
<%=link_to 支付#{@order.fee 元", '#', onclick: "callpay()", class: 'btn btn-info'%>
The gem is available as open source under the terms of the MITLicense.
Everyone interacting in the Wechatruby project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the https://github.com/zhongsheng/wechatruby/blob/master/CODE_OF_CONDUCT.md
Wechatruby.session(code) return a hash object contain
字段 | 类型 | 说明 |
---|---|---|
openid | string | 用户唯一标识 |
session_key | string | 会话密钥 |
unionid | string | 用户在开放平台的唯一标识符, |
errcode | number | 错误码 |
errMsg | string | 错误信息 |
Wechatruby.decrypt encryptedData, return a hash object
{
"openId": "OPENID",
"nickName": "NICKNAME",
"gender": GENDER,
"city": "CITY",
"province": "PROVINCE",
"country": "COUNTRY",
"avatarUrl": "AVATARURL",
"unionId": "UNIONID",
"watermark": {
"appid": "APPID",
"timestamp": TIMESTAMP
}
}