veritrans 2.1.3 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +6 -1
- data/.travis.yml +3 -5
- data/CHANGELOG.md +20 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +89 -94
- data/Procfile +1 -1
- data/README.md +62 -13
- data/api_reference.md +10 -10
- data/example/rails/cable/Gemfile +48 -0
- data/example/rails/cable/Gemfile.lock +184 -0
- data/example/rails/cable/README.md +29 -0
- data/example/rails/cable/Rakefile +6 -0
- data/example/rails/cable/app/assets/config/manifest.js +3 -0
- data/example/rails/cable/app/assets/images/.keep +0 -0
- data/example/rails/cable/app/assets/javascripts/application.js +15 -0
- data/example/rails/cable/app/assets/javascripts/cable.js +13 -0
- data/example/rails/cable/app/assets/javascripts/channels/.keep +0 -0
- data/example/rails/cable/app/assets/javascripts/chats.js +39 -0
- data/example/rails/cable/app/assets/javascripts/rooms.js +55 -0
- data/example/rails/cable/app/assets/stylesheets/application.css +16 -0
- data/example/rails/cable/app/assets/stylesheets/chatbox.scss +31 -0
- data/example/rails/cable/app/assets/stylesheets/peoplebox.scss +6 -0
- data/example/rails/cable/app/channels/application_cable/channel.rb +4 -0
- data/example/rails/cable/app/channels/application_cable/connection.rb +4 -0
- data/example/rails/cable/app/channels/rooms_texting_channel.rb +13 -0
- data/example/rails/cable/app/controllers/application_controller.rb +3 -0
- data/example/rails/cable/app/controllers/chats_controller.rb +18 -0
- data/example/rails/cable/app/controllers/concerns/.keep +0 -0
- data/example/rails/cable/app/controllers/pays_controller.rb +28 -0
- data/example/rails/cable/app/controllers/rooms_controller.rb +4 -0
- data/example/rails/cable/app/helpers/application_helper.rb +2 -0
- data/example/rails/cable/app/helpers/chats_helper.rb +2 -0
- data/example/rails/cable/app/helpers/rooms_helper.rb +5 -0
- data/example/rails/cable/app/jobs/application_job.rb +2 -0
- data/example/rails/cable/app/jobs/chat_broadcaster_job.rb +15 -0
- data/example/rails/cable/app/mailers/application_mailer.rb +4 -0
- data/example/rails/cable/app/models/application_record.rb +3 -0
- data/example/rails/cable/app/models/chat.rb +41 -0
- data/example/rails/cable/app/models/concerns/.keep +0 -0
- data/example/rails/cable/app/models/order.rb +2 -0
- data/example/rails/cable/app/models/user.rb +2 -0
- data/example/rails/cable/app/views/chats/_chat.html.erb +18 -0
- data/example/rails/cable/app/views/layouts/application.html.erb +19 -0
- data/example/rails/cable/app/views/layouts/mailer.html.erb +13 -0
- data/example/rails/cable/app/views/layouts/mailer.text.erb +1 -0
- data/example/rails/cable/app/views/rooms/_chatbox.html.erb +13 -0
- data/example/rails/cable/app/views/rooms/_online_people.html.erb +53 -0
- data/example/rails/cable/app/views/rooms/index.html.erb +9 -0
- data/example/rails/cable/bin/bundle +3 -0
- data/example/rails/cable/bin/rails +9 -0
- data/example/rails/cable/bin/rake +9 -0
- data/example/rails/cable/bin/setup +34 -0
- data/example/rails/cable/bin/spring +16 -0
- data/example/rails/cable/bin/update +29 -0
- data/example/rails/cable/config.ru +5 -0
- data/example/rails/cable/config/application.rb +16 -0
- data/example/rails/cable/config/boot.rb +3 -0
- data/example/rails/cable/config/cable.yml +9 -0
- data/example/rails/cable/config/database.yml +20 -0
- data/example/rails/cable/config/environment.rb +5 -0
- data/example/rails/cable/config/environments/development.rb +57 -0
- data/example/rails/cable/config/environments/production.rb +86 -0
- data/example/rails/cable/config/environments/test.rb +42 -0
- data/example/rails/cable/config/initializers/application_controller_renderer.rb +6 -0
- data/example/rails/cable/config/initializers/assets.rb +11 -0
- data/example/rails/cable/config/initializers/backtrace_silencers.rb +7 -0
- data/example/rails/cable/config/initializers/cookies_serializer.rb +5 -0
- data/example/rails/cable/config/initializers/filter_parameter_logging.rb +4 -0
- data/example/rails/cable/config/initializers/inflections.rb +16 -0
- data/example/rails/cable/config/initializers/mime_types.rb +4 -0
- data/example/rails/cable/config/initializers/new_framework_defaults.rb +24 -0
- data/example/rails/cable/config/initializers/session_store.rb +3 -0
- data/example/rails/cable/config/initializers/sidekiq.rb +2 -0
- data/example/rails/cable/config/initializers/veritrans.rb +46 -0
- data/example/rails/cable/config/initializers/wrap_parameters.rb +14 -0
- data/example/rails/cable/config/locales/en.yml +23 -0
- data/example/rails/cable/config/puma.rb +47 -0
- data/example/rails/cable/config/routes.rb +18 -0
- data/example/rails/cable/config/secrets.yml +22 -0
- data/example/rails/cable/config/spring.rb +6 -0
- data/example/rails/cable/config/veritrans.yml +13 -0
- data/example/rails/cable/db/development.sqlite3 +0 -0
- data/example/rails/cable/db/migrate/20161215070044_create_chats.rb +10 -0
- data/example/rails/cable/db/migrate/20161215072021_create_users.rb +10 -0
- data/example/rails/cable/db/migrate/20161219110219_create_orders.rb +11 -0
- data/example/rails/cable/db/schema.rb +37 -0
- data/example/rails/cable/db/seeds.rb +41 -0
- data/example/rails/cable/db/test.sqlite3 +0 -0
- data/example/rails/cable/lib/assets/.keep +0 -0
- data/example/rails/cable/lib/tasks/.keep +0 -0
- data/example/rails/cable/public/404.html +67 -0
- data/example/rails/cable/public/422.html +67 -0
- data/example/rails/cable/public/500.html +66 -0
- data/example/rails/cable/public/apple-touch-icon-precomposed.png +0 -0
- data/example/rails/cable/public/apple-touch-icon.png +0 -0
- data/example/rails/cable/public/favicon.ico +0 -0
- data/example/rails/cable/public/images/avatar1.jpg +0 -0
- data/example/rails/cable/public/images/avatar2.jpg +0 -0
- data/example/rails/cable/public/images/avatar3.jpg +0 -0
- data/example/rails/cable/public/images/avatar4.jpg +0 -0
- data/example/rails/cable/public/images/avatar5.jpg +0 -0
- data/example/rails/cable/public/images/avatar6.jpg +0 -0
- data/example/rails/cable/public/robots.txt +5 -0
- data/example/rails/cable/vendor/assets/javascripts/.keep +0 -0
- data/example/rails/cable/vendor/assets/stylesheets/.keep +0 -0
- data/example/rails/cable/vendor/assets/stylesheets/photon.css +2333 -0
- data/example/rails/simplepay/Gemfile +54 -0
- data/example/rails/simplepay/Gemfile.lock +178 -0
- data/example/rails/simplepay/README.md +30 -0
- data/example/rails/simplepay/Rakefile +6 -0
- data/example/rails/simplepay/app/assets/config/manifest.js +3 -0
- data/example/rails/simplepay/app/assets/images/.keep +0 -0
- data/example/rails/simplepay/app/assets/javascripts/application.js +16 -0
- data/example/rails/simplepay/app/assets/javascripts/cable.js +13 -0
- data/example/rails/simplepay/app/assets/javascripts/channels/.keep +0 -0
- data/example/rails/simplepay/app/assets/javascripts/pay.js +18 -0
- data/example/rails/simplepay/app/assets/stylesheets/application.css +15 -0
- data/example/rails/simplepay/app/assets/stylesheets/style.css +254 -0
- data/example/rails/simplepay/app/channels/application_cable/channel.rb +4 -0
- data/example/rails/simplepay/app/channels/application_cable/connection.rb +4 -0
- data/example/rails/simplepay/app/controllers/application_controller.rb +3 -0
- data/example/rails/simplepay/app/controllers/concerns/.keep +0 -0
- data/example/rails/simplepay/app/controllers/home_controller.rb +16 -0
- data/example/rails/simplepay/app/controllers/pay_controller.rb +10 -0
- data/example/rails/simplepay/app/helpers/application_helper.rb +2 -0
- data/example/rails/simplepay/app/helpers/pay_helper.rb +2 -0
- data/example/rails/simplepay/app/jobs/application_job.rb +2 -0
- data/example/rails/simplepay/app/mailers/application_mailer.rb +4 -0
- data/example/rails/simplepay/app/models/application_record.rb +3 -0
- data/example/rails/simplepay/app/models/concerns/.keep +0 -0
- data/example/rails/simplepay/app/models/order.rb +2 -0
- data/example/rails/simplepay/app/views/home/index.html.erb +19 -0
- data/example/rails/simplepay/app/views/layouts/application.html.erb +15 -0
- data/example/rails/simplepay/app/views/layouts/mailer.html.erb +13 -0
- data/example/rails/simplepay/app/views/layouts/mailer.text.erb +1 -0
- data/example/rails/simplepay/app/views/pay/notify.html.erb +2 -0
- data/example/rails/simplepay/bin/bundle +3 -0
- data/example/rails/simplepay/bin/rails +9 -0
- data/example/rails/simplepay/bin/rake +9 -0
- data/example/rails/simplepay/bin/setup +34 -0
- data/example/rails/simplepay/bin/spring +16 -0
- data/example/rails/simplepay/bin/update +29 -0
- data/example/rails/simplepay/config.ru +5 -0
- data/example/rails/simplepay/config/application.rb +15 -0
- data/example/rails/simplepay/config/boot.rb +3 -0
- data/example/rails/simplepay/config/cable.yml +9 -0
- data/example/rails/simplepay/config/database.yml +25 -0
- data/example/rails/simplepay/config/environment.rb +5 -0
- data/example/rails/simplepay/config/environments/development.rb +57 -0
- data/example/rails/simplepay/config/environments/production.rb +86 -0
- data/example/rails/simplepay/config/environments/test.rb +42 -0
- data/example/rails/simplepay/config/initializers/application_controller_renderer.rb +6 -0
- data/example/rails/simplepay/config/initializers/assets.rb +11 -0
- data/example/rails/simplepay/config/initializers/backtrace_silencers.rb +7 -0
- data/example/rails/simplepay/config/initializers/cookies_serializer.rb +5 -0
- data/example/rails/simplepay/config/initializers/filter_parameter_logging.rb +4 -0
- data/example/rails/simplepay/config/initializers/inflections.rb +16 -0
- data/example/rails/simplepay/config/initializers/mime_types.rb +4 -0
- data/example/rails/simplepay/config/initializers/new_framework_defaults.rb +24 -0
- data/example/rails/simplepay/config/initializers/session_store.rb +3 -0
- data/example/rails/simplepay/config/initializers/veritrans.rb +46 -0
- data/example/rails/simplepay/config/initializers/wrap_parameters.rb +14 -0
- data/example/rails/simplepay/config/locales/en.yml +23 -0
- data/example/rails/simplepay/config/puma.rb +47 -0
- data/example/rails/simplepay/config/routes.rb +5 -0
- data/example/rails/simplepay/config/secrets.yml +22 -0
- data/example/rails/simplepay/config/spring.rb +6 -0
- data/example/rails/simplepay/config/veritrans.yml +18 -0
- data/example/rails/simplepay/db/development.sqlite3 +0 -0
- data/example/rails/simplepay/db/migrate/20161221090855_create_orders.rb +10 -0
- data/example/rails/simplepay/db/schema.rb +22 -0
- data/example/rails/simplepay/db/seeds.rb +7 -0
- data/example/rails/simplepay/db/test.sqlite3 +0 -0
- data/example/rails/simplepay/lib/assets/.keep +0 -0
- data/example/rails/simplepay/lib/tasks/.keep +0 -0
- data/example/rails/simplepay/public/404.html +67 -0
- data/example/rails/simplepay/public/422.html +67 -0
- data/example/rails/simplepay/public/500.html +66 -0
- data/example/rails/simplepay/public/apple-touch-icon-precomposed.png +0 -0
- data/example/rails/simplepay/public/apple-touch-icon.png +0 -0
- data/example/rails/simplepay/public/favicon.ico +0 -0
- data/example/rails/simplepay/public/robots.txt +5 -0
- data/example/rails/simplepay/vendor/assets/javascripts/.keep +0 -0
- data/example/rails/simplepay/vendor/assets/stylesheets/.keep +0 -0
- data/example/{README.md → sinatra/README.md} +0 -0
- data/example/{config.ru → sinatra/config.ru} +3 -0
- data/example/{index.erb → sinatra/index.erb} +7 -6
- data/example/{localization.erb → sinatra/localization.erb} +6 -5
- data/example/{points.erb → sinatra/points.erb} +6 -5
- data/example/{recurring.erb → sinatra/recurring.erb} +6 -6
- data/example/{response.erb → sinatra/response.erb} +4 -1
- data/example/{sinatra.rb → sinatra/sinatra.rb} +9 -3
- data/example/{style.css → sinatra/style.css} +11 -0
- data/example/{veritrans.yml → sinatra/veritrans.yml} +2 -2
- data/example/{widget.erb → sinatra/widget.erb} +18 -6
- data/lib/generators/templates/assets/credit_card_form.js +6 -0
- data/lib/generators/templates/payments_controller.rb +4 -4
- data/lib/generators/templates/veritrans.yml +5 -5
- data/lib/generators/templates/views/_credit_card_form.erb +2 -2
- data/lib/generators/templates/views/_veritrans_include.erb +1 -1
- data/lib/generators/veritrans/install_generator.rb +1 -1
- data/lib/generators/veritrans/payment_form_generator.rb +1 -1
- data/lib/veritrans.rb +106 -5
- data/lib/veritrans/api.rb +7 -7
- data/lib/veritrans/cli.rb +11 -5
- data/lib/veritrans/client.rb +7 -4
- data/lib/veritrans/config.rb +5 -3
- data/lib/veritrans/events.rb +46 -35
- data/lib/veritrans/result.rb +58 -2
- data/lib/veritrans/testing.rb +156 -0
- data/lib/veritrans/version.rb +1 -1
- data/spec/cli_spec.rb +2 -2
- data/spec/fixtures/approve_failed.yml +1 -1
- data/spec/fixtures/cancel_failed.yml +1 -1
- data/spec/fixtures/cancel_success.yml +2 -2
- data/spec/fixtures/capture_failed.yml +1 -1
- data/spec/fixtures/charge.yml +2 -2
- data/spec/fixtures/charge_direct.yml +1 -1
- data/spec/fixtures/charge_vtweb.yml +2 -2
- data/spec/fixtures/cli_test_1111-not-exists.yml +1 -1
- data/spec/fixtures/cli_test_not_exists.yml +1 -1
- data/spec/fixtures/cli_test_real_txn.yml +1 -1
- data/spec/fixtures/cli_test_unauthorized.yml +1 -1
- data/spec/fixtures/events_test_real_txn.yml +1 -1
- data/spec/fixtures/expire_failed.yml +1 -1
- data/spec/fixtures/expire_success.yml +1 -1
- data/spec/fixtures/midtrans_status.yml +2 -2
- data/spec/fixtures/status_fail.yml +1 -1
- data/spec/fixtures/status_success.yml +2 -2
- data/spec/rails_plugin_spec.rb +37 -20
- data/spec/spec_helper.rb +0 -1
- data/spec/veritrans_client_spec.rb +1 -1
- data/spec/veritrans_config_spec.rb +1 -1
- data/spec/veritrans_events_spec.rb +6 -6
- data/spec/veritrans_testing_spec.rb +184 -0
- data/testing_webhooks.md +2 -2
- data/veritrans.gemspec +1 -1
- metadata +195 -16
- 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
|
-
|
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
|
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
|
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://
|
3
|
+
# https://dashboard.sandbox.midtrans.com/settings/config_info
|
4
4
|
client_key: ""
|
5
5
|
server_key: ""
|
6
|
-
api_host: https://api.sandbox.
|
6
|
+
api_host: https://api.sandbox.midtrans.com
|
7
7
|
|
8
8
|
production:
|
9
9
|
# Register and get your keys here:
|
10
|
-
# https://
|
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.
|
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.
|
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="
|
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 /
|
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/
|
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";
|
data/lib/veritrans.rb
CHANGED
@@ -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
|
-
#
|
65
|
-
#
|
66
|
-
#
|
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
|
data/lib/veritrans/api.rb
CHANGED
@@ -5,9 +5,8 @@ require 'uri'
|
|
5
5
|
class Veritrans
|
6
6
|
module Api
|
7
7
|
|
8
|
-
# POST /v2/charge { payment_type: "
|
9
|
-
# Docs
|
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
|
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
|
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
|
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
|
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})"
|
data/lib/veritrans/cli.rb
CHANGED
@@ -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
|
123
|
-
data = 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
|
data/lib/veritrans/client.rb
CHANGED
@@ -7,7 +7,8 @@ require 'excon'
|
|
7
7
|
class Veritrans
|
8
8
|
module Client
|
9
9
|
|
10
|
-
#
|
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
|
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
|
-
}.
|
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'
|
data/lib/veritrans/config.rb
CHANGED
@@ -7,7 +7,7 @@ class Veritrans
|
|
7
7
|
class Config
|
8
8
|
|
9
9
|
def initialize(options = nil)
|
10
|
-
@api_host = "https://api.sandbox.
|
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.
|
44
|
+
# Should be "https://api.sandbox.midtrans.com" or "https://api.midtrans.com"
|
45
45
|
#
|
46
|
-
# Default is "https://api.sandbox.
|
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)
|
data/lib/veritrans/events.rb
CHANGED
@@ -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
|