veritrans 1.2.6 → 2.0.0beta

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.
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