ecpay_payment 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/Rakefile +6 -0
- data/conf/payment_conf.xml +29 -0
- data/ecpay.gemspec +25 -0
- data/lib/ecpay_payment/ECpayPayment.xml +623 -0
- data/lib/ecpay_payment/core_ext/hash.rb +13 -0
- data/lib/ecpay_payment/core_ext/string.rb +5 -0
- data/lib/ecpay_payment/error.rb +8 -0
- data/lib/ecpay_payment/exec_grant_refund.rb +82 -0
- data/lib/ecpay_payment/helper.rb +205 -0
- data/lib/ecpay_payment/payment_client.rb +217 -0
- data/lib/ecpay_payment/query_client.rb +142 -0
- data/lib/ecpay_payment/verification.rb +469 -0
- data/lib/ecpay_payment/version.rb +3 -0
- data/lib/ecpay_payment.rb +7 -0
- metadata +101 -0
@@ -0,0 +1,469 @@
|
|
1
|
+
# require "../../../gem/lib/ecpay_payment/error"
|
2
|
+
require "ecpay_payment/error"
|
3
|
+
require "nokogiri"
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
module ECpayPayment
|
7
|
+
class PaymentVerifyBase
|
8
|
+
include ECpayErrorDefinition
|
9
|
+
@@param_xml = Nokogiri::XML(File.open(File.join(File.dirname(__FILE__), 'ECpayPayment.xml')))
|
10
|
+
|
11
|
+
def get_svc_url(apiname, mode)
|
12
|
+
url = @@param_xml.xpath("/ECPayPayment/#{apiname}/ServiceAddress/url[@type=\"#{mode}\"]").text
|
13
|
+
return url
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_special_encode_param(apiname)
|
17
|
+
ret = []
|
18
|
+
node = @@param_xml.xpath("/ECPayPayment/#{apiname}/Parameters//param[@urlencode=\"1\"]")
|
19
|
+
node.each {|elem| ret.push(elem.attributes['name'].value)}
|
20
|
+
return ret
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_basic_params(apiname)
|
24
|
+
basic_param = []
|
25
|
+
@@param_xml.xpath("/ECPayPayment/#{apiname}/Parameters/param[@require=\"1\"]").each do |elem|
|
26
|
+
basic_param.push(elem.attributes['name'].value)
|
27
|
+
end
|
28
|
+
return basic_param
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_cond_param(apiname)
|
32
|
+
aio_sw_param = []
|
33
|
+
conditional_param = {}
|
34
|
+
@@param_xml.xpath("/ECPayPayment/#{apiname}/Config/switchparam/n").each do |elem|
|
35
|
+
aio_sw_param.push(elem.text)
|
36
|
+
end
|
37
|
+
aio_sw_param.each do |pname|
|
38
|
+
opt_param = {}
|
39
|
+
node = @@param_xml.xpath("/ECPayPayment/#{apiname}/Parameters//param[@name=\"#{pname}\"]")
|
40
|
+
node.xpath('./condparam').each do |elem|
|
41
|
+
opt = elem.attributes['owner'].value
|
42
|
+
params = []
|
43
|
+
elem.xpath('./param[@require="1"]').each do |pa|
|
44
|
+
params.push(pa.attributes['name'].value)
|
45
|
+
end
|
46
|
+
opt_param[opt] = params
|
47
|
+
end
|
48
|
+
conditional_param[pname] = opt_param
|
49
|
+
end
|
50
|
+
return conditional_param
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_param_type(apiname)
|
54
|
+
param_type = {}
|
55
|
+
@@param_xml.xpath("/ECPayPayment/#{apiname}/Parameters//param").each do |elem|
|
56
|
+
param_type[elem.attributes['name'].value] = elem.attributes['type'].value
|
57
|
+
end
|
58
|
+
return param_type
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_opt_param_pattern(apiname)
|
62
|
+
pattern = {}
|
63
|
+
node = @@param_xml.xpath("/ECPayPayment/#{apiname}/Parameters//param[@type=\"Opt\"]")
|
64
|
+
node.each do |param_elem|
|
65
|
+
opt_elems = param_elem.xpath('./option')
|
66
|
+
opt = []
|
67
|
+
opt_elems.each{|oe|opt.push(oe.text)}
|
68
|
+
pattern[param_elem.attributes['name'].value] = opt
|
69
|
+
end
|
70
|
+
return pattern
|
71
|
+
end
|
72
|
+
|
73
|
+
def get_int_param_pattern(apiname)
|
74
|
+
pattern = {}
|
75
|
+
node = @@param_xml.xpath("/ECPayPayment/#{apiname}/Parameters//param[@type=\"Int\"]")
|
76
|
+
node.each do |param_elem|
|
77
|
+
mode = param_elem.xpath('./mode').text
|
78
|
+
mx = param_elem.xpath('./maximum').text
|
79
|
+
mn = param_elem.xpath('./minimal').text
|
80
|
+
a = []
|
81
|
+
[mode, mx, mn].each{|f|a.push(f)}
|
82
|
+
pattern[param_elem.attributes['name'].value] = a
|
83
|
+
end
|
84
|
+
return pattern
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_str_param_pattern(apiname)
|
88
|
+
pattern = {}
|
89
|
+
node = @@param_xml.xpath("/ECPayPayment/#{apiname}/Parameters//param[@type=\"String\"]")
|
90
|
+
node.each do |param_elem|
|
91
|
+
p_name = param_elem.attributes['name'].value
|
92
|
+
pat_elems = param_elem.xpath('./pattern')
|
93
|
+
# if pat_elems.length > 1
|
94
|
+
# raise "Only 1 pattern tag is allowed for each parameter (#{p_name}) "
|
95
|
+
# elsif pat_elems.length = 0
|
96
|
+
# raise "No pattern tag found for parameter (#{p_name}) "
|
97
|
+
# end
|
98
|
+
pat = pat_elems.text
|
99
|
+
pattern[p_name] = pat
|
100
|
+
end
|
101
|
+
return pattern
|
102
|
+
end
|
103
|
+
|
104
|
+
def get_depopt_param_pattern(apiname)
|
105
|
+
pattern = {}
|
106
|
+
|
107
|
+
node = @@param_xml.xpath("/ECPayPayment/#{apiname}/Parameters//param[@type=\"DepOpt\"]")
|
108
|
+
node.each do |param_elem|
|
109
|
+
parent_n_opts = {}
|
110
|
+
sub_opts = {}
|
111
|
+
p_name = param_elem.attributes['name'].value
|
112
|
+
parent_name = param_elem.attributes['main'].value
|
113
|
+
param_elem.xpath('./mainoption').each do |elem|
|
114
|
+
k = elem.attributes['name'].value
|
115
|
+
opt = []
|
116
|
+
elem.element_children.each{|c|opt.push(c.text)}
|
117
|
+
sub_opts[k] = opt
|
118
|
+
end
|
119
|
+
parent_n_opts[parent_name] = sub_opts
|
120
|
+
pattern[p_name] = parent_n_opts
|
121
|
+
end
|
122
|
+
return pattern
|
123
|
+
end
|
124
|
+
|
125
|
+
def get_all_pattern(apiname)
|
126
|
+
res = {}
|
127
|
+
res['Type_idx'] = self.get_param_type(apiname)
|
128
|
+
res['Int'] = self.get_int_param_pattern(apiname)
|
129
|
+
res['String'] = self.get_str_param_pattern(apiname)
|
130
|
+
res['Opt'] = self.get_opt_param_pattern(apiname)
|
131
|
+
res['DepOpt'] = self.get_depopt_param_pattern(apiname)
|
132
|
+
return res
|
133
|
+
end
|
134
|
+
|
135
|
+
def verify_param_by_pattern(params, pattern)
|
136
|
+
type_index = pattern['Type_idx']
|
137
|
+
params.keys.each do |p_name|
|
138
|
+
p_type = type_index[p_name]
|
139
|
+
patt_container = pattern[p_type]
|
140
|
+
case
|
141
|
+
when p_type == 'String'
|
142
|
+
regex_patt = patt_container[p_name]
|
143
|
+
mat = /#{regex_patt}/.match(params[p_name])
|
144
|
+
if mat.nil?
|
145
|
+
raise ECpayInvalidParam, "Wrong format of param #{p_name} or length exceeded."
|
146
|
+
end
|
147
|
+
when p_type == 'Opt'
|
148
|
+
aval_opt = patt_container[p_name]
|
149
|
+
mat = aval_opt.include?(params[p_name])
|
150
|
+
if mat == false
|
151
|
+
raise ECpayInvalidParam, "Unexpected option of param #{p_name} (#{params[p_name]}). Avaliable option: (#{aval_opt})."
|
152
|
+
end
|
153
|
+
when p_type == 'Int'
|
154
|
+
criteria = patt_container[p_name]
|
155
|
+
mode = criteria[0]
|
156
|
+
max = criteria[1].to_i
|
157
|
+
min = criteria[2].to_i
|
158
|
+
val = params[p_name].to_i
|
159
|
+
case
|
160
|
+
when mode == 'BETWEEN'
|
161
|
+
if val < min or val > max
|
162
|
+
raise ECpayInvalidParam, "Value of #{p_name} should be between #{min} and #{max} ."
|
163
|
+
end
|
164
|
+
when mode == 'GE'
|
165
|
+
if val < min
|
166
|
+
raise ECpayInvalidParam, "Value of #{p_name} should be greater than or equal to #{min}."
|
167
|
+
end
|
168
|
+
when mode == 'LE'
|
169
|
+
if val > max
|
170
|
+
raise ECpayInvalidParam, "Value of #{p_name} should be less than or equal to #{max}."
|
171
|
+
end
|
172
|
+
when mode == 'EXCLUDE'
|
173
|
+
if val >= min and val <= max
|
174
|
+
raise ECpayInvalidParam, "Value of #{p_name} can NOT be between #{min} and #{max} .."
|
175
|
+
end
|
176
|
+
else
|
177
|
+
raise "Unexpected integer verification mode for parameter #{p_name}: #{mode}. "
|
178
|
+
end
|
179
|
+
when p_type == 'DepOpt'
|
180
|
+
dep_opt = patt_container[p_name]
|
181
|
+
parent_param = dep_opt.keys()[0]
|
182
|
+
all_dep_opt = dep_opt[parent_param]
|
183
|
+
parent_val = params[parent_param]
|
184
|
+
aval_opt = all_dep_opt[parent_val]
|
185
|
+
if aval_opt.nil? and pattern['Opt'][parent_param].include?(parent_val) == false
|
186
|
+
raise ECpayInvalidParam, "Cannot find avaliable option of [#{p_name}] by related param [#{parent_param}](Value: #{parent_val})."
|
187
|
+
elsif aval_opt.is_a?(Array)
|
188
|
+
unless aval_opt.include?(params[p_name])
|
189
|
+
raise ECpayInvalidParam, "Unexpected option of param #{p_name} (#{params[p_name]}). Avaliable option: (#{aval_opt})."
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
else
|
194
|
+
raise "Unexpected type (#{p_type}) for parameter #{p_name}. "
|
195
|
+
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
class AioCheckOutParamVerify < PaymentVerifyBase
|
202
|
+
include ECpayErrorDefinition
|
203
|
+
def initialize
|
204
|
+
@aio_basic_param = self.get_basic_params('AioCheckOut').freeze
|
205
|
+
@aio_conditional_param = self.get_cond_param('AioCheckOut').freeze
|
206
|
+
@all_param_pattern = self.get_all_pattern('AioCheckOut').freeze
|
207
|
+
end
|
208
|
+
|
209
|
+
def get_serialized_data
|
210
|
+
p @aio_basic_param
|
211
|
+
p '---'
|
212
|
+
p @aio_conditional_param
|
213
|
+
new_di = @aio_conditional_param
|
214
|
+
new_di.delete('InvoiceMark')
|
215
|
+
p @aio_conditional_param
|
216
|
+
p '-----'
|
217
|
+
p new_di
|
218
|
+
#return @aio_conditional_param['InvoiceMark']['Y']
|
219
|
+
#p @@param_xml
|
220
|
+
end
|
221
|
+
|
222
|
+
def verify_aio_payment_param(params)
|
223
|
+
if params.is_a?(Hash)
|
224
|
+
#Force specify : DeviceSource, IgnorePayment, PlatformID EncryptType
|
225
|
+
fix_params = {
|
226
|
+
'DeviceSource' => '',
|
227
|
+
#'PlatformID' => '',
|
228
|
+
'EncryptType' => '1',
|
229
|
+
'PaymentType' => 'aio'
|
230
|
+
}
|
231
|
+
params.merge!(fix_params)
|
232
|
+
#Verify Basic param requirement
|
233
|
+
# if param == {}
|
234
|
+
# raise ECpayInvalidParam, %Q{Parameter hash is empty.}
|
235
|
+
# end
|
236
|
+
param_diff = @aio_basic_param - params.keys
|
237
|
+
unless param_diff == []
|
238
|
+
raise ECpayInvalidParam, "Lack required param #{param_diff}"
|
239
|
+
end
|
240
|
+
|
241
|
+
# Verify Extend param requirement
|
242
|
+
ext_param = @aio_conditional_param.dup
|
243
|
+
ext_param.delete('InvoiceMark')
|
244
|
+
ext_param.keys.each do |pa|
|
245
|
+
val = params[pa]
|
246
|
+
related_require_param = ext_param[pa][val]
|
247
|
+
if related_require_param.nil? == false and related_require_param != []
|
248
|
+
related_require_param.each do |e|
|
249
|
+
unless params.keys.include?(e)
|
250
|
+
raise ECpayInvalidParam, "Lack required parameter [#{e}] when [#{pa}] is set to [#{val}] "
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
#Verify Value pattern of each param
|
257
|
+
self.verify_param_by_pattern(params, @all_param_pattern)
|
258
|
+
|
259
|
+
else
|
260
|
+
raise TypeError, "Recieved argument is not a hash"
|
261
|
+
end
|
262
|
+
|
263
|
+
end
|
264
|
+
|
265
|
+
def verify_aio_inv_param(params)
|
266
|
+
if params.is_a?(Hash)
|
267
|
+
#發票所有參數預設要全帶
|
268
|
+
|
269
|
+
if params.has_value?(nil)
|
270
|
+
raise ECpayInvalidParam, %Q{Parameter value cannot be nil}
|
271
|
+
end
|
272
|
+
#1. 比對欄位是否缺乏
|
273
|
+
inv_param_names = @aio_conditional_param['InvoiceMark']['Y']
|
274
|
+
param_diff = inv_param_names - params.keys()
|
275
|
+
unless param_diff == []
|
276
|
+
raise ECpayInvalidParam, %Q{Lack required invoice param #{param_diff}}
|
277
|
+
end
|
278
|
+
unexp_param = params.keys() - inv_param_names
|
279
|
+
unless unexp_param == []
|
280
|
+
raise ECpayInvalidParam, %Q{Unexpected parameter in Invoice parameters #{unexp_param}}
|
281
|
+
end
|
282
|
+
|
283
|
+
#2. 比對特殊欄位值相依需求
|
284
|
+
|
285
|
+
#a [CarruerType]為 1 => CustomerID 不能為空
|
286
|
+
if params['CarruerType'].to_s == '1'
|
287
|
+
if params['CustomerID'].to_s.empty?
|
288
|
+
raise ECpayInvoiceRuleViolate, "[CustomerID] can not be empty when [CarruerType] is 1."
|
289
|
+
end
|
290
|
+
# [CustomerID]不為空 => CarruerType 不能為空
|
291
|
+
elsif params['CarruerType'].to_s == ''
|
292
|
+
unless params['CustomerID'].to_s.empty?
|
293
|
+
raise ECpayInvoiceRuleViolate, "[CarruerType] can not be empty when [CustomerID] is not empty."
|
294
|
+
end
|
295
|
+
end
|
296
|
+
#b 列印註記[Print]為 1 => CustomerName, CustomerAddr
|
297
|
+
if params['Print'].to_s == '1'
|
298
|
+
if params['CustomerName'].to_s.empty? or params['CustomerAddr'].to_s.empty?
|
299
|
+
raise ECpayInvoiceRuleViolate, "[CustomerName] and [CustomerAddr] can not be empty when [Print] is 1."
|
300
|
+
end
|
301
|
+
unless params['CustomerID'].to_s.empty?
|
302
|
+
raise ECpayInvoiceRuleViolate, "[Print] can not be '1' when [CustomerID] is not empty."
|
303
|
+
end
|
304
|
+
end
|
305
|
+
#c CustomerPhone和CustomerEmail至少一個有值
|
306
|
+
if params['CustomerPhone'].to_s.empty? and params['CustomerEmail'].to_s.empty?
|
307
|
+
raise ECpayInvoiceRuleViolate, "[CustomerPhone] and [CustomerEmail] can not both be empty."
|
308
|
+
end
|
309
|
+
#d 別[TaxType]為 2 => ClearanceMark = 1 or 2
|
310
|
+
if params['TaxType'].to_s == '2'
|
311
|
+
unless ['1', '2'].include?(params['ClearanceMark'].to_s)
|
312
|
+
raise ECpayInvoiceRuleViolate, "[ClearanceMark] has to be 1 or 2 when [TaxType] is 2."
|
313
|
+
end
|
314
|
+
end
|
315
|
+
#e 統一編號[CustomerIdentifier]有值時 => CarruerType != 1 or 2, *Donation = 0, Print = 1
|
316
|
+
# 統一編號為空值時剔除該欄位
|
317
|
+
#if params['CustomerIdentifier'].to_s.empty?
|
318
|
+
#params.delete('CustomerIdentifier')
|
319
|
+
#else
|
320
|
+
unless params['CustomerIdentifier'].to_s.empty?
|
321
|
+
if ['1', '2'].include?(params['CarruerType'].to_s)
|
322
|
+
raise ECpayInvoiceRuleViolate, "[CarruerType] Cannot be 1 or 2 when [CustomerIdentifier] is given."
|
323
|
+
end
|
324
|
+
unless params['Donation'].to_s == '2' and params['Print'].to_s == '1'
|
325
|
+
raise ECpayInvoiceRuleViolate, "[Print] must be 1 and [Donation] must be 2 when [CustomerIdentifier] is given."
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
# [CarruerType]為'' or 1 時 => CarruerNum = '', [CarruerType]為 2, CarruerNum = 固定長度為 16 且格式為 2 碼大小寫字母加上 14 碼數字。 [CarruerType]為 3 ,帶固定長度為 8 且格式為 1 碼斜線「/」加上由 7 碼數字及大小寫字母組成
|
330
|
+
if ['', '1'].include?(params['CarruerType'].to_s)
|
331
|
+
unless params['CarruerNum'].to_s == ''
|
332
|
+
raise ECpayInvoiceRuleViolate, "[CarruerNum] must be empty when [CarruerType] is empty or 1."
|
333
|
+
end
|
334
|
+
elsif params['CarruerType'].to_s == '2'
|
335
|
+
if /[A-Za-z]{2}[0-9]{14}/.match(params['CarruerNum']).nil?
|
336
|
+
raise ECpayInvoiceRuleViolate, "[CarruerNum] must be 2 alphabets and 14 numbers when [CarruerType] is 2."
|
337
|
+
end
|
338
|
+
elsif params['CarruerType'].to_s == '3'
|
339
|
+
if /^\/[A-Za-z0-9\s+-]{7}$/.match(params['CarruerNum']).nil?
|
340
|
+
raise ECpayInvoiceRuleViolate, "[CarruerNum] must start with '/' followed by 7 alphabet and number characters when [CarruerType] is 3."
|
341
|
+
end
|
342
|
+
else
|
343
|
+
raise ECpayInvoiceRuleViolate, "Unexpected value in [CarruerType]."
|
344
|
+
end
|
345
|
+
|
346
|
+
#[CarruerType]有值時,Print必須為0
|
347
|
+
if params['CarruerType'].to_s != '' and params['Print'].to_s != '0'
|
348
|
+
raise ECpayInvoiceRuleViolate, "[Print] must be 0 when [CarruerType] has value."
|
349
|
+
end
|
350
|
+
|
351
|
+
# Donation = 1 => LoveCode不能為空, Print = 0
|
352
|
+
if params['Donation'].to_s == '1'
|
353
|
+
if params['LoveCode'].to_s.empty?
|
354
|
+
raise ECpayInvoiceRuleViolate, "[LoveCode] cannot be empty when [Donation] is 1."
|
355
|
+
end
|
356
|
+
unless params['Print'].to_s == '0'
|
357
|
+
raise ECpayInvoiceRuleViolate, "[Print] must be 0 when [Donation] is 1."
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
#3. 比對商品名稱,數量,單位,價格,tax項目數量是否一致
|
362
|
+
item_params = ['InvoiceItemCount', 'InvoiceItemWord', 'InvoiceItemPrice', 'InvoiceItemTaxType']
|
363
|
+
#商品名稱含有管線 => 認為是多樣商品 *InvoiceItemName, *InvoiceItemCount ,*InvoiceItemWord, *InvoiceItemPrice InvoiceItemTaxType逐一用管線分割,計算數量後與第一個比對
|
364
|
+
if params['InvoiceItemName'].empty?
|
365
|
+
raise ECpayInvoiceRuleViolate, "[InvoiceItemName] is empty."
|
366
|
+
else
|
367
|
+
if params['InvoiceItemName'].include?('|')
|
368
|
+
item_cnt = params['InvoiceItemCount'].split('|').length
|
369
|
+
item_params.each do |param_name|
|
370
|
+
# Check if there's empty value.
|
371
|
+
unless /(\|\||^\||\|$)/.match(params[param_name]).nil?
|
372
|
+
raise ECpayInvoiceRuleViolate, "[#{param_name}] contains empty value."
|
373
|
+
end
|
374
|
+
p_cnt = params[param_name].split('|').length
|
375
|
+
unless item_cnt == p_cnt
|
376
|
+
raise ECpayInvoiceRuleViolate, %Q{Count of item info [#{param_name}] (#{p_cnt}) not match item count from [InvoiceItemCount] (#{item_cnt})}
|
377
|
+
end
|
378
|
+
end
|
379
|
+
# 課稅類別[TaxType] = 9 時 => InvoiceItemTaxType 能含有1,2 3(and at least contains one 1 and other)
|
380
|
+
item_tax = params['InvoiceItemTaxType'].split('|')
|
381
|
+
aval_tax_type = ['1', '2', '3']
|
382
|
+
vio_tax_t = (item_tax - aval_tax_type)
|
383
|
+
unless vio_tax_t == []
|
384
|
+
raise ECpayInvoiceRuleViolate, "Ilegal [InvoiceItemTaxType]: #{vio_tax_t}"
|
385
|
+
end
|
386
|
+
if params['TaxType'].to_s == '9'
|
387
|
+
unless item_tax.include?('1')
|
388
|
+
raise ECpayInvoiceRuleViolate, "[InvoiceItemTaxType] must contain at lease one '1'."
|
389
|
+
end
|
390
|
+
if item_tax.include?('2') and item_tax.include?('3')
|
391
|
+
raise ECpayInvoiceRuleViolate, "[InvoiceItemTaxType] cannot contain 2 and 3 at the same time."
|
392
|
+
end
|
393
|
+
end
|
394
|
+
else
|
395
|
+
#沒有管線 => 逐一檢查後4項有無管線
|
396
|
+
item_params.each do |param_name|
|
397
|
+
if params[param_name].include?('|')
|
398
|
+
raise "Item info [#{param_name}] contains pipeline delimiter but there's only one item in param [InvoiceItemName]"
|
399
|
+
end
|
400
|
+
end
|
401
|
+
end
|
402
|
+
end
|
403
|
+
#4 比對所有欄位Pattern
|
404
|
+
self.verify_param_by_pattern(params, @all_param_pattern)
|
405
|
+
|
406
|
+
else
|
407
|
+
raise TypeError, "Recieved argument is not a hash"
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
#可能要寫一個hash list 轉 這五個參數的method
|
412
|
+
# def hash_to_inv_item_params
|
413
|
+
# end
|
414
|
+
|
415
|
+
|
416
|
+
end
|
417
|
+
|
418
|
+
class QueryParamVerify < PaymentVerifyBase
|
419
|
+
include ECpayErrorDefinition
|
420
|
+
def initialize(apiname)
|
421
|
+
@aio_basic_param = self.get_basic_params(apiname).freeze
|
422
|
+
@aio_conditional_param = self.get_cond_param(apiname).freeze
|
423
|
+
@all_param_pattern = self.get_all_pattern(apiname).freeze
|
424
|
+
end
|
425
|
+
|
426
|
+
def verify_query_param(params)
|
427
|
+
if params.is_a?(Hash)
|
428
|
+
param_diff = @aio_basic_param - params.keys
|
429
|
+
unless param_diff == []
|
430
|
+
raise ECpayInvalidParam, "Lack required param #{param_diff}"
|
431
|
+
end
|
432
|
+
|
433
|
+
#Verify Value pattern of each param
|
434
|
+
self.verify_param_by_pattern(params, @all_param_pattern)
|
435
|
+
|
436
|
+
else
|
437
|
+
raise TypeError, "Recieved argument is not a hash"
|
438
|
+
end
|
439
|
+
|
440
|
+
end
|
441
|
+
|
442
|
+
end
|
443
|
+
|
444
|
+
class ActParamVerify < PaymentVerifyBase
|
445
|
+
include ECpayErrorDefinition
|
446
|
+
def initialize(apiname)
|
447
|
+
@aio_basic_param = self.get_basic_params(apiname).freeze
|
448
|
+
@aio_conditional_param = self.get_cond_param(apiname).freeze
|
449
|
+
@all_param_pattern = self.get_all_pattern(apiname).freeze
|
450
|
+
end
|
451
|
+
|
452
|
+
def verify_act_param(params)
|
453
|
+
if params.is_a?(Hash)
|
454
|
+
param_diff = @aio_basic_param - params.keys
|
455
|
+
unless param_diff == []
|
456
|
+
raise ECpayInvalidParam, "Lack required param #{param_diff}"
|
457
|
+
end
|
458
|
+
|
459
|
+
#Verify Value pattern of each param
|
460
|
+
self.verify_param_by_pattern(params, @all_param_pattern)
|
461
|
+
|
462
|
+
else
|
463
|
+
raise TypeError, "Recieved argument is not a hash"
|
464
|
+
end
|
465
|
+
|
466
|
+
end
|
467
|
+
|
468
|
+
end
|
469
|
+
end
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ecpay_payment
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ying Wu
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-05-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.12'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.12'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '11.1'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '11.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.4'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.4'
|
55
|
+
description: ''
|
56
|
+
email:
|
57
|
+
- ying.wu@ecpay.com.tw
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- Gemfile
|
63
|
+
- Rakefile
|
64
|
+
- conf/payment_conf.xml
|
65
|
+
- ecpay.gemspec
|
66
|
+
- lib/ecpay_payment.rb
|
67
|
+
- lib/ecpay_payment/ECpayPayment.xml
|
68
|
+
- lib/ecpay_payment/core_ext/hash.rb
|
69
|
+
- lib/ecpay_payment/core_ext/string.rb
|
70
|
+
- lib/ecpay_payment/error.rb
|
71
|
+
- lib/ecpay_payment/exec_grant_refund.rb
|
72
|
+
- lib/ecpay_payment/helper.rb
|
73
|
+
- lib/ecpay_payment/payment_client.rb
|
74
|
+
- lib/ecpay_payment/query_client.rb
|
75
|
+
- lib/ecpay_payment/verification.rb
|
76
|
+
- lib/ecpay_payment/version.rb
|
77
|
+
homepage: ''
|
78
|
+
licenses:
|
79
|
+
- MIT
|
80
|
+
metadata: {}
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
requirements: []
|
96
|
+
rubyforge_project:
|
97
|
+
rubygems_version: 2.6.14
|
98
|
+
signing_key:
|
99
|
+
specification_version: 4
|
100
|
+
summary: 綠界全方位金流串接用SDK
|
101
|
+
test_files: []
|