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
README.md
... ... @@ -36,13 +36,15 @@ Create `config/initializers/wx_pay.rb` and put following configurations into it.
36 36 WxPay.appid = 'YOUR_APPID'
37 37 WxPay.key = 'YOUR_KEY'
38 38 WxPay.mch_id = 'YOUR_MCH_ID'
39   -WxPay.appsecret = 'YOUR_SECREDT'
40 39 WxPay.debug_mode = true # default is `true`
41 40  
42 41 # cert, see https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_3
43 42 # using PCKS12
44 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 48 # optional - configurations for RestClient timeout, etc.
47 49 WxPay.extra_rest_client_options = {timeout: 2, open_timeout: 3}
48 50 ```
... ... @@ -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 98 If your trade type is "NATIVE", the result would be like this.
101 99  
... ... @@ -188,7 +186,7 @@ def notify
188 186 end
189 187 ```
190 188  
191   -### Integretion with QRCode(二维码)
  189 +### Integrate with QRCode(二维码)
192 190  
193 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 1 require 'rest_client'
2 2 require 'json'
3   -require 'rails'
  3 +require 'securerandom'
4 4 require 'active_support/core_ext/hash/conversions'
5 5  
6 6 module WxPay
7 7 module Service
8 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 25 end
34 26  
35 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 212 nonce_str: SecureRandom.uuid.tr('-', '')
221 213 }.merge(params)
222 214  
223   - check_required_options(params, ORDER_QUERY_REQUIRED_FIELDS)
224 215  
225 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 219 yield r if block_given?
228 220  
... ... @@ -294,7 +286,7 @@ module WxPay
294 286 private
295 287  
296 288 def check_required_options(options, names)
297   - return if !WxPay.debug_mode?
  289 + return unless WxPay.debug_mode?
298 290 names.each do |name|
299 291 warn("WxPay Warn: missing required option: #{name}") unless options.has_key?(name)
300 292 end
... ...