unionpei 1.0.0 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/gem-push.yml +45 -0
- data/.gitignore +17 -0
- data/Gemfile +6 -0
- data/README.md +67 -0
- data/Rakefile +11 -0
- data/certs/acp_test_enc.cer +25 -0
- data/certs/acp_test_middle.cer +23 -0
- data/certs/acp_test_root.cer +22 -0
- data/certs/acp_test_sign.pfx +0 -0
- data/install.sh +2 -0
- data/lib/unionpei/acp_service.rb +37 -42
- data/lib/unionpei/cert_util.rb +61 -82
- data/lib/unionpei/configuration.rb +15 -0
- data/lib/unionpei/log_util.rb +24 -31
- data/lib/unionpei/payment.rb +78 -48
- data/lib/unionpei/sdk_config.rb +46 -48
- data/lib/unionpei/sdk_util.rb +164 -186
- data/lib/unionpei/version.rb +3 -7
- data/lib/unionpei.rb +17 -2
- data/unionpei.gemspec +31 -0
- metadata +87 -4
data/lib/unionpei/sdk_util.rb
CHANGED
@@ -1,328 +1,309 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'singleton'
|
4
4
|
require 'logger'
|
5
5
|
require 'net/https'
|
6
6
|
require 'uri'
|
7
7
|
require 'base64'
|
8
|
-
require
|
8
|
+
require 'zlib'
|
9
9
|
require_relative 'sdk_config'
|
10
10
|
require_relative 'cert_util'
|
11
11
|
|
12
|
-
|
13
12
|
module UnionPei
|
14
13
|
class SDKUtil
|
15
|
-
|
16
|
-
|
17
|
-
LogUtil.info("post
|
18
|
-
LogUtil.info("post content:["+content+"]")
|
14
|
+
def self.post(url, content)
|
15
|
+
LogUtil.info("post url:[#{url}]")
|
16
|
+
LogUtil.info("post content:[#{content}]")
|
19
17
|
uri = URI.parse(url)
|
20
18
|
http = Net::HTTP.new(uri.host, uri.port)
|
21
|
-
http.use_ssl = true if uri.scheme ==
|
22
|
-
|
23
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
24
|
-
end
|
19
|
+
http.use_ssl = true if uri.scheme == 'https'
|
20
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless SDKConfig.instance.ifValidateRemoteCert
|
25
21
|
res = http.post(uri.path, content).body.force_encoding(SDKConfig.instance.encoding)
|
26
|
-
LogUtil.info(
|
27
|
-
|
22
|
+
LogUtil.info("resp:[#{res}]")
|
23
|
+
res
|
28
24
|
end
|
29
25
|
|
30
|
-
def
|
31
|
-
linkString =
|
26
|
+
def self.createLinkString(para, sort, encode)
|
27
|
+
linkString = ''
|
32
28
|
keys = para.keys
|
33
|
-
if sort
|
34
|
-
|
35
|
-
end
|
36
|
-
for key in keys
|
29
|
+
keys = keys.sort if sort
|
30
|
+
keys.each do |key|
|
37
31
|
value = para[key]
|
38
32
|
# print(key + ":" + value)
|
39
|
-
if encode
|
40
|
-
value = URI.encode_www_form_component(value)
|
41
|
-
end
|
33
|
+
value = URI.encode_www_form_component(value) if encode
|
42
34
|
# print(str(type(key))+":"+str(type(value))+":"+str(key)+":"+str(value))
|
43
|
-
linkString = linkString
|
35
|
+
linkString = "#{linkString}#{key}=#{value}&"
|
44
36
|
end
|
45
|
-
linkString
|
37
|
+
linkString[0, linkString.length - 1]
|
46
38
|
# print (linkString)
|
47
|
-
return linkString
|
48
39
|
end
|
49
40
|
|
50
|
-
def
|
41
|
+
def self.filterNoneValue(para)
|
51
42
|
keys = para.keys
|
52
|
-
|
43
|
+
keys.each do |key|
|
53
44
|
value = para[key]
|
54
|
-
if !value
|
55
|
-
para.delete(key)
|
56
|
-
end
|
45
|
+
para.delete(key) if !value || (value == '')
|
57
46
|
end
|
58
47
|
end
|
59
48
|
|
60
|
-
def
|
61
|
-
|
49
|
+
def self.buildSignature(req, signCertPath = SDKConfig.instance.signCertPath, signCertPwd = SDKConfig.instance.signCertPwd, secureKey = SDKConfig.instance.secureKey)
|
62
50
|
SDKUtil.filterNoneValue(req)
|
63
|
-
|
64
|
-
LogUtil.error(
|
51
|
+
unless req['signMethod']
|
52
|
+
LogUtil.error('signMethod must not null')
|
65
53
|
return nil
|
66
54
|
end
|
67
|
-
|
68
|
-
LogUtil.error(
|
55
|
+
unless req['version']
|
56
|
+
LogUtil.error('version must not null')
|
69
57
|
return nil
|
70
58
|
end
|
71
|
-
if
|
72
|
-
req[
|
73
|
-
LogUtil.info(
|
59
|
+
if req['signMethod'] == '01'
|
60
|
+
req['certId'] = CertUtil.getSignCertId(signCertPath, signCertPwd)
|
61
|
+
LogUtil.info('=== start to sign ===')
|
74
62
|
prestr = SDKUtil.createLinkString(req, true, false)
|
75
|
-
LogUtil.info("sorted: [
|
63
|
+
LogUtil.info("sorted: [#{prestr}]")
|
76
64
|
prestr = SDKUtil.sha256(prestr)
|
77
|
-
LogUtil.info("sha256: [
|
78
|
-
LogUtil.info("sign cert: [
|
65
|
+
LogUtil.info("sha256: [#{prestr}]")
|
66
|
+
LogUtil.info("sign cert: [#{signCertPath}], pwd: [#{signCertPwd}]")
|
79
67
|
key = CertUtil.getSignPriKey(signCertPath, signCertPwd)
|
80
68
|
signature = Base64.encode64(key.sign('sha256', prestr)).gsub(/\n|\r/, '')
|
81
|
-
LogUtil.info("signature: [
|
82
|
-
elsif
|
83
|
-
LogUtil.info(
|
69
|
+
LogUtil.info("signature: [#{signature}]")
|
70
|
+
elsif req['signMethod'] == '11'
|
71
|
+
LogUtil.info('=== start to sign ===')
|
84
72
|
prestr = createLinkString(req, true, false)
|
85
|
-
LogUtil.info("sorted: [
|
73
|
+
LogUtil.info("sorted: [#{prestr}]")
|
86
74
|
if secureKey.nil?
|
87
|
-
LogUtil.error(
|
75
|
+
LogUtil.error('secureKey must not null')
|
88
76
|
return nil
|
89
77
|
end
|
90
|
-
prestr = prestr
|
91
|
-
LogUtil.debug("before final sha256: [
|
78
|
+
prestr = "#{prestr}&#{sha256(secureKey)}"
|
79
|
+
LogUtil.debug("before final sha256: [#{prestr}]")
|
92
80
|
signature = SDKUtil.sha256(prestr)
|
93
|
-
LogUtil.info("signature: [
|
94
|
-
elsif
|
95
|
-
LogUtil.error(
|
81
|
+
LogUtil.info("signature: [#{signature}]")
|
82
|
+
elsif '12' == ['signMethod']
|
83
|
+
LogUtil.error('sm3算法暂未实现,请勿使用。')
|
96
84
|
return nil
|
97
85
|
else
|
98
|
-
LogUtil.info("invalid signMethod: [
|
86
|
+
LogUtil.info("invalid signMethod: [#{req['signMethod']}]")
|
99
87
|
end
|
100
|
-
LogUtil.info(
|
101
|
-
req[
|
102
|
-
|
88
|
+
LogUtil.info('=== end of sign ===')
|
89
|
+
req['signature'] = signature
|
90
|
+
signature
|
103
91
|
end
|
104
92
|
|
105
|
-
def
|
93
|
+
def self.paraFilter(para)
|
106
94
|
result = {}
|
107
|
-
|
108
|
-
if (key ==
|
95
|
+
para.each_key do |key|
|
96
|
+
if (key == 'signature') || (para[key] == '')
|
109
97
|
next
|
110
98
|
else
|
111
99
|
result[key] = para[key]
|
112
100
|
end
|
113
101
|
end
|
114
|
-
|
102
|
+
result
|
115
103
|
end
|
116
104
|
|
117
|
-
def
|
118
|
-
OpenSSL::Digest::SHA256.digest(data).
|
105
|
+
def self.sha256(data)
|
106
|
+
OpenSSL::Digest::SHA256.digest(data).unpack1('H*').downcase
|
119
107
|
end
|
120
108
|
|
121
|
-
def
|
109
|
+
def self.putKeyValueToMap(temp, isKey, key, m, decode)
|
122
110
|
if isKey
|
123
|
-
m[key.to_s] =
|
111
|
+
m[key.to_s] = ''
|
124
112
|
else
|
125
|
-
if decode
|
126
|
-
temp = URI.decode_www_form_component(temp)
|
127
|
-
end
|
113
|
+
temp = URI.decode_www_form_component(temp) if decode
|
128
114
|
m[key.to_s] = temp
|
129
115
|
end
|
130
116
|
end
|
131
117
|
|
132
|
-
def
|
118
|
+
def self.parseQString(respString, decode = false)
|
133
119
|
resp = {}
|
134
|
-
temp =
|
135
|
-
key =
|
120
|
+
temp = ''
|
121
|
+
key = ''
|
136
122
|
isKey = true
|
137
|
-
isOpen = false
|
138
|
-
openName = "\0"
|
123
|
+
isOpen = false
|
124
|
+
openName = "\0"
|
139
125
|
|
140
|
-
|
141
|
-
if
|
142
|
-
if
|
143
|
-
|
144
|
-
|
145
|
-
temp = temp + curChar
|
146
|
-
elsif (curChar == "{")
|
126
|
+
respString.split('').each do |curChar| # 遍历整个带解析的字符串
|
127
|
+
if isOpen
|
128
|
+
isOpen = false if curChar == openName
|
129
|
+
temp += curChar
|
130
|
+
elsif curChar == '{'
|
147
131
|
isOpen = true
|
148
|
-
openName =
|
149
|
-
temp
|
150
|
-
elsif
|
132
|
+
openName = '}'
|
133
|
+
temp += curChar
|
134
|
+
elsif curChar == '['
|
151
135
|
isOpen = true
|
152
|
-
openName =
|
153
|
-
temp
|
154
|
-
elsif
|
136
|
+
openName = ']'
|
137
|
+
temp += curChar
|
138
|
+
elsif isKey && (curChar == '=')
|
155
139
|
key = temp
|
156
|
-
temp =
|
140
|
+
temp = ''
|
157
141
|
isKey = false
|
158
|
-
elsif (curChar ==
|
142
|
+
elsif (curChar == '&') && !isOpen # 如果读取到&分割符
|
159
143
|
SDKUtil.putKeyValueToMap(temp, isKey, key, resp, decode)
|
160
|
-
temp =
|
144
|
+
temp = ''
|
161
145
|
isKey = true
|
162
146
|
else
|
163
|
-
temp
|
147
|
+
temp += curChar
|
164
148
|
end
|
165
149
|
end
|
166
150
|
SDKUtil.putKeyValueToMap(temp, isKey, key, resp, decode)
|
167
|
-
|
151
|
+
resp
|
168
152
|
end
|
169
153
|
|
170
|
-
def
|
171
|
-
|
172
|
-
LogUtil.error(
|
154
|
+
def self.verify(resp)
|
155
|
+
unless resp['signMethod']
|
156
|
+
LogUtil.error('signMethod must not null')
|
173
157
|
return nil
|
174
158
|
end
|
175
|
-
|
176
|
-
LogUtil.error(
|
159
|
+
unless resp['version']
|
160
|
+
LogUtil.error('version must not null')
|
177
161
|
return nil
|
178
162
|
end
|
179
|
-
|
180
|
-
LogUtil.error(
|
163
|
+
unless resp['signature']
|
164
|
+
LogUtil.error('signature must not null')
|
181
165
|
return nil
|
182
166
|
end
|
183
|
-
signMethod = resp[
|
184
|
-
version = resp[
|
167
|
+
signMethod = resp['signMethod']
|
168
|
+
version = resp['version']
|
185
169
|
result = false
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
170
|
+
case signMethod
|
171
|
+
when '01'
|
172
|
+
LogUtil.info('=== start to verify signature ===')
|
173
|
+
signature = resp.delete('signature')
|
174
|
+
LogUtil.info("signature: [#{signature}]")
|
190
175
|
prestr = SDKUtil.createLinkString(resp, true, false)
|
191
|
-
LogUtil.info("sorted: [
|
176
|
+
LogUtil.info("sorted: [#{prestr}]")
|
192
177
|
prestr = SDKUtil.sha256(prestr)
|
193
|
-
LogUtil.info("sha256: [
|
194
|
-
key = CertUtil.verifyAndGetVerifyKey(resp[
|
178
|
+
LogUtil.info("sha256: [#{prestr}]")
|
179
|
+
key = CertUtil.verifyAndGetVerifyKey(resp['signPubKeyCert'])
|
195
180
|
if !key
|
196
|
-
LogUtil.info("no cert was found by signPubKeyCert:
|
181
|
+
LogUtil.info("no cert was found by signPubKeyCert: #{resp['signPubKeyCert']}")
|
197
182
|
result = false
|
198
183
|
else
|
199
184
|
signature = Base64.decode64(signature)
|
200
|
-
result = key.verify(
|
185
|
+
result = key.verify('sha256', signature, prestr)
|
201
186
|
end
|
202
|
-
LogUtil.info("verify signature
|
203
|
-
LogUtil.info(
|
204
|
-
|
205
|
-
|
206
|
-
|
187
|
+
LogUtil.info("verify signature #{result ? 'succeed' : 'fail'}")
|
188
|
+
LogUtil.info('=== end of verify signature ===')
|
189
|
+
result
|
190
|
+
when '11', '12'
|
191
|
+
SDKUtil.verifyBySecureKey(resp, SDKConfig.instance.secureKey)
|
207
192
|
else
|
208
|
-
LogUtil.info("Error signMethod [
|
209
|
-
|
193
|
+
LogUtil.info("Error signMethod [#{signMethod}] in validate. ")
|
194
|
+
false
|
210
195
|
end
|
211
196
|
end
|
212
197
|
|
213
|
-
def
|
214
|
-
if resp[
|
215
|
-
LogUtil.error(
|
198
|
+
def self.verifyBySecureKey(resp, secureKey)
|
199
|
+
if resp['signMethod'].nil?
|
200
|
+
LogUtil.error('signMethod must not null')
|
216
201
|
return nil
|
217
202
|
end
|
218
|
-
if resp[
|
219
|
-
LogUtil.error(
|
203
|
+
if resp['signature'].nil?
|
204
|
+
LogUtil.error('signature must not null')
|
220
205
|
return nil
|
221
206
|
end
|
222
|
-
signMethod = resp[
|
207
|
+
signMethod = resp['signMethod']
|
223
208
|
result = false
|
224
|
-
LogUtil.info(
|
225
|
-
|
226
|
-
|
227
|
-
|
209
|
+
LogUtil.info('=== start to verify signature ===')
|
210
|
+
case signMethod
|
211
|
+
when '11'
|
212
|
+
signature = resp.delete('signature')
|
213
|
+
LogUtil.info("signature: [#{signature}]")
|
228
214
|
prestr = createLinkString(resp, true, false)
|
229
|
-
LogUtil.info("sorted: [
|
230
|
-
beforeSha256 = prestr
|
231
|
-
LogUtil.debug("before final sha256: [
|
215
|
+
LogUtil.info("sorted: [#{prestr}]")
|
216
|
+
beforeSha256 = "#{prestr}&#{sha256(secureKey)}"
|
217
|
+
LogUtil.debug("before final sha256: [#{beforeSha256}]")
|
232
218
|
afterSha256 = sha256(beforeSha256)
|
233
219
|
result = (afterSha256 == signature)
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
elsif "12" == signMethod
|
238
|
-
LogUtil.error("sm3算法暂未实现,请勿使用。")
|
220
|
+
LogUtil.debug("after final sha256: [#{afterSha256}]") unless result
|
221
|
+
when '12'
|
222
|
+
LogUtil.error('sm3算法暂未实现,请勿使用。')
|
239
223
|
else
|
240
|
-
LogUtil.info("Error signMethod [
|
224
|
+
LogUtil.info("Error signMethod [#{signMethod}] in validate. ")
|
241
225
|
end
|
242
|
-
LogUtil.info("verify signature
|
243
|
-
LogUtil.info(
|
244
|
-
|
226
|
+
LogUtil.info("verify signature #{result ? 'succeed' : 'fail'}")
|
227
|
+
LogUtil.info('=== end of verify signature ===')
|
228
|
+
result
|
245
229
|
end
|
246
230
|
|
247
|
-
def
|
248
|
-
result = "<html><head> <meta http-equiv=\"Content-Type\" content=\"text/html; charset
|
249
|
-
|
231
|
+
def self.createAutoFormHtml(params, reqUrl)
|
232
|
+
result = "<html><head> <meta http-equiv=\"Content-Type\" content=\"text/html; charset=#{SDKConfig.instance.encoding}\" /></head><body onload=\"javascript:document.pay_form.submit();\"> <form id=\"pay_form\" name=\"pay_form\" action=\"#{reqUrl}\" method=\"post\">"
|
233
|
+
params.each_key do |key|
|
250
234
|
value = params[key]
|
251
|
-
result += " <input type=\"hidden\" name=\"
|
235
|
+
result += " <input type=\"hidden\" name=\"#{key}\" id=\"#{key}\" value=\"#{value}\" />\n"
|
252
236
|
end
|
253
|
-
result +=
|
254
|
-
LogUtil.info("auto post html
|
255
|
-
|
237
|
+
result += '<!-- <input type="submit" type="hidden">--> </form></body></html>'
|
238
|
+
LogUtil.info("auto post html:#{result}")
|
239
|
+
result
|
256
240
|
end
|
257
241
|
|
258
|
-
def
|
242
|
+
def self.encryptPub(data, certPath = SDKConfig.instance.encryptCertPath)
|
259
243
|
rsaKey = CertUtil.getEncryptKey(certPath)
|
260
244
|
result = rsaKey.public_encrypt(data)
|
261
|
-
|
262
|
-
return result
|
245
|
+
Base64.encode64(result).gsub(/\n|\r/, '')
|
263
246
|
end
|
264
247
|
|
265
|
-
def
|
248
|
+
def self.decryptPri(data, certPath = SDKConfig.instance.signCertPath, certPwd = SDKConfig.instance.signCertPwd)
|
266
249
|
pkey = CertUtil.getDecryptPriKey(certPath, certPwd)
|
267
250
|
data = Base64.decode64(data)
|
268
|
-
|
269
|
-
return result
|
251
|
+
pkey.private_decrypt(data)
|
270
252
|
end
|
271
253
|
|
272
|
-
def
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
LogUtil.info("文件内容为空")
|
254
|
+
def self.deCodeFileContent(params, fileDirectory)
|
255
|
+
return false unless params['fileContent']
|
256
|
+
|
257
|
+
LogUtil.info('---------处理后台报文返回的文件---------')
|
258
|
+
fileContent = params['fileContent']
|
259
|
+
unless fileContent
|
260
|
+
LogUtil.info('文件内容为空')
|
280
261
|
return false
|
281
262
|
end
|
282
263
|
fileContent = Zlib::Inflate.inflate(Base64.decode64(fileContent))
|
283
264
|
filePath = ''
|
284
|
-
if !params[
|
285
|
-
LogUtil.info(
|
286
|
-
filePath = fileDirectory
|
265
|
+
if !params['fileName']
|
266
|
+
LogUtil.info('文件名为空')
|
267
|
+
filePath = "#{fileDirectory}/#{params['merId']}_#{params['batchNo']}_#{params['txnTime']}.txt"
|
287
268
|
else
|
288
|
-
filePath = fileDirectory
|
269
|
+
filePath = "#{fileDirectory}/#{params['fileName']}"
|
289
270
|
end
|
290
271
|
output = File.new(filePath, 'w')
|
291
|
-
|
292
|
-
LogUtil.error
|
272
|
+
unless output
|
273
|
+
LogUtil.error 'Unable to open file!'
|
293
274
|
return false
|
294
275
|
end
|
295
276
|
output.syswrite(fileContent)
|
296
|
-
LogUtil.info "文件位置
|
277
|
+
LogUtil.info "文件位置 >:#{filePath}"
|
297
278
|
output.close
|
298
|
-
|
279
|
+
true
|
299
280
|
end
|
300
281
|
|
301
|
-
def
|
282
|
+
def self.enCodeFileContent(path)
|
302
283
|
fileContent = IO.binread(path)
|
303
284
|
fileContent = Base64.encode64(Zlib::Deflate.deflate(fileContent)).gsub(/\n|\r/, '')
|
304
285
|
end
|
305
286
|
|
306
|
-
def
|
307
|
-
if params['encryptPubKeyCert'].nil?
|
308
|
-
LogUtil.error(
|
287
|
+
def self.getEncryptCert(params)
|
288
|
+
if params['encryptPubKeyCert'].nil? || params['certType'].nil?
|
289
|
+
LogUtil.error('encryptPubKeyCert or certType is null')
|
309
290
|
return -1
|
310
291
|
end
|
311
292
|
strCert = params['encryptPubKeyCert']
|
312
293
|
certType = params['certType']
|
313
294
|
|
314
295
|
x509Cert = CertUtil.getX509Cert(strCert)
|
315
|
-
|
296
|
+
case certType
|
297
|
+
when '01'
|
316
298
|
# 更新敏感信息加密公钥
|
317
|
-
if x509Cert.serial.to_s == CertUtil.getEncryptCertId
|
318
|
-
|
319
|
-
end
|
299
|
+
return 0 if x509Cert.serial.to_s == CertUtil.getEncryptCertId
|
300
|
+
|
320
301
|
localCertPath = SDKConfig.instance.encryptCertPath
|
321
302
|
newLocalCertPath = SDKUtil.genBackupName(localCertPath)
|
322
303
|
# 将本地证书进行备份存储
|
323
304
|
File.rename(localCertPath, newLocalCertPath)
|
324
|
-
f = File.new(localCertPath,
|
325
|
-
|
305
|
+
f = File.new(localCertPath, 'w')
|
306
|
+
unless f
|
326
307
|
LogUtil.error 'Unable to open file!'
|
327
308
|
return -1
|
328
309
|
end
|
@@ -330,23 +311,20 @@ module UnionPei
|
|
330
311
|
f.close
|
331
312
|
LogUtil.info('save new encryptPubKeyCert success')
|
332
313
|
CertUtil.resetEncryptCertPublicKey
|
333
|
-
|
334
|
-
|
335
|
-
|
314
|
+
1
|
315
|
+
when '02'
|
316
|
+
0
|
336
317
|
else
|
337
|
-
LogUtil.error("unknown cerType
|
338
|
-
|
318
|
+
LogUtil.error("unknown cerType:#{certType}")
|
319
|
+
-1
|
339
320
|
end
|
340
321
|
end
|
341
322
|
|
342
|
-
def
|
323
|
+
def self.genBackupName(fileName)
|
343
324
|
i = fileName.rindex('.')
|
344
325
|
leftFileName = fileName[0, i]
|
345
326
|
rightFileName = fileName[i + 1, fileName.length - i]
|
346
|
-
|
347
|
-
return newFileName
|
327
|
+
"#{leftFileName}_backup.#{rightFileName}"
|
348
328
|
end
|
349
329
|
end
|
350
330
|
end
|
351
|
-
|
352
|
-
|
data/lib/unionpei/version.rb
CHANGED
data/lib/unionpei.rb
CHANGED
@@ -1,9 +1,24 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module UnionPei
|
4
|
+
class Error < StandardError; end
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def configuration
|
8
|
+
@configuration ||= Configuration.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def configure
|
12
|
+
yield(configuration)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'unionpei/configuration'
|
3
18
|
require 'unionpei/version'
|
4
19
|
require 'unionpei/sdk_config'
|
5
20
|
require 'unionpei/log_util'
|
6
21
|
require 'unionpei/cert_util'
|
7
22
|
require 'unionpei/sdk_util'
|
8
23
|
require 'unionpei/acp_service'
|
9
|
-
require 'unionpei/payment'
|
24
|
+
require 'unionpei/payment'
|
data/unionpei.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'unionpei/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = 'unionpei'
|
9
|
+
s.version = UnionPei::VERSION
|
10
|
+
s.summary = 'An unofficial unionpay gem'
|
11
|
+
s.description = 'An unofficial unionpay gem'
|
12
|
+
s.authors = ['memorycancel', 'tianlu1677']
|
13
|
+
s.email = 'memorycancel@gmail.com'
|
14
|
+
s.files = `git ls-files -z`.split("\x0").reject do |f|
|
15
|
+
f.match(%r{^(test|spec|features)/})
|
16
|
+
end
|
17
|
+
s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
|
+
s.require_paths = ['lib']
|
19
|
+
|
20
|
+
s.homepage = 'https://rubygems.org/gems/unionpei'
|
21
|
+
s.license = 'MIT'
|
22
|
+
s.add_runtime_dependency 'iniparse'
|
23
|
+
s.add_runtime_dependency 'jruby-openssl' if RUBY_PLATFORM == 'java'
|
24
|
+
s.add_runtime_dependency 'openssl' if RUBY_PLATFORM == 'ruby'
|
25
|
+
|
26
|
+
s.add_development_dependency 'bundler'
|
27
|
+
s.add_development_dependency 'minitest'
|
28
|
+
s.add_development_dependency 'pry'
|
29
|
+
s.add_development_dependency 'rake'
|
30
|
+
s.add_development_dependency 'webmock'
|
31
|
+
end
|