导轨实现电脑商城的微信扫码支付(原生微信支付)

Wei Xiao
11 min readMay 31, 2019

--

摘要:轨道实现电脑商城的微信扫码支付(原生微信支付)

电脑商城扫码支付,调用微信统一下单接口,参考微信官方的开发文档调用统一下单接口进行支付。

在这之前先把装备工作做好,微信需要申请的各种账号,商户在微信公众平台(申请扫码支付),审核通过之后登录账号能获得一些参数。

邮件中参数API参数名详细说明APPIDappidappid是微信公众账号或开放平台APP的唯一标识,在公众平台申请公众账号或者在开放平台申请APP账号后,微信会自动分配对应的应用标识,用于标识该应用。可在微信公众平台→开发→基本配置里面查看,商户的微信支付审核通过邮件中也会包含该字段值。微信支付商户号mch_id商户申请微信支付后,由微信支付分配的商户收款账号。 API密钥关键交易过程生成签名的密钥,仅保留在商户系统和微信支付后台,不会在网络中传播。商户妥善保管该密钥,切勿在网络中传输,不能在其他客户端中存储,保证密钥不会被泄漏商户可根据邮件提示登录微信商户平台进行设置也可按一下路径设置:微信商户平台(pay.weixin.qq.com)→账户中心→账户设置→API安全→密钥设置AppsecretsecretAppSecret是APPID对应的接口密码,用于获取 调用证书的access_token时使用。在微信支付中,先通过OAuth2.0的接口获取用户的OpenID,此OpenID的用于微信内网页支付模式下单接口使用。可登录公众平台→微信支付,获取AppSecret(需成为开发者且帐号没有异常状态)。

准备工作好之后可以开始集成微信支付了。

1.微信支付过程中最麻烦的就是签名验证签名的这一列的过程,所以我们使用已有的轮子来帮我们解决这个问题,https://github.com/jasl/wx_pay。在宝石文中添加:

gem 'wx_pay', :github => 'jasl/wx_pay' 
gem 'rqrcode', '0.10.1' #生成二维码的gem

2.bundle,然后在settings.yml文件文件中添加上面申请的一些参数

#微信支付参数
wechat_pay:
app_id: "xxxxxxxxxxxx"
app_key: "xxxxxxxxxxxxxxxxxxxx"
mch_id: "xxxxxxxxx"

3.model / payment.rb中添加向微信服务器请求支付的方法,以及根据微信返回的参数生成二维码的方法。

def self.wechat_pay(order_id)
logger.info "=======开始调用微信支付========"
order = Order.find_by_order_id(order_id)
artwork_id = order.buy_goods.first.artwork_id
order_name = Artwork.find(artwork_id).name
params = {
body: order_name,
out_trade_no: order_id,
total_fee: (order.total_cost * 100).to_i,
notify_url: 'http://shop.art-bank.net/interface/payments/wx_pay_notify',
trade_type: 'NATIVE', # could be "JSAPI", "NATIVE" or "APP",
}
result = WxPay::Service.invoke_unifiedorder params
end
def self.generate_qr_code(code_url, order_id)
logger.info "========开始生成用户支付的二维码========"
qrcode = RQRCode::QRCode.new(code_url)
end

4.在对应的控制器,我这里是在orders_controller.rb中添加调用微信扫码支付的方法。

def  go_wechat_pay
result = Payment.wechat_pay(order.order_id) #order_id是商户平台生成的订单号。
redirect_to wx_pay_qrcode_orders_path(:code_url => result["code_url"], :order_id => order.order_id)
end
def wx_pay_qrcode
@qr = RQRCode::QRCode.new(params[:code_url])
order = Order.find_by_order_id(params[:order_id])
artwork_id = order.buy_goods.first.artwork_id
@order_name = Artwork.find(artwork_id).name
@total_cost = Order.find_by_order_id(params[:order_id]).total_cost if params[:order_id].present?
end

5.对应的应用程序/视图/命令/ wx_pay_qrcode.html.erb,直接跳到二维码页面,如下图。

