wechat-api 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 719b629d7118b6d301d4aefe2f7672165dd911bf
4
- data.tar.gz: ef220a300a12fde99086b07d82146dec8778b28c
3
+ metadata.gz: 8a1da7465e7436ff9a4d1f959f198a63ffc3e028
4
+ data.tar.gz: 4bfc9ba3e18733fe9146679b32b295665934d2d8
5
5
  SHA512:
6
- metadata.gz: 1cfb62e73ee7d3b47ae830f98a3cfbe28ce65883b8cc33e2ebc49a13d363bdb0f25459d498508c1a307836871bfd890f8cd5096be42045ed7f16c3e335d7f44a
7
- data.tar.gz: 95e2407f7f8e3d0273424754ef9d7a2f1008ce1ea5055397878bcdf39b8ff78e82b5f2e57113a6bee31051c7e751a22d8ab32a638d944df488bc21b73cf310cb
6
+ metadata.gz: d79b3b01a2fbb922ea6019af273d12244cdda7e15bc250e30f648a2c9c7a94c76f8759619304edb91f911563a5c5e4e47ff62c035e70bab10bdd00abaaab2bf7
7
+ data.tar.gz: 4a7aba85ce5c46fb22b8101c25b97c28330b9795db8cbeaf5acb2fc1da5fd2526ae3fbef4279bf7b520c0454ca1392ca76ff1aae4f024bfcff5d1fdc3fe36ec4
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source 'http://ruby.taobao.org'
1
+ source 'https://ruby.taobao.org'
2
2
  # Specify your gem's dependencies in ucpaas.gemspec
3
3
  gemspec
4
4
 
@@ -1 +1,2 @@
1
1
  require 'wechat/api'
2
+ require 'wechat/pay'
@@ -42,7 +42,7 @@ module Wechat
42
42
  response = MultiJson.load(resp.body)
43
43
  return handle_error(response) if response['errcode']
44
44
  @access_token = response['access_token']
45
- File.open(@token_file, 'w') { |f| f.write(resp.body) } if token
45
+ File.open(@token_file, 'w') { |f| f.write(resp.body) } if @access_token
46
46
  @access_token
47
47
  end
48
48
 
@@ -27,6 +27,11 @@ module Wechat
27
27
 
28
28
  post 'qrcode/create', params
29
29
  end
30
+
31
+ def js_ticket
32
+ res = get 'ticket/getticket', type: :jsapi
33
+ res['ticket']
34
+ end
30
35
  end
31
36
  end
32
37
  end
@@ -2,6 +2,6 @@
2
2
  module Wechat
3
3
  #
4
4
  module Api
5
- VERSION = '0.1.1'
5
+ VERSION = '0.1.3'
6
6
  end
7
7
  end
