veritrans 2.1.3 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (240) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -1
  3. data/.travis.yml +3 -5
  4. data/CHANGELOG.md +20 -0
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +89 -94
  7. data/Procfile +1 -1
  8. data/README.md +62 -13
  9. data/api_reference.md +10 -10
  10. data/example/rails/cable/Gemfile +48 -0
  11. data/example/rails/cable/Gemfile.lock +184 -0
  12. data/example/rails/cable/README.md +29 -0
  13. data/example/rails/cable/Rakefile +6 -0
  14. data/example/rails/cable/app/assets/config/manifest.js +3 -0
  15. data/example/rails/cable/app/assets/images/.keep +0 -0
  16. data/example/rails/cable/app/assets/javascripts/application.js +15 -0
  17. data/example/rails/cable/app/assets/javascripts/cable.js +13 -0
  18. data/example/rails/cable/app/assets/javascripts/channels/.keep +0 -0
  19. data/example/rails/cable/app/assets/javascripts/chats.js +39 -0
  20. data/example/rails/cable/app/assets/javascripts/rooms.js +55 -0
  21. data/example/rails/cable/app/assets/stylesheets/application.css +16 -0
  22. data/example/rails/cable/app/assets/stylesheets/chatbox.scss +31 -0
  23. data/example/rails/cable/app/assets/stylesheets/peoplebox.scss +6 -0
  24. data/example/rails/cable/app/channels/application_cable/channel.rb +4 -0
  25. data/example/rails/cable/app/channels/application_cable/connection.rb +4 -0
  26. data/example/rails/cable/app/channels/rooms_texting_channel.rb +13 -0
  27. data/example/rails/cable/app/controllers/application_controller.rb +3 -0
  28. data/example/rails/cable/app/controllers/chats_controller.rb +18 -0
  29. data/example/rails/cable/app/controllers/concerns/.keep +0 -0
  30. data/example/rails/cable/app/controllers/pays_controller.rb +28 -0
  31. data/example/rails/cable/app/controllers/rooms_controller.rb +4 -0
  32. data/example/rails/cable/app/helpers/application_helper.rb +2 -0
  33. data/example/rails/cable/app/helpers/chats_helper.rb +2 -0
  34. data/example/rails/cable/app/helpers/rooms_helper.rb +5 -0
  35. data/example/rails/cable/app/jobs/application_job.rb +2 -0
  36. data/example/rails/cable/app/jobs/chat_broadcaster_job.rb +15 -0
  37. data/example/rails/cable/app/mailers/application_mailer.rb +4 -0
  38. data/example/rails/cable/app/models/application_record.rb +3 -0
  39. data/example/rails/cable/app/models/chat.rb +41 -0
  40. data/example/rails/cable/app/models/concerns/.keep +0 -0
  41. data/example/rails/cable/app/models/order.rb +2 -0
  42. data/example/rails/cable/app/models/user.rb +2 -0
  43. data/example/rails/cable/app/views/chats/_chat.html.erb +18 -0
  44. data/example/rails/cable/app/views/layouts/application.html.erb +19 -0
  45. data/example/rails/cable/app/views/layouts/mailer.html.erb +13 -0
  46. data/example/rails/cable/app/views/layouts/mailer.text.erb +1 -0
  47. data/example/rails/cable/app/views/rooms/_chatbox.html.erb +13 -0
  48. data/example/rails/cable/app/views/rooms/_online_people.html.erb +53 -0
  49. data/example/rails/cable/app/views/rooms/index.html.erb +9 -0
  50. data/example/rails/cable/bin/bundle +3 -0
  51. data/example/rails/cable/bin/rails +9 -0
  52. data/example/rails/cable/bin/rake +9 -0
  53. data/example/rails/cable/bin/setup +34 -0
  54. data/example/rails/cable/bin/spring +16 -0
  55. data/example/rails/cable/bin/update +29 -0
  56. data/example/rails/cable/config.ru +5 -0
  57. data/example/rails/cable/config/application.rb +16 -0
  58. data/example/rails/cable/config/boot.rb +3 -0
  59. data/example/rails/cable/config/cable.yml +9 -0
  60. data/example/rails/cable/config/database.yml +20 -0
  61. data/example/rails/cable/config/environment.rb +5 -0
  62. data/example/rails/cable/config/environments/development.rb +57 -0
  63. data/example/rails/cable/config/environments/production.rb +86 -0
  64. data/example/rails/cable/config/environments/test.rb +42 -0
  65. data/example/rails/cable/config/initializers/application_controller_renderer.rb +6 -0
  66. data/example/rails/cable/config/initializers/assets.rb +11 -0
  67. data/example/rails/cable/config/initializers/backtrace_silencers.rb +7 -0
  68. data/example/rails/cable/config/initializers/cookies_serializer.rb +5 -0
  69. data/example/rails/cable/config/initializers/filter_parameter_logging.rb +4 -0
  70. data/example/rails/cable/config/initializers/inflections.rb +16 -0
  71. data/example/rails/cable/config/initializers/mime_types.rb +4 -0
  72. data/example/rails/cable/config/initializers/new_framework_defaults.rb +24 -0
  73. data/example/rails/cable/config/initializers/session_store.rb +3 -0
  74. data/example/rails/cable/config/initializers/sidekiq.rb +2 -0
  75. data/example/rails/cable/config/initializers/veritrans.rb +46 -0
  76. data/example/rails/cable/config/initializers/wrap_parameters.rb +14 -0
  77. data/example/rails/cable/config/locales/en.yml +23 -0
  78. data/example/rails/cable/config/puma.rb +47 -0
  79. data/example/rails/cable/config/routes.rb +18 -0
  80. data/example/rails/cable/config/secrets.yml +22 -0
  81. data/example/rails/cable/config/spring.rb +6 -0
  82. data/example/rails/cable/config/veritrans.yml +13 -0
  83. data/example/rails/cable/db/development.sqlite3 +0 -0
  84. data/example/rails/cable/db/migrate/20161215070044_create_chats.rb +10 -0
  85. data/example/rails/cable/db/migrate/20161215072021_create_users.rb +10 -0
  86. data/example/rails/cable/db/migrate/20161219110219_create_orders.rb +11 -0
  87. data/example/rails/cable/db/schema.rb +37 -0
  88. data/example/rails/cable/db/seeds.rb +41 -0
  89. data/example/rails/cable/db/test.sqlite3 +0 -0
  90. data/example/rails/cable/lib/assets/.keep +0 -0
  91. data/example/rails/cable/lib/tasks/.keep +0 -0
  92. data/example/rails/cable/public/404.html +67 -0
  93. data/example/rails/cable/public/422.html +67 -0
  94. data/example/rails/cable/public/500.html +66 -0
  95. data/example/rails/cable/public/apple-touch-icon-precomposed.png +0 -0
  96. data/example/rails/cable/public/apple-touch-icon.png +0 -0
  97. data/example/rails/cable/public/favicon.ico +0 -0
  98. data/example/rails/cable/public/images/avatar1.jpg +0 -0
  99. data/example/rails/cable/public/images/avatar2.jpg +0 -0
  100. data/example/rails/cable/public/images/avatar3.jpg +0 -0
  101. data/example/rails/cable/public/images/avatar4.jpg +0 -0
  102. data/example/rails/cable/public/images/avatar5.jpg +0 -0
  103. data/example/rails/cable/public/images/avatar6.jpg +0 -0
  104. data/example/rails/cable/public/robots.txt +5 -0
  105. data/example/rails/cable/vendor/assets/javascripts/.keep +0 -0
  106. data/example/rails/cable/vendor/assets/stylesheets/.keep +0 -0
  107. data/example/rails/cable/vendor/assets/stylesheets/photon.css +2333 -0
  108. data/example/rails/simplepay/Gemfile +54 -0
  109. data/example/rails/simplepay/Gemfile.lock +178 -0
  110. data/example/rails/simplepay/README.md +30 -0
  111. data/example/rails/simplepay/Rakefile +6 -0
  112. data/example/rails/simplepay/app/assets/config/manifest.js +3 -0
  113. data/example/rails/simplepay/app/assets/images/.keep +0 -0
  114. data/example/rails/simplepay/app/assets/javascripts/application.js +16 -0
  115. data/example/rails/simplepay/app/assets/javascripts/cable.js +13 -0
  116. data/example/rails/simplepay/app/assets/javascripts/channels/.keep +0 -0
  117. data/example/rails/simplepay/app/assets/javascripts/pay.js +18 -0
  118. data/example/rails/simplepay/app/assets/stylesheets/application.css +15 -0
  119. data/example/rails/simplepay/app/assets/stylesheets/style.css +254 -0
  120. data/example/rails/simplepay/app/channels/application_cable/channel.rb +4 -0
  121. data/example/rails/simplepay/app/channels/application_cable/connection.rb +4 -0
  122. data/example/rails/simplepay/app/controllers/application_controller.rb +3 -0
  123. data/example/rails/simplepay/app/controllers/concerns/.keep +0 -0
  124. data/example/rails/simplepay/app/controllers/home_controller.rb +16 -0
  125. data/example/rails/simplepay/app/controllers/pay_controller.rb +10 -0
  126. data/example/rails/simplepay/app/helpers/application_helper.rb +2 -0
  127. data/example/rails/simplepay/app/helpers/pay_helper.rb +2 -0
  128. data/example/rails/simplepay/app/jobs/application_job.rb +2 -0
  129. data/example/rails/simplepay/app/mailers/application_mailer.rb +4 -0
  130. data/example/rails/simplepay/app/models/application_record.rb +3 -0
  131. data/example/rails/simplepay/app/models/concerns/.keep +0 -0
  132. data/example/rails/simplepay/app/models/order.rb +2 -0
  133. data/example/rails/simplepay/app/views/home/index.html.erb +19 -0
  134. data/example/rails/simplepay/app/views/layouts/application.html.erb +15 -0
  135. data/example/rails/simplepay/app/views/layouts/mailer.html.erb +13 -0
  136. data/example/rails/simplepay/app/views/layouts/mailer.text.erb +1 -0
  137. data/example/rails/simplepay/app/views/pay/notify.html.erb +2 -0
  138. data/example/rails/simplepay/bin/bundle +3 -0
  139. data/example/rails/simplepay/bin/rails +9 -0
  140. data/example/rails/simplepay/bin/rake +9 -0
  141. data/example/rails/simplepay/bin/setup +34 -0
  142. data/example/rails/simplepay/bin/spring +16 -0
  143. data/example/rails/simplepay/bin/update +29 -0
  144. data/example/rails/simplepay/config.ru +5 -0
  145. data/example/rails/simplepay/config/application.rb +15 -0
  146. data/example/rails/simplepay/config/boot.rb +3 -0
  147. data/example/rails/simplepay/config/cable.yml +9 -0
  148. data/example/rails/simplepay/config/database.yml +25 -0
  149. data/example/rails/simplepay/config/environment.rb +5 -0
  150. data/example/rails/simplepay/config/environments/development.rb +57 -0
  151. data/example/rails/simplepay/config/environments/production.rb +86 -0
  152. data/example/rails/simplepay/config/environments/test.rb +42 -0
  153. data/example/rails/simplepay/config/initializers/application_controller_renderer.rb +6 -0
  154. data/example/rails/simplepay/config/initializers/assets.rb +11 -0
  155. data/example/rails/simplepay/config/initializers/backtrace_silencers.rb +7 -0
  156. data/example/rails/simplepay/config/initializers/cookies_serializer.rb +5 -0
  157. data/example/rails/simplepay/config/initializers/filter_parameter_logging.rb +4 -0
  158. data/example/rails/simplepay/config/initializers/inflections.rb +16 -0
  159. data/example/rails/simplepay/config/initializers/mime_types.rb +4 -0
  160. data/example/rails/simplepay/config/initializers/new_framework_defaults.rb +24 -0
  161. data/example/rails/simplepay/config/initializers/session_store.rb +3 -0
  162. data/example/rails/simplepay/config/initializers/veritrans.rb +46 -0
  163. data/example/rails/simplepay/config/initializers/wrap_parameters.rb +14 -0
  164. data/example/rails/simplepay/config/locales/en.yml +23 -0
  165. data/example/rails/simplepay/config/puma.rb +47 -0
  166. data/example/rails/simplepay/config/routes.rb +5 -0
  167. data/example/rails/simplepay/config/secrets.yml +22 -0
  168. data/example/rails/simplepay/config/spring.rb +6 -0
  169. data/example/rails/simplepay/config/veritrans.yml +18 -0
  170. data/example/rails/simplepay/db/development.sqlite3 +0 -0
  171. data/example/rails/simplepay/db/migrate/20161221090855_create_orders.rb +10 -0
  172. data/example/rails/simplepay/db/schema.rb +22 -0
  173. data/example/rails/simplepay/db/seeds.rb +7 -0
  174. data/example/rails/simplepay/db/test.sqlite3 +0 -0
  175. data/example/rails/simplepay/lib/assets/.keep +0 -0
  176. data/example/rails/simplepay/lib/tasks/.keep +0 -0
  177. data/example/rails/simplepay/public/404.html +67 -0
  178. data/example/rails/simplepay/public/422.html +67 -0
  179. data/example/rails/simplepay/public/500.html +66 -0
  180. data/example/rails/simplepay/public/apple-touch-icon-precomposed.png +0 -0
  181. data/example/rails/simplepay/public/apple-touch-icon.png +0 -0
  182. data/example/rails/simplepay/public/favicon.ico +0 -0
  183. data/example/rails/simplepay/public/robots.txt +5 -0
  184. data/example/rails/simplepay/vendor/assets/javascripts/.keep +0 -0
  185. data/example/rails/simplepay/vendor/assets/stylesheets/.keep +0 -0
  186. data/example/{README.md → sinatra/README.md} +0 -0
  187. data/example/{config.ru → sinatra/config.ru} +3 -0
  188. data/example/{index.erb → sinatra/index.erb} +7 -6
  189. data/example/{localization.erb → sinatra/localization.erb} +6 -5
  190. data/example/{points.erb → sinatra/points.erb} +6 -5
  191. data/example/{recurring.erb → sinatra/recurring.erb} +6 -6
  192. data/example/{response.erb → sinatra/response.erb} +4 -1
  193. data/example/{sinatra.rb → sinatra/sinatra.rb} +9 -3
  194. data/example/{style.css → sinatra/style.css} +11 -0
  195. data/example/{veritrans.yml → sinatra/veritrans.yml} +2 -2
  196. data/example/{widget.erb → sinatra/widget.erb} +18 -6
  197. data/lib/generators/templates/assets/credit_card_form.js +6 -0
  198. data/lib/generators/templates/payments_controller.rb +4 -4
  199. data/lib/generators/templates/veritrans.yml +5 -5
  200. data/lib/generators/templates/views/_credit_card_form.erb +2 -2
  201. data/lib/generators/templates/views/_veritrans_include.erb +1 -1
  202. data/lib/generators/veritrans/install_generator.rb +1 -1
  203. data/lib/generators/veritrans/payment_form_generator.rb +1 -1
  204. data/lib/veritrans.rb +106 -5
  205. data/lib/veritrans/api.rb +7 -7
  206. data/lib/veritrans/cli.rb +11 -5
  207. data/lib/veritrans/client.rb +7 -4
  208. data/lib/veritrans/config.rb +5 -3
  209. data/lib/veritrans/events.rb +46 -35
  210. data/lib/veritrans/result.rb +58 -2
  211. data/lib/veritrans/testing.rb +156 -0
  212. data/lib/veritrans/version.rb +1 -1
  213. data/spec/cli_spec.rb +2 -2
  214. data/spec/fixtures/approve_failed.yml +1 -1
  215. data/spec/fixtures/cancel_failed.yml +1 -1
  216. data/spec/fixtures/cancel_success.yml +2 -2
  217. data/spec/fixtures/capture_failed.yml +1 -1
  218. data/spec/fixtures/charge.yml +2 -2
  219. data/spec/fixtures/charge_direct.yml +1 -1
  220. data/spec/fixtures/charge_vtweb.yml +2 -2
  221. data/spec/fixtures/cli_test_1111-not-exists.yml +1 -1
  222. data/spec/fixtures/cli_test_not_exists.yml +1 -1
  223. data/spec/fixtures/cli_test_real_txn.yml +1 -1
  224. data/spec/fixtures/cli_test_unauthorized.yml +1 -1
  225. data/spec/fixtures/events_test_real_txn.yml +1 -1
  226. data/spec/fixtures/expire_failed.yml +1 -1
  227. data/spec/fixtures/expire_success.yml +1 -1
  228. data/spec/fixtures/midtrans_status.yml +2 -2
  229. data/spec/fixtures/status_fail.yml +1 -1
  230. data/spec/fixtures/status_success.yml +2 -2
  231. data/spec/rails_plugin_spec.rb +37 -20
  232. data/spec/spec_helper.rb +0 -1
  233. data/spec/veritrans_client_spec.rb +1 -1
  234. data/spec/veritrans_config_spec.rb +1 -1
  235. data/spec/veritrans_events_spec.rb +6 -6
  236. data/spec/veritrans_testing_spec.rb +184 -0
  237. data/testing_webhooks.md +2 -2
  238. data/veritrans.gemspec +1 -1
  239. metadata +195 -16
  240. data/lib/veritrans/core_extensions.rb +0 -32