<div class="pay_cost">
<div class="logo_image" style="">
<%= image_tag "http://siweitech.b0.upaiyun.com/cms/2018-01-10-WePayLogo.png", style: "width: 250px;" %>
</div>
<div style="padding: 20px; border-bottom: 1px solid gainsboro;">
<span class="order_detail">
订单号: <span class="price"><%= params[:order_id] %></span>
</span>
<span class="order_detail">
订单名称: <span class="price"><%= @order_name %></span>
</span>
<span class="order_detail">
支付金额: <span class="price">¥<%= @total_cost %></span>
</span>
</div>
<div class="qr_code">
<table>
<% @qr.modules.each_index do |x| -%>
<tr>
<% @qr.modules.each_index do |y| -%>
<% if @qr.dark?(x,y) -%>
<td class="black"/>
<% else -%>
<td class="white"/>
<% end -%>
<% end -%>
</tr>
<% end -%>
</table>
<div style="text-align: center; margin:40px 0;">
<%#= image_tag "http://siweitech.b0.upaiyun.com/cms/2018-01-10-%E8%AF%B4%E6%98%8E%E6%96%87%E5%AD%97.png", style:
<span class="order_detail">
请使用<span class="wx_text">微信扫码二维码</span>完成支付
</span>
</div>
</div>
</div>
<style type="text/css">
.qr_code {
margin: 80px;
}
.logo_image {
text-align: center;
padding: 25px;
background: #f3f3f3;
}
.order_detail {
margin: 0 70px;
color: #9E9E9E;
}
.pay_cost{
font-size: 18px;
line-height: 60px;
margin: 20px 0;
text-align: center;
border: 2px solid gainsboro;
}
.price{
font-size: 20px;
margin-left: 10px;
color: #0fbf0f;
}
.wx_text {
font-size: 20px;
margin-left: 0px;
color: #f56f2e;
}
table {
border-width: 0;
border-style: none;
border-color: #0000ff;
border-collapse: collapse;
}
td {
border-width: 0;
border-style: none;
border-color: #0000ff;
border-collapse: collapse;
padding: 0;
margin: 0;
width: 7px;
height: 7px;
}
td.black { background-color: #000; }
td.white { background-color: #fff; }
</style>

6.支付成功之后订单状态会更改为已支付,页面上使用ajax发起请求。轮询来判断支付状态app / views / orders / wx_pay_qrcode.html.erb

<script>
setInterval(function() {
$.post("/interface/payments/is_wxpay_success",
{
order_id: <%= params[:order_id] %>
},
function(data) {
if (data.is_pay_success == "yes") {
window.location.href = "/orders/alipay_success?order_id=<%= params[:order_id] %>"
}
})
}, 2000);
</script>

7.支付成功之后订单状态会更改为已支付,页面上使用ajax发起请求。轮询来判断支付状态。

def is_wxpay_success
order = Order.find_by_order_id(params[:order_id])
if order.order_status
logger.info("======用户扫码支付成功=====")
render :json => {
:is_pay_success => "yes"
}
else
logger.info("======用户还未支付=====")
render :json => {
:is_pay_success => "no"
}
end
end

8.用户扫码支付成功之后需要回调,app / controllers / interface / payments_controller.rb接口添加回调方法。

def wx_pay_notify
Rails.logger.info "=============== 扫码支付成功,后台回调 =============="
result = Hash.from_xml(request.body.read)["xml"]
if WxPay::Sign.verify?(result)
logger.info "======== 验证签名成功 ======= "
order_id = result["out_trade_no"].to_s
logger.info "订单编号: #{result["out_trade_no"]}-------"
order = Order.find_by_order_id(order_id)
unless order.blank?
time = Time.now.to_datetime
payed_price = result["total_fee"].to_f / 100.0
Order.transaction do
order.update_attributes(
:order_status => true,
:payed_price => payed_price,
:payed_at => time,
:payed_response => result.to_s
:payed_response => result.to_s
)
end
end
render :xml => {return_code: "SUCCESS"}.to_xml(root: 'xml', dasherize: false)
else
render :xml => {return_code: "FAIL", return_msg: "签名失败"}.to_xml(root: 'xml', dasherize: false)
end
end

本文标题:rails实现pc商城的微信扫码支付(本地微信支付)

本文链接:http://wenyc.cn/blog/native_wechat_pay

--

--

No responses yet