ecpay_invoice 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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