Li Yafei
A senior Ruby on Rails developer
80学院第八次课
# /app/models/order.rb
class Order < ApplicationRecord
aasm do
state :submitted, :initial => true
state :paid
state :cancelled
event :pay, after: [:payback_writer, :payback_shared_by_user] do
transitions from: [:submitted, :cancelled], to: :paid
end
event :cancel do
transitions from: :submitted, to: :cancelled
end
end
end
# app/controllers/reader/orders_controller.rb
def notify
result = Hash.from_xml(request.body.read)["xml"]
if WxPay::Sign.verify?(result)
trade_no = result["out_trade_no"]
@order = Order.find_by(trade_no: trade_no)
@order.lock!
if( @order.paid? )
order_token_for_order_id
render :xml => {return_code: "SUCCESS"}.to_xml(root: 'xml', dasherize: false)
return
end
if( @order.may_pay? )
@order.pay!
@order.send_cable_notify
order_token_for_order_id
render :xml => {return_code: "SUCCESS"}.to_xml(root: 'xml', dasherize: false)
else
logger.warn "操作订单失败: order = #{@order}, notify result=#{result}"
render :xml => {return_code: "FAIL", return_msg: "操作订单失败"}.to_xml(root: 'xml', dasherize: false)
end
else
render :xml => {return_code: "FAIL", return_msg: "签名失败"}.to_xml(root: 'xml', dasherize: false)
end
end
# app/controllers/reader/orders_controller.rb
def pay
@hash = WxPay::Service.invoke_unifiedorder(tmp)
if @hash["return_code"] != "SUCCESS"
logger.warn " WxPay::Service.invoke_unifiedorder return error: #{@hash}"
render js: "alert('error call WxPay::Service.invoke_unifiedorder')"
return
end
if params[:qrcode].present?
@qrcode_url = @hash["code_url"]
render 'pay_qrcode'
return
end
@js_pay_hash = {
appId: WxPay.appid,
timeStamp: Time.zone.now.to_i.to_s,
nonceStr: SecureRandom.uuid.tr('-', ''),
package: "prepay_id=#{@hash["prepay_id"]}",
signType: "MD5",
}
@js_pay_hash["paySign"] = WxPay::Sign.generate(@js_pay_hash)
logger.debug @js_pay_hash
end
# config/routes.rb
namespace :admin do
root 'dashboard#index'
end
namespace :reader do
root 'dashboard#index'
end
namespace :writer do
root 'dashboard#index'
end
# app/controllers/reader/application_controller.rb
class Reader::ApplicationController < ApplicationController
before_action :authenticate_user!
layout 'wechat_base'
end
# app/controllers/writer/application_controller.rb
class Writer::ApplicationController < ApplicationController
before_action :authenticate_user!
layout 'writer_base'
end
# app/views/layouts/reader_base.html.slim
# app/views/layouts/writer_base.html.slim
# app/views/layouts/admin_base.html.slim
doctype html
html
head
meta charset='utf-8'
meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"
meta name="renderer" content="webkit"
meta http-equiv="cleartype" content="on"
meta name="HandheldFriendly" content="True"
meta name="MobileOptimized" content="320"
meta name="format-detection" content="telephone=no"
- if content_for?(:title)
= yield(:title)
- else
title 八十二十 - 有价值的文章分享工具
= csrf_meta_tags
= action_cable_meta_tag
= content_for?(:head) ? yield(:head) : ''
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
= javascript_include_tag 'application', 'data-turbolinks-track': 'reload'
= javascript_include_tag 'ga', 'data-turbolinks-track': 'reload'
= javascript_include_tag "https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"
= favicon_link_tag "favicon.png"
body
main
== render 'layouts/flash'
.container
== yield
By Li Yafei