veritrans 1.2.6 → 2.0.0beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +111 -0
- data/README.md +258 -0
- data/Rakefile +7 -0
- data/api_reference.md +219 -0
- data/bin/veritrans +59 -48
- data/example/index.erb +118 -0
- data/example/response.erb +28 -0
- data/example/sinatra.rb +76 -0
- data/example/style.css +45 -0
- data/example/veritrans.yml +12 -0
- data/lib/generators/templates/assets/credit_card_form.js +50 -0
- data/lib/generators/templates/payments_controller.rb +81 -0
- data/lib/generators/templates/veritrans.rb +43 -0
- data/lib/generators/templates/veritrans.yml +13 -0
- data/lib/generators/templates/views/_credit_card_form.erb +42 -0
- data/lib/generators/templates/views/_veritrans_include.erb +10 -0
- data/lib/generators/templates/views/payments/create.erb +15 -0
- data/lib/generators/templates/views/payments/new.erb +6 -0
- data/lib/generators/veritrans/install_generator.rb +32 -0
- data/lib/generators/veritrans/payment_form_generator.rb +45 -0
- data/lib/veritrans/api.rb +90 -0
- data/lib/veritrans/cli.rb +166 -0
- data/lib/veritrans/client.rb +77 -209
- data/lib/veritrans/config.rb +48 -62
- data/lib/veritrans/events.rb +125 -0
- data/lib/veritrans/result.rb +81 -0
- data/lib/veritrans/version.rb +1 -41
- data/lib/veritrans.rb +79 -15
- data/license.txt +202 -0
- data/spec/cli_spec.rb +86 -0
- data/spec/configs/veritrans.yml +7 -0
- data/spec/configs/veritrans_flat.yml +2 -0
- data/spec/fixtures/approve_failed.yml +48 -0
- data/spec/fixtures/cancel_failed.yml +48 -0
- data/spec/fixtures/cancel_success.yml +106 -0
- data/spec/fixtures/capture_failed.yml +48 -0
- data/spec/fixtures/charge.yml +50 -0
- data/spec/fixtures/charge_direct.yml +56 -0
- data/spec/fixtures/charge_vtweb.yml +50 -0
- data/spec/fixtures/cli_test_1111-not-exists.yml +45 -0
- data/spec/fixtures/cli_test_not_exists.yml +45 -0
- data/spec/fixtures/cli_test_real_txn.yml +55 -0
- data/spec/fixtures/cli_test_unauthorized.yml +47 -0
- data/spec/fixtures/events_test_real_txn.yml +55 -0
- data/spec/fixtures/status_fail.yml +46 -0
- data/spec/fixtures/status_success.yml +109 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/veritrans_client_spec.rb +83 -0
- data/spec/veritrans_config_spec.rb +48 -0
- data/spec/veritrans_events_spec.rb +70 -0
- data/spec/veritrans_logger_spec.rb +46 -0
- data/testing_webhooks.md +80 -0
- data/veritrans.gemspec +23 -0
- metadata +82 -31
- data/config/veritrans.yml +0 -24
- data/lib/generators/install_generator.rb +0 -78
- data/lib/generators/templates/app/controllers/vtlink/merchant_controller.rb +0 -7
- data/lib/generators/templates/app/controllers/vtlink/veritrans_controller.rb +0 -112
- data/lib/generators/templates/app/views/layouts/layout_auto_post.html.erb +0 -15
- data/lib/generators/templates/app/views/vtlink/merchant/checkout.html.erb +0 -43
- data/lib/generators/templates/app/views/vtlink/veritrans/cancel.html.erb +0 -2
- data/lib/generators/templates/app/views/vtlink/veritrans/confirm.html.erb +0 -13
- data/lib/generators/templates/app/views/vtlink/veritrans/error.html.erb +0 -2
- data/lib/generators/templates/app/views/vtlink/veritrans/finish.html.erb +0 -2
- data/lib/generators/templates/app/views/vtlink/veritrans/pay.html.erb +0 -2
- data/lib/generators/templates/config/veritrans.yml +0 -13
- data/lib/veritrans/hash_generator.rb +0 -19
- data/lib/veritrans/post_data.rb +0 -163
- data/lib/veritrans/v_t_direct.rb +0 -145
data/bin/veritrans
CHANGED
@@ -1,57 +1,68 @@
|
|
1
|
-
|
2
|
-
File.join(File.dirname(__FILE__),%w[.. lib veritrans]))
|
3
|
-
wpath= File.dirname(__FILE__).gsub(/bin$/,'')
|
1
|
+
#!/usr/bin/env ruby
|
4
2
|
|
5
|
-
|
6
|
-
puts <<END
|
3
|
+
$:.push(File.expand_path("../../lib", __FILE__))
|
7
4
|
|
8
|
-
|
9
|
-
|
10
|
-
syntax:
|
11
|
-
veritrans -irb
|
5
|
+
require 'optparse'
|
6
|
+
require "veritrans/version"
|
12
7
|
|
13
|
-
|
14
|
-
veritrans -irb #=> Start IRB
|
8
|
+
OPERATIONS = %w(testhook)
|
15
9
|
|
16
|
-
|
17
|
-
|
10
|
+
CONFIG = {}
|
11
|
+
option_parser = OptionParser.new do |opts|
|
12
|
+
opts.banner = "Veritrans #{Veritrans::VERSION}"
|
13
|
+
"Usage: veritrans testhook [options] {url}\n" +
|
14
|
+
" -o specify order id"
|
18
15
|
|
19
|
-
|
16
|
+
opts.on("-h", "--help", "Show help") do
|
17
|
+
puts option_parser.help
|
18
|
+
exit
|
19
|
+
end
|
20
|
+
|
21
|
+
opts.on("-o [ORDER_ID]", "--order [ORDER_ID]", "Select order") do |order|
|
22
|
+
CONFIG[:order] = order
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on("-c [PATH]", "--config [PATH]", "Path to config (defualt .)") do |config|
|
26
|
+
CONFIG[:config_path] = config
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.separator <<-EOS
|
30
|
+
|
31
|
+
Supported commands:
|
32
|
+
|
33
|
+
testhook [url] Send testing webhook to specified url
|
34
|
+
|
35
|
+
Example:
|
36
|
+
veritrans testhook http://localhost:3000/vt_events
|
37
|
+
veritrans testhook -o my-order-1 -c ~/path/to/veritrans.yml http://localhost:3000/vt_events
|
38
|
+
|
39
|
+
EOS
|
20
40
|
|
21
|
-
arg = ARGV
|
22
|
-
if arg.size==0
|
23
|
-
howto_veritrans
|
24
|
-
exit
|
25
41
|
end
|
26
42
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
require 'veritrans'
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
client.get_keys
|
53
|
-
client
|
54
|
-
EOF
|
55
|
-
|
56
|
-
IRB.start
|
43
|
+
option_parser.parse!
|
44
|
+
|
45
|
+
op = ARGV.shift
|
46
|
+
|
47
|
+
if OPERATIONS.include?(op)
|
48
|
+
require 'veritrans'
|
49
|
+
require 'veritrans/cli'
|
50
|
+
|
51
|
+
begin
|
52
|
+
case op
|
53
|
+
when "testhook" then
|
54
|
+
Veritrans::CLI.test_webhook(ARGV)
|
55
|
+
end
|
56
|
+
|
57
|
+
rescue Veritrans::CLI::OrderNotFound, Veritrans::CLI::AuthenticationError => ex
|
58
|
+
puts ex.message
|
59
|
+
rescue ArgumentError => ex
|
60
|
+
puts ex.message
|
61
|
+
rescue Exception => e
|
62
|
+
puts "Uh oh, I didn't expect this:"
|
63
|
+
puts e.message
|
64
|
+
puts e.backtrace.join("\n")
|
65
|
+
end
|
66
|
+
else
|
67
|
+
puts option_parser.help
|
57
68
|
end
|
data/example/index.erb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
<link rel="stylesheet" href="/style.css">
|
2
|
+
|
3
|
+
<header>
|
4
|
+
<h3>Veritrans sinatra app</h3>
|
5
|
+
</header>
|
6
|
+
|
7
|
+
<section>
|
8
|
+
<p>
|
9
|
+
Charge request VT-Web <a href="/charge_vtweb">click to see payment page</a>
|
10
|
+
</p>
|
11
|
+
</section>
|
12
|
+
|
13
|
+
<section>
|
14
|
+
<p>
|
15
|
+
Charge request VT-Direct
|
16
|
+
</p>
|
17
|
+
|
18
|
+
<form action="/charge_vtdirect" method="post" id="card_form">
|
19
|
+
<input type="hidden" name="token_id" id="card_token">
|
20
|
+
<fieldset>
|
21
|
+
<legend>Credit card</legend>
|
22
|
+
<p>
|
23
|
+
<label for="gross_amount">Amount, Rp.</label>
|
24
|
+
<input type="text" name="gross_amount" id="gross_amount" value="30000">
|
25
|
+
</p>
|
26
|
+
<p>
|
27
|
+
<label for="card_number">Card number</label>
|
28
|
+
<input type="text" id="card_number" style="width: 150px" value="4811 1111 1111 1114">
|
29
|
+
<br>
|
30
|
+
<small style="margin-left: 100px" class="card-numbers">
|
31
|
+
<a onclick="$('#card_number').val('4811 1111 1111 1114')">success Visa</a>
|
32
|
+
<a onclick="$('#card_number').val('5810 1111 1111 1112')">success MasterCard</a>
|
33
|
+
<a onclick="$('#card_number').val('4511 1111 1111 1117')">challenge</a>
|
34
|
+
<a onclick="$('#card_number').val('4611 1111 1111 1116')">Deny by FDS</a>
|
35
|
+
<a onclick="$('#card_number').val('4911 1111 1111 1113')">Deny by bank</a>
|
36
|
+
<a href="http://docs.veritrans.co.id/sandbox/card_list.html" target="_blank">documentation</a>
|
37
|
+
</small>
|
38
|
+
</p>
|
39
|
+
<p>
|
40
|
+
<label for="card_cvc">Security Code</label>
|
41
|
+
<input type="text" id="card_cvc" style="width: 30px" placeholder="cvc" value="123">
|
42
|
+
</p>
|
43
|
+
<p>
|
44
|
+
<label for="card_exp">Expiration date</label>
|
45
|
+
<input type="text" id="card_exp" placeholder="MM / YY" value="12 / 16">
|
46
|
+
</p>
|
47
|
+
|
48
|
+
<p>
|
49
|
+
<label for="card_secure">3D-secure</label>
|
50
|
+
<input type="checkbox" id="card_secure">
|
51
|
+
</p>
|
52
|
+
|
53
|
+
</fieldset>
|
54
|
+
|
55
|
+
<input id="submit_btn" type="submit">
|
56
|
+
</form>
|
57
|
+
</section>
|
58
|
+
|
59
|
+
<script src="//api.sandbox.veritrans.co.id/v2/assets/veritrans.js"></script>
|
60
|
+
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
|
61
|
+
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery.payment/1.0.2/jquery.payment.js"></script>
|
62
|
+
<script src="//cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/0.9.9/jquery.magnific-popup.min.js"></script>
|
63
|
+
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/0.9.9/magnific-popup.css">
|
64
|
+
|
65
|
+
<script type="text/javascript">
|
66
|
+
// set Veritrans settings
|
67
|
+
Veritrans.url = "<%= Veritrans.config.api_host %>/v2/token";
|
68
|
+
Veritrans.client_key = "<%= Veritrans.config.client_key %>";
|
69
|
+
|
70
|
+
function createTokenData() {
|
71
|
+
return {
|
72
|
+
// Optional params:
|
73
|
+
// secure: true
|
74
|
+
// bank: 'MANDIRI'
|
75
|
+
|
76
|
+
card_number: $('#card_number').val(),
|
77
|
+
card_cvv: $('#card_cvc').val(),
|
78
|
+
card_exp_month: $('#card_exp').val().match(/(\d+) \//)[1],
|
79
|
+
card_exp_year: '20' + $('#card_exp').val().match(/\/ (\d+)/)[1],
|
80
|
+
gross_amount: $('#gross_amount').val(),
|
81
|
+
secure: $('#card_secure')[0].checked
|
82
|
+
};
|
83
|
+
}
|
84
|
+
|
85
|
+
$(document).ready(function () {
|
86
|
+
$('#card_number').payment('formatCardNumber');
|
87
|
+
$('#card_cvc').payment('formatCardCVC');
|
88
|
+
$('#card_exp').payment('formatCardExpiry');
|
89
|
+
|
90
|
+
$('#card_form').on('submit', function (event) {
|
91
|
+
var form = this;
|
92
|
+
$('#submit_btn').attr('disabled', true).val("Processing ...");
|
93
|
+
event.preventDefault();
|
94
|
+
|
95
|
+
Veritrans.token(createTokenData, function (data) {
|
96
|
+
console.log('Token data:', data);
|
97
|
+
// if we get url then it's 3d-secure transaction
|
98
|
+
// so we need to open that page
|
99
|
+
// this callback function will be called again after user confirm 3d-secure
|
100
|
+
// you can also redirect on server side
|
101
|
+
if (data.redirect_url) {
|
102
|
+
$.magnificPopup.open({
|
103
|
+
items: { type: 'iframe', src: data.redirect_url }
|
104
|
+
});
|
105
|
+
$.magnificPopup.instance.content.find('iframe').height(590);
|
106
|
+
// if no redirect_url and we have token_id then just make charge request
|
107
|
+
} else if (data.token_id) {
|
108
|
+
$('#card_token').val(data.token_id);
|
109
|
+
form.submit();
|
110
|
+
// if no redirect_url and no token_id, then it should be error
|
111
|
+
} else {
|
112
|
+
alert(data.validation_messages ? data.validation_messages.join("\n") : data.status_message);
|
113
|
+
$('#submit_btn').removeAttr('disabled').removeAttr("value");
|
114
|
+
}
|
115
|
+
});
|
116
|
+
});
|
117
|
+
});
|
118
|
+
</script>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<link rel="stylesheet" href="/style.css">
|
2
|
+
|
3
|
+
<header>
|
4
|
+
<h3>Veritrans sinatra app</h3>
|
5
|
+
</header>
|
6
|
+
|
7
|
+
<% if @result.redirect_url %>
|
8
|
+
<section>
|
9
|
+
<p>Here's redirect url <a href='<%= @result.redirect_url %>'><%= @result.redirect_url %></a> </p>
|
10
|
+
</section>
|
11
|
+
<% end %>
|
12
|
+
|
13
|
+
<section>
|
14
|
+
<strong>
|
15
|
+
Veritrans response:
|
16
|
+
<% if @result.success? %>
|
17
|
+
<span style="color: green">success</span>
|
18
|
+
<% end %>
|
19
|
+
</strong>
|
20
|
+
|
21
|
+
<code>
|
22
|
+
<pre>
|
23
|
+
<%= @result.response.body %>
|
24
|
+
</pre>
|
25
|
+
</code>
|
26
|
+
|
27
|
+
<a href="/">Go back</a>
|
28
|
+
</section>
|
data/example/sinatra.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
$:.push(File.expand_path("../../lib", __FILE__))
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
require 'veritrans'
|
6
|
+
require 'sinatra'
|
7
|
+
|
8
|
+
Veritrans.setup do
|
9
|
+
config.load_yml "./veritrans.yml#development"
|
10
|
+
|
11
|
+
# config.server_key = "..."
|
12
|
+
# config.client_key = "..."
|
13
|
+
# config.api_host = "https://api.sandbox.veritrans.co.id" (default)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Veritrans.config.server_key
|
17
|
+
# Veritrans.config.client_key
|
18
|
+
# Veritrans.config.api_host
|
19
|
+
|
20
|
+
set :public_folder, "."
|
21
|
+
set :views, "."
|
22
|
+
|
23
|
+
def generate_order_id
|
24
|
+
"testing-#{rand.round(4)}-#{Time.now.to_i}"
|
25
|
+
end
|
26
|
+
|
27
|
+
get "/" do
|
28
|
+
erb :index
|
29
|
+
end
|
30
|
+
|
31
|
+
post "/charge_vtdirect" do
|
32
|
+
@result = Veritrans.charge(
|
33
|
+
payment_type: "credit_card",
|
34
|
+
credit_card: { token_id: params[:token_id] },
|
35
|
+
transaction_details: {
|
36
|
+
order_id: generate_order_id,
|
37
|
+
gross_amount: params[:gross_amount]
|
38
|
+
}
|
39
|
+
)
|
40
|
+
|
41
|
+
erb :response
|
42
|
+
end
|
43
|
+
|
44
|
+
get "/charge_vtweb" do
|
45
|
+
@result = Veritrans.charge(
|
46
|
+
payment_type: "VTWEB",
|
47
|
+
transaction_details: {
|
48
|
+
order_id: generate_order_id,
|
49
|
+
gross_amount: 100_000
|
50
|
+
}
|
51
|
+
)
|
52
|
+
|
53
|
+
erb :response
|
54
|
+
end
|
55
|
+
|
56
|
+
post "/webhook" do
|
57
|
+
post_body = request.body.read
|
58
|
+
request_data = Veritrans.decode_notification_json(post_body)
|
59
|
+
|
60
|
+
#puts "Recieved #{post_body.size} bytes"
|
61
|
+
#p request_data
|
62
|
+
|
63
|
+
verified_data = Veritrans.status(request_data['transaction_id'])
|
64
|
+
|
65
|
+
if verified_data.status_code != 404
|
66
|
+
puts "--- Transaction callback ---"
|
67
|
+
puts "Payment: #{verified_data.data[:order_id]}"
|
68
|
+
puts "Payment type: #{verified_data.data[:payment_type]}"
|
69
|
+
puts "Payment status: #{verified_data.data[:transaction_status]}"
|
70
|
+
puts "Fraud status: #{verified_data.data[:fraud_status]}" if verified_data.data[:fraud_status]
|
71
|
+
puts "Payment amount: #{verified_data.data[:gross_amount]}"
|
72
|
+
puts "--- Transaction callback ---"
|
73
|
+
end
|
74
|
+
|
75
|
+
return "ok"
|
76
|
+
end
|
data/example/style.css
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
body {
|
2
|
+
max-width: 900px;
|
3
|
+
margin: 0 auto;
|
4
|
+
}
|
5
|
+
a {
|
6
|
+
color: #00E;
|
7
|
+
}
|
8
|
+
a:hover, a:focus {
|
9
|
+
color: #00E;
|
10
|
+
}
|
11
|
+
|
12
|
+
header {
|
13
|
+
background: #F5FAFC;
|
14
|
+
padding: 3px 5px;
|
15
|
+
border-bottom: 1px solid #ccc;
|
16
|
+
}
|
17
|
+
|
18
|
+
section {
|
19
|
+
padding: 1em 0;
|
20
|
+
}
|
21
|
+
|
22
|
+
section + section {
|
23
|
+
border-top: 1px solid #ccc;
|
24
|
+
}
|
25
|
+
|
26
|
+
label {
|
27
|
+
display: inline-block; min-width: 100px;
|
28
|
+
}
|
29
|
+
.card-numbers {
|
30
|
+
margin-left: 100px;
|
31
|
+
}
|
32
|
+
.card-numbers a {
|
33
|
+
text-decoration: none;
|
34
|
+
border-bottom: 1px dotted #88f;
|
35
|
+
margin-right: 10px;
|
36
|
+
cursor: pointer;
|
37
|
+
}
|
38
|
+
.card-numbers a[href] {
|
39
|
+
text-decoration: underline;
|
40
|
+
border: none;
|
41
|
+
}
|
42
|
+
|
43
|
+
fieldset {
|
44
|
+
margin: 25px 0 12px;
|
45
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
development:
|
2
|
+
# merchant_id: M000937
|
3
|
+
|
4
|
+
client_key: VT-client-NArmatJZqzsmTmzR
|
5
|
+
server_key: VT-server-9Htb-RxXkg7-7hznSCCjxvoY
|
6
|
+
|
7
|
+
# api_host: http://papi.vt-stage.info:8080
|
8
|
+
# For production use
|
9
|
+
# api_host: https://api.veritrans.co.id
|
10
|
+
|
11
|
+
# For sandbox use
|
12
|
+
# api_host: https://api.sandbox.veritrans.co.id
|
@@ -0,0 +1,50 @@
|
|
1
|
+
$(document).ready(function () {
|
2
|
+
|
3
|
+
function VT_createTokenData() {
|
4
|
+
return {
|
5
|
+
// Optional params:
|
6
|
+
// secure: true
|
7
|
+
// bank: 'MANDIRI'
|
8
|
+
// gross_amount: 1000
|
9
|
+
|
10
|
+
card_number: $('#credit_card_number').val(),
|
11
|
+
card_cvv: $('#credit_card_cvv').val(),
|
12
|
+
card_exp_month: $('#credit_card_expire').val().match(/(\d+) \//)[1],
|
13
|
+
card_exp_year: '20' + $('#credit_card_expire').val().match(/\/ (\d+)/)[1],
|
14
|
+
gross_amount: $('#payment_amount').val(),
|
15
|
+
secure: $('#payment_credit_card_secure')[0].checked
|
16
|
+
};
|
17
|
+
}
|
18
|
+
|
19
|
+
$('.veritrans-payment-form').on('submit', function (event) {
|
20
|
+
event.preventDefault();
|
21
|
+
|
22
|
+
var form = this;
|
23
|
+
var button = $(form).find('input[type=submit]:last');
|
24
|
+
var buttonValBefore = button.val();
|
25
|
+
button.val("Processing ...");
|
26
|
+
|
27
|
+
Veritrans.token(VT_createTokenData, function (data) {
|
28
|
+
console.log('Get token response:');
|
29
|
+
console.log(data);
|
30
|
+
|
31
|
+
// if we get redirect_url then it's 3d-secure transaction
|
32
|
+
// so we need to open that page
|
33
|
+
// this callback function will be called again after user confirm 3d-secure
|
34
|
+
// you can also redirect on server side
|
35
|
+
|
36
|
+
if (data.redirect_url) {
|
37
|
+
// it works nice with lightbox js libraries
|
38
|
+
$('#3d-secure-iframe').attr('src', data.redirect_url).show();
|
39
|
+
// if no redirect_url and we have token_id then just make charge request
|
40
|
+
} else if (data.token_id) {
|
41
|
+
$('#payment_token_id').val(data.token_id);
|
42
|
+
form.submit();
|
43
|
+
// if no redirect_url and no token_id, then it should be error
|
44
|
+
} else {
|
45
|
+
alert(data.validation_messages ? data.validation_messages.join("\n") : data.status_message);
|
46
|
+
button.removeAttr('disabled').val(buttonValBefore);
|
47
|
+
}
|
48
|
+
});
|
49
|
+
});
|
50
|
+
});
|
@@ -0,0 +1,81 @@
|
|
1
|
+
class PaymentsController < ApplicationController
|
2
|
+
skip_before_filter :verify_authenticity_token, only: [:receive_webhook]
|
3
|
+
|
4
|
+
def new
|
5
|
+
@payment = make_payment
|
6
|
+
end
|
7
|
+
|
8
|
+
def create
|
9
|
+
@payment = make_payment
|
10
|
+
|
11
|
+
if params[:type] == "vtweb"
|
12
|
+
@result = Veritrans.charge(
|
13
|
+
payment_type: "VTWEB",
|
14
|
+
transaction_details: {
|
15
|
+
order_id: @payment.order_id,
|
16
|
+
gross_amount: @payment.amount
|
17
|
+
}
|
18
|
+
)
|
19
|
+
redirect_to @result.redirect_url
|
20
|
+
return
|
21
|
+
end
|
22
|
+
|
23
|
+
@result = Veritrans.charge(
|
24
|
+
payment_type: "credit_card",
|
25
|
+
credit_card: { token_id: params[:payment][:token_id] },
|
26
|
+
transaction_details: {
|
27
|
+
order_id: @payment.order_id,
|
28
|
+
gross_amount: params[:payment][:amount].presence || @payment.amount
|
29
|
+
}
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def receive_webhook
|
34
|
+
post_body = request.body.read
|
35
|
+
callback_params = Veritrans.decode_notification_json(post_body)
|
36
|
+
|
37
|
+
Veritrans.file_logger.info("Callback for order: " +
|
38
|
+
"#{callback_params[:order_id]} #{callback_params[:transaction_status]}\n" +
|
39
|
+
post_body + "\n"
|
40
|
+
)
|
41
|
+
|
42
|
+
verified_data = Veritrans.status(callback_params["transaction_id"])
|
43
|
+
|
44
|
+
if verified_data.status_code != 404
|
45
|
+
puts "--- Transaction callback ---"
|
46
|
+
puts "Payment: #{verified_data.data[:order_id]}"
|
47
|
+
puts "Payment type: #{verified_data.data[:payment_type]}"
|
48
|
+
puts "Payment status: #{verified_data.data[:transaction_status]}"
|
49
|
+
puts "Fraud status: #{verified_data.data[:fraud_status]}" if verified_data.data[:fraud_status]
|
50
|
+
puts "Payment amount: #{verified_data.data[:gross_amount]}"
|
51
|
+
puts "--- Transaction callback ---"
|
52
|
+
|
53
|
+
render text: "ok"
|
54
|
+
else
|
55
|
+
Veritrans.file_logger.info("Callback verification failed for order: " +
|
56
|
+
"#{callback_params[:order_id]} #{callback_params[:transaction_status]}}\n" +
|
57
|
+
verified_data.body + "\n"
|
58
|
+
)
|
59
|
+
|
60
|
+
render text: "ok", :status => :not_found
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
def make_payment
|
67
|
+
@paymentKlass = Struct.new("Payment", :amount, :token_id, :order_id, :credit_card_secure) do
|
68
|
+
extend ActiveModel::Naming
|
69
|
+
include ActiveModel::Conversion
|
70
|
+
|
71
|
+
def persisted?; false; end
|
72
|
+
|
73
|
+
def self.name
|
74
|
+
"Payment"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
@paymentKlass.new(100_000, '', "testing-#{rand.round(4)}-#{Time.now.to_i}", false)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
Veritrans.setup do
|
2
|
+
config.load_config Rails.root.join("config/veritrans.yml")
|
3
|
+
|
4
|
+
# Or set it manually...
|
5
|
+
# config.server_key = ""
|
6
|
+
# config.client_key = ""
|
7
|
+
# config.api_host = ""
|
8
|
+
|
9
|
+
# Veritrans::Events is rack application to handle http notifications from Veritrans
|
10
|
+
# To enable it, add in config/routes.rb
|
11
|
+
# mount Veritrans::Events.new => '/vt_events'
|
12
|
+
|
13
|
+
# All possible events:
|
14
|
+
#
|
15
|
+
# * payment.success == ['authorize', 'capture', 'settlement']
|
16
|
+
# * payment.failed == ['deny', 'canel', 'expire']
|
17
|
+
# * payment.challenge # when payment.froud_status == 'challenge'
|
18
|
+
#
|
19
|
+
# * payment.authorize
|
20
|
+
# * payment.capture
|
21
|
+
# * payment.settlement
|
22
|
+
# * payment.deny
|
23
|
+
# * payment.canel
|
24
|
+
# * payment.expire
|
25
|
+
|
26
|
+
# events.subscribe 'payment.success' do |payment|
|
27
|
+
# payment.mark_paid!
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# events.subscribe 'payment.failed' do |payment|
|
31
|
+
# payment.mark_failed!
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# events.subscribe 'payment.challenge' do |payment|
|
35
|
+
# payment.mark_challenge!
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# events.subscribe /.+/ do |payment, event_name|
|
39
|
+
# p "Event: #{event_name}"
|
40
|
+
# p payment
|
41
|
+
# end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
development:
|
2
|
+
# Register in sandbox veritrans and get your keys here:
|
3
|
+
# https://my.sandbox.veritrans.co.id/settings/config_info
|
4
|
+
client_key: ""
|
5
|
+
server_key: ""
|
6
|
+
api_host: https://api.sandbox.veritrans.co.id
|
7
|
+
|
8
|
+
production:
|
9
|
+
# Register and get your keys here:
|
10
|
+
# https://my.veritrans.co.id/settings/config_info
|
11
|
+
client_key: ""
|
12
|
+
server_key: ""
|
13
|
+
api_host: https://api.veritrans.co.id
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<%= form_for @payment, html: {class: "veritrans-payment-form"} do |f| %>
|
2
|
+
<%= f.hidden_field :token_id %>
|
3
|
+
<input type="submit" style="display: none">
|
4
|
+
<p>
|
5
|
+
<%= f.label :amount %>
|
6
|
+
<%= f.number_field :amount %>
|
7
|
+
</p>
|
8
|
+
|
9
|
+
<p>
|
10
|
+
<%= label_tag :credit_card_number %>
|
11
|
+
<%= text_field_tag :credit_card_number, '4811 1111 1111 1114', name: nil, size: 25 %>
|
12
|
+
</p>
|
13
|
+
<p>
|
14
|
+
<button onclick="$('#credit_card_number').val('5810 1111 1111 1112'); return false">success MasterCard</button>
|
15
|
+
<button onclick="$('#credit_card_number').val('4811 1111 1111 1114'); return false">success Visa</button>
|
16
|
+
<button onclick="$('#credit_card_number').val('4511 1111 1111 1117'); return false">challenge</button>
|
17
|
+
<button onclick="$('#credit_card_number').val('4611 1111 1111 1116'); return false">Deny by FDS</button>
|
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>
|
20
|
+
</p>
|
21
|
+
|
22
|
+
<p>
|
23
|
+
<%= label_tag :credit_card_cvv %>
|
24
|
+
<%= text_field_tag :credit_card_cvv, '123', name: nil %>
|
25
|
+
</p>
|
26
|
+
|
27
|
+
<p>
|
28
|
+
<%= label_tag :credit_card_expire %>
|
29
|
+
<%= text_field_tag :credit_card_expire, '12 / 16', placeholder: "MM / YY", name: nil %>
|
30
|
+
</p>
|
31
|
+
|
32
|
+
<p>
|
33
|
+
<%= f.label :credit_card_secure, "3D-secure" %>
|
34
|
+
<%= f.check_box :credit_card_secure %>
|
35
|
+
</p>
|
36
|
+
|
37
|
+
<p>
|
38
|
+
<%= f.submit "Pay via VT-Direct" %>
|
39
|
+
</p>
|
40
|
+
<% end %>
|
41
|
+
|
42
|
+
<iframe id="3d-secure-iframe" style="display: none; width: 500px; height: 600px"></iframe>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%= javascript_include_tag "#{Veritrans.config.api_host}/v2/assets/veritrans.js" %>
|
2
|
+
|
3
|
+
<script type="text/javascript">
|
4
|
+
Veritrans.url = "<%= Veritrans.config.api_host %>/v2/token";
|
5
|
+
Veritrans.client_key = "<%= Veritrans.config.client_key %>";
|
6
|
+
</script>
|
7
|
+
|
8
|
+
<% unless Veritrans.config.client_key.present? %>
|
9
|
+
<h4 style="color: red">Please add client_key in config/veritrans.yml</h4>
|
10
|
+
<% end %>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<strong>
|
2
|
+
<% if @result.success? %><span style="color: green"><% end %>
|
3
|
+
<%= @result.status_message %>
|
4
|
+
</span>
|
5
|
+
</strong>
|
6
|
+
|
7
|
+
<br>
|
8
|
+
|
9
|
+
<code>
|
10
|
+
<pre>
|
11
|
+
<%= @result.response.body %>
|
12
|
+
</pre>
|
13
|
+
</code>
|
14
|
+
|
15
|
+
<%= link_to "Go back", :new_payment %>
|