Commit 19660247ff6b8047be081ad44d0334ab9a833434

Authored by jasl
1 parent 17de31b7
Exists in master

Separate authenticate_open_id to two functions

Showing 2 changed files with 24 additions and 34 deletions   Show diff stats
@@ -36,13 +36,15 @@ Create `config/initializers/wx_pay.rb` and put following configurations into it. @@ -36,13 +36,15 @@ Create `config/initializers/wx_pay.rb` and put following configurations into it.
36 WxPay.appid = 'YOUR_APPID' 36 WxPay.appid = 'YOUR_APPID'
37 WxPay.key = 'YOUR_KEY' 37 WxPay.key = 'YOUR_KEY'
38 WxPay.mch_id = 'YOUR_MCH_ID' 38 WxPay.mch_id = 'YOUR_MCH_ID'
39 -WxPay.appsecret = 'YOUR_SECREDT'  
40 WxPay.debug_mode = true # default is `true` 39 WxPay.debug_mode = true # default is `true`
41 40
42 # cert, see https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_3 41 # cert, see https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_3
43 # using PCKS12 42 # using PCKS12
44 WxPay.set_apiclient_by_pkcs12(File.read(pkcs12_filepath), pass) 43 WxPay.set_apiclient_by_pkcs12(File.read(pkcs12_filepath), pass)
45 44
  45 +# if you want to use `generate_authorize_req` and `authenticate`
  46 +WxPay.appsecret = 'YOUR_SECRET'
  47 +
