veritrans 2.1.2 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +10 -1
  3. data/.idea/.gitignore +8 -0
  4. data/.rubocop.yml +35 -0
  5. data/.travis.yml +10 -5
  6. data/CHANGELOG.md +45 -0
  7. data/Gemfile +6 -7
  8. data/Gemfile.lock +134 -146
  9. data/Maintaining.MD +8 -0
  10. data/README.md +266 -226
  11. data/api_reference.md +534 -143
  12. data/example/coreapi/core_api_credit_card_example.rb +66 -0
  13. data/example/coreapi/readme.md +4 -0
  14. data/example/sinatra/Gemfile +7 -0
  15. data/example/sinatra/README.md +6 -0
  16. data/example/sinatra/index.erb +202 -0
  17. data/example/sinatra/response.erb +1 -0
  18. data/example/sinatra/snap.erb +33 -0
  19. data/example/sinatra/snap_redirect.erb +10 -0
  20. data/example/sinatra/webapp.rb +113 -0
  21. data/example/snap/readme.md +4 -0
  22. data/example/snap/snap_example.rb +39 -0
  23. data/lib/test/all.rb +1 -0
  24. data/lib/test/api_test.rb +319 -0
  25. data/lib/test/config_test.rb +26 -0
  26. data/lib/test/gopay_tokenization_test.rb +80 -0
  27. data/lib/test/snap_test.rb +79 -0
  28. data/lib/test/subscription_test.rb +116 -0
  29. data/lib/test/transaction_test.rb +160 -0
  30. data/lib/veritrans/api.rb +146 -22
  31. data/lib/veritrans/client.rb +48 -12
  32. data/lib/veritrans/config.rb +31 -6
  33. data/lib/veritrans/events.rb +46 -35
  34. data/lib/veritrans/midtrans_error.rb +15 -0
  35. data/lib/veritrans/result.rb +66 -5
  36. data/lib/veritrans/version.rb +1 -1
  37. data/lib/veritrans.rb +121 -12
  38. data/veritrans.gemspec +2 -9
  39. metadata +30 -146
  40. data/.rspec +0 -2
  41. data/Procfile +0 -1
  42. data/Rakefile +0 -16
  43. data/bin/midtrans +0 -3
  44. data/bin/veritrans +0 -68
  45. data/example/README.md +0 -8
  46. data/example/config.ru +0 -6
  47. data/example/index.erb +0 -213
  48. data/example/localization.erb +0 -248
  49. data/example/points.erb +0 -187
  50. data/example/recurring.erb +0 -201
  51. data/example/response.erb +0 -37
  52. data/example/sinatra.rb +0 -188
  53. data/example/style.css +0 -126
  54. data/example/veritrans.yml +0 -11
  55. data/example/widget.erb +0 -51
  56. data/lib/generators/templates/assets/credit_card_form.js +0 -51
  57. data/lib/generators/templates/payments_controller.rb +0 -85
  58. data/lib/generators/templates/veritrans.rb +0 -46
  59. data/lib/generators/templates/veritrans.yml +0 -18
  60. data/lib/generators/templates/views/_credit_card_form.erb +0 -42
  61. data/lib/generators/templates/views/_veritrans_include.erb +0 -10
  62. data/lib/generators/templates/views/payments/create.erb +0 -15
  63. data/lib/generators/templates/views/payments/new.erb +0 -6
  64. data/lib/generators/veritrans/install_generator.rb +0 -32
  65. data/lib/generators/veritrans/payment_form_generator.rb +0 -45
  66. data/lib/veritrans/cli.rb +0 -155
  67. data/lib/veritrans/core_extensions.rb +0 -32
  68. data/spec/cli_spec.rb +0 -83
  69. data/spec/configs/real_key.yml +0 -4
  70. data/spec/configs/veritrans.yml +0 -7
  71. data/spec/configs/veritrans_flat.yml +0 -2
  72. data/spec/configs/veritrans_with_erb.yml +0 -2
  73. data/spec/fixtures/approve_failed.yml +0 -48
  74. data/spec/fixtures/cancel_failed.yml +0 -48
  75. data/spec/fixtures/cancel_success.yml +0 -106
  76. data/spec/fixtures/capture_failed.yml +0 -48
  77. data/spec/fixtures/charge.yml +0 -50
  78. data/spec/fixtures/charge_direct.yml +0 -56
  79. data/spec/fixtures/charge_vtweb.yml +0 -50
  80. data/spec/fixtures/cli_test_1111-not-exists.yml +0 -45
  81. data/spec/fixtures/cli_test_not_exists.yml +0 -45
  82. data/spec/fixtures/cli_test_real_txn.yml +0 -55
  83. data/spec/fixtures/cli_test_unauthorized.yml +0 -47
  84. data/spec/fixtures/events_test_real_txn.yml +0 -55
  85. data/spec/fixtures/expire_failed.yml +0 -50
  86. data/spec/fixtures/expire_success.yml +0 -56
  87. data/spec/fixtures/midtrans_status.yml +0 -117
  88. data/spec/fixtures/status_fail.yml +0 -46
  89. data/spec/fixtures/status_success.yml +0 -109
  90. data/spec/midtrans_rename_spec.rb +0 -27
  91. data/spec/rails_plugin_spec.rb +0 -281
  92. data/spec/spec_helper.rb +0 -61
  93. data/spec/veritrans_client_spec.rb +0 -184
  94. data/spec/veritrans_config_spec.rb +0 -70
  95. data/spec/veritrans_events_spec.rb +0 -72
  96. data/spec/veritrans_logger_spec.rb +0 -46
  97. data/spec/veritrans_snap_spec.rb +0 -39
  98. data/testing_webhooks.md +0 -78
