Commit 19660247ff6b8047be081ad44d0334ab9a833434
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 | ... | ... |