yhsd_api 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.travis.yml +5 -0
- data/ChangeLog.md +54 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +242 -0
- data/Rakefile +2 -0
- data/lib/yhsd_api/configuration.rb +48 -0
- data/lib/yhsd_api/exception.rb +41 -0
- data/lib/yhsd_api/helper.rb +78 -0
- data/lib/yhsd_api/http.rb +135 -0
- data/lib/yhsd_api/private_app.rb +114 -0
- data/lib/yhsd_api/public_app.rb +124 -0
- data/lib/yhsd_api/resources/account.rb +25 -0
- data/lib/yhsd_api/resources/asset.rb +37 -0
- data/lib/yhsd_api/resources/base.rb +25 -0
- data/lib/yhsd_api/resources/city.rb +25 -0
- data/lib/yhsd_api/resources/country.rb +25 -0
- data/lib/yhsd_api/resources/customer.rb +43 -0
- data/lib/yhsd_api/resources/customer_address.rb +43 -0
- data/lib/yhsd_api/resources/district.rb +25 -0
- data/lib/yhsd_api/resources/metafield.rb +55 -0
- data/lib/yhsd_api/resources/open_payment.rb +31 -0
- data/lib/yhsd_api/resources/order.rb +31 -0
- data/lib/yhsd_api/resources/page.rb +43 -0
- data/lib/yhsd_api/resources/payment.rb +25 -0
- data/lib/yhsd_api/resources/payment_method.rb +25 -0
- data/lib/yhsd_api/resources/product.rb +43 -0
- data/lib/yhsd_api/resources/product_image.rb +43 -0
- data/lib/yhsd_api/resources/product_variant.rb +43 -0
- data/lib/yhsd_api/resources/province.rb +25 -0
- data/lib/yhsd_api/resources/redirect.rb +43 -0
- data/lib/yhsd_api/resources/script_tag.rb +43 -0
- data/lib/yhsd_api/resources/shipment.rb +37 -0
- data/lib/yhsd_api/resources/shipment_supplier.rb +25 -0
- data/lib/yhsd_api/resources/shop.rb +13 -0
- data/lib/yhsd_api/resources/theme.rb +37 -0
- data/lib/yhsd_api/resources/webhook.rb +45 -0
- data/lib/yhsd_api/resources.rb +2 -0
- data/lib/yhsd_api/version.rb +3 -0
- data/lib/yhsd_api.rb +16 -0
- data/spec/configuration_spec.rb +49 -0
- data/spec/helper_spec.rb +75 -0
- data/spec/private_app_spec.rb +68 -0
- data/spec/public_app_spec.rb +93 -0
- data/spec/resources/account_spec.rb +31 -0
- data/spec/resources/asset_spec.rb +56 -0
- data/spec/resources/city_spec.rb +30 -0
- data/spec/resources/country_spec.rb +28 -0
- data/spec/resources/customer_address_spec.rb +66 -0
- data/spec/resources/customer_spec.rb +67 -0
- data/spec/resources/district_spec.rb +31 -0
- data/spec/resources/metafield_spec.rb +79 -0
- data/spec/resources/open_payment_spec.rb +40 -0
- data/spec/resources/order_spec.rb +41 -0
- data/spec/resources/page_spec.rb +54 -0
- data/spec/resources/payment_method_spec.rb +28 -0
- data/spec/resources/payment_spec.rb +29 -0
- data/spec/resources/product_image_spec.rb +59 -0
- data/spec/resources/product_spec.rb +123 -0
- data/spec/resources/product_variant_spec.rb +74 -0
- data/spec/resources/province_spec.rb +29 -0
- data/spec/resources/redirect_spec.rb +58 -0
- data/spec/resources/script_tag_spec.rb +54 -0
- data/spec/resources/shipment_spec.rb +43 -0
- data/spec/resources/shipment_supplier_spec.rb +31 -0
- data/spec/resources/shop_spec.rb +18 -0
- data/spec/resources/theme_spec.rb +38 -0
- data/spec/resources/webhook_spec.rb +54 -0
- data/spec/spec_helper.rb +9 -0
- data/yhsd_api.gemspec +26 -0
- metadata +217 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5b1916d01e246ed4dac2598fd229b84d692c39fa
|
4
|
+
data.tar.gz: 2ba0a91ef0824d7bb72663bd0319d9871bbf4327
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 10d5566ad6402f501fba2a275074fb6cb0ecaccd15d4b89706f09e28511eef9aab0104bcd29ee94e988a59205dc6791f71496c304b2ea60a25f4fbbcceca2165
|
7
|
+
data.tar.gz: 373540abd96aa6e84aeb3a14412b8f99b50012cfee0a0cbdc19410c04104e790a9a95dc9e9b5d8a2f2e9f3b8a8a750fe0024707d00d7e423c12683aad93a36f1
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/ChangeLog.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# Yhsd-api-ruby Changes
|
2
|
+
next
|
3
|
+
-----------
|
4
|
+
-YhsdPublicApi and YhsdPrivateApi get post delete put function change url params to path
|
5
|
+
|
6
|
+
-FIX scope /r/n change to URI bug
|
7
|
+
|
8
|
+
0.0.2
|
9
|
+
-----------
|
10
|
+
|
11
|
+
- Add yhsd api resources
|
12
|
+
you can use like:
|
13
|
+
```ruby
|
14
|
+
#get the shop customers limit 50 and page 2 find id,name fields
|
15
|
+
params = {:fields => "id,name", :page => 2, :limit => 50}
|
16
|
+
YhsdApi::Customer.all(token, params)
|
17
|
+
|
18
|
+
#create a customer for your shop
|
19
|
+
params = {
|
20
|
+
"customer": {
|
21
|
+
"reg_type":"email",
|
22
|
+
"reg_identity": "for@example.com",
|
23
|
+
"password":"123456",
|
24
|
+
"notify_email":"for@example.com",
|
25
|
+
"notify_phone":"13632269380"
|
26
|
+
}
|
27
|
+
}
|
28
|
+
YhsdApi::Customer.create(token, params)
|
29
|
+
|
30
|
+
#update the 1120 id customer
|
31
|
+
params = {
|
32
|
+
"customer": {
|
33
|
+
"notify_email":"new@example.com",
|
34
|
+
"notify_phone":"13632269381"
|
35
|
+
}
|
36
|
+
}
|
37
|
+
YhsdApi::Customer.update(token, 1120, params)
|
38
|
+
```
|
39
|
+
- Add call limit configure
|
40
|
+
you can open call limit configure by use
|
41
|
+
```ruby
|
42
|
+
YhsdApi.configure do |config|
|
43
|
+
config.call_limit_protect = true
|
44
|
+
end
|
45
|
+
```
|
46
|
+
this call limit is basic on shop token, so i advice open it in private app and close in public app , public app manage mutil shops, so may be some shop request api over call limit , other shop
|
47
|
+
will be affect
|
48
|
+
|
49
|
+
0.0.1
|
50
|
+
-----------
|
51
|
+
|
52
|
+
|
53
|
+
- Basic support yhsd api
|
54
|
+
- About how to use you can see [README.md](https://github.com/yeezon/yhsd-api-ruby/blob/master/README.md)
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 TODO: Write your name
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,242 @@
|
|
1
|
+
# yhsd-api-ruby
|
2
|
+
|
3
|
+
友好速搭应用开发 Ruby SDK
|
4
|
+
|
5
|
+
## 安装
|
6
|
+
|
7
|
+
在应用的gem file 中添加:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'yhsd_api'
|
11
|
+
```
|
12
|
+
|
13
|
+
执行:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
或者直接使用命令行进行安装:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
$ gem install yhsd_api
|
23
|
+
```
|
24
|
+
|
25
|
+
## 使用方法
|
26
|
+
|
27
|
+
###1,私有应用
|
28
|
+
|
29
|
+
配置私有应用的app_key, app_secret
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
YhsdApi.configure do |config|
|
33
|
+
config.app_key = '配置你的app_key'
|
34
|
+
config.app_secret = '配置你的app_secret'
|
35
|
+
config.token_url = 'https://apps.youhaosuda.com/oauth2/token/'
|
36
|
+
config.api_url = 'https://api.youhaosuda.com/'
|
37
|
+
config.api_version = 'v1/'
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
获取友好速搭token
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
YhsdApi::PrivateApp.generate_token
|
45
|
+
```
|
46
|
+
|
47
|
+
调用友好速搭api接口
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
#get 接口调用
|
51
|
+
#url 需要访问的api接口的地址
|
52
|
+
#返回结果
|
53
|
+
#code :200
|
54
|
+
#body hash 数据
|
55
|
+
#header hash 数据
|
56
|
+
YhsdApi::PrivateApp.get(url)
|
57
|
+
|
58
|
+
#put 接口调用
|
59
|
+
#url 需要访问的api接口的地址
|
60
|
+
#params 参数
|
61
|
+
#返回结果
|
62
|
+
#code :200
|
63
|
+
#body hash 数据
|
64
|
+
#header hash 数据
|
65
|
+
YhsdApi::PrivateApp.put(url, params)
|
66
|
+
|
67
|
+
#post 接口调用
|
68
|
+
#url 需要访问的api接口的地址
|
69
|
+
#params 参数
|
70
|
+
#返回结果
|
71
|
+
#code :200
|
72
|
+
#body hash 数据
|
73
|
+
#header hash 数据
|
74
|
+
YhsdApi::PrivateApp.post(url, params)
|
75
|
+
|
76
|
+
#delete 接口调用
|
77
|
+
#url 需要访问的api接口的地址
|
78
|
+
#返回结果
|
79
|
+
#code :200
|
80
|
+
#body hash 数据
|
81
|
+
#header hash 数据
|
82
|
+
YhsdApi::PrivateApp.delete(url)
|
83
|
+
```
|
84
|
+
|
85
|
+
例子
|
86
|
+
```ruby
|
87
|
+
YhsdApi::PrivateApp.token = '获取到的token'
|
88
|
+
|
89
|
+
#get 接口调用
|
90
|
+
code, body, header = YhsdApi::PrivateApp.get("shop")
|
91
|
+
|
92
|
+
#put 接口调用
|
93
|
+
params = {
|
94
|
+
"redirect": {
|
95
|
+
"path": "/12345",
|
96
|
+
"target": "/blogs"
|
97
|
+
}
|
98
|
+
}
|
99
|
+
code, body, header = YhsdApi::PrivateApp.put("redirects/1", params)
|
100
|
+
|
101
|
+
#post 接口调用
|
102
|
+
params = {
|
103
|
+
"redirect": {
|
104
|
+
"path": "/12345",
|
105
|
+
"target": "/blogs"
|
106
|
+
}
|
107
|
+
}
|
108
|
+
code, body, header = YhsdApi::PrivateApp.put("redirects", params)
|
109
|
+
|
110
|
+
#delete 接口调用
|
111
|
+
code, body, header = YhsdApi::PrivateApp.delete("redirects/1")
|
112
|
+
```
|
113
|
+
|
114
|
+
友好速搭的token是不过期的,你也可以通过
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
YhsdApi::PrivateApp.token = '你的私有应用token'
|
118
|
+
```
|
119
|
+
|
120
|
+
来进行指定token值,这样就不需要调用generate_token来获取token值了。
|
121
|
+
|
122
|
+
###2,开放应用
|
123
|
+
|
124
|
+
配置公有一用的app_key, app_secret
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
YhsdApi.configure do |config|
|
128
|
+
config.app_key = '配置你的app_key'
|
129
|
+
config.app_secret = '配置你的app_secret'
|
130
|
+
config.scope = '配置你的应用scope'
|
131
|
+
config.auth_url = "https://apps.youhaosuda.com/oauth2/authorize/"
|
132
|
+
config.token_url = 'https://apps.youhaosuda.com/oauth2/token/'
|
133
|
+
config.api_url = 'https://api.youhaosuda.com/'
|
134
|
+
config.api_version = 'v1/'
|
135
|
+
end
|
136
|
+
```
|
137
|
+
|
138
|
+
友好速搭hmac验证,获取到参数后调用
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
#true 表示验证正确 false 表示错误
|
142
|
+
#params 为获取到的所有参数
|
143
|
+
YhsdApi::PublicApp.verify_hmac(params)
|
144
|
+
```
|
145
|
+
|
146
|
+
友好速搭授权回调url获取
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
#返回结果 友好速搭授权url
|
150
|
+
#redirect_url应用的跳转地址
|
151
|
+
#shop_key 友好速搭安装应用的店铺唯一key
|
152
|
+
#state 自定义的参数
|
153
|
+
YhsdApi::PublicApp.authorize_url(redirect_url, shop_key, state)
|
154
|
+
```
|
155
|
+
|
156
|
+
友好速搭店铺token获取
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
#返回结果 店铺的开放应用token
|
160
|
+
#redirect_url 应用的跳转地址
|
161
|
+
#code友好速搭返回获取授权码的code
|
162
|
+
YhsdApi::PublicApp::generate_token(redirect_url, code)
|
163
|
+
```
|
164
|
+
|
165
|
+
调用友好速搭api接口
|
166
|
+
|
167
|
+
```ruby
|
168
|
+
#get 接口调用
|
169
|
+
#token 访问token
|
170
|
+
#url 需要访问的api接口的地址
|
171
|
+
#返回结果
|
172
|
+
#code :200
|
173
|
+
#body hash 数据
|
174
|
+
#header hash 数据
|
175
|
+
YhsdApi::PublicApp.get(token, url)
|
176
|
+
|
177
|
+
#put 接口调用
|
178
|
+
#token 访问token
|
179
|
+
#url 需要访问的api接口的地址
|
180
|
+
#params 参数
|
181
|
+
#返回结果
|
182
|
+
#code :200
|
183
|
+
#body hash 数据
|
184
|
+
#header hash 数据
|
185
|
+
YhsdApi::PublicApp.put(token, url, params)
|
186
|
+
|
187
|
+
#post 接口调用
|
188
|
+
#token 访问token
|
189
|
+
#url 需要访问的api接口的地址
|
190
|
+
#params 参数
|
191
|
+
#返回结果
|
192
|
+
#code :200
|
193
|
+
#body hash 数据
|
194
|
+
#header hash 数据
|
195
|
+
YhsdApi::PublicApp.post(token, url, params)
|
196
|
+
|
197
|
+
#delete 接口调用
|
198
|
+
#token 访问token
|
199
|
+
#url 需要访问的api接口的地址
|
200
|
+
#返回结果
|
201
|
+
#code :200
|
202
|
+
#body hash 数据
|
203
|
+
#header hash 数据
|
204
|
+
YhsdApi::PublicApp.delete(token, url)
|
205
|
+
```
|
206
|
+
|
207
|
+
例子
|
208
|
+
```ruby
|
209
|
+
token = '店铺的访问token'
|
210
|
+
|
211
|
+
#get 接口调用
|
212
|
+
code, body, header = YhsdApi::PublicApp.get(token, "shop")
|
213
|
+
|
214
|
+
#put 接口调用
|
215
|
+
params = {
|
216
|
+
"redirect": {
|
217
|
+
"path": "/12345",
|
218
|
+
"target": "/blogs"
|
219
|
+
}
|
220
|
+
}
|
221
|
+
code, body, header = YhsdApi::PublicApp.put(token, "redirects/1", params)
|
222
|
+
|
223
|
+
#post 接口调用
|
224
|
+
params = {
|
225
|
+
"redirect": {
|
226
|
+
"path": "/12345",
|
227
|
+
"target": "/blogs"
|
228
|
+
}
|
229
|
+
}
|
230
|
+
code, body, header = YhsdApi::PublicApp.put("token, "redirects", params)
|
231
|
+
|
232
|
+
#delete 接口调用
|
233
|
+
code, body, header = YhsdApi::PublicApp.delete(token, "redirects/1")
|
234
|
+
```
|
235
|
+
|
236
|
+
## 贡献
|
237
|
+
|
238
|
+
1. Fork it ( https://github.com/yeezon/yhsd-api-ruby/fork )
|
239
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
240
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
241
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
242
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module YhsdApi
|
2
|
+
|
3
|
+
class Configuration
|
4
|
+
|
5
|
+
attr_accessor :app_key
|
6
|
+
attr_accessor :app_secret
|
7
|
+
attr_accessor :scope
|
8
|
+
attr_accessor :auth_url
|
9
|
+
attr_accessor :token_url
|
10
|
+
attr_accessor :api_url
|
11
|
+
attr_accessor :api_version
|
12
|
+
attr_accessor :call_limit_protect
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@auth_url = 'https://apps.youhaosuda.com/oauth2/authorize/'
|
16
|
+
@token_url = 'https://apps.youhaosuda.com/oauth2/token/'
|
17
|
+
@api_url = 'https://api.youhaosuda.com/'
|
18
|
+
@api_version = 'v1/'
|
19
|
+
@call_limit_protect = false
|
20
|
+
end
|
21
|
+
|
22
|
+
def scope
|
23
|
+
@scope.to_s.gsub(/\s+/, "")
|
24
|
+
end
|
25
|
+
|
26
|
+
def api_version
|
27
|
+
unless @api_version.end_with?("/")
|
28
|
+
@api_version.to_s + "/"
|
29
|
+
else
|
30
|
+
@api_version
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.configuration
|
37
|
+
@configuration ||= Configuration.new
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.configuration=(config)
|
41
|
+
@configuration = config
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.configure
|
45
|
+
yield configuration
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module YhsdApi
|
2
|
+
|
3
|
+
class MissingToken < Exception
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
super('token is empty.')
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
class MissingAppKey < Exception
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
super('app key is empty.')
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
class MissingScope < Exception
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
super('scope is empty.')
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
class MissingAppSecret < Exception
|
28
|
+
|
29
|
+
def initialize
|
30
|
+
super('app secret is empty.')
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
class MissingURI < Exception
|
36
|
+
def initialize
|
37
|
+
super('url is empty.')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module YhsdApi
|
2
|
+
|
3
|
+
class Helper
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
###
|
8
|
+
#私有APP 通过 app key 和 app secret 生成标准的 0auth2 头部内容
|
9
|
+
###
|
10
|
+
def authorization(key, secret)
|
11
|
+
content = "#{key}:#{secret}"
|
12
|
+
# 使用遵循 RFC 4648 的 Base64 编码函数
|
13
|
+
encode = Base64.urlsafe_encode64(content)
|
14
|
+
"Basic #{encode}"
|
15
|
+
end
|
16
|
+
|
17
|
+
###
|
18
|
+
#通过app secret和友好速搭回传的参数,验证当前请求是否来自于友好速搭
|
19
|
+
###
|
20
|
+
def hmac_verify(secret, params = {})
|
21
|
+
raise 'secret can not be empty' if secret.to_s.empty?
|
22
|
+
if params.has_key?(:hmac)
|
23
|
+
hmac = params[:hmac].to_s
|
24
|
+
elsif params.has_key?("hmac")
|
25
|
+
hmac = params["hmac"].to_s
|
26
|
+
else
|
27
|
+
return false
|
28
|
+
end
|
29
|
+
return false if hmac.empty?
|
30
|
+
p = params.delete_if{|key, value| key.to_s == "hmac"}
|
31
|
+
str = p.keys.sort.map do |k|
|
32
|
+
"#{k.to_s}=#{params[k].to_s}"
|
33
|
+
end.join('&')
|
34
|
+
digest = OpenSSL::Digest.new('sha256')
|
35
|
+
hmac == OpenSSL::HMAC.hexdigest(digest, secret, str)
|
36
|
+
end
|
37
|
+
|
38
|
+
###
|
39
|
+
#第三方App接入参数生成函数
|
40
|
+
###
|
41
|
+
def thirdapp_aes_encrypt(secret, data = {})
|
42
|
+
raise 'secret can not be empty' if secret.to_s.empty?
|
43
|
+
cipher = OpenSSL::Cipher::Cipher.new("aes-128-cbc")
|
44
|
+
cipher.encrypt
|
45
|
+
cipher.key = secret[0, 16]
|
46
|
+
cipher.iv = secret[16, 16]
|
47
|
+
ciphertext = cipher.update(data) + cipher.final
|
48
|
+
Base64.urlsafe_encode64(ciphertext)
|
49
|
+
end
|
50
|
+
|
51
|
+
###
|
52
|
+
#友好速搭webhook通知验证
|
53
|
+
###
|
54
|
+
def webhook_verify(token, data, hmac)
|
55
|
+
digest = OpenSSL::Digest.new('sha256')
|
56
|
+
calculated_hmac = Base64.encode64(OpenSSL::HMAC.digest(digest, token, data)).strip
|
57
|
+
calculated_hmac == hmac
|
58
|
+
end
|
59
|
+
|
60
|
+
def generate_hmac(secret, params = {})
|
61
|
+
raise 'secret can not be empty' if secret.to_s.empty?
|
62
|
+
str = params.keys.sort.map do |k|
|
63
|
+
"#{k.to_s}=#{params[k].to_s}"
|
64
|
+
end.join('&')
|
65
|
+
digest = OpenSSL::Digest.new('sha256')
|
66
|
+
OpenSSL::HMAC.hexdigest(digest, secret, str)
|
67
|
+
end
|
68
|
+
|
69
|
+
###
|
70
|
+
#友好速搭开放支付回调验证
|
71
|
+
###
|
72
|
+
alias_method :openpayment_verify, :webhook_verify
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
|
3
|
+
module YhsdApi
|
4
|
+
|
5
|
+
class HTTP
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
@@last_at = nil
|
10
|
+
@@limit = 0
|
11
|
+
@@total = 0
|
12
|
+
|
13
|
+
def get(url, opts = {})
|
14
|
+
validate_url(url)
|
15
|
+
|
16
|
+
req_headers = {}
|
17
|
+
|
18
|
+
if opts[:headers].is_a?(Hash)
|
19
|
+
req_headers.merge!(opts[:headers])
|
20
|
+
end
|
21
|
+
|
22
|
+
begin
|
23
|
+
begin_request if YhsdApi.configuration.call_limit_protect
|
24
|
+
response = RestClient.get(url.to_s, req_headers)
|
25
|
+
after_request(response.raw_headers) if YhsdApi.configuration.call_limit_protect
|
26
|
+
return response.code.to_i, response.body, response.raw_headers
|
27
|
+
rescue Exception => e
|
28
|
+
if e.class.to_s.split("::").first.to_s == 'RestClient'
|
29
|
+
return e.http_code.to_i, e.response, {}
|
30
|
+
else
|
31
|
+
raise e
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def post(url, req_body = nil, opts = {})
|
38
|
+
validate_url(url)
|
39
|
+
|
40
|
+
req_headers = {}
|
41
|
+
|
42
|
+
if opts[:headers].is_a?(Hash)
|
43
|
+
req_headers.merge!(opts[:headers])
|
44
|
+
end
|
45
|
+
|
46
|
+
begin
|
47
|
+
begin_request if YhsdApi.configuration.call_limit_protect
|
48
|
+
response = RestClient.post(url.to_s, req_body, req_headers)
|
49
|
+
after_request(response.raw_headers) if YhsdApi.configuration.call_limit_protect
|
50
|
+
return response.code.to_i, response.body, response.raw_headers
|
51
|
+
rescue Exception => e
|
52
|
+
if e.class.to_s.split("::").first.to_s == 'RestClient'
|
53
|
+
return e.http_code.to_i, e.response, {}
|
54
|
+
else
|
55
|
+
raise e
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
def put(url, req_body = nil, opts = {})
|
62
|
+
validate_url(url)
|
63
|
+
|
64
|
+
req_headers = {}
|
65
|
+
|
66
|
+
if opts[:headers].is_a?(Hash)
|
67
|
+
req_headers.merge!(opts[:headers])
|
68
|
+
end
|
69
|
+
|
70
|
+
begin
|
71
|
+
begin_request if YhsdApi.configuration.call_limit_protect
|
72
|
+
response = RestClient.put(url.to_s, req_body, req_headers)
|
73
|
+
after_request(response.raw_headers) if YhsdApi.configuration.call_limit_protect
|
74
|
+
return response.code.to_i, response.body, response.raw_headers
|
75
|
+
rescue Exception => e
|
76
|
+
if e.class.to_s.split("::").first.to_s == 'RestClient'
|
77
|
+
return e.http_code.to_i, e.response, {}
|
78
|
+
else
|
79
|
+
raise e
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
def delete(url, opts = {})
|
86
|
+
validate_url(url)
|
87
|
+
|
88
|
+
req_headers = {}
|
89
|
+
|
90
|
+
if opts[:headers].is_a?(Hash)
|
91
|
+
req_headers.merge!(opts[:headers])
|
92
|
+
end
|
93
|
+
|
94
|
+
begin
|
95
|
+
begin_request if YhsdApi.configuration.call_limit_protect
|
96
|
+
response = RestClient.delete(url.to_s, req_headers)
|
97
|
+
after_request(response.raw_headers) if YhsdApi.configuration.call_limit_protect
|
98
|
+
return response.code.to_i, response.body, response.raw_headers
|
99
|
+
rescue Exception => e
|
100
|
+
if e.class.to_s.split("::").first.to_s == 'RestClient'
|
101
|
+
return e.http_code.to_i, e.response, {}
|
102
|
+
else
|
103
|
+
raise e
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
def validate_url(url)
|
110
|
+
raise MissingURI if url.to_s.empty?
|
111
|
+
end
|
112
|
+
|
113
|
+
def after_request(header)
|
114
|
+
begin
|
115
|
+
if header && header.is_a?(Hash) && header.keys.include?("x-yhsd-shop-api-call-limit")
|
116
|
+
call_limit = header["x-yhsd-shop-api-call-limit"].first.split("/")
|
117
|
+
@@limit, @@total = call_limit[0].to_i, call_limit[1].to_i
|
118
|
+
@@last_at = Time.now.to_i
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def begin_request
|
124
|
+
if @@last_at
|
125
|
+
if Time.now.to_i - @@last_at <= 1000 && @@total - @@limit <= 2
|
126
|
+
sleep(1)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|