data/README.md CHANGED
@@ -1,285 +1,329 @@
1
- # Veritrans ruby library
1
+ # Midtrans Ruby library
2
+
3
+ Midtrans ❤️ Ruby!
4
+
5
+ This is the Official Ruby API client/library for Midtrans Payment API. Visit [https://midtrans.com](https://midtrans.com). More information about the product and see documentation at [http://docs.midtrans.com](https://docs.midtrans.com) for more technical details.
2
6
 
3
7
  [![Gem Version](https://badge.fury.io/rb/veritrans.svg)](http://badge.fury.io/rb/veritrans)
4
8
  [![Build Status](https://travis-ci.org/veritrans/veritrans-ruby.svg?branch=master)](https://travis-ci.org/veritrans/veritrans-ruby)
5
9
 
6
- ## How to use (Rails)
7
-
8
- ### Add gem veritrans to Gemfile
10
+ ## 1. Installation
9
11
 
12
+ ### Using Gemfile
13
+ Add gem veritrans to Gemfile
10
14
  ```ruby
11
15
  gem 'veritrans'
12
16
  ```
17
+ Run this command in your terminal
18
+ ```ruby
19
+ gem install veritrans
20
+ ```
21
+ ```ruby
22
+ bundle install
23
+ ```
13
24
 
14
- bundle install
25
+ ## 2. Usage
26
+ ### 2.1 Choose Product/Method
15
27
 
16
- ### Generate veritrans.yml
28
+ We have [3 different products](https://docs.midtrans.com/en/welcome/index.html) of payment that you can use:
29
+ - [Snap](#22A-snap) - Customizable payment popup will appear on **your web/app** (no redirection). [doc ref](https://snap-docs.midtrans.com/)
30
+ - [Snap Redirect](#22B-snap-redirect) - Customer need to be redirected to payment url **hosted by midtrans**. [doc ref](https://snap-docs.midtrans.com/)
31
+ - [Core API (VT-Direct)](#22C-core-api-vt-direct) - Basic backend implementation, you can customize the frontend embedded on **your web/app** as you like (no redirection). [doc ref](https://api-docs.midtrans.com/)
17
32
 
18
- rails g veritrans:install
33
+ Choose one that you think best for your unique needs.
19
34
 
20
- ### Create simple payment form (optional)
35
+ ### 2.2 Client Initialization and Configuration
21
36
 
22
- rails g veritrans:payment_form
37
+ Get your client key and server key from [Midtrans Dashboard](https://dashboard.midtrans.com)
23
38
 
24
- ### Edit api keys in config/veritrans.yml
39
+ Create instance of Midtrans client
25
40
 
26
- ```yml
27
- # config/veritrans.yml
28
- development:
29
- client_key: # your api client key
30
- server_key: # your api client key
41
+ ```ruby
42
+ require 'veritrans'
43
+
44
+ mt_client = Midtrans.new(
45
+ server_key: "your server key",
46
+ client_key: "your client key",
47
+ api_host: "https://api.sandbox.midtrans.com", # default
48
+ http_options: { }, # optional
49
+ logger: Logger.new(STDOUT), # optional
50
+ file_logger: Logger.new(STDOUT), # optional
51
+ )
52
+
53
+ mt_client.status("order-id-123456")
31
54
  ```
32
55
 
33
- See out example sinatra application in [example](https://github.com/veritrans/veritrans-ruby/tree/master/example) folder or [online](https://veritrans-ruby-example.herokuapp.com/)
56
+ Alternatively, you can also set config by declaring each one like below:
34
57
 
58
+ ```ruby
59
+ Midtrans.config.server_key = "your server key"
60
+ Midtrans.config.client_key = "your client key"
61
+ Midtrans.config.api_host = "https://api.sandbox.midtrans.com"
62
+ ```
35
63
 
36
- ## STEP 1: Process credit cards
64
+ ### 2.2.A Snap
65
+ You can see Snap example [with Sinatra](example/sinatra) and [without framework](example/snap).
66
+
67
+ ```ruby
68
+ # Create Snap payment page, with this version returning full API response
69
+ create_snap_token(parameter)
37
70
 
71
+ # Create Snap payment page, with this version returning token
72
+ create_snap_token_string(parameter)
38
73
 
39
- #### VT-Web
74
+ # Create Snap payment page, with this version returning redirect url
75
+ create_snap_redirect_url_str(parameter)
76
+ ```
77
+ `parameter` is Object or String of JSON of [SNAP Parameter](https://snap-docs.midtrans.com/#json-objects)
40
78
 
41
- *If you want to use VT-Web, add `payment_type: "VTWEB"`*
79
+ #### Get Snap Token
42
80
 
43
81
  ```ruby
44
- @result = Veritrans.charge(
45
- payment_type: "VTWEB",
82
+ result = Midtrans.create_snap_token(
46
83
  transaction_details: {
47
- order_id: "my-unique-order-id",
48
- gross_amount: 100_000
84
+ order_id: "test-transaction-order-123",
85
+ gross_amount: 100000,
86
+ secure: true
49
87
  }
50
88
  )
89
+ @token = result.token
90
+ ```
51
91
 
52
- redirect_to @result.redirect_url
92
+ #### Initialize Snap JS when customer click pay button
93
+
94
+ On frontend / html:
95
+ Replace `PUT_TRANSACTION_TOKEN_HERE` with `transactionToken` acquired above
96
+ ```html
97
+ <html>
98
+ <body>
99
+ <button id="pay-button">Pay!</button>
100
+ <pre><div id="result-json">JSON result will appear here after payment:<br></div></pre>
101
+
102
+ <!-- TODO: Remove ".sandbox" from script src URL for production environment. Also input your client key in "data-client-key" -->
103
+ <script src="https://app.sandbox.midtrans.com/snap/snap.js" data-client-key="<Set your ClientKey here>"></script>
104
+ <script type="text/javascript">
105
+ document.getElementById('pay-button').onclick = function(){
106
+ // SnapToken acquired from previous step
107
+ snap.pay('PUT_TRANSACTION_TOKEN_HERE', {
108
+ // Optional
109
+ onSuccess: function(result){
110
+ /* You may add your own js here, this is just example */ document.getElementById('result-json').innerHTML += JSON.stringify(result, null, 2);
111
+ },
112
+ // Optional
113
+ onPending: function(result){
114
+ /* You may add your own js here, this is just example */ document.getElementById('result-json').innerHTML += JSON.stringify(result, null, 2);
115
+ },
116
+ // Optional
117
+ onError: function(result){
118
+ /* You may add your own js here, this is just example */ document.getElementById('result-json').innerHTML += JSON.stringify(result, null, 2);
119
+ }
120
+ });
121
+ };
122
+ </script>
123
+ </body>
124
+ </html>
53
125
  ```
54
126
 
55
- #### VT-Direct
127
+ ### 2.2.B Snap Redirect
128
+ You can see Snap example [with Sinatra](example/sinatra) and [without framework](example/snap).
56
129
 
57
- It's little more complicated, because credit_card is sensitive data,
58
- you need put credit card number in our safe storage first using `veritrans.js` library, then send received token to with other payment details.
130
+ #### Get Redirection URL of a Payment Page
59
131
 
60
- We don't want you to send credit card number to your server, especially for websites not using https.
132
+ ```ruby
133
+ result = Midtrans.create_snap_redirect_url(
134
+ transaction_details: {
135
+ order_id: "test-transaction-order-123",
136
+ gross_amount: 100000,
137
+ secure: true
138
+ }
139
+ )
140
+ @redirecturl = result.redirect_url
141
+ ```
61
142
 
62
- File: "app/views/shared/_veritrans_include.erb"
143
+ ### 2.2.C Core API (VT-Direct)
144
+ You can see some Core API examples [with Sinatra](example/sinatra) and [without framework](example/coreapi).
63
145
 
64
- ```html
65
- <script src="//api.sandbox.veritrans.co.id/v2/assets/veritrans.js"></script>
146
+ Available methods for `CoreApi` class
66
147
 
67
- <script type="text/javascript">
68
- Veritrans.url = "<%= Veritrans.config.api_host %>/v2/token";
69
- Veritrans.client_key = "<%= Veritrans.config.client_key %>";
70
- </script>
71
- ```
148
+ ```ruby
149
+ # charge : Do `/charge` API request to Midtrans Core API
150
+ def charge(payment_type, data = nil)
72
151
 
73
- Payment form: (same as if you use `rails g veritrans:payment_form`)
74
-
75
- ```erb
76
- <%= form_tag "/charge_vtdirect", id: "card_form" do %>
77
- <%= hidden_field_tag :token_id, nil, id: "card_token" %>
78
- <%= hidden_field_tag :gross_amount, 30000 %>
79
- <p>
80
- <%= label_tag "card_number", "Card number" %>
81
- <%= text_field_tag :card_number, "4811 1111 1111 1114", name: nil, style: "width: 150px" %>
82
- </p>
83
- <p>
84
- <%= label_tag "card_cvc", "Security Code" %>
85
- <%= text_field_tag :card_cvc, "123", name: nil, style: "width: 30px", placeholder: "cvc" %>
86
- </p>
87
- <p>
88
- <%= label_tag "card_exp", "Expiration date" %>
89
- <%= text_field_tag :card_exp, "12 / 16", name: nil, placeholder: "MM / YY" %>
90
- </p>
91
- <%= submit_tag "Make payment", id: "submit_btn" %>
92
- <% end %>
93
- <iframe id="3d-secure-iframe" style="display: none; width: 500px; height: 600px"></iframe>
94
- ```
152
+ # test_token : Do `/token` API request to Midtrans Core API
153
+ def test_token(options = {})
154
+
155
+ # point_inquiry : Do `/point_inquiry/{tokenId}` API request to Midtrans Core API
156
+ def point_inquiry(token_id)
95
157
 
96
- For sinatra:
158
+ # status : Do `/{orderId}/status` API request to Midtrans Core API
159
+ def status(payment_id)
97
160
 
98
- ```html
99
- <form action="/charge_vtdirect" method="post" id="card_form">
100
- <input type="hidden" name="token_id" id="card_token">
101
- <input type="hidden" id="gross_amount" value="30000">
102
- <p>
103
- <label for="card_number">Card number</label>
104
- <input type="text" id="card_number" style="width: 150px" value="4811 1111 1111 1114">
105
- </p>
106
- <p>
107
- <label for="card_cvc">Security Code</label>
108
- <input type="text" id="card_cvc" style="width: 30px" placeholder="cvc" value="123">
109
- </p>
110
- <p>
111
- <label for="card_exp">Expiration date</label>
112
- <input type="text" id="card_exp" placeholder="MM / YY" value="12 / 16">
113
- </p>
114
- <p>
115
- <label for="card_secure">3D-secure</label>
116
- <input id="card_secure" name="card_secure" type="checkbox" value="1" />
117
- </p>
118
- <input id="submit_btn" type="submit">
119
- </form>
120
- <iframe id="3d-secure-iframe" style="display: none; width: 500px; height: 600px"></iframe>
121
- ```
161
+ # approve : Do `/{orderId}/approve` API request to Midtrans Core API
162
+ def approve(payment_id, options = {})
122
163
 
123
- Sending "get-token" request:
124
-
125
- ```js
126
- $(document).ready(function () {
127
- // function to prepare our credit card data before send
128
- function createTokenData() {
129
- return {
130
- card_number: $('#card_number').val(),
131
- card_cvv: $('#card_cvc').val(),
132
- card_exp_month: $('#card_exp').val().match(/(\d+) \//)[1],
133
- card_exp_year: '20' + $('#card_exp').val().match(/\/ (\d+)/)[1],
134
- gross_amount: $('#gross_amount').val(),
135
- secure: $('#card_secure')[0].checked
136
- };
137
- }
138
- // Add custom event for form submition
139
- $('#card_form').on('submit', function (event) {
140
- var form = this;
141
- event.preventDefault();
142
-
143
- Veritrans.token(createTokenData, function (data) {
144
- console.log('Token data:', data);
145
- // when you making 3D-secure transaction,
146
- // this callback function will be called again after user confirm 3d-secure
147
- // but you can also redirect on server side
148
- if (data.redirect_url) {
149
- // if we get url then it's 3d-secure transaction
150
- // so we need to open that page
151
- $('#3d-secure-iframe').attr('src', data.redirect_url).show();
152
- // if no redirect_url and we have token_id then just make charge request
153
- } else if (data.token_id) {
154
- $('#card_token').val(data.token_id);
155
- form.submit();
156
- // if no redirect_url and no token_id, then it should be error
157
- } else {
158
- alert(data.validation_messages ? data.validation_messages.join("\n") : data.status_message);
159
- }
160
- });
161
- });
162
- });
163
- ```
164
+ # deny : Do `/{orderId}/deny` API request to Midtrans Core API
165
+ def deny(payment_id, options = {})
164
166
 
165
- On a server side:
167
+ # cancel : Do `/{orderId}/cancel` API request to Midtrans Core API
168
+ def cancel(payment_id, options = {})
166
169
 
167
- ```ruby
168
- @result = Veritrans.charge(
169
- payment_type: "credit_card",
170
- credit_card: { token_id: params[:token_id] },
171
- transaction_details: {
172
- order_id: @payment.order_id,
173
- gross_amount: @payment.amount
174
- }
175
- )
176
- if @result.success?
177
- puts "Success"
178
- end
179
- ```
170
+ # expire : Do `/{orderId}/expire` API request to Midtrans Core API
171
+ def expire(payment_id)
172
+
173
+ # refund : Do `/{orderId}/refund` API request to Midtrans Core API
174
+ def refund(payment_id, options = {})
180
175
 
181
- ## STEP 2: Process not credit cards
176
+ # capture : Do `/{orderId}/capture` API request to Midtrans Core API
177
+ def capture(payment_id, gross_amount, options = {})
182
178
 
183
- We provide many payment channels to receive money, but API is almost same.
179
+ # link_payment_account : Do `/pay/account` API request to Midtrans Core API
180
+ def link_payment_account(param)
184
181
 
185
- For VT-Web in only one request, and payment page will have all available payment options.
182
+ # get_payment_account : Do `/pay/account/{account_id}` API request to Midtrans Core API
183
+ def get_payment_account(account_id)
186
184
 
187
- For VT-Direct you have to specify payment method (token required only for credit card transactions).
185
+ # unlink_payment_account : Do `/pay/account/{account_id}/unbind` API request to Midtrans Core API
186
+ def unlink_payment_account(account_id)
188
187
 
189
- ```ruby
190
- @result = Veritrans.charge(
191
- payment_type: "bank_transfer",
192
- bank_transfer: { bank: 'permata' },
193
- transaction_details: {
194
- order_id: @payment.order_id,
195
- gross_amount: @payment.amount
196
- }
197
- )
198
- puts "Please send money to account no. #{@result.permata_va_number} in bank Permata"
188
+ # create_subscription : Do `/subscription` API request to Midtrans Core API
189
+ def create_subscription(param)
190
+
191
+ # get_subscription : Do `/subscription/{subscription_id}` API request to Midtrans Core API
192
+ def get_subscription(subscription_id)
193
+
194
+ # disable_subscription : Do `/subscription/{subscription_id}/disable` API request to Midtrans Core API
195
+ def disable_subscription(subscription_id)
196
+
197
+ # enable_subscription : Do `/subscription/{subscription_id}/enable` API request to Midtrans Core API
198
+ def enable_subscription(subscription_id)
199
+
200
+ # update_subscription : Do `/subscription/{subscription_id}` API request to Midtrans Core API
201
+ def update_subscription(subscription_id, param)
199
202
  ```
200
203
 
201
- See [our documentation](http://docs.veritrans.co.id/sandbox/charge.html) for other available options.
204
+ #### Credit Card Get Token
202
205
 
206
+ Get token should be handled on Frontend please refer to [API docs](https://docs.midtrans.com/en/core-api/credit-card).
207
+ Further example to demonstrate Core API card integration (including get card token on frontend), available on [Sinatra example](/example/sinatra)
208
+
209
+ #### Credit Card Charge
210
+
211
+ ```ruby
212
+ result = Midtrans.charge(
213
+ payment_type: "credit_card",
214
+ credit_card: {
215
+ token_id: "CREDIT_CARD_TOKEN", # change with your card token,
216
+ authentication: true
217
+ },
218
+ transaction_details: {
219
+ order_id: "test-transaction-12345",
220
+ gross_amount: 20000
221
+ })
222
+ # result.data this will be Hash representation of the API JSON response:
223
+ puts result.data
224
+ ```
203
225
 
204
- ## STEP 3: Receive notification callback
226
+ #### Credit Card 3DS Authentication
205
227
 
206
- For every transaction success and failed we will send you HTTP POST notification (aka webhook)
228
+ The credit card charge result may contains `redirect_url` for 3DS authentication. 3DS Authentication should be handled on Frontend please refer to [API docs](https://api-docs.midtrans.com/#card-features-3d-secure)
207
229
 
208
- First you should set callback url in our dashboard https://my.sandbox.veritrans.co.id/settings/vtweb_configuration
230
+ For full example on Credit Card 3DS transaction refer to:
231
+ - [Sinatra example](/example/sinatra) that implement Snap & Core Api
209
232
 
210
- For testing in development phase please read our [Testing webhooks tutorial](https://github.com/veritrans/veritrans-ruby/blob/new_api/testing_webhooks.md) and [command line tool](#command-line-tool)
211
233
 
234
+ ### 2.3 Handle HTTP Notification
235
+ > **IMPORTANT NOTE**: To update transaction status on your backend/database, **DO NOT** solely rely on frontend callbacks! For security reason to make sure the status is authentically coming from Midtrans, only update transaction status based on HTTP Notification or API Get Status.
212
236
 
213
- For rails:
237
+ Create separated web endpoint (notification url) to receive HTTP POST notification callback/webhook.
238
+ HTTP notification will be sent whenever transaction status is changed.
239
+ Example also available [here](example/sinatra)
214
240
 
215
241
  ```ruby
216
- # config/routes.rb
217
- match "/payments/receive_webhook" => "payments#receive_webhook", via: [:post]
218
-
219
- # app/controllers/payments_controller.rb
220
- def receive_webhook
221
- post_body = request.body.read
222
- callback_params = Veritrans.decode_notification_json(post_body)
223
-
224
- verified_data = Veritrans.status(callback_params['transaction_id'])
225
-
226
- if verified_data.status_code != 404
227
- puts "--- Transaction callback ---"
228
- puts "Payment: #{verified_data.data[:order_id]}"
229
- puts "Payment type: #{verified_data.data[:payment_type]}"
230
- puts "Payment status: #{verified_data.data[:transaction_status]}"
231
- puts "Fraud status: #{verified_data.data[:fraud_status]}" if verified_data.data[:fraud_status]
232
- puts "Payment amount: #{verified_data.data[:gross_amount]}"
233
- puts "--- Transaction callback ---"
234
-
235
- render text: "ok"
236
- else
237
- render text: "ok", :status => :not_found
238
- end
242
+ post_body = JSON.parse(request.body.read)
243
+ notification = Midtrans.status(post_body['transaction_id'])
244
+
245
+ order_id = notification.data[:order_id]
246
+ payment_type = notification.data[:payment_type]
247
+ transaction_status = notification.data[:transaction_status]
248
+ fraud_status = notification.data[:fraud_status]
249
+
250
+ puts "Transaction order_id: #{order_id}"
251
+ puts "Payment type: #{payment_type}"
252
+ puts "Transaction status: #{transaction_status}"
253
+ puts "Fraud status: #{fraud_status}"
254
+
255
+ return "Transaction notification received. Order ID: #{order_id}. Transaction status: #{transaction_status}. Fraud status: #{fraud_status}"
256
+
257
+ # Sample transactionStatus handling logic
258
+ if transaction_status == "capture" && fraud_status == "challange"
259
+ # TODO set transaction status on your databaase to 'challenge'
260
+ elsif transaction_status == "capture" && fraud_status == "success"
261
+ # TODO set transaction status on your databaase to 'success'
262
+ elsif transaction_status == "settlement"
263
+ # TODO set transaction status on your databaase to 'success'
264
+ elsif transaction_status == "deny"
265
+ # TODO you can ignore 'deny', because most of the time it allows payment retries
266
+ elsif transaction_status == "cancel" || transaction_status == "expire"
267
+ # TODO set transaction status on your databaase to 'failure'
268
+ elsif transaction_status == "pending"
269
+ # Todo set transaction status on your databaase to 'pending' / waiting payment
239
270
  end
240
271
  ```
241
272
 
242
- ----
243
-
244
- #### Veritrans::Events
273
+ ### 2.4 Transaction Action
274
+ For full example on transaction action refer to: [Api Reference](api_reference.md)
245
275
 
246
- Other option to handle callbacks is our rack-based handler
276
+ ## 3. Handling Error / Exception
277
+ When using function that result in Midtrans API call e.g: `Midtrans.charge(...)` or `Midtrans.create_snap_token(...)`
278
+ there's a chance it may throw error (`MidtransError` object), the error object will contains below properties that can be used as information to your error handling logic:
247
279
 
248
280
  ```ruby
249
- # config/routes.rb
250
- mount Veritrans::Events.new => '/vt_events'
251
-
252
- # config/initalizers/veritrans.rb
253
- Veritrans.setup do
254
- config.server_key = "..."
255
- config.client_key = "..."
256
-
257
- events.subscribe('payment.success') do |payment|
258
- # payment variable is hash with params recieved from Veritrans
259
- # assuming you have model Order in your project
260
- Order.find_by(order_id: payment.order_id).mark_paid!(payment.masked_card)
261
- end
262
-
263
- events.subscribe('payment.failed', 'payment.challenge') do |payment|
264
- # payment variable is hash with params recieved from Veritrans
265
- # assuming you have model Order in your project
266
- Order.find_by(order_id: payment.order_id) ...
267
- end
281
+ begin
282
+ Midtrans.create_snap_token(parameter)
283
+ rescue MidtransError => e
284
+ puts e.message # Basic error message string
285
+ puts e.http_status_code # HTTP status code e.g: 400, 401, etc.
286
+ puts e.api_response # API response body in String
287
+ puts e.raw_http_client_data # Raw HTTP client response
268
288
  end
269
289
  ```
270
290
 
271
- #### Logging
291
+ ## 4. Advanced Usage
292
+ ### Override Notification URL
293
+
294
+ You can opt to change or add custom notification urls on every transaction. It can be achieved by adding additional HTTP headers into charge request.
295
+ ```ruby
296
+ # Add new notification url(s) alongside the settings on Midtrans Dashboard Portal (MAP)
297
+ Midtrans.config.append_notif_url = "https://example.com/test1,https://example.com/test2"
298
+ # Use new notification url(s) disregarding the settings on Midtrans Dashboard Portal (MAP)
299
+ Midtrans.config.override_notif_url = "https://example.com/test1"
300
+ ```
301
+
302
+ [More details](https://api-docs.midtrans.com/#override-notification-url)
303
+ > **Note:** When both `appendNotifUrl` and `overrideNotifUrl` are used together then only `overrideNotifUrl` will be used.
272
304
 
273
- By default gem veritrans will show information via rails' logger. And in addition save important information to `RAILS_APP/log/veritrans.log`
305
+ > Both header can only receive up to maximum of **3 urls**.
274
306
 
275
- It's configurable.
307
+ ### Idempotency-Key
308
+ Is a unique value that is put on header on API request. Midtrans API accept Idempotency-Key on header to safely handle retry request
309
+ without performing the same operation twice. This is helpful for cases where merchant didn't receive the response because of network issue or other unexpected error.
310
+ You can opt to add idempotency key by adding additional HTTP headers into charge request.
311
+ ```ruby
312
+ Midtrans.config.idempotency_key = "Unique-ID"
313
+ ```
314
+ [More details](http://api-docs.midtrans.com/#idempotent-requests)
315
+
316
+ ### Log Configuration
317
+ By default if you are using Rails, gem Veritrans will show information via Rails logger and in addition save important information to `RAILS_APP/log/Midtrans.log` <br>
318
+ You can configure it like example below:
276
319
 
277
320
  ```ruby
278
- Veritrans.logger = Rails.logger
279
- Veritrans.file_logger = Logger.new("/my/important_logs/veritrans.log")
321
+ Midtrans.logger = Rails.logger
322
+ # To set custom logger
323
+ Midtrans.file_logger = Logger.new("./log/midtrans.log")
280
324
  ```
281
325
 
282
- `Veritrans.file_logger` save information about:
326
+ `Midtrans.file_logger` save information about:
283
327
 
284
328
  * "charge", "cancel", "approve" api calls
285
329
  * Validation errors for "charge", "cancel", "approve"
@@ -288,25 +332,21 @@ Veritrans.file_logger = Logger.new("/my/important_logs/veritrans.log")
288
332
 
289
333
  ----
290
334
 
291
- #### Command line tool
292
-
293
- **Installation**
335
+ ### To see it in action, we have made example:
294
336
 
295
- $ gem install veritrans
337
+ Sinatra, which demonstrate in as succint code as possible. Please [have a look here](https://github.com/veritrans/veritrans-ruby/tree/master/example/sinatra)
296
338
 
297
- **Usage**
298
-
299
- Testing http notification:
300
-
301
- $ veritrans testhook http://localhost:3000/vt_events
302
- $ veritrans testhook -o my-order-1 -c ~/path/to/veritrans.yml http://localhost:3000/vt_events
303
339
 
340
+ ### Get help
304
341
 
342
+ * [Veritrans gem reference](https://github.com/veritrans/veritrans-ruby/blob/master/api_reference.md)
343
+ * [Midtrans login](https://account.midtrans.com/login)
344
+ * [Midtrans registration](https://account.midtrans.com/register)
345
+ * [Midtrans documentation](http://docs.midtrans.com)
346
+ * Technical support [support@midtrans.com](mailto:support@midtrans.com)
305
347
 
306
- #### Get help
348
+ ## Important Changes
307
349
 
308
- * [Veritrans gem reference](https://github.com/veritrans/veritrans-ruby/blob/master/api_reference.md)
309
- * [Veritrans login](https://my.veritrans.co.id/login)
310
- * [Veritrans registration](https://my.veritrans.co.id/register)
311
- * [Veritrans documentation](http://docs.veritrans.co.id)
312
- * Technical support [support@veritrans.co.id](mailto:support@veritrans.co.id)
350
+ ### v2.4.0
351
+ - API client methods will now raise `MidtransError` when getting unexpected API response. You may need to update your error handling. [Handling Error / Exception](#3-Handling-Error--Exception)
352
+ - Removed features: CLI, TestingLib. Mainly removed due to no longer relevant/essential to this library's purpose.