@@ -1,3 +1,8 @@
1
+ // Veritrans is defined in https://api.midtrans.com/v2/assets/js/midtrans.min.js
2
+ // and it has no JS dependecies, but this example uses jquery for simplicity
3
+
4
+ //= require jquery
5
+
1
6
  $(document).ready(function () {
2
7
 
3
8
  function VT_createTokenData() {
@@ -23,6 +28,7 @@ $(document).ready(function () {
23
28
  var button = $(form).find('input[type=submit]:last');
24
29
  var buttonValBefore = button.val();
25
30
  button.val("Processing ...");
31
+ button.attr('disabled', true); // prevent double submit
26
32
 
27
33
  Veritrans.token(VT_createTokenData, function (data) {
28
34
  //console.log('Get token response:');
@@ -1,5 +1,5 @@
1
- class PaymentsController < ApplicationController
2
- skip_before_filter :verify_authenticity_token, only: [:receive_webhook]
1
+ class PaymentsController < ApplicationController # :nodoc:
2
+ skip_before_action :verify_authenticity_token, only: [:receive_webhook]
3
3
 
4
4
  def new
5
5
  @payment = make_payment
@@ -53,14 +53,14 @@ class PaymentsController < ApplicationController
53
53
  puts "Payment amount: #{verified_data.data[:gross_amount]}"
54
54
  puts "--- Transaction callback ---"
55
55
 
56
- render text: "ok"
56
+ render plain: "ok"
57
57
  else
58
58
  Veritrans.file_logger.info("Callback verification failed for order: " +
59
59
  "#{params[:order_id]} #{params[:transaction_status]}}\n" +
60
60
  verified_data.body + "\n"
61
61
  )
62
62
 
63
- render text: "ok", :status => :not_found
63
+ render plain: "ok", :status => :not_found
64
64
  end
65
65
 
66
66
  end
@@ -1,18 +1,18 @@
1
1
  development:
2
2
  # Register in sandbox veritrans and get your keys here:
3
- # https://my.sandbox.veritrans.co.id/settings/config_info
3
+ # https://dashboard.sandbox.midtrans.com/settings/config_info
4
4
  client_key: ""
5
5
  server_key: ""
6
- api_host: https://api.sandbox.veritrans.co.id
6
+ api_host: https://api.sandbox.midtrans.com
7
7
 
8
8
  production:
9
9
  # Register and get your keys here:
10
- # https://my.veritrans.co.id/settings/config_info
10
+ # https://dashboard.midtrans.com/settings/config_info
11
11
  client_key: <%= ENV['VERITRANS_CLIENT_KEY'] %>
12
12
  server_key: <%= ENV['VERITRANS_SERVER_KEY'] %>
13
- api_host: https://api.veritrans.co.id
13
+ api_host: https://api.midtrans.com
14
14
 
15
15
  staging:
16
16
  client_key: <%= ENV['VT_SANDBOX_CLIENT_KEY'] %>
17
17
  server_key: <%= ENV['VT_SANDBOX_SERVER_KEY'] %>
18
- api_host: https://api.sandbox.veritrans.co.id
18
+ api_host: https://api.sandbox.midtrans.com
@@ -16,7 +16,7 @@
16
16
  <button onclick="$('#credit_card_number').val('4511 1111 1111 1117'); return false">challenge</button>
17
17
  <button onclick="$('#credit_card_number').val('4611 1111 1111 1116'); return false">Deny by FDS</button>
18
18
  <button onclick="$('#credit_card_number').val('4911 1111 1111 1113'); return false">Deny by bank</button>
19
- <a href="http://docs.veritrans.co.id/sandbox/card_list.html" target="_blank">documentation</a>
19
+ <a href="https://docs.midtrans.com/en/reference/test.html" target="_blank">documentation</a>
20
20
  </p>
21
21
 
22
22
  <p>
@@ -26,7 +26,7 @@
26
26
 
27
27
  <p>
28
28
  <%= label_tag :credit_card_expire %>
29
- <%= text_field_tag :credit_card_expire, '12 / 16', placeholder: "MM / YY", name: nil %>
29
+ <%= text_field_tag :credit_card_expire, '12 / 18', placeholder: "MM / YY", name: nil %>
30
30
  </p>
31
31
 
32
32
  <p>
@@ -1,4 +1,4 @@
1
- <%= javascript_include_tag "#{Veritrans.config.api_host}/v2/assets/veritrans.js" %>
1
+ <%= javascript_include_tag "#{Veritrans.config.api_host}/v2/assets/js/midtrans.min.js" %>
2
2
 
3
3
  <script type="text/javascript">
4
4
  Veritrans.url = "<%= Veritrans.config.api_host %>/v2/token";
@@ -1,5 +1,5 @@
1
1
  class Veritrans
2
- class InstallGenerator < ::Rails::Generators::Base
2
+ class InstallGenerator < ::Rails::Generators::Base # :nodoc:
3
3
  source_root File.expand_path("../../templates", __FILE__)
4
4
 
5
5
  desc %{
@@ -1,5 +1,5 @@
1
1
  class Veritrans
2
- class PaymentFormGenerator < ::Rails::Generators::Base
2
+ class PaymentFormGenerator < ::Rails::Generators::Base # :nodoc:
3
3
  source_root File.expand_path("../../templates", __FILE__)
4
4
 
5
5
  desc %{
@@ -1,5 +1,4 @@
1
1
  require 'veritrans/version'
2
- require 'veritrans/core_extensions'
3
2
  require 'veritrans/config'
4
3
  require 'veritrans/client'
5
4
  require 'veritrans/api'
@@ -13,6 +12,11 @@ class Veritrans
13
12
  include Veritrans::Client
14
13
  include Veritrans::Api
15
14
 
15
+ autoload :Testing, 'veritrans/testing'
16
+ autoload :TestingLib, 'veritrans/testing'
17
+ autoload :CLI, 'veritrans/cli'
18
+ autoload :Events, 'veritrans/events'
19
+
16
20
  class << self
17
21
  extend Forwardable
18
22
 
@@ -20,11 +24,19 @@ class Veritrans
20
24
  def_delegators :instance, :request_with_logging, :basic_auth_header, :get, :post, :delete, :make_request
21
25
  def_delegators :instance, :charge, :cancel, :approve, :status, :capture, :expire
22
26
  def_delegators :instance, :create_vtlink, :delete_vtlink, :inquiry_points, :create_widget_token, :create_snap_token
27
+ def_delegators :instance, :checksum, :events
23
28
 
29
+ # Shortcut for Veritrans::Events
24
30
  def events
31
+ if defined?(ActiveSupport::Deprecation)
32
+ ActiveSupport::Deprecation.warn("`Veritrans.events` is deprecated. Please use `Veritrans::Events`.")
33
+ else
34
+ warn "`Veritrans.events` is deprecated. Please use `Veritrans::Events`."
35
+ end
25
36
  Veritrans::Events if defined?(Veritrans::Events)
26
37
  end
27
38
 
39
+ # More safe json parser
28
40
  def decode_notification_json(input)
29
41
  return Veritrans::Client._json_decode(input)
30
42
  end
@@ -35,6 +47,23 @@ class Veritrans
35
47
 
36
48
  end
37
49
 
50
+ def events
51
+ self.class.events
52
+ end
53
+
54
+ # If you want to use multiple instances of Midtrans in your code (e.g. process payments in different accounts),
55
+ # then you can create instance of Midtrans client
56
+ #
57
+ # mt_client = Midtrans.new(
58
+ # server_key: "My-Different-Key",
59
+ # client_key: "...",
60
+ # api_host: "https://api.sandbox.midtrans.com", # default
61
+ # http_options: { }, # optional
62
+ # logger: Logger.new(STDOUT), # optional
63
+ # file_logger: Logger.new(STDOUT), # optional
64
+ # )
65
+ # mt_client.status("my-different-order-id")
66
+ #
38
67
  def initialize(options = nil)
39
68
  if options && options[:logger]
40
69
  self.logger = options.delete(:logger)
@@ -51,6 +80,22 @@ class Veritrans
51
80
  end
52
81
  end
53
82
 
83
+ # Midtrans configuration. Can be used as DSL and as object
84
+ #
85
+ # Use with block:
86
+ #
87
+ # Midtrans.setup do
88
+ # config.load_yml "./midtrans.yml", Rails.env # load values from config
89
+ # # also can set one by one:
90
+ # config.server_key = "..."
91
+ # config.client_key = "..."
92
+ # config.api_host = "https://api.sandbox.midtrans.com" # (default)
93
+ # end
94
+ #
95
+ # Use as object:
96
+ #
97
+ # Midtrans.config.server_key
98
+ #
54
99
  def config(&block)
55
100
  if block
56
101
  instance_eval(&block)
@@ -58,12 +103,59 @@ class Veritrans
58
103
  @config ||= Veritrans::Config.new
59
104
  end
60
105
  end
61
-
62
106
  alias_method :setup, :config
63
107
 
64
- # General logger
65
- # for rails apps it's === Rails.logger
66
- # for non-rails apps it's logging to stdout
108
+ # Calculate signature_key sha512 checksum for validating HTTP notifications
109
+ #
110
+ # Arguments:
111
+ # [params] A hash, should contain <tt>:order_id, :status_code, :gross_amount</tt>.
112
+ # Additional key <tt>:server_key</tt> is required if Midtrans.config.server_key is not set
113
+ #
114
+ # Example
115
+ #
116
+ # Midtrans.checksum(order_id: "aa11", status_code: "200", gross_amount: 1000, server_key: "my-key")
117
+ # # => "5e00499b23a8932e833238b2f65dd4dd3d10451708c7ec4d93da69e8e7a2bac4f7f97f9f35a986a7d100d7fc58034e12..."
118
+ #
119
+ # Raises:
120
+ # - <tt>ArgumentError</tt> when missing or invalid parameters
121
+ #
122
+ def checksum(params)
123
+ require 'digest' unless defined?(Digest)
124
+
125
+ params_sym = {}
126
+ params.each do |key, value|
127
+ params_sym[key.to_sym] = value
128
+ end
129
+
130
+ if (config.server_key.nil? || config.server_key == "") && params_sym[:server_key].nil?
131
+ raise ArgumentError, "Server key is required. Please set Veritrans.config.server_key or :server_key key"
132
+ end
133
+
134
+ required = [:order_id, :status_code, :gross_amount]
135
+ missing = required - params_sym.keys.select {|k| !!params_sym[k] }
136
+ if missing.size > 0
137
+ raise ArgumentError, "Missing required parameters: #{missing.map(&:inspect).join(", ")}"
138
+ end
139
+
140
+ if params_sym[:gross_amount].is_a?(Numeric)
141
+ params_sym[:gross_amount] = "%0.2f" % params_sym[:gross_amount]
142
+ elsif params_sym[:gross_amount].is_a?(String) && params_sym[:gross_amount] !~ /\d+\.\d\d$/
143
+ raise ArgumentError, %{gross_amount has invalid format, should be a number or string with cents e.g "52.00" (given: #{params_sym[:gross_amount].inspect})}
144
+ end
145
+
146
+ seed = "#{params_sym[:order_id]}#{params_sym[:status_code]}" +
147
+ "#{params_sym[:gross_amount]}#{params_sym[:server_key] || config.server_key}"
148
+
149
+ logger.debug("checksum source: #{seed}")
150
+
151
+ Digest::SHA2.new(512).hexdigest(seed)
152
+ end
153
+
154
+ # General Midtrans logger.
155
+ # For rails apps it will try to use <tt>Rails.logger</tt>, for non-rails apps -- it print to stdout
156
+ #
157
+ # Midtrans.logger.info "Processing payment"
158
+ #
67
159
  def logger
68
160
  return @logger if @logger
69
161
  if defined?(Rails)
@@ -78,6 +170,10 @@ class Veritrans
78
170
  end
79
171
  end
80
172
 
173
+ # Set custom logger
174
+ #
175
+ # Midtrans.logger = Logger.new("./log/midtrans.log")
176
+ #
81
177
  def logger=(value)
82
178
  @logger = value
83
179
  end
@@ -97,10 +193,15 @@ class Veritrans
97
193
  @file_logger
98
194
  end
99
195
 
196
+ # Set custom file_logger
197
+ #
198
+ # Midtrans.file_logger = Logger.new("./log/midtrans.log")
199
+ #
100
200
  def file_logger=(value)
101
201
  @file_logger = value
102
202
  end
103
203
 
104
204
  end
105
205
 
206
+ # Alias constant for new name of company
106
207
  Midtrans = Veritrans
@@ -5,9 +5,8 @@ require 'uri'
5
5
  class Veritrans
6
6
  module Api
7
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
8
+ # POST /v2/charge { payment_type: "credit_card" }
9
+ # Docs https://api-docs.midtrans.com/#charge-features
11
10
  #
12
11
  # Example:
13
12
  # Veritrans.charge(
@@ -55,7 +54,7 @@ class Veritrans
55
54
  alias_method :create_widget_token, :create_snap_token
56
55
 
57
56
  # POST /v2/{id}/cancel
58
- # Docs http://docs.veritrans.co.id/en/api/methods.html#Cancel
57
+ # Docs https://api-docs.midtrans.com/#cancel-transaction
59
58
  def cancel(payment_id, options = {})
60
59
  if !payment_id || payment_id.to_s == ""
61
60
  raise ArgumentError, "parameter payment_id can not be blank (got #{payment_id.class} : #{payment_id.inspect})"
@@ -65,7 +64,7 @@ class Veritrans
65
64
  end
66
65
 
67
66
  # POST /v2/{id}/approve
68
- # Docs http://docs.veritrans.co.id/en/api/methods.html#Approve
67
+ # Docs https://api-docs.midtrans.com/#approve-transaction
69
68
  def approve(payment_id, options = {})
70
69
  if !payment_id || payment_id.to_s == ""
71
70
  raise ArgumentError, "parameter payment_id can not be blank (got #{payment_id.class} : #{payment_id.inspect})"
@@ -75,7 +74,7 @@ class Veritrans
75
74
  end
76
75
 
77
76
  # GET /v2/{id}/status
78
- # Docs http://docs.veritrans.co.id/en/api/methods.html#Status
77
+ # Docs https://api-docs.midtrans.com/#get-status-transaction
79
78
  def status(payment_id)
80
79
  if !payment_id || payment_id.to_s == ""
81
80
  raise ArgumentError, "parameter payment_id can not be blank (got #{payment_id.class} : #{payment_id.inspect})"
@@ -85,7 +84,7 @@ class Veritrans
85
84
  end
86
85
 
87
86
  # POST /v2/capture
88
- # Docs http://docs.veritrans.co.id/en/api/methods.html#Capture
87
+ # Docs https://api-docs.midtrans.com/#capture-transaction
89
88
  def capture(payment_id, gross_amount, options = {})
90
89
  if !payment_id || payment_id.to_s == ""
91
90
  raise ArgumentError, "parameter payment_id can not be blank (got #{payment_id.class} : #{payment_id.inspect})"
@@ -95,6 +94,7 @@ class Veritrans
95
94
  end
96
95
 
97
96
  # POST /v2/{id}/expire
97
+ # Docs https://api-docs.midtrans.com/#expire-transaction
98
98
  def expire(payment_id)
99
99
  if !payment_id || payment_id.to_s == ""
100
100
  raise ArgumentError, "parameter payment_id can not be blank (got #{payment_id.class} : #{payment_id.inspect})"
@@ -3,10 +3,10 @@ require 'securerandom'
3
3
  require 'logger'
4
4
 
5
5
  class Veritrans
6
- module CLI
6
+ module CLI #:nodoc:
7
7
  # can't find order
8
- class OrderNotFound < Exception; end
9
- class AuthenticationError < Exception; end
8
+ class OrderNotFound < Exception; end # :nodoc:
9
+ class AuthenticationError < Exception; end # :nodoc:
10
10
 
11
11
  extend self
12
12
 
@@ -119,8 +119,8 @@ class Veritrans
119
119
  if CONFIG[:order]
120
120
  load_local_config!
121
121
  order_info = get_order_info(CONFIG[:order])
122
- order_data = order_info.data.except(:status_message, :signature_key)
123
- data = data.except(:fraud_status, :masked_card).merge(order_data)
122
+ order_data = hash_except(order_info.data, :status_message, :signature_key)
123
+ data = hash_except(data, :fraud_status, :masked_card).merge(order_data)
124
124
  end
125
125
 
126
126
  JSON.pretty_generate(data)
@@ -151,5 +151,11 @@ class Veritrans
151
151
  end
152
152
  def cyan(str); colorize(str, 36) end
153
153
 
154
+ def hash_except(hash, *except_keys)
155
+ copy = hash.dup
156
+ except_keys.each { |key| copy.delete(key) }
157
+ copy
158
+ end
159
+
154
160
  end
155
161
  end
@@ -7,7 +7,8 @@ require 'excon'
7
7
  class Veritrans
8
8
  module Client
9
9
 
10
- # Failback for activesupport
10
+ # If you using Rails then it will call ActiveSupport::JSON.encode
11
+ # Otherwise JSON.pretty_generate
11
12
  def self._json_encode(params)
12
13
  if defined?(ActiveSupport) && defined?(ActiveSupport::JSON)
13
14
  ActiveSupport::JSON.encode(params)
@@ -21,6 +22,8 @@ class Veritrans
21
22
  Veritrans::Client._json_encode(params)
22
23
  end
23
24
 
25
+ # If you using Rails then it will call ActiveSupport::JSON.decode
26
+ # Otherwise JSON.parse
24
27
  def self._json_decode(params)
25
28
  if defined?(ActiveSupport) && defined?(ActiveSupport::JSON)
26
29
  ActiveSupport::JSON.decode(params)
@@ -78,7 +81,7 @@ class Veritrans
78
81
  default_options = config.http_options || {}
79
82
 
80
83
  # Add authentication and content type
81
- # Docs http://docs.veritrans.co.id/sandbox/introduction.html
84
+ # Docs https://api-docs.midtrans.com/#http-s-header
82
85
  request_options = {
83
86
  :path => URI.parse(url).path,
84
87
  :headers => {
@@ -99,7 +102,7 @@ class Veritrans
99
102
  read_timeout: 120,
100
103
  write_timeout: 120,
101
104
  connect_timeout: 120
102
- }.deep_merge(default_options)
105
+ }.merge(default_options)
103
106
 
104
107
  s_time = Time.now
105
108
  request = Excon.new(url, connection_options)
@@ -111,7 +114,7 @@ class Veritrans
111
114
  Result.new(response, url, request_options, Time.now - s_time)
112
115
 
113
116
  rescue Excon::Errors::SocketError => error
114
- logger.info "Veritrans: socket error, can not connect"
117
+ logger.info "Veritrans: socket error, can not connect (#{error.message})"
115
118
  error_response = Excon::Response.new(
116
119
  body: '{"status_code": "500", "status_message": "Internal server error, no response from backend. Try again later"}',
117
120
  status: '500'
@@ -7,7 +7,7 @@ class Veritrans
7
7
  class Config
8
8
 
9
9
  def initialize(options = nil)
10
- @api_host = "https://api.sandbox.veritrans.co.id"
10
+ @api_host = "https://api.sandbox.midtrans.com"
11
11
  apply(options) if options
12
12
  end
13
13
 
@@ -41,9 +41,9 @@ class Veritrans
41
41
  ##
42
42
  # API Server hostname, this allow to switch between production and sandbox
43
43
  #
44
- # Should be "https://api.sandbox.veritrans.co.id" or "https://api.veritrans.co.id"
44
+ # Should be "https://api.sandbox.midtrans.com" or "https://api.midtrans.com"
45
45
  #
46
- # Default is "https://api.sandbox.veritrans.co.id"
46
+ # Default is "https://api.sandbox.midtrans.com"
47
47
  #
48
48
  def api_host=(value)
49
49
  @api_host = value
@@ -93,6 +93,8 @@ class Veritrans
93
93
  #
94
94
  # Veritrans.setup do
95
95
  # config.load_yml "#{Rails.root.to_s}/config/veritrans.yml#development"
96
+ # # or
97
+ # config.load_yml "#{Rails.root.to_s}/config/veritrans.yml", :development
96
98
  # end
97
99
  #
98
100
  def load_config(filename, yml_section = nil)
@@ -1,41 +1,45 @@
1
- # Rack based event notification callback processor
2
- #
3
- # Usage:
4
- #
5
- # Rails.application.routes.draw do
6
- # ...
7
- # mount Veritrans::Events.new => '/vt_events'
8
- # end
9
- #
10
- # Veritrans.events.subscribe('payment.success') do |payment|
11
- # payment.mark_paid!(payment.masked_card)
12
- # end
13
- #
14
-
15
- # All possible events:
16
- #
17
- # * payment.success == ['authorize', 'capture', 'settlement']
18
- # * payment.failed == ['deny', 'cancel', 'expire']
19
- # * payment.challenge # when payment.fraud_status == 'challenge'
20
- #
21
- # * payment.authorize
22
- # * payment.capture
23
- # * payment.settlement
24
- # * payment.deny
25
- # * payment.cancel
26
- # * payment.expire
27
- #
28
- # * error
29
-
30
- # For sinatra you can use Rack::URLMap
31
- #
32
- # run Rack::URLMap.new("/" => MyApp.new, "/payment_events" => Veritrans::Events.new)
33
- #
34
-
35
1
  class Veritrans
2
+ #
3
+ # Rack based event notification callback processor
4
+ #
5
+ # Usage:
6
+ #
7
+ # Rails.application.routes.draw do
8
+ # # ...
9
+ # mount Veritrans::Events.new => '/vt_events'
10
+ # end
11
+ #
12
+ # Veritrans::Events.subscribe('payment.success') do |payment|
13
+ # payment.mark_paid!(payment.masked_card)
14
+ # end
15
+ #
16
+ #
17
+ # All possible events:
18
+ #
19
+ # * payment.success == ['authorize', 'capture', 'settlement']
20
+ # * payment.failed == ['deny', 'cancel', 'expire']
21
+ # * payment.challenge # when payment.fraud_status == 'challenge'
22
+ #
23
+ # * payment.authorize
24
+ # * payment.capture
25
+ # * payment.settlement
26
+ # * payment.deny
27
+ # * payment.cancel
28
+ # * payment.expire
29
+ #
30
+ # * error
31
+ #
32
+ # For sinatra you can use Rack::URLMap
33
+ #
34
+ # run Rack::URLMap.new("/" => MyApp.new, "/payment_events" => Veritrans::Events.new)
35
+ #
36
36
  class Events
37
37
 
38
38
  # This is rack application
39
+ # Can be used as:
40
+ #
41
+ # use Veritrans::Events.new
42
+ #
39
43
  def call(env)
40
44
  Veritrans.logger.info "Receive notification callback"
41
45
 
@@ -92,7 +96,7 @@ class Veritrans
92
96
  return send_text("Server error:\n#{error.message}", 500)
93
97
  end
94
98
 
95
- def send_text(body, status = 200)
99
+ def send_text(body, status = 200) # :nodoc:
96
100
  [status, {"Content-Type" => "text/html"}, [body]]
97
101
  end
98
102
 
@@ -101,6 +105,12 @@ class Veritrans
101
105
  class << self
102
106
  attr_accessor :listeners
103
107
 
108
+ # Subscribe for events. The event object will be an instance of Midtrans::Result
109
+ #
110
+ # Midtrans::Events.subscribe('payment.success') do |payment_status|
111
+ # Order.find_by(order_id: payment_status.order_id).mark_paid!
112
+ # end
113
+ #
104
114
  def subscribe(*event_types, &handler)
105
115
  @listeners ||= []
106
116
  event_types.each do |event_type|
@@ -108,6 +118,7 @@ class Veritrans
108
118
  end
109
119
  end
110
120
 
121
+ # Used internally to dispatch event
111
122
  def dispatch(new_event, event_data)
112
123
  @listeners.each do |pair|
113
124
  event_type, handler = *pair