46 # optional - configurations for RestClient timeout, etc. 48 # optional - configurations for RestClient timeout, etc.
47 WxPay.extra_rest_client_options = {timeout: 2, open_timeout: 3} 49 WxPay.extra_rest_client_options = {timeout: 2, open_timeout: 3}
48 ``` 50 ```
@@ -89,13 +91,9 @@ r = WxPay::Service.invoke_unifiedorder params @@ -89,13 +91,9 @@ r = WxPay::Service.invoke_unifiedorder params
89 # } 91 # }
90 ``` 92 ```
91 93
92 -"JSAPI" requires openid in params, authenticate_openid can be used to get it, in case there is not wechat auth integration.  
93 -  
94 -```ruby  
95 -code = params[:code]  
96 -r = WxPay::Service.authenticate_openid code  
97 -# => 'OPENID'  
98 -``` 94 +> "JSAPI" requires openid in params,
  95 +in most cases I suggest you using [omniauth](https://github.com/omniauth/omniauth) with [omniauth-wechat-oauth2](https://github.com/skinnyworm/omniauth-wechat-oauth2) to resolve this,
  96 +but `wx_pay` provides `generate_authorize_url` and `authenticate` to help you get Wechat authorization in simple case.
99 97
100 If your trade type is "NATIVE", the result would be like this. 98 If your trade type is "NATIVE", the result would be like this.
101 99
@@ -188,7 +186,7 @@ def notify @@ -188,7 +186,7 @@ def notify
188 end 186 end
189 ``` 187 ```
190 188
191 -### Integretion with QRCode(二维码) 189 +### Integrate with QRCode(二维码)
192 190
193 Wechat payment integrating with QRCode is a recommended process flow which will bring users comfortable experience. It is recommended to generate QRCode using `rqrcode` and `rqrcode_png`. 191 Wechat payment integrating with QRCode is a recommended process flow which will bring users comfortable experience. It is recommended to generate QRCode using `rqrcode` and `rqrcode_png`.
194 192
lib/wx_pay/service.rb
1 require 'rest_client' 1 require 'rest_client'
2 require 'json' 2 require 'json'
3 -require 'rails' 3 +require 'securerandom'
4 require 'active_support/core_ext/hash/conversions' 4 require 'active_support/core_ext/hash/conversions'
5 5
6 module WxPay 6 module WxPay
7 module Service 7 module Service
8 GATEWAY_URL = 'https://api.mch.weixin.qq.com' 8 GATEWAY_URL = 'https://api.mch.weixin.qq.com'
9 9
10 - def self.authenticate_openid(code)  
11 - """  
12 - Acquire openid from wechat server.  
13 - When trade type is JSAPI, openid is required in params to do unifiedorder.  
14 - If application does not integrate wechat auth plugin, this function can be used to get openid.  
15 - Wechat doc for explaining acquire openid: http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html  
16 -  
17 - params:  
18 - code, the code return by wechat server after user authentification  
19 - return:  
20 - openid  
21 - """  
22 - # step 1. Redirect to wechat server to get code. If code exits, it can be skiped.  
23 - if code.nil?  
24 - redirect_to "https://open.weixin.qq.com/connect/oauth2/authorize?appid=#{WxPay.appid}&redirect_uri=#{request.url}&response_type=code&scope=snsapi_base&state=#{request.url}#wechat_redirect"  
25 - end 10 + def self.generate_authorize_url(redirect_uri, state = nil)
  11 + state ||= SecureRandom.hex 16
  12 + "https://open.weixin.qq.com/connect/oauth2/authorize?appid=#{WxPay.appid}&redirect_uri=#{redirect_uri}&response_type=code&scope=snsapi_base&state=#{state}"
  13 + end
26 14
27 - # step 2. Get Auth Info and openid from wechat server with code  
28 - begin  
29 - url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=#{WxPay.appid}&secret=#{WxPay.appsecret}&code=#{code}&grant_type=authorization_code"  
30 - weixin_openid = JSON.parse(URI.parse(url).read)["openid"]  
31 - end  
32 - weixin_openid 15 + def self.authenticate(authorization_code, options = {})
  16 + options = WxPay.extra_rest_client_options.merge(options)
  17 + url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=#{WxPay.appid}&secret=#{WxPay.appsecret}&code=#{authorization_code}&grant_type=authorization_code"
  18 +
  19 + ::JSON.parse(RestClient::Request.execute(
  20 + {
  21 + method: :get,
  22 + url: url
  23 + }.merge(options)
  24 + ), quirks_mode: true)
33 end 25 end
34 26
35 INVOKE_UNIFIEDORDER_REQUIRED_FIELDS = [:body, :out_trade_no, :total_fee, :spbill_create_ip, :notify_url, :trade_type] 27 INVOKE_UNIFIEDORDER_REQUIRED_FIELDS = [:body, :out_trade_no, :total_fee, :spbill_create_ip, :notify_url, :trade_type]
@@ -220,9 +212,9 @@ module WxPay @@ -220,9 +212,9 @@ module WxPay
220 nonce_str: SecureRandom.uuid.tr('-', '') 212 nonce_str: SecureRandom.uuid.tr('-', '')
221 }.merge(params) 213 }.merge(params)
222 214
223 - check_required_options(params, ORDER_QUERY_REQUIRED_FIELDS)  
224 215
225 r = WxPay::Result.new(Hash.from_xml(invoke_remote("#{GATEWAY_URL}/pay/orderquery", make_payload(params), options))) 216 r = WxPay::Result.new(Hash.from_xml(invoke_remote("#{GATEWAY_URL}/pay/orderquery", make_payload(params), options)))
  217 + check_required_options(params, ORDER_QUERY_REQUIRED_FIELDS)
226 218
227 yield r if block_given? 219 yield r if block_given?
228 220
@@ -294,7 +286,7 @@ module WxPay @@ -294,7 +286,7 @@ module WxPay
294 private 286 private
295 287
296 def check_required_options(options, names) 288 def check_required_options(options, names)
297 - return if !WxPay.debug_mode? 289 + return unless WxPay.debug_mode?
298 names.each do |name| 290 names.each do |name|
299 warn("WxPay Warn: missing required option: #{name}") unless options.has_key?(name) 291 warn("WxPay Warn: missing required option: #{name}") unless options.has_key?(name)
300 end 292 end