1、使用 gem 包 我使用的是 wx_pay 这个 gem,github:https://github.com/jasl/wx_pay 【建议自己 fork 一下,然后在 gem 里面引用自己的 github 地址】 例如: gem 'wx_pay', :github => 'greatbody/wx_pay' 2、配置信息 参见https://github.com/jasl/wx_pay 其中需要注意的是: WxPay.appid = '微信给的公众号的 id' WxPay.key = '自己设置的 api Key',32 个字符,推荐自己去随机生成 32 个 16 进制数。【这个 key 不可以长了,长了会导致认证失败】 WxPay.mch_id = '微信支付商户号' 3、提交预订单
# required fields
params = {
body: '商品名',
out_trade_no: '交易序列号,',
total_fee: 1,
spbill_create_ip: '127.0.0.1',
notify_url: 'http://xxx.xxxx.xxx/static/receive_pay_notify/',
trade_type: 'JSAPI', # could be "JSAPI", "NATIVE" or "APP",
openid: session[:openid] # required when trade_type is `JSAPI`
}
@result = WxPay::Service.invoke_unifiedorder(params)
@sign_package = $weixin_client.get_jssign_package(request.url)
if @result.nil?
render html: "no"
else
render html: "#{@result.to_s},#{params.to_s}" if @result['return_code']=='FAIL'
@pay_ticket_param = {
timeStamp: @sign_package["timestamp"],
nonceStr: @sign_package["nonceStr"],
package: "prepay_id=#{@result['prepay_id']}", #这里一定注意,不仅仅是prepay_id,还需要拼接上“prepay_id=”
signType: "MD5",
appId: WxPay.appid,
key: WxPay.key
}
@pay_ticket_param = {
paySign: WxPay::Sign.generate(@pay_ticket_param) #然后我们手动进行paySign计算
}.merge(@pay_ticket_param)
end
4、页面上 js-sdk 的授权部分,参见 weixin_authorize 这个 gem 的说明,其实上面已经获取了授权信息,并且存在了@sign_package中。
wx.config({
debug: false,
appId: '<%= @sign_package["appId"] %>',
url: '<%= @sign_package["url"] %>',
timestamp: '<%= @sign_package["timestamp"] %>' ,
nonceStr: '<%= @sign_package["nonceStr"] %>',
signature: '<%= @sign_package["signature"] %>',
jsApiList: ['chooseWXPay']
});
wx.ready(function() {
window.weixin_ready = true;
});
wx.error(function() {
window.weixin_ready = false;
});
然后,加一个支付函数
function pay() {
if (window.weixin_ready) {
wx.chooseWXPay({
timestamp: <%= @pay_ticket_param[:timeStamp] %>, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr: "<%= @pay_ticket_param[:nonceStr] %>", // 支付签名随机串,不长于 32 位
package: "<%= @pay_ticket_param[:package] %>", //统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***
signType: "<%= @pay_ticket_param[:signType] %>", // 签名方式,默认为"SHA1",使用新版支付需传入"MD5"
paySign: "<%= @pay_ticket_param[:paySign] %>", // 支付签名
success: function(res) {
// 支付成功后的回调函数
alert("支付成功");
}
});
} else {
alert('wait for authentication!');
}
}
页面上调用这个支付函数就可以了。
坑点: 1、第三步提交预订单中,out_trade_no 记得每次成功后要改变,最好的就是按照一个规则生成不重复的单号 2、关于授权目录的事情 首先,登陆进入:https://mp.weixin.qq.com 然后,登陆后,点击左侧导航栏的,“微信支付”,然后再点开“开发配置”,在里面寻找“公众号支付->支付授权目录”,设置支付授权目录时一定注意,这个路径就是 routes 里面处理支付页面的那个 get 的 path,例如:http://xx.xxxx.xx/weixin/pay/ 对应我的 routes 是:
namespace :weixin do
get 'pay' => :pay
end