@@ -0,0 +1,7 @@
1
+ require 'wechat/pay/client'
2
+
3
+ module Wechat
4
+ #
5
+ module Pay
6
+ end
7
+ end
@@ -0,0 +1,116 @@
1
+ require 'rest-client'
2
+ require 'logger'
3
+ require 'multi_json'
4
+ require 'openssl'
5
+ require 'nori'
6
+ require 'gyoku'
7
+
8
+ require 'wechat/pay/redpack'
9
+
10
+ module Wechat
11
+ module Pay
12
+ class PayError < StandardError; end
13
+ class NoAuthError < PayError; end
14
+ class NotEnoughError < PayError; end
15
+ class TimeLimitedError < PayError; end
16
+ class MoneyLimitedError < PayError; end
17
+
18
+ #
19
+ class Client
20
+ include Redpack
21
+ BASE_URL = 'https://api.mch.weixin.qq.com'
22
+ REQUIRED_OPTS = %w(key password cert sign_key).map(&:to_sym).freeze
23
+ ERRORS = {
24
+ 'NO_AUTH' => NoAuthError,
25
+ 'NOTENOUGH' => NotEnoughError,
26
+ 'TIME_LIMITED' => TimeLimitedError,
27
+ 'MONEY_LIMITED' => MoneyLimitedError
28
+ }
29
+
30
+ attr_accessor :logger
31
+
32
+ def initialize(mch_id, wxappid, opts = {})
33
+ @mch_id = mch_id
34
+ @wxappid = wxappid
35
+ @opts = Hash[opts.map { |k, v| [k.to_sym, v] }]
36
+ unless (REQUIRED_OPTS - @opts.keys).empty?
37
+ fail format('%s required', REQUIRED_OPTS.join(','))
38
+ end
39
+ @logger = Logger.new(STDOUT)
40
+ rsa_setup
41
+ @parser = Nori.new
42
+ end
43
+
44
+ def post(path, params)
45
+ merged_params = merge(params)
46
+ logger.debug { merged_params }
47
+ resp = resource(path).post(xml(sign(merged_params)))
48
+ handle(resp)
49
+ rescue RestClient::ExceptionWithResponse => err
50
+ raise PayError, err.response
51
+ end
52
+
53
+ private
54
+
55
+ def handle(resp)
56
+ response = parser.parse(resp)
57
+ check(response)
58
+ response
59
+ end
60
+
61
+ def check(r)
62
+ return if r['xml']['result_code'] == 'SUCCESS'
63
+ handle_error(r['xml']['err_code'], r)
64
+ end
65
+
66
+ def handle_error(error_code, response)
67
+ fail ERRORS[error_code] || PayError, response.inspect
68
+ end
69
+
70
+ def rsa_setup
71
+ @rsa_key = OpenSSL::PKey::RSA.new @opts[:key], @opts[:password]
72
+ @rsa_cert = OpenSSL::X509::Certificate.new @opts[:cert]
73
+ rescue StandardError => e
74
+ logger.error { e.inspect }
75
+ end
76
+
77
+ def resource(path)
78
+ RestClient.log = logger
79
+ RestClient::Resource.new\
80
+ [BASE_URL, path].join,
81
+ ssl_client_key: @rsa_key,
82
+ ssl_client_cert: @rsa_cert,
83
+ verify_ssl: OpenSSL::SSL::VERIFY_NONE
84
+ end
85
+
86
+ def xml(hash)
87
+ Gyoku.xml({ xml: hash }, key_converter: :none)
88
+ end
89
+
90
+ def sign(params)
91
+ ordered = trim_and_sort(params)
92
+ keystr = format('key=%s', @opts[:sign_key])
93
+ origin =
94
+ ordered.map { |k, v| [k, v].join('=') }.push(keystr).join('&')
95
+ sign = Digest::MD5.hexdigest(origin).upcase
96
+ logger.debug { format('origin: %s, sign: %s', origin, sign) }
97
+ params.merge(sign: sign)
98
+ end
99
+
100
+ def trim_and_sort(params)
101
+ params.delete_if { |_k, v| v.blank? }
102
+ Hash[params.sort]
103
+ end
104
+
105
+ def merge(params)
106
+ params.reverse_merge\
107
+ mch_id: @mch_id,
108
+ nonce_str: nonce_str
109
+ end
110
+
111
+ def nonce_str
112
+ SecureRandom.hex
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,39 @@
1
+ require 'securerandom'
2
+
3
+ module Wechat
4
+ module Pay
5
+ #
6
+ module Redpack
7
+ def redpack(transaction_id, openid, params = {})
8
+ post\
9
+ '/mmpaymkttransfers/sendredpack',
10
+ params.merge(
11
+ mch_billno: tran_id(transaction_id),
12
+ wxappid: @wxappid, re_openid: openid
13
+ )
14
+ end
15
+
16
+ def group_redpack(transaction_id, openid, params = {})
17
+ post\
18
+ '/mmpaymkttransfers/sendgroupredpack',
19
+ params.merge(
20
+ mch_billno: tran_id(transaction_id),
21
+ wxappid: @wxappid, re_openid: openid
22
+ )
23
+ end
24
+
25
+ def redpack_info(transaction_id)
26
+ post\
27
+ '/mmpaymkttransfers/gethbinfo',
28
+ mch_billno: tran_id(transaction_id),
29
+ bill_type: 'MCHT', appid: @wxappid
30
+ end
31
+
32
+ private
33
+
34
+ def tran_id(origin)
35
+ format('%s%s', @mch_id, origin)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,24 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ RSpec.describe Wechat::Pay::Client do
4
+ subject do
5
+ described_class.new\
6
+ 'mch_id', 'wxappid',
7
+ key: 'key', password: 'password', cert: 'cert',
8
+ sign_key: 'sign_key'
9
+ end
10
+
11
+ it :trim_and_sort do
12
+ expect(
13
+ subject.send(:trim_and_sort, b: 2, c: 3, a: 1).values
14
+ ).to start_with(1)
15
+ end
16
+
17
+ it :sign do
18
+ expect(subject.send(:sign, b: 2, a: 1)).to have_key(:sign)
19
+ end
20
+
21
+ it :xml do
22
+ expect(subject.send(:xml, b_1: 2, a: 1)).to match(/xml/)
23
+ end
24
+ end
@@ -17,8 +17,11 @@ Gem::Specification.new do |spec|
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ["lib"]
19
19
 
20
- spec.add_runtime_dependency "faraday", "~> 0.9"
21
- spec.add_runtime_dependency "multi_json", "~> 1.2"
20
+ spec.add_runtime_dependency "faraday", ">= 0.9"
21
+ spec.add_runtime_dependency "rest-client", ">= 1.7.0"
22
+ spec.add_runtime_dependency "multi_json", ">= 1.2"
23
+ spec.add_runtime_dependency 'gyoku', '>= 1.0.0'
24
+ spec.add_runtime_dependency 'nori'
22
25
  spec.add_development_dependency "bundler"
23
26
  spec.add_development_dependency "rake"
24
27
  spec.add_development_dependency "pry"
metadata CHANGED
@@ -1,43 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wechat-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Wong
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-25 00:00:00.000000000 Z
11
+ date: 2015-10-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.9'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rest-client
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.7.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.7.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: multi_json
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - "~>"
45
+ - - ">="
32
46
  - !ruby/object:Gem::Version
33
47
  version: '1.2'
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - "~>"
52
+ - - ">="
39
53
  - !ruby/object:Gem::Version
40
54
  version: '1.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: gyoku
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 1.0.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 1.0.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: nori
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
41
83
  - !ruby/object:Gem::Dependency
42
84
  name: bundler
43
85
  requirement: !ruby/object:Gem::Requirement
@@ -129,8 +171,12 @@ files:
129
171
  - lib/wechat/api/user.rb
130
172
  - lib/wechat/api/util.rb
131
173
  - lib/wechat/api/version.rb
174
+ - lib/wechat/pay.rb
175
+ - lib/wechat/pay/client.rb
176
+ - lib/wechat/pay/redpack.rb
132
177
  - spec/spec_helper.rb
133
178
  - spec/wechat/api/client_spec.rb
179
+ - spec/wechat/pay/client_spec.rb
134
180
  - wechat-api.gemspec
135
181
  homepage: https://github.com/lazing/wechat-api
136
182
  licenses:
@@ -159,4 +205,5 @@ summary: Wechat API wrapper
159
205
  test_files:
160
206
  - spec/spec_helper.rb
161
207
  - spec/wechat/api/client_spec.rb
208
+ - spec/wechat/pay/client_spec.rb
162
209
  has_rdoc: