ecpay_invoice 0.1.0

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.
@@ -0,0 +1,13 @@
1
+ class Hash
2
+ def stringify_keys
3
+ result = self.class.new
4
+ orig_key_len = keys.length()
5
+ each_key do |key|
6
+ result[key.to_s] = self[key]
7
+ end
8
+ unless result.keys.length() == orig_key_len
9
+ raise "Duplicate key name during convertion, there might be symbol & string key with the same name."
10
+ end
11
+ return result
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ class String
2
+ def hashify
3
+ Hash[self.force_encoding("UTF-8").split("&").map! { |i| i.split("=") }]
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ module ECpayErrorDefinition
2
+ # Generic ECpay exception class.
3
+ class ECpayError < StandardError; end
4
+ class ECpayMissingOption < ECpayError; end
5
+ class ECpayInvalidMode < ECpayError; end
6
+ class ECpayInvalidParam < ECpayError; end
7
+ class ECpayInvoiceRuleViolate < ECpayError; end
8
+ end
@@ -0,0 +1,164 @@
1
+ require 'digest'
2
+ require 'uri'
3
+ require 'cgi'
4
+ require 'net/http'
5
+ require 'nokogiri'
6
+ require 'date'
7
+
8
+ class APIHelper
9
+ conf = File.join(File.dirname(__FILE__), '..', '..', 'conf', 'invoice_conf.xml')
10
+ @@conf_xml = Nokogiri::XML(File.open(conf))
11
+
12
+ def initialize
13
+ active_merc_info = @@conf_xml.xpath('/Conf/MercProfile').text
14
+ @op_mode = @@conf_xml.xpath('/Conf/OperatingMode').text
15
+ @contractor_stat = @@conf_xml.xpath('/Conf/IsProjectContractor').text
16
+ merc_info = @@conf_xml.xpath("/Conf/MerchantInfo/MInfo[@name=\"#{active_merc_info}\"]")
17
+ @ignore_payment = []
18
+ @@conf_xml.xpath('/Conf/IgnorePayment//Method').each {|t| @ignore_payment.push(t.text)}
19
+ if merc_info != []
20
+ @merc_id = merc_info[0].xpath('./MerchantID').text.freeze
21
+ @hkey = merc_info[0].xpath('./HashKey').text.freeze
22
+ @hiv = merc_info[0].xpath('./HashIV').text.freeze
23
+
24
+ else
25
+ raise "Specified merchant setting name (#{active_merc_info}) not found."
26
+ end
27
+ end
28
+
29
+ def get_mercid()
30
+ return @merc_id
31
+ end
32
+
33
+ def get_op_mode()
34
+ return @op_mode
35
+ end
36
+
37
+ def get_ignore_pay()
38
+ return @ignore_payment
39
+ end
40
+
41
+ def get_curr_unixtime()
42
+ return Time.now.to_i
43
+ end
44
+
45
+ def is_contractor?()
46
+ if @contractor_stat == 'N'
47
+ return false
48
+ elsif @contractor_stat == 'Y'
49
+ return true
50
+ else
51
+ raise "Unknown [IsProjectContractor] configuration."
52
+ end
53
+ end
54
+
55
+ def urlencode_dot_net(raw_data, case_tr:'DOWN')
56
+ if raw_data.is_a?(String)
57
+ encoded_data = CGI.escape(raw_data)
58
+ case case_tr
59
+ when 'KEEP'
60
+ # Do nothing
61
+ when 'UP'
62
+ encoded_data.upcase!
63
+ when 'DOWN'
64
+ encoded_data.downcase!
65
+ end
66
+ # Process encoding difference between .NET & CGI
67
+ encoded_data.gsub!('%21', '!')
68
+ encoded_data.gsub!('%2a', '*')
69
+ encoded_data.gsub!('%28', '(')
70
+ encoded_data.gsub!('%29', ')')
71
+ return encoded_data
72
+ else
73
+ raise "Data recieved is not a string."
74
+ end
75
+ end
76
+
77
+ def encode_special_param!(params, target_arr)
78
+ if params.is_a?(Hash)
79
+ target_arr.each do |n|
80
+ if params.keys.include?(n)
81
+ val = self.urlencode_dot_net(params[n])
82
+ params[n] = val
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+
89
+
90
+ def gen_chk_mac_value(params, mode: 1)
91
+ if params.is_a?(Hash)
92
+ # raise exception if param contains CheckMacValue, HashKey, HashIV
93
+ sec = ['CheckMacValue', 'HashKey', 'HashIV']
94
+ sec.each do |pa|
95
+ if params.keys.include?(pa)
96
+ raise "Parameters shouldn't contain #{pa}"
97
+ end
98
+ end
99
+
100
+ raw = params.sort_by{|key,val|key.downcase}.map!{|key,val| "#{key}=#{val}"}.join('&')
101
+ raw = self.urlencode_dot_net(["HashKey=#{@hkey}", raw, "HashIV=#{@hiv}"].join("&"), case_tr: 'DOWN')
102
+ p raw
103
+
104
+
105
+ case mode
106
+ when 0
107
+ chksum = Digest::MD5.hexdigest(raw)
108
+ when 1
109
+ chksum = Digest::SHA256.hexdigest(raw)
110
+ else
111
+ raise "Unexpected hash mode."
112
+ end
113
+ return chksum.upcase!
114
+ else
115
+ raise "Data recieved is not a Hash."
116
+ end
117
+ end
118
+
119
+
120
+ def http_request(method:, url:, payload:)
121
+
122
+ target_url = URI.parse(url)
123
+
124
+ case method
125
+ when 'GET'
126
+ target_url.query = URI.encode_www_form(payload)
127
+ res = Net::HTTP.get_response(target_url)
128
+ when 'POST'
129
+ res = Net::HTTP.post_form(target_url, payload)
130
+ else
131
+ raise ArgumentError, "Only GET & POST method are avaliable."
132
+ end
133
+ return res.body
134
+ # if res == Net::HTTPOK
135
+ # return res
136
+ # else
137
+ # raise "#{res.message}, #{res}"
138
+ # end
139
+
140
+ # when Net::HTTPClientError, Net::HTTPInternalServerError
141
+ # raise Net::HTTPError.new(http_response.message, http_response)
142
+ # else
143
+ # raise Net::HTTPError.new("Unexpected HTTP response.", http_response)
144
+ # end
145
+ end
146
+
147
+
148
+ def gen_html_post_form(act:, id:, parameters:, input_typ:'hidden', submit: true)
149
+ f = Nokogiri::HTML::Builder.new do |doc|
150
+ doc.form(method: 'post', action: act, id: id) {
151
+ parameters.map{|key,val|
152
+ doc.input(type: input_typ, name: key, id: key, value: val)
153
+ }
154
+ if submit == true
155
+ doc.script(type: 'text/javascript').text("document.getElementById(\"#{id}\").submit();")
156
+ end
157
+ }
158
+ end
159
+ return f.to_html
160
+ end
161
+
162
+
163
+
164
+ end
@@ -0,0 +1,166 @@
1
+ require "digest"
2
+ require "uri"
3
+ require "net/http"
4
+ require "net/https"
5
+ require "json"
6
+ require "cgi"
7
+ require "securerandom"
8
+ require "ecpay_invoice/helper"
9
+ require "ecpay_invoice/verification"
10
+ require "ecpay_invoice/error"
11
+ require "ecpay_invoice/core_ext/hash"
12
+ require "ecpay_invoice/core_ext/string"
13
+ # require "../../../gem/lib/ecpay_invoice/helper"
14
+ # require "../../../gem/lib/ecpay_invoice/verification"
15
+ # require "../../../gem/lib/ecpay_invoice/error"
16
+ # require "../../../gem/lib/ecpay_invoice/core_ext/hash"
17
+ # require "../../../gem/lib/ecpay_invoice/core_ext/string"
18
+
19
+ module ECpayInvoice
20
+
21
+ class InvoiceClientECPay
22
+ include ECpayErrorDefinition
23
+
24
+ def initialize
25
+ @helper = APIHelper.new
26
+ end
27
+
28
+ def ecpay_invoice_issue(param)
29
+ invoice_base_proc!(params: param)
30
+ unix_time = get_curr_unix_time() - 120
31
+ param['TimeStamp'] = unix_time.to_s
32
+ param['CarruerNum'] = param['CarruerNum'].to_s.gsub('+', ' ')
33
+ p param['TimeStamp']
34
+ res = invoice_pos_proc!(params: param, apiname: 'InvoiceIssue')
35
+ return res
36
+ end
37
+
38
+ def ecpay_invoice_delay(param)
39
+ invoice_base_proc!(params: param)
40
+ unix_time = get_curr_unix_time() - 120
41
+ param['TimeStamp'] = unix_time.to_s
42
+ param['CarruerNum'] = param['CarruerNum'].to_s.gsub('+', ' ')
43
+ param['PayType'] = '2'
44
+ param['PayAct'] = 'ECPAY'
45
+ p param['TimeStamp']
46
+ res = invoice_pos_proc!(params: param, apiname: 'InvoiceDelayIssue')
47
+ return res
48
+ end
49
+
50
+ def ecpay_invoice_trigger(param)
51
+ invoice_base_proc!(params: param)
52
+ unix_time = get_curr_unix_time() - 120
53
+ param['TimeStamp'] = unix_time.to_s
54
+ param['PayType'] = '2'
55
+ p param['TimeStamp']
56
+ res = invoice_pos_proc!(params: param, apiname: 'InvoiceTriggerIssue')
57
+ return res
58
+ end
59
+
60
+ def ecpay_invoice_allowance(param)
61
+ invoice_base_proc!(params: param)
62
+ unix_time = get_curr_unix_time() - 120
63
+ param['TimeStamp'] = unix_time.to_s
64
+ p param['TimeStamp']
65
+ res = invoice_pos_proc!(params: param, apiname: 'InvoiceAllowance')
66
+ return res
67
+ end
68
+
69
+ def ecpay_invoice_issue_invalid(param)
70
+ invoice_base_proc!(params: param)
71
+ unix_time = get_curr_unix_time() - 120
72
+ param['TimeStamp'] = unix_time.to_s
73
+ p param['TimeStamp']
74
+ res = invoice_pos_proc!(params: param, apiname: 'InvoiceIssueInvalid')
75
+ return res
76
+ end
77
+
78
+ def ecpay_invoice_allowance_invalid(param)
79
+ invoice_base_proc!(params: param)
80
+ unix_time = get_curr_unix_time() - 120
81
+ param['TimeStamp'] = unix_time.to_s
82
+ p param['TimeStamp']
83
+ res = invoice_pos_proc!(params: param, apiname: 'InvoiceAllowanceInvalid')
84
+ return res
85
+ end
86
+
87
+ ### Private method definition start ###
88
+ private
89
+
90
+ def get_curr_unix_time()
91
+ return Time.now.to_i
92
+ end
93
+
94
+ def invoice_base_proc!(params:)
95
+ if params.is_a?(Hash)
96
+ # Transform param key to string
97
+ params.stringify_keys()
98
+
99
+ params['MerchantID'] = @helper.get_mercid
100
+
101
+ #gem_uid = SecureRandom::hex
102
+ #p gem_uid.to_s[0, 30]
103
+ #params['RelateNumber'] = gem_uid.to_s[0, 30]
104
+
105
+ else
106
+ raise ECpayInvalidParam, "Recieved parameter object must be a Hash"
107
+ end
108
+ end
109
+
110
+ def invoice_pos_proc!(params:, apiname:)
111
+ verify_query_api = ECpayInvoice::InvoiceParamVerify.new(apiname)
112
+ if apiname == 'InvoiceIssue'
113
+ exclusive_list = ['InvoiceRemark', 'ItemName', 'ItemRemark', 'ItemWord']
114
+ verify_query_api.verify_inv_issue_param(params)
115
+ elsif apiname == 'InvoiceDelayIssue'
116
+ exclusive_list = ['InvoiceRemark', 'ItemName', 'ItemRemark', 'ItemWord']
117
+ verify_query_api.verify_inv_delay_param(params)
118
+ elsif apiname == 'InvoiceTriggerIssue'
119
+ exclusive_list = []
120
+ verify_query_api.verify_inv_trigger_param(params)
121
+ elsif apiname == 'InvoiceAllowance'
122
+ exclusive_list = ['ItemName', 'ItemWord']
123
+ verify_query_api.verify_inv_allowance_param(params)
124
+ elsif apiname == 'InvoiceIssueInvalid'
125
+ exclusive_list = ['Reason']
126
+ verify_query_api.verify_inv_issue_invalid_param(params)
127
+ elsif apiname == 'InvoiceAllowanceInvalid'
128
+ exclusive_list = ['Reason']
129
+ verify_query_api.verify_inv_allowance_invalid_param(params)
130
+ end
131
+
132
+ #encode special param
133
+ sp_param = verify_query_api.get_special_encode_param(apiname)
134
+ @helper.encode_special_param!(params, sp_param)
135
+
136
+ exclusive_ele = {}
137
+ for param in exclusive_list
138
+ exclusive_ele[param] = params[param]
139
+ params.delete(param)
140
+ end
141
+
142
+ # Insert chkmacval
143
+ chkmac = @helper.gen_chk_mac_value(params, mode: 0)
144
+ params['CheckMacValue'] = chkmac
145
+
146
+ for param in exclusive_list
147
+ params[param] = exclusive_ele[param]
148
+ end
149
+
150
+ sp_param.each do |key|
151
+ params[key] = CGI::unescape(params[key])
152
+ end
153
+
154
+ # gen post html
155
+ api_url = verify_query_api.get_svc_url(apiname, @helper.get_op_mode)
156
+ #post from server
157
+ resp = @helper.http_request(method: 'POST', url: api_url, payload: params)
158
+
159
+ # return post response
160
+ return resp
161
+ end
162
+
163
+ ### Private method definition end ###
164
+
165
+ end
166
+ end
@@ -0,0 +1,79 @@
1
+ require "digest"
2
+ require "uri"
3
+ require "net/http"
4
+ require "net/https"
5
+ require "json"
6
+ require "date"
7
+ require "cgi"
8
+ require "ecpay_invoice/helper"
9
+ require "ecpay_invoice/verification"
10
+ require "ecpay_invoice/error"
11
+ require "ecpay_invoice/core_ext/hash"
12
+ require "ecpay_invoice/core_ext/string"
13
+ # require "../../../gem/lib/ecpay_invoice/helper"
14
+ # require "../../../gem/lib/ecpay_invoice/verification"
15
+ # require "../../../gem/lib/ecpay_invoice/error"
16
+ # require "../../../gem/lib/ecpay_invoice/core_ext/hash"
17
+ # require "../../../gem/lib/ecpay_invoice/core_ext/string"
18
+
19
+ module ECpayInvoice
20
+
21
+ class NotifyClientECPay
22
+
23
+ def initialize
24
+ @helper = APIHelper.new
25
+ end
26
+
27
+ def ecpay_invoice_notify(param)
28
+ notify_base_proc!(params: param)
29
+ unix_time = get_curr_unix_time() - 120
30
+ param['TimeStamp'] = unix_time.to_s
31
+ p param['TimeStamp']
32
+ res = notify_pos_proc!(params: param, apiname: 'InvoiceNotify')
33
+ return res
34
+ end
35
+
36
+ ### Private method definition start ###
37
+ private
38
+
39
+ def get_curr_unix_time()
40
+ return Time.now.to_i
41
+ end
42
+
43
+ def notify_base_proc!(params:)
44
+ if params.is_a?(Hash)
45
+ # Transform param key to string
46
+ params.stringify_keys()
47
+
48
+ params['MerchantID'] = @helper.get_mercid
49
+
50
+ else
51
+ raise ECpayInvalidParam, "Recieved parameter object must be a Hash"
52
+ end
53
+ end
54
+
55
+ def notify_pos_proc!(params:, apiname:)
56
+ verify_query_api = ECpayInvoice::NotifyParamVerify.new(apiname)
57
+ verify_query_api.verify_notify_param(params)
58
+ #encode special param
59
+ sp_param = verify_query_api.get_special_encode_param(apiname)
60
+ @helper.encode_special_param!(params, sp_param)
61
+
62
+ # Insert chkmacval
63
+ chkmac = @helper.gen_chk_mac_value(params, mode: 0)
64
+ params['CheckMacValue'] = chkmac
65
+ params['NotifyMail'] = CGI::unescape(params['NotifyMail'])
66
+ p params
67
+ # gen post html
68
+ api_url = verify_query_api.get_svc_url(apiname, @helper.get_op_mode)
69
+ #post from server
70
+ resp = @helper.http_request(method: 'POST', url: api_url, payload: params)
71
+
72
+ # return post response
73
+ return resp
74
+ end
75
+
76
+ ### Private method definition end ###
77
+
78
+ end
79
+ end
@@ -0,0 +1,120 @@
1
+ require "digest"
2
+ require "uri"
3
+ require "net/http"
4
+ require "net/https"
5
+ require "json"
6
+ require "date"
7
+ require "ecpay_invoice/helper"
8
+ require "ecpay_invoice/verification"
9
+ require "ecpay_invoice/error"
10
+ require "ecpay_invoice/core_ext/hash"
11
+ require "ecpay_invoice/core_ext/string"
12
+ # require "../../../gem/lib/ecpay_invoice/helper"
13
+ # require "../../../gem/lib/ecpay_invoice/verification"
14
+ # require "../../../gem/lib/ecpay_invoice/error"
15
+ # require "../../../gem/lib/ecpay_invoice/core_ext/hash"
16
+ # require "../../../gem/lib/ecpay_invoice/core_ext/string"
17
+
18
+ module ECpayInvoice
19
+
20
+ class QueryClientECPay
21
+
22
+ def initialize
23
+ @helper = APIHelper.new
24
+ end
25
+
26
+ def ecpay_query_invoice_issue(param)
27
+ query_base_proc!(params: param)
28
+ unix_time = get_curr_unix_time() + 120
29
+ param['TimeStamp'] = unix_time.to_s
30
+ p param['TimeStamp']
31
+ res = query_pos_proc!(params: param, apiname: 'QueryIssue')
32
+ return res
33
+ end
34
+
35
+ def ecpay_query_invoice_allowance(param)
36
+ query_base_proc!(params: param)
37
+ unix_time = get_curr_unix_time() + 120
38
+ param['TimeStamp'] = unix_time.to_s
39
+ p param['TimeStamp']
40
+ res = query_pos_proc!(params: param, apiname: 'QueryAllowance')
41
+ return res
42
+ end
43
+
44
+ def ecpay_query_invoice_issue_invalid(param)
45
+ query_base_proc!(params: param)
46
+ unix_time = get_curr_unix_time() + 120
47
+ param['TimeStamp'] = unix_time.to_s
48
+ p param['TimeStamp']
49
+ res = query_pos_proc!(params: param, apiname: 'QueryIssueInvalid')
50
+ return res
51
+ end
52
+
53
+ def ecpay_query_invoice_allowance_invalid(param)
54
+ query_base_proc!(params: param)
55
+ unix_time = get_curr_unix_time() + 120
56
+ param['TimeStamp'] = unix_time.to_s
57
+ p param['TimeStamp']
58
+ res = query_pos_proc!(params: param, apiname: 'QueryAllowanceInvalid')
59
+ return res
60
+ end
61
+
62
+ def ecpay_query_check_mob_barcode(param)
63
+ query_base_proc!(params: param)
64
+ unix_time = get_curr_unix_time() + 120
65
+ param['TimeStamp'] = unix_time.to_s
66
+ param['BarCode'] = param['BarCode'].to_s.gsub('+', ' ')
67
+ p param['BarCode']
68
+ p param['TimeStamp']
69
+ res = query_pos_proc!(params: param, apiname: 'CheckMobileBarCode')
70
+ return res
71
+ end
72
+
73
+ def query_check_love_code(param)
74
+ query_base_proc!(params: param)
75
+ unix_time = get_curr_unix_time() + 120
76
+ param['TimeStamp'] = unix_time.to_s
77
+ p param['TimeStamp']
78
+ res = query_pos_proc!(params: param, apiname: 'CheckLoveCode')
79
+ return res
80
+ end
81
+
82
+ ### Private method definition start ###
83
+ private
84
+
85
+ def get_curr_unix_time()
86
+ return Time.now.to_i
87
+ end
88
+
89
+ def query_base_proc!(params:)
90
+ if params.is_a?(Hash)
91
+ # Transform param key to string
92
+ params.stringify_keys()
93
+
94
+ params['MerchantID'] = @helper.get_mercid
95
+ else
96
+ raise ECpayInvalidParam, "Recieved parameter object must be a Hash"
97
+ end
98
+ end
99
+
100
+ def query_pos_proc!(params:, apiname:)
101
+ verify_query_api = ECpayInvoice::QueryParamVerify.new(apiname)
102
+ verify_query_api.verify_query_param(params)
103
+ #encode special param
104
+
105
+ # Insert chkmacval
106
+ chkmac = @helper.gen_chk_mac_value(params, mode: 0)
107
+ params['CheckMacValue'] = chkmac
108
+ p params
109
+ # gen post html
110
+ api_url = verify_query_api.get_svc_url(apiname, @helper.get_op_mode)
111
+ #post from server
112
+ resp = @helper.http_request(method: 'POST', url: api_url, payload: params)
113
+
114
+ # return post response
115
+ return resp
116
+ end
117
+ ### Private method definition end ###
118
+
119
+ end
120
+ end