veritrans 1.2.6 → 2.0.0beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +13 -5
  2. data/.gitignore +4 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +5 -0
  5. data/Gemfile.lock +111 -0
  6. data/README.md +258 -0
  7. data/Rakefile +7 -0
  8. data/api_reference.md +219 -0
  9. data/bin/veritrans +59 -48
  10. data/example/index.erb +118 -0
  11. data/example/response.erb +28 -0
  12. data/example/sinatra.rb +76 -0
  13. data/example/style.css +45 -0
  14. data/example/veritrans.yml +12 -0
  15. data/lib/generators/templates/assets/credit_card_form.js +50 -0
  16. data/lib/generators/templates/payments_controller.rb +81 -0
  17. data/lib/generators/templates/veritrans.rb +43 -0
  18. data/lib/generators/templates/veritrans.yml +13 -0
  19. data/lib/generators/templates/views/_credit_card_form.erb +42 -0
  20. data/lib/generators/templates/views/_veritrans_include.erb +10 -0
  21. data/lib/generators/templates/views/payments/create.erb +15 -0
  22. data/lib/generators/templates/views/payments/new.erb +6 -0
  23. data/lib/generators/veritrans/install_generator.rb +32 -0
  24. data/lib/generators/veritrans/payment_form_generator.rb +45 -0
  25. data/lib/veritrans/api.rb +90 -0
  26. data/lib/veritrans/cli.rb +166 -0
  27. data/lib/veritrans/client.rb +77 -209
  28. data/lib/veritrans/config.rb +48 -62
  29. data/lib/veritrans/events.rb +125 -0
  30. data/lib/veritrans/result.rb +81 -0
  31. data/lib/veritrans/version.rb +1 -41
  32. data/lib/veritrans.rb +79 -15
  33. data/license.txt +202 -0
  34. data/spec/cli_spec.rb +86 -0
  35. data/spec/configs/veritrans.yml +7 -0
  36. data/spec/configs/veritrans_flat.yml +2 -0
  37. data/spec/fixtures/approve_failed.yml +48 -0
  38. data/spec/fixtures/cancel_failed.yml +48 -0
  39. data/spec/fixtures/cancel_success.yml +106 -0
  40. data/spec/fixtures/capture_failed.yml +48 -0
  41. data/spec/fixtures/charge.yml +50 -0
  42. data/spec/fixtures/charge_direct.yml +56 -0
  43. data/spec/fixtures/charge_vtweb.yml +50 -0
  44. data/spec/fixtures/cli_test_1111-not-exists.yml +45 -0
  45. data/spec/fixtures/cli_test_not_exists.yml +45 -0
  46. data/spec/fixtures/cli_test_real_txn.yml +55 -0
  47. data/spec/fixtures/cli_test_unauthorized.yml +47 -0
  48. data/spec/fixtures/events_test_real_txn.yml +55 -0
  49. data/spec/fixtures/status_fail.yml +46 -0
  50. data/spec/fixtures/status_success.yml +109 -0
  51. data/spec/spec_helper.rb +29 -0
  52. data/spec/veritrans_client_spec.rb +83 -0
  53. data/spec/veritrans_config_spec.rb +48 -0
  54. data/spec/veritrans_events_spec.rb +70 -0
  55. data/spec/veritrans_logger_spec.rb +46 -0
  56. data/testing_webhooks.md +80 -0
  57. data/veritrans.gemspec +23 -0
  58. metadata +82 -31
  59. data/config/veritrans.yml +0 -24
  60. data/lib/generators/install_generator.rb +0 -78
  61. data/lib/generators/templates/app/controllers/vtlink/merchant_controller.rb +0 -7
  62. data/lib/generators/templates/app/controllers/vtlink/veritrans_controller.rb +0 -112
  63. data/lib/generators/templates/app/views/layouts/layout_auto_post.html.erb +0 -15
  64. data/lib/generators/templates/app/views/vtlink/merchant/checkout.html.erb +0 -43
  65. data/lib/generators/templates/app/views/vtlink/veritrans/cancel.html.erb +0 -2
  66. data/lib/generators/templates/app/views/vtlink/veritrans/confirm.html.erb +0 -13
  67. data/lib/generators/templates/app/views/vtlink/veritrans/error.html.erb +0 -2
  68. data/lib/generators/templates/app/views/vtlink/veritrans/finish.html.erb +0 -2
  69. data/lib/generators/templates/app/views/vtlink/veritrans/pay.html.erb +0 -2
  70. data/lib/generators/templates/config/veritrans.yml +0 -13
  71. data/lib/veritrans/hash_generator.rb +0 -19
  72. data/lib/veritrans/post_data.rb +0 -163
  73. data/lib/veritrans/v_t_direct.rb +0 -145
@@ -0,0 +1,32 @@
1
+ module Veritrans
2
+ class InstallGenerator < ::Rails::Generators::Base
3
+ source_root File.expand_path("../../templates", __FILE__)
4
+
5
+ desc %{
6
+ Description:
7
+ Copies Veritrans configuration file to your application's initializer directory.
8
+ }
9
+
10
+ desc "copy veritrans.yml"
11
+ def copy_config_file
12
+ copy_file "veritrans.yml", "config/veritrans.yml"
13
+ end
14
+
15
+ desc "copy initializer veritrans.rb"
16
+ def copy_initializer_file
17
+ copy_file "./veritrans.rb", "config/initializers/veritrans.rb"
18
+
19
+ say_status "", %{
20
+
21
+ We copy configs in your rails application
22
+ Please edit:
23
+
24
+ config/veritrans.yml
25
+
26
+ }
27
+
28
+
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,45 @@
1
+ module Veritrans
2
+ class PaymentFormGenerator < ::Rails::Generators::Base
3
+ source_root File.expand_path("../../templates", __FILE__)
4
+
5
+ desc %{
6
+ Description:
7
+ Copies Veritrans payment form example to your rails application.
8
+ }
9
+
10
+ def copy_shared_views
11
+ copy_file "views/_veritrans_include.erb", "app/views/shared/_veritrans_include.erb"
12
+ copy_file "views/_credit_card_form.erb", "app/views/shared/_credit_card_form.erb"
13
+ end
14
+
15
+ def copy_controller
16
+ copy_file "payments_controller.rb", "app/controllers/payments_controller.rb"
17
+
18
+ route "resources :payments do\n" +
19
+ " collection do\n" +
20
+ " post :receive_webhook\n" +
21
+ " end\n" +
22
+ " end"
23
+
24
+ copy_file "views/payments/new.erb", "app/views/payments/new.erb"
25
+ copy_file "views/payments/create.erb", "app/views/payments/create.erb"
26
+ end
27
+
28
+ def append_javascript_file
29
+ copy_file "assets/credit_card_form.js", "app/assets/javascripts/credit_card_form.js"
30
+ insert_into_file "app/assets/javascripts/application.js", :after => %r{//= require +['"]?jquery['"]?$} do
31
+ "\n//= require credit_card_form"
32
+ end
33
+
34
+ say_status "", %{
35
+
36
+ Sample form installed in you app!
37
+ It contains example for VT-Web and VT-Direct
38
+
39
+ Now open http://localhost:3000/payments/new
40
+
41
+ }
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,90 @@
1
+ # Veritrans API methods
2
+
3
+ require 'uri'
4
+
5
+ module Veritrans
6
+ module Api
7
+
8
+ # POST /v2/charge { payment_type: "vtlink" }
9
+ # Docs http://docs.veritrans.co.id/vtdirect/integration_cc.html#step2
10
+ # Docs http://docs.veritrans.co.id/sandbox/charge.html
11
+ #
12
+ # Example:
13
+ # Veritrans.charge(
14
+ # payment_type: "credit_card",
15
+ # credit_card: { token_id: "<token from client>" },
16
+ # transaction_details: {
17
+ # order_id: "order_123",
18
+ # gross_amount: 100_000
19
+ # }
20
+ # )
21
+ def charge(payment_type, data = nil)
22
+ if payment_type.kind_of?(Hash) && data.nil?
23
+ data = payment_type
24
+ payment_type = nil
25
+ end
26
+
27
+ data = data.deep_symbolize_keys if data.respond_to?(:deep_symbolize_keys)
28
+
29
+ data[:payment_type] = payment_type if payment_type
30
+
31
+ if data.has_key?(:payment_options)
32
+ data[ payment_type.to_sym ] = data.delete(:payment_options)
33
+ end
34
+
35
+ # Rename keys:
36
+ # payment -> transaction_details
37
+ # transaction -> transaction_details
38
+ # items -> item_details
39
+ # customer -> customer_details
40
+
41
+ data[:transaction_details] = data.delete(:payment) if data[:payment]
42
+ data[:transaction_details] = data.delete(:transaction) if data[:transaction]
43
+ data[:item_details] = data.delete(:items) if data[:items]
44
+ data[:customer_details] = data.delete(:customer) if data[:customer]
45
+
46
+ request_with_logging(:post, config.api_host + "/v2/charge", data)
47
+ end
48
+
49
+ # POST /v2/{id}/cancel
50
+ # Docs http://docs.veritrans.co.id/sandbox/other_commands.html
51
+ def cancel(payment_id, options = {})
52
+ request_with_logging(:post, config.api_host + "/v2/#{URI.escape(payment_id)}/cancel", options)
53
+ end
54
+
55
+ # POST /v2/{id}/approve
56
+ # Docs http://docs.veritrans.co.id/sandbox/other_commands.html
57
+ def approve(payment_id, options = {})
58
+ request_with_logging(:post, config.api_host + "/v2/#{URI.escape(payment_id)}/approve", options)
59
+ end
60
+
61
+ # GET /v2/{id}/status
62
+ # Docs http://docs.veritrans.co.id/sandbox/other_commands.html
63
+ def status(payment_id)
64
+ if !payment_id || payment_id == ""
65
+ raise ArgumentError, "parameter payment_id can not be bank"
66
+ end
67
+
68
+ get(config.api_host + "/v2/#{URI.escape(payment_id)}/status")
69
+ end
70
+
71
+ # POST /v2/capture
72
+ # Docs http://docs.veritrans.co.id/sandbox/other_features.html
73
+ def capture(payment_id, gross_amount, options = {})
74
+ post(config.api_host + "/v2/capture", options.merge(transaction_id: payment_id, gross_amount: gross_amount))
75
+ end
76
+
77
+ # POST /v2/charge { payment_type: "vtlink" }
78
+ def create_vtlink(data)
79
+ data = data.dup
80
+ data[:payment_type] = "vtlink"
81
+ request_with_logging(:post, config.api_host + "/v2/charge", data)
82
+ end
83
+
84
+ # DELETE /v2/vtlink/{id}
85
+ def delete_vtlink(id, options)
86
+ request_with_logging(:delete, config.api_host + "/v2/vtlink/#{URI.escape(id)}", options)
87
+ end
88
+
89
+ end
90
+ end
@@ -0,0 +1,166 @@
1
+ require 'json'
2
+ require 'securerandom'
3
+ require 'logger'
4
+
5
+ class Hash
6
+ def except!(*keys)
7
+ keys.each { |key| delete(key) }
8
+ self
9
+ end
10
+
11
+ def except(*keys)
12
+ dup.except!(*keys)
13
+ end
14
+ end
15
+
16
+ module Veritrans
17
+ module CLI
18
+ # can't find order
19
+ class OrderNotFound < Exception; end
20
+ class AuthenticationError < Exception; end
21
+
22
+ extend self
23
+
24
+ def test_webhook(args)
25
+ url = args.shift
26
+ raise ArgumentError, "missing required parameter URL" unless url && url != ""
27
+
28
+ options = {
29
+ body: json_data,
30
+ headers: {
31
+ :Accept => "application/json",
32
+ :"Content-Type" => "application/json",
33
+ :"User-Agent" => "Veritrans gem #{Veritrans::VERSION} - webhook tester"
34
+ },
35
+ read_timeout: 10,
36
+ write_timeout: 10,
37
+ connect_timeout: 10
38
+ }
39
+
40
+ puts "Sending #{options[:body].length} bytes to:"
41
+ puts " => #{cyan(url)}"
42
+ # Print body if it's custom
43
+ puts options[:body] + "\n\n" if CONFIG[:order]
44
+
45
+ s_time = Time.now
46
+ response = Excon.post(url, options)
47
+ response.body = response.body.to_s.encode('UTF-8', {:invalid => :replace, :undef => :replace, :replace => '?'})
48
+
49
+ puts "Got response: (#{((Time.now - s_time) * 1000).round}ms)"
50
+ puts " status: #{response.status}"
51
+ puts " body: #{response.body}"
52
+
53
+ if response.status >= 200 && response.status < 300
54
+ puts green("Success!")
55
+ else
56
+ puts red("Failed!")
57
+ puts "Response status is #{response.status} not 200"
58
+ end
59
+ #rescue Object => error
60
+ # puts red("Failed!")
61
+ # puts error.message
62
+ end
63
+
64
+ def load_local_config!
65
+ if CONFIG[:config_path]
66
+ if File.exists?(CONFIG[:config_path])
67
+ config_file = CONFIG[:config_path]
68
+ else
69
+ raise ArgumentError, "Can not find config at #{CONFIG[:config_path]}" unless config_file
70
+ end
71
+ end
72
+
73
+
74
+ if File.exists?("./veritrans.yml")
75
+ config_file = "./veritrans.yml"
76
+ end
77
+ if File.exists?("./config/veritrans.yml")
78
+ config_file = "./config/veritrans.yml"
79
+ end
80
+
81
+ raise ArgumentError, "Can not find config at ./config/veritrans.yml or ./veritrans.yml" unless config_file
82
+
83
+ puts "#{green('*')} Load config #{config_file}"
84
+ ENV['RAILS_ENV'] ||= 'development'
85
+ Veritrans.setup.load_yml("#{config_file}##{ENV['RAILS_ENV']}")
86
+
87
+ if !Veritrans.config.client_key || Veritrans.config.client_key == ""
88
+ puts red("Error")
89
+ raise ArgumentError, "Can not find client_key in #{config_file}"
90
+ end
91
+
92
+ if !Veritrans.config.server_key || Veritrans.config.server_key == ""
93
+ puts red("Error")
94
+ raise ArgumentError, "Can not find server_key in #{config_file}"
95
+ end
96
+
97
+ end
98
+
99
+ def get_order_info(order_id)
100
+ puts "#{green('*')} Getting order #{order_id}"
101
+ Veritrans.logger = Logger.new("/dev/null")
102
+ response = Veritrans.status(order_id)
103
+ if response.success?
104
+ return response
105
+ else
106
+ puts red("Error")
107
+
108
+ if response.status_code == 401
109
+ raise AuthenticationError, "Can not find order with id=#{order_id} (#{response.status_message})"
110
+ else
111
+ raise OrderNotFound, "Can not find order with id=#{order_id} (#{response.status_message})"
112
+ end
113
+ end
114
+ end
115
+
116
+ def json_data
117
+ data = {
118
+ status_code: "200",
119
+ status_message: "Veritrans payment notification",
120
+ transaction_id: SecureRandom.uuid,
121
+ order_id: "cli-testin-#{rand}",
122
+ payment_type: "credit_card",
123
+ transaction_time: Time.now.strftime("%Y-%m-%d %H:%M:%S"),
124
+ transaction_status: "capture",
125
+ fraud_status: "accept",
126
+ masked_card: "411111-1111",
127
+ gross_amount: "50000.0"
128
+ }
129
+
130
+ if CONFIG[:order]
131
+ load_local_config!
132
+ order_info = get_order_info(CONFIG[:order])
133
+ order_data = order_info.data.except(:status_message, :signature_key)
134
+ data = data.except(:fraud_status, :masked_card).merge(order_data)
135
+ end
136
+
137
+ JSON.dump(JSON.pretty_generate(data))
138
+ end
139
+
140
+ def colorize(str, color_code)
141
+ "\e[#{color_code}m#{str}\e[0m"
142
+ end
143
+
144
+ def red(str)
145
+ colorize(str, 31)
146
+ end
147
+
148
+ def green(str)
149
+ colorize(str, 32)
150
+ end
151
+
152
+ def yellow(str)
153
+ colorize(str, 33)
154
+ end
155
+
156
+ def blue(str)
157
+ colorize(str, 34)
158
+ end
159
+
160
+ def pink(str)
161
+ colorize(str, 35)
162
+ end
163
+ def cyan(str); colorize(str, 36) end
164
+
165
+ end
166
+ end
@@ -1,240 +1,108 @@
1
- # :nodoc:
2
- module Veritrans
3
-
4
- # :nodoc:
5
- class Client
6
- include Config
7
-
8
- # constructor to create instance of Veritrans::Client
9
- def initialize(&block)
10
- class <<self
11
- self
12
- end.class_eval do
13
- attr_accessor(:commodity, *PostData::PostParam)
14
- end
15
-
16
- # return-back to merchant-web
17
- self.customer_specification_flag = Config::CUSTOMER_SPECIFICATION_FLAG
18
- self.settlement_type = Config::SETTLEMENT_TYPE_CARD
19
-
20
- # if block_given?
21
- # yield(self) #self.instance_eval(&block)
22
- # return self.get_keys
23
- # end
24
- end
25
-
26
- #
27
- # Example:
28
- #
29
- # client = Veritrans::Client.new
30
- # client.order_id = "dummy#{(0...12).map{65.+(rand(25))}.join}"
31
- # client.session_id = "session#{(0...12).map{65.+(rand(25))}.join}"
32
- # client.gross_amount = "10"
33
- # client.commodity = [{
34
- # "COMMODITY_ID" => "IDxx1",
35
- # "COMMODITY_UNIT" => "10",
36
- # "COMMODITY_NUM" => "1",
37
- # "COMMODITY_NAME1" => "Waterbotle",
38
- # "COMMODITY_NAME2" => "Waterbottle in Indonesian"}]
39
- # client.get_keys
40
- #
41
- def get_keys
42
- init_instance
43
-
44
- if customer_specification_flag == "0" && shipping_flag == "0"
45
- raise "required_shipping_address must be '1'"
46
- end
47
-
48
- params = prepare_params(PostData::ServerParam,PostData::PostParam)
49
-
50
- if !params[:promo_bins].blank?
51
- params.merge!({ "promo_bins[]" => params[:promo_bins]})
52
- params.delete :promo_bins
53
- end
54
-
55
- if !params[:point_banks].blank?
56
- params.merge!({ "point_banks[]" => params[:point_banks]})
57
- params.delete :point_banks
58
- end
1
+ # Veritrans HTTP Client
59
2
 
60
- if !params[:installment_banks].blank?
61
- params.merge!({ "installment_banks[]" => params[:installment_banks]})
62
- params.delete :installment_banks
63
- end
3
+ require "base64"
4
+ require 'uri'
5
+ require 'excon'
64
6
 
65
- if !params[:installment_terms].blank?
66
- params.merge!({ "installment_terms" => params[:installment_terms].to_json })
67
- params.delete :installment_terms
68
- end
69
-
70
- if !params[:payment_methods].blank?
71
- params.merge!({ "payment_methods[]" => params[:payment_methods]})
72
- params.delete :payment_methods
73
- end
74
-
75
- commodity = @commodity.collect do |data|
76
- data.keys.map do |key|
77
- if key.downcase == "commodity_id"
78
- data["item_id[]"] = data[key]
79
- end
80
-
81
- if key.downcase == "commodity_unit"
82
- data["price[]"] = data[key]
83
- end
84
-
85
- if key.downcase == "commodity_num"
86
- data["quantity[]"] = data[key]
87
- end
88
-
89
- if key.downcase == "commodity_name1"
90
- data["item_name1[]"] = data[key]
91
- end
92
-
93
- if key.downcase == "commodity_name2"
94
- data["item_name2[]"] = data[key]
95
- end
96
-
97
- data.delete key
98
- end
99
-
100
- # construct commodity
101
- orders_uri = Addressable::URI.new
102
- orders_uri.query_values = data
103
- # return list of commodity as query string format
104
- orders_uri.query
105
- end
7
+ module Veritrans
8
+ module Client
9
+ extend self
106
10
 
107
- uri = Addressable::URI.new
108
- uri.query_values = params
109
- query_string = "#{uri.query}&repeat_line=#{commodity.length}&#{commodity.join('&')}"
110
-
111
- conn = Faraday.new(:url => server_host)
112
- @resp = conn.post do |req|
113
- req.url(Config::REQUEST_KEY_URL)
114
- req.body = query_string
115
- end.env
116
-
117
- delete_keys
118
- @resp[:url] = @resp[:url].to_s
119
-
120
- if version.to_i == 1
121
- @token = JSON.parse(@resp[:body])
122
- else
123
- @token = parse_body(@resp[:body])
11
+ # Failback for activesupport
12
+ def _json_encode(params)
13
+ if defined?(ActiveSupport) && defined?(ActiveSupport::JSON)
14
+ ActiveSupport::JSON.encode(params)
15
+ else
16
+ require 'json' unless defined?(JSON)
17
+ JSON.generate(params)
124
18
  end
125
19
  end
126
20
 
127
- # :nodoc:
128
- def server_host
129
- return Client.config["server_host"] ? Client.config["server_host"] : Config::SERVER_HOST
130
- end
131
-
132
- def redirect_url
133
- "#{server_host}/web1/paymentStart.action"
134
- end
135
-
136
- # :nodoc:
137
- def merchant_id
138
- return Client.config["merchant_id"]
21
+ def _json_decode(params)
22
+ if defined?(ActiveSupport) && defined?(ActiveSupport::JSON)
23
+ ActiveSupport::JSON.decode(params)
24
+ else
25
+ require 'json' unless defined?(JSON)
26
+ JSON.parse(params)
27
+ end
139
28
  end
140
29
 
141
- # :nodoc:
142
- def merchant_id= new_merchant_id
143
- Client.config["merchant_id"] = new_merchant_id
144
- end
30
+ # This is proxy method for make_request to save request and response to logfile
31
+ def request_with_logging(method, url, params)
32
+ short_url = url.sub(config.api_host, '')
33
+ file_logger.info("Perform #{short_url} \nSending: " + _json_encode(params))
145
34
 
146
- # :nodoc:
147
- def merchant_hash_key
148
- return Client.config["merchant_hash_key"]
149
- end
35
+ result = make_request(method, url, params)
150
36
 
151
- # :nodoc:
152
- def merchant_hash_key= new_merchant_hash_key
153
- Client.config["merchant_hash_key"] = new_merchant_hash_key
154
- end
37
+ if result.status_code < 300
38
+ file_logger.info("Success #{short_url} \nGot: " + _json_encode(result.data) + "\n")
39
+ else
40
+ file_logger.warn("Failed #{short_url} \nGot: " + _json_encode(result.data) + "\n")
41
+ end
155
42
 
156
- # :nodoc:
157
- def error_payment_return_url
158
- return Client.config["error_payment_return_url"]
43
+ result
159
44
  end
160
45
 
161
- # :nodoc:
162
- def finish_payment_return_url
163
- return Client.config["finish_payment_return_url"]
164
- end
46
+ private
165
47
 
166
- # :nodoc:
167
- def unfinish_payment_return_url
168
- return Client.config["unfinish_payment_return_url"]
48
+ def basic_auth_header(server_key = SERVER_KEY)
49
+ key = Base64.strict_encode64(server_key + ":")
50
+ "Basic #{key}"
169
51
  end
170
52
 
171
- # :nodoc:
172
- def token
173
- return @token
53
+ def get(url, params = {})
54
+ make_request(:get, url, params)
174
55
  end
175
56
 
176
- # :nodoc:
177
- def billing_address_different_with_shipping_address
178
- @customer_specification_flag
57
+ def delete(url, params)
58
+ make_request(:delete, url, params)
179
59
  end
180
60
 
181
- # :nodoc:
182
- def billing_address_different_with_shipping_address=(flag)
183
- @customer_specification_flag = customer_specification_flag
61
+ def post(url, params)
62
+ make_request(:post, url, params)
184
63
  end
185
64
 
186
- # :nodoc:
187
- def required_shipping_address
188
- @shipping_flag
189
- end
65
+ def make_request(method, url, params, auth_header = nil)
66
+ if !config.server_key || config.server_key == ''
67
+ raise "Please add server_key to config/veritrans.yml"
68
+ end
190
69
 
191
- # :nodoc:
192
- def required_shipping_address=(flag)
193
- @shipping_flag = flag
194
- end
70
+ method = method.to_s.upcase
71
+ logger.info "Veritrans: #{method} #{url} #{_json_encode(params)}"
72
+
73
+ # Add authentication and content type
74
+ # Docs http://docs.veritrans.co.id/sandbox/introduction.html
75
+ options = {
76
+ :body => _json_encode(params),
77
+ :headers => {
78
+ :Authorization => auth_header || basic_auth_header(config.server_key),
79
+ :Accept => "application/json",
80
+ :"Content-Type" => "application/json",
81
+ :"User-Agent" => "Veritrans ruby gem #{Veritrans::VERSION}"
82
+ }
83
+ }
84
+
85
+ if method == "GET"
86
+ options.delete(:body)
87
+ options[:query] = URI.encode_www_form(params)
88
+ end
195
89
 
196
- def new_api
197
- return true
198
- end
90
+ s_time = Time.now
91
+ request = Excon.new(url, read_timeout: 40, write_timeout: 40, connect_timeout: 40)
199
92
 
200
- private
201
- # Generate merchant hash code
202
- def merchanthash
203
- if version.to_i == 1
204
- return HashGenerator::generate(merchant_hash_key, merchant_id, order_id);
205
- else
206
- return Digest::SHA512.hexdigest("#{merchant_hash_key},#{merchant_id},01,#{order_id},#{gross_amount}")
207
- end
208
- end
93
+ response = request.send(method.downcase.to_sym, options.merge(path: URI.parse(url).path))
209
94
 
210
- # deprecated
211
- def parse_body(body)
212
- arrs = body.split("\r\n")
213
- arrs = arrs[-2,2] if arrs.length > 1
214
- return Hash[arrs.collect{|x|x.split("=")}]
215
- end
216
-
217
- def init_instance
218
- @token = nil
219
- end
95
+ logger.info "Veritrans: got #{(Time.now - s_time).round(3)} sec #{response.status} #{response.body}"
220
96
 
221
- def prepare_params(*arg)
222
- params = {}
223
- # extract keys from post data
224
- arg.flatten.each do |key|
225
- # retrieve value from client configuration
226
- value = self.send(key)
227
- params[key.downcase] = value if value
228
- end
229
- return params
230
- end
97
+ Result.new(response, url, options, Time.now - s_time)
231
98
 
232
- def delete_keys
233
- @resp.delete(:ssl)
234
- @resp.delete(:request)
235
- @resp.delete(:response)
236
- @resp.delete(:request_headers)
237
- @resp.delete(:parallel_manager)
99
+ rescue Excon::Errors::SocketError => error
100
+ logger.info "PAPI: socket error, can not connect"
101
+ error_response = Excon::Response.new(
102
+ body: '{"status_code": "500", "status_message": "Internal server error, no response from backend. Try again later"}',
103
+ status: '500'
104
+ )
105
+ Veritrans::Result.new(error_response, url, options, Time.now - s_time)
238
106
  end
239
107
 
240
108
  end