genesis_ruby 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -0
  3. data/Gemfile.lock +24 -25
  4. data/README.md +401 -2
  5. data/VERSION +1 -1
  6. data/genesis_ruby.gemspec +7 -4
  7. data/lib/genesis_ruby/api/constants/date_time_formats.rb +1 -1
  8. data/lib/genesis_ruby/api/constants/transactions/parameters/refund/bank_account_types.rb +27 -0
  9. data/lib/genesis_ruby/api/notification.rb +156 -0
  10. data/lib/genesis_ruby/api/requests/base/financials/credit_card.rb +0 -2
  11. data/lib/genesis_ruby/api/requests/base/reference.rb +29 -0
  12. data/lib/genesis_ruby/api/requests/financial/capture.rb +30 -0
  13. data/lib/genesis_ruby/api/requests/financial/cards/threeds/v2/method_continue.rb +145 -0
  14. data/lib/genesis_ruby/api/requests/financial/refund.rb +48 -0
  15. data/lib/genesis_ruby/api/requests/financial/void.rb +28 -0
  16. data/lib/genesis_ruby/api/requests/non_financial/reconcile/date_range.rb +95 -0
  17. data/lib/genesis_ruby/api/requests/non_financial/reconcile/transaction.rb +37 -0
  18. data/lib/genesis_ruby/api/requests/wpf/reconcile.rb +33 -0
  19. data/lib/genesis_ruby/api/response.rb +6 -5
  20. data/lib/genesis_ruby/builder.rb +3 -2
  21. data/lib/genesis_ruby/builders/form.rb +44 -0
  22. data/lib/genesis_ruby/dependencies.rb +8 -0
  23. data/lib/genesis_ruby/network/adapter/base_adapter.rb +10 -0
  24. data/lib/genesis_ruby/network/adapter/net_http_adapter.rb +30 -8
  25. data/lib/genesis_ruby/network/base_network.rb +16 -0
  26. data/lib/genesis_ruby/network/net_http.rb +5 -0
  27. data/lib/genesis_ruby/utils/common.rb +8 -1
  28. data/lib/genesis_ruby/utils/options/api_config.rb +15 -12
  29. data/lib/genesis_ruby/utils/options/network_adapter_config.rb +3 -4
  30. data/lib/genesis_ruby/utils/threeds/v2.rb +21 -0
  31. data/lib/genesis_ruby/version.rb +1 -1
  32. data/lib/genesis_ruby.rb +5 -2
  33. metadata +20 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88fa7a15b9a49833d8de193195478d25730cd08832a9f1c77a9e8029bead7fe7
4
- data.tar.gz: 17a9e30b42dc026cd920e7be4d5983b0631baad23655bf2703b28b92c7f61d04
3
+ metadata.gz: b8cc160e0cdb5cb22dd4726e2471a9d85ba199c4ee2bdd2e8cbd57b057657ce8
4
+ data.tar.gz: 824dc704419375ffd6276a45d757f1b45e40f6e5d542462d73b18c207392df9e
5
5
  SHA512:
6
- metadata.gz: 1c7ea66d38e6ce58bf8a9560ade34eff61013a580e2af31f96164482891738874a70c3d481fcf4ab19158b5105003df849e6f145c1dbf1e1d46ddb405fd48134
7
- data.tar.gz: 836820c824e0eb854e9b7c22eb95cfdfcdf990f4f8c0362a77ff6935e28c7fbbaeb81dd046a11e66661018797d77c8ade7e01d19a1ac0d2e664a16c955789b29
6
+ metadata.gz: 4cd6c2db4ec7da458a87d82ad550af947585fea23158117d5458f324aa966db882601fba8490357a349ae551c528825bf6d1e52381e3e3d06c24746a25af3ef3
7
+ data.tar.gz: 253fe2aaaec0df2023a6a2d37c74b04dd12eba99da1d376ff01f5566084449dbdbd3d4fe33560eb6d68e7ba98119baf33caa235879ffad9af743c2dc392ebd66
data/CHANGELOG.md CHANGED
@@ -1,3 +1,30 @@
1
+ 0.1.2
2
+ -----
3
+ **Features**:
4
+
5
+ * Added 3D Secure Method Continue API request support
6
+ * Updated Gateway response handling upon error cases like 3D Secure Method Continue with invalid identifier a Network error will be raised
7
+ * Added `GenesisRuby::Api::Notification` handler that provides an easy way of handling Gateway instant payment notifications
8
+
9
+ 0.1.1
10
+ -----
11
+ **Features**:
12
+
13
+ * Added request support for the following transaction reference actions:
14
+ * Capture
15
+ * Void
16
+ * Refund
17
+ * Added support for the following Reconcile API requests:
18
+ * Transaction
19
+ * By Date Range
20
+ * Web Payment Form Reconcile
21
+ * Added Documentation URI to the project metadata description
22
+
23
+ **Fixes**:
24
+
25
+ * Fixed response parser handling with attributes inside the root element
26
+ * Fixed Changelog URI in the project metadata description
27
+
1
28
  0.1.0
2
29
  -----
3
30
  **Features**:
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- genesis_ruby (0.1.0)
4
+ genesis_ruby (0.1.2)
5
5
  net-http (~> 0.3.2)
6
6
  nokogiri (~> 1.14)
7
7
 
@@ -11,14 +11,14 @@ GEM
11
11
  addressable (2.8.5)
12
12
  public_suffix (>= 2.0.2, < 6.0)
13
13
  ast (2.4.2)
14
- base64 (0.1.1)
14
+ base64 (0.2.0)
15
15
  concurrent-ruby (1.2.2)
16
16
  crack (0.4.5)
17
17
  rexml
18
18
  diff-lcs (1.5.0)
19
19
  faker (2.23.0)
20
20
  i18n (>= 1.8.11, < 2)
21
- faraday (2.7.11)
21
+ faraday (2.7.12)
22
22
  base64
23
23
  faraday-net_http (>= 2.0, < 3.1)
24
24
  ruby2_keywords (>= 0.0.4)
@@ -37,26 +37,26 @@ GEM
37
37
  json (2.6.3)
38
38
  language_server-protocol (3.17.0.3)
39
39
  mini_mime (1.1.5)
40
- mini_portile2 (2.8.4)
40
+ mini_portile2 (2.8.5)
41
41
  multi_xml (0.6.0)
42
42
  mustermann (3.0.0)
43
43
  ruby2_keywords (~> 0.0.1)
44
44
  net-http (0.3.2)
45
45
  uri
46
- nokogiri (1.15.4)
46
+ nokogiri (1.15.5)
47
47
  mini_portile2 (~> 2.8.2)
48
48
  racc (~> 1.4)
49
- octokit (6.1.1)
49
+ octokit (7.2.0)
50
50
  faraday (>= 1, < 3)
51
51
  sawyer (~> 0.9)
52
52
  parallel (1.23.0)
53
- parser (3.2.2.3)
53
+ parser (3.2.2.4)
54
54
  ast (~> 2.4.1)
55
55
  racc
56
- pronto (0.11.1)
56
+ pronto (0.11.2)
57
57
  gitlab (>= 4.4.0, < 5.0)
58
58
  httparty (>= 0.13.7, < 1.0)
59
- octokit (>= 4.7.0, < 7.0)
59
+ octokit (>= 4.7.0, < 8.0)
60
60
  rainbow (>= 2.2, < 4.0)
61
61
  rexml (>= 3.2.5, < 4.0)
62
62
  rugged (>= 0.23.0, < 2.0)
@@ -64,14 +64,14 @@ GEM
64
64
  pronto-rubocop (0.11.5)
65
65
  pronto (~> 0.11.0)
66
66
  rubocop (>= 0.63.1, < 2.0)
67
- public_suffix (5.0.3)
68
- racc (1.7.1)
67
+ public_suffix (5.0.4)
68
+ racc (1.7.3)
69
69
  rack (2.2.8)
70
70
  rack-protection (3.1.0)
71
71
  rack (~> 2.2, >= 2.2.4)
72
72
  rainbow (3.1.1)
73
- rake (13.0.6)
74
- regexp_parser (2.8.1)
73
+ rake (13.1.0)
74
+ regexp_parser (2.8.2)
75
75
  rexml (3.2.6)
76
76
  rspec (3.12.0)
77
77
  rspec-core (~> 3.12.0)
@@ -86,29 +86,28 @@ GEM
86
86
  diff-lcs (>= 1.2.0, < 2.0)
87
87
  rspec-support (~> 3.12.0)
88
88
  rspec-support (3.12.1)
89
- rubocop (1.56.3)
90
- base64 (~> 0.1.1)
89
+ rubocop (1.57.2)
91
90
  json (~> 2.3)
92
91
  language_server-protocol (>= 3.17.0)
93
92
  parallel (~> 1.10)
94
- parser (>= 3.2.2.3)
93
+ parser (>= 3.2.2.4)
95
94
  rainbow (>= 2.2.2, < 4.0)
96
95
  regexp_parser (>= 1.8, < 3.0)
97
96
  rexml (>= 3.2.5, < 4.0)
98
97
  rubocop-ast (>= 1.28.1, < 2.0)
99
98
  ruby-progressbar (~> 1.7)
100
99
  unicode-display_width (>= 2.4.0, < 3.0)
101
- rubocop-ast (1.29.0)
100
+ rubocop-ast (1.30.0)
102
101
  parser (>= 3.2.1.0)
103
- rubocop-capybara (2.18.0)
102
+ rubocop-capybara (2.19.0)
104
103
  rubocop (~> 1.41)
105
- rubocop-factory_bot (2.23.1)
104
+ rubocop-factory_bot (2.24.0)
106
105
  rubocop (~> 1.33)
107
106
  rubocop-faker (1.1.0)
108
107
  faker (>= 2.12.0)
109
108
  rubocop (>= 0.82.0)
110
- rubocop-rspec (2.24.0)
111
- rubocop (~> 1.33)
109
+ rubocop-rspec (2.25.0)
110
+ rubocop (~> 1.40)
112
111
  rubocop-capybara (~> 2.17)
113
112
  rubocop-factory_bot (~> 2.22)
114
113
  ruby-progressbar (1.13.0)
@@ -124,10 +123,10 @@ GEM
124
123
  tilt (~> 2.0)
125
124
  terminal-table (3.0.2)
126
125
  unicode-display_width (>= 1.1.1, < 3)
127
- thor (1.2.2)
126
+ thor (1.3.0)
128
127
  tilt (2.3.0)
129
- unicode-display_width (2.4.2)
130
- uri (0.12.2)
128
+ unicode-display_width (2.5.0)
129
+ uri (0.13.0)
131
130
  webmock (3.19.1)
132
131
  addressable (>= 2.8.0)
133
132
  crack (>= 0.3.2)
@@ -140,7 +139,7 @@ PLATFORMS
140
139
  x86_64-linux
141
140
 
142
141
  DEPENDENCIES
143
- bundler
142
+ bundler (~> 2.1)
144
143
  faker (~> 2.22)
145
144
  faraday-retry (~> 2.0)
146
145
  genesis_ruby!
data/README.md CHANGED
@@ -12,6 +12,8 @@ Client Library for processing payments through Genesis Payment Processing Gatewa
12
12
  ## Requirements
13
13
 
14
14
  * Ruby version 2.7 or newer
15
+ * [net-http](https://rubygems.org/gems/net-http) 0.3.2 or newer
16
+ * [nokogiri](https://rubygems.org/gems/nokogiri) 1.14 or newer
15
17
 
16
18
  ## Installation
17
19
 
@@ -103,6 +105,8 @@ rescue GenesisRuby::Error => error
103
105
  end
104
106
  ```
105
107
 
108
+ A full list of the Transaction Types and Custom Attributes can be found [here](https://emerchantpay.github.io/gateway-api-docs/?shell#wpf-transaction-types).
109
+
106
110
  ### Transactions
107
111
 
108
112
  ```ruby
@@ -142,7 +146,280 @@ rescue GenesisRuby::Error => error
142
146
  end
143
147
  ```
144
148
 
145
- A full list of the Transaction Types and Custom Attributes can be found [here](https://emerchantpay.github.io/gateway-api-docs/?shell#wpf-transaction-types).
149
+ ### Example 3DSv2 Request
150
+
151
+ Sample request including all the conditionally required/optional params for initiating a 3DS transaction with the 3DSv2-Method authentication protocol.
152
+
153
+ Also, an example is provided for the 3DS-Method-continue API call that will have to be submitted after the 3DS-Method is initiated.
154
+ <details>
155
+
156
+ ```ruby
157
+ require 'genesis_ruby'
158
+
159
+ begin
160
+ genesis_3ds_v2 = GenesisRuby::Genesis.for(config: configuration, request: GenesisRuby::Api::Requests::Financial::Cards::Sale3d) do |request|
161
+ # Common Attributes
162
+ request.transaction_id = '12345-67890'
163
+ request.remote_ip = '127.0.0.1'
164
+ request.amount = '0.99'
165
+ request.currency = 'EUR'
166
+ request.usage = 'Example usage'
167
+ request.customer_email = 'travis@example.com'
168
+ request.customer_phone = '+1987987987987'
169
+
170
+ # Credit Card Attributes
171
+ request.card_holder = 'Travis Pastrana'
172
+
173
+ # Test Cases
174
+ request.card_number = '4012000000060085' # Test Case: Synchronous 3DSv2 Request with Frictionless flow
175
+ # request.card_number = '4066330000000004' # Test Case: Asynchronous 3DSv2 Request with 3DS-Method and Frictionless flow
176
+ # request.card_number = '4918190000000002' # Test Case: Asynchronous 3DSv2 Request with Challenge flow
177
+ # request.card_number = '4938730000000001' # Test Case: Asynchronous 3DSv2 Request with 3DS-Method Challenge flow
178
+ # request.card_number = '4901170000000003' # Test Case: Asynchronous 3DSv2 Request with Fallback flow
179
+ # request.card_number = '4901164281364345' # Test Case: Asynchronous 3DSv2 Request with 3DS-Method Fallback flow
180
+
181
+ request.expiration_month = '12'
182
+ request.expiration_year = '2040'
183
+ request.cvv = '123'
184
+
185
+ # Async Attributes
186
+ request.notification_url = 'https://example.com/notification'
187
+ request.return_success_url = 'https://example.com/success'
188
+ request.return_failure_url = 'https://example.com/failure'
189
+
190
+ # Billing Attributes
191
+ request.billing_first_name = 'Travis'
192
+ request.billing_last_name = 'Pastrana'
193
+ request.billing_address1 = 'Kreisfreie Stadt Berlin'
194
+ request.billing_zip_code = '10115'
195
+ request.billing_city = 'Berlin'
196
+ request.billing_country = 'DE'
197
+
198
+ # Threeds V2 Attributes
199
+
200
+ ## Method Attributes
201
+ request.threeds_v2_method_callback_url = 'https://www.example.com/threeds/threeds_method/callback'
202
+
203
+ ## Control Attributes
204
+ request.threeds_v2_control_device_type =
205
+ GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::Control::DeviceTypes::BROWSER
206
+ request.threeds_v2_control_challenge_window_size =
207
+ GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::Control::ChallengeWindowSizes::FULLSCREEN
208
+ request.threeds_v2_control_challenge_indicator =
209
+ GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::Control::ChallengeIndicators::MANDATE
210
+
211
+ ## Browser Attributes
212
+ ## When Control Device Type is Browser
213
+ request.threeds_v2_browser_accept_header = '*/*'
214
+ request.threeds_v2_browser_java_enabled = true
215
+ request.threeds_v2_browser_language = 'en-GB'
216
+ request.threeds_v2_browser_color_depth = 48
217
+ request.threeds_v2_browser_screen_height = 900
218
+ request.threeds_v2_browser_screen_width = 1440
219
+ request.threeds_v2_browser_time_zone_offset = '+0'
220
+ request.threeds_v2_browser_user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36'
221
+
222
+ ## SDK
223
+ ## When Control Device Type is SDK
224
+ request.threeds_v2_sdk_interface =
225
+ GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::Sdk::Interfaces::BOTH
226
+ request.threeds_v2_sdk_ui_types =
227
+ GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::Sdk::UiTypes::TEXT
228
+ request.threeds_v2_sdk_ui_types =
229
+ GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::Sdk::UiTypes::SINGLE_SELECT
230
+ request.threeds_v2_sdk_ui_types =
231
+ GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::Sdk::UiTypes::MULTI_SELECT
232
+ request.threeds_v2_sdk_application_id = 'fc1650c0-5778-0138-8205-2cbc32a32d65'
233
+ request.threeds_v2_sdk_encrypted_data = 'encrypted-data-here'
234
+ request.threeds_v2_sdk_ephemeral_public_key_pair = 'public-key-pair'
235
+ request.threeds_v2_sdk_max_timeout = 10
236
+ request.threeds_v2_sdk_reference_number = 'sdk-reference-number-her'
237
+
238
+
239
+ ## Purchase Attributes
240
+ request.threeds_v2_purchase_category =
241
+ GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::Purchase::Categories::GOODS
242
+
243
+ ## Recurring
244
+ request.threeds_v2_recurring_expiration_date = '12-12-2024'
245
+ request.threeds_v2_recurring_frequency = 30
246
+
247
+ ## Merchant Risk Attributes
248
+ request.threeds_v2_merchant_risk_shipping_indicator =
249
+ GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::MerchantRisk::ShippingIndicators::SAME_AS_BILLING
250
+ request.threeds_v2_merchant_risk_delivery_timeframe =
251
+ GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::MerchantRisk::DeliveryTimeframes::ANOTHER_DAY
252
+ request.threeds_v2_merchant_risk_reorder_items_indicator =
253
+ GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::MerchantRisk::ReorderItemIndicators::FIRST_TIME
254
+ request.threeds_v2_merchant_risk_pre_order_purchase_indicator =
255
+ GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::MerchantRisk::PreOrderPurchaseIndicators::MERCHANDISE_AVAILABLE
256
+ request.threeds_v2_merchant_risk_pre_order_date = '31-12-2030'
257
+ request.threeds_v2_merchant_risk_gift_card = true
258
+ request.threeds_v2_merchant_risk_gift_card_count = 99
259
+
260
+ ## Card Holder Account Attributes
261
+ request.threeds_v2_card_holder_account_creation_date = '31-12-2022'
262
+ request.threeds_v2_card_holder_account_update_indicator =
263
+ GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::CardHolderAccount::UpdateIndicators::MORE_THAN_60DAYS
264
+ request.threeds_v2_card_holder_account_last_change_date = '31-12-2022'
265
+ request.threeds_v2_card_holder_account_password_change_indicator =
266
+ GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::CardHolderAccount::PasswordChangeIndicators::NO_CHANGE
267
+ request.threeds_v2_card_holder_account_password_change_date = '31-12-2022'
268
+ request.threeds_v2_card_holder_account_shipping_address_usage_indicator =
269
+ GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::CardHolderAccount::ShippingAddressUsageIndicators::MORE_THAN_60DAYS
270
+ request.threeds_v2_card_holder_account_shipping_address_date_first_used = '31-12-2022'
271
+ request.threeds_v2_card_holder_account_transactions_activity_last24_hours = 2
272
+ request.threeds_v2_card_holder_account_transactions_activity_previous_year = 10
273
+ request.threeds_v2_card_holder_account_provision_attempts_last24_hours = 1
274
+ request.threeds_v2_card_holder_account_purchases_count_last6_months = 5
275
+ request.threeds_v2_card_holder_account_suspicious_activity_indicator =
276
+ GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::CardHolderAccount::SuspiciousActivityIndicators::NO_SUSPICIOUS_OBSERVED
277
+ request.threeds_v2_card_holder_account_registration_indicator =
278
+ GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::CardHolderAccount::RegistrationIndicators::MORE_THAN_60DAYS
279
+ request.threeds_v2_card_holder_account_registration_date = '31-12-2022'
280
+
281
+ end.execute
282
+
283
+ response_3ds_v2 = genesis_3ds_v2.response
284
+
285
+ if response_3ds_v2.approved?
286
+ # Transaction approved no customer action required
287
+ # Test Case: Synchronous 3DSv2 Request with Frictionless flow
288
+ puts response_3ds_v2.response_object
289
+ end
290
+
291
+ if response_3ds_v2.declined? || response_3ds_v2.error?
292
+ # Transaction declined no customer action required
293
+ # Synchronous 3DSv2 Request with Frictionless flow
294
+ puts response_3ds_v2.response_object
295
+ end
296
+
297
+ if response_3ds_v2.pending_async?
298
+ # Additional Actions Required
299
+ response_object_3ds_v2 = response_3ds_v2.response_object
300
+
301
+ if response_object_3ds_v2[:redirect_url]
302
+ # An interaction between consumer and issuer is required
303
+ # 3DSv2 Challenge required
304
+ # 3DSv1 payer authentication required - fallback from 3DSv2 to 3DSv1
305
+ # Test Case: Asynchronous 3DSv2 Request with Challenge flow
306
+ # Test Case: Asynchronous 3DSv2 Request with Fallback flow
307
+ puts response_object_3ds_v2[:redirect_url_type]
308
+ puts response_object_3ds_v2[:redirect_url]
309
+ end
310
+
311
+ if response_object_3ds_v2[:threeds_method_url]
312
+ # 3DS-Method submission is required
313
+ # Generate 3DSv2-Method Signature token used for Threeds Method Continue Request. It's not required when the 3DS-Method continue request is built by the initial request's response object.
314
+ puts GenesisRuby::Utils::Threeds::V2.generate_signature(
315
+ unique_id: response_object_3ds_v2[:unique_id],
316
+ amount: response_object_3ds_v2[:amount],
317
+ timestamp: response_object_3ds_v2[:timestamp].strftime(GenesisRuby::Api::Constants::DateTimeFormats::YYYY_MM_DD_H_I_S_ZULU),
318
+ merchant_password: configuration.password
319
+ )
320
+
321
+ # Execute 3DS-Method Continue Request after initiating the 3DS-Method submission
322
+ # The new request is loaded from the response object of the initial request
323
+ genesis_3ds_v2_continue = GenesisRuby::Api::Requests::Financial::Cards::Threeds::V2::MethodContinue.build_from_response_object(
324
+ configuration,
325
+ genesis_3ds_v2.response.response_object
326
+ )
327
+
328
+ genesis_3ds_v2_continue.execute
329
+
330
+ response_3ds_v2_continue = genesis_3ds_v2_continue.response
331
+
332
+ if response_3ds_v2_continue.approved?
333
+ # Transaction APPROVED no customer action required
334
+ # Test Case: Asynchronous 3DSv2 Request with 3DS-Method and Frictionless flow
335
+ puts response_3ds_v2_continue.response_object
336
+ end
337
+
338
+ if response_3ds_v2_continue.declined? || response_3ds_v2_continue.error?
339
+ # Transaction declined no customer action required
340
+ puts response_3ds_v2_continue.response_object
341
+ end
342
+
343
+ if response_3ds_v2_continue.pending_async?
344
+ # Customer action required
345
+ continue_response_object = response_3ds_v2_continue.response_object
346
+
347
+ if continue_response_object[:redirect_url]
348
+ # Test Case: Asynchronous 3DSv2 Request with 3DS-Method Challenge flow
349
+ # Test Case: Asynchronous 3DSv2 Request with 3DS-Method Fallback flow
350
+ puts continue_response_object[:redirect_url_type]
351
+ puts continue_response_object[:redirect_url]
352
+ end
353
+ end
354
+ end
355
+ end
356
+
357
+ rescue GenesisRuby::Error => error
358
+ puts error.message
359
+ end
360
+ ```
361
+
362
+ </details>
363
+
364
+ ### Standalone ThreedsV2 Method Continue Request.
365
+
366
+ <details>
367
+
368
+ ```ruby
369
+ require 'genesis_ruby'
370
+
371
+ begin
372
+ genesis = GenesisRuby::Genesis.for(config: configuration, request: GenesisRuby::Api::Requests::Financial::Cards::Threeds::V2::MethodContinue) do |request|
373
+ # Amount in minor currency unit
374
+ # If the AMOUNT is not in a minor currency unit then SET the CURRENCY. The AMOUNT will be converted into minor currency unit internally using the CURRENCY property.
375
+ # Ex. amount = 10.00
376
+ # currency = 'EUR'
377
+ # The AMOUNT in that case for signature generation will be 1000
378
+ # Amount is included in the response from the initial request in major currency unit genesis.response.response_object[:amount]
379
+ request.amount = 10.00
380
+
381
+ # If CURRENCY is set, AMOUNT value will be converted into MINOR currency unit
382
+ # If you SET the AMOUNT in MINOR currency unit DO NOT set CURRENCY
383
+ # Currency is included in the response from the initial request in major currency unit genesis.response.response_object[:currency]
384
+ request.currency = 'EUR'
385
+
386
+ # Set only one of the unique_id or url
387
+ # request.url = 'https://staging.gate.emerchantpay.net/threeds/threeds_method/d6a6aa96292e4856d4a352ce634a4335'
388
+ request.transaction_unique_id = 'd6a6aa96292e4856d4a352ce634a4335'
389
+
390
+ # String representation of the timestamp
391
+ # request.transaction_timestamp = genesis.response
392
+ # .response_object[:timestamp].strftime(GenesisRuby::Api::Constants::DateTimeFormats::YYYY_MM_DD_H_I_S_ZULU)
393
+ request.transaction_timestamp = '2020-12-31T23:59:59Z'
394
+ end.execute
395
+
396
+ response = genesis.response
397
+
398
+ if response.approved?
399
+ # Asynchronous 3DSv2 Request with 3DS-Method and Frictionless flow
400
+ # Transaction approved no customer action required
401
+ puts response.response_object
402
+ end
403
+
404
+ if response.pending_async?
405
+ # Customer action required
406
+ response_object = response.response_object
407
+
408
+ if response_object[:redirect_url]
409
+ # Asynchronous 3DSv2 Request with 3DS-Method Challenge flow
410
+ # Asynchronous 3DSv2 Request with 3DS-Method Fallback flow
411
+ puts response_object[:redirect_url_type]
412
+ puts response_object[:redirect_url]
413
+ end
414
+ end
415
+
416
+ rescue GenesisRuby::Error => error
417
+ puts error.message
418
+ end
419
+ ```
420
+
421
+ </details>
422
+
146
423
 
147
424
  ### Recurring
148
425
 
@@ -246,6 +523,117 @@ If an error occurs during the Transaction Execution the status is one of the fol
246
523
  ```
247
524
  </details>
248
525
 
526
+ ### Reference actions
527
+ The Reference transaction requests allow actions over an existing payment. The payment can be modified with:
528
+ * Capture - settles a transaction that has been authorized before
529
+ * Void - undo other transactions
530
+ * Refund - allow to return already billed amounts to customers
531
+
532
+ <kbd>!</kbd> Void transaction request doesn't require amount and currency parameters
533
+
534
+ After a successful response of a payment, reference actions can be executed by using the `unique_id`.
535
+
536
+ ```ruby
537
+ require 'genesis_ruby'
538
+
539
+ begin
540
+ genesis = GenesisRuby::Genesis.for(config: configuration, request: GenesisRuby::Api::Requests::Financial::Refund) do |request|
541
+ request.transaction_id = '12345-67890'
542
+ request.amount = '0.99' # not available for GenesisRuby::Api::Requests::Financial::Void
543
+ request.currency = 'EUR' # not available for GenesisRuby::Api::Requests::Financial::Void
544
+ request.usage = 'Example usage'
545
+ request.reference_id = 'unique_id received upon successful payment transaction'
546
+ end.execute
547
+
548
+ puts genesis.response.response_object
549
+
550
+ rescue GenesisRuby::Error => error
551
+ puts error.message
552
+ end
553
+ ```
554
+
555
+ ### Gateway Notification
556
+
557
+ With the asynchronous payment flows like Web Payment Form the Gateway sends the transaction events upon status change on the defined `notification_url`.
558
+ The library contains a Notification module that helps handle the received gateway notification and can provide easy reconciliation execution.
559
+
560
+ #### Initialization
561
+ The notification module requires notification data or any object that responds to `to_h` with a Hash return value.
562
+ For example, with Ruby on Rails you can permit the params and to_h method can be executed without errors:
563
+
564
+ ```ruby
565
+ permitted_params = params.permit(:transaction_id, :terminal_token, :unique_id, :transaction_type, :status, :signature, :amount)
566
+ ```
567
+ A full list of the available params that can be received upon notification can be found [here](https://emerchantpay.github.io/gateway-api-docs/?shell#asynchronous-transactions).
568
+
569
+ ```ruby
570
+ begin
571
+ notification = GenesisRuby::Api::Notification.new configuration, permitted_params
572
+
573
+ # Helper methods
574
+ notification.api_notification?
575
+ notification.wpf_notification?
576
+ notification.unique_id
577
+
578
+ # Executes Gateway Transaction Reconciliation
579
+ # This provides the latest information on the transaction from the Gateway
580
+ notification.reconcile
581
+
582
+ # Provides information if the given reconcile response contains transaction information
583
+ notification.transaction_reconciliation?
584
+
585
+ # Get the Reconcile Response Object in Hash data structure
586
+ notification.reconciliation.response_object
587
+
588
+ # Generate response document expected from the Gateway
589
+ notification.generate_response
590
+ rescue GenesisRuby::ParameterError => error
591
+ puts error.message
592
+ end
593
+ ```
594
+
595
+ #### Reconcile
596
+ Minimum required data for execution of `reconcile`:
597
+
598
+ ```ruby
599
+ {
600
+ unique_id: 'unique_id received from the gateway in the notification params',
601
+ signature: 'the signature received in the notification'
602
+ }
603
+ ```
604
+
605
+ If the signature can't be verified Genesis::Ruby::ParameterError will be raised.
606
+
607
+ #### Helpers
608
+ `notification.reconcile` returns GenesisRuby::Api::Response. The response object can be accessed via `notification.reconciliation`.
609
+ The reconciliation object has every helper that [Response](#response-helpers) contains like checking the status with `error?`, `approved?`, etc.
610
+
611
+ For checking if the `reconciliation.response_object` is a successful transaction response you can use `notification.transaction_reconciliation?`
612
+
613
+ #### Errors
614
+ Upon wrong data like configuration terminal token, `reconciliation.response_object` can be similar:
615
+
616
+ ```ruby
617
+ {
618
+ status: 'error',
619
+ code: '220',
620
+ message: 'Reconcile request failed, please contact support!',
621
+ technical_message: 'Invalid Terminal'
622
+ }
623
+ ```
624
+
625
+ #### Respond to the Gateway
626
+ When receiving the notification, you are required to render an xml page containing the transaction’s unique id so that the gateway knows that you have accepted the notification.
627
+ If the XML is not delivered, the notification is sent periodically until the XML is received.
628
+
629
+ `GenesisRuby::Api::Notification` provides helper method for generation of the expected xml content. The Gateway expects a response with:
630
+ * Status 200
631
+ * Content Type `text/xml`
632
+
633
+ ```ruby
634
+ notification.generate_response
635
+ ```
636
+
249
637
  ### Response Helpers
250
638
 
251
639
  #### Sates
@@ -284,7 +672,7 @@ configuration.sanitize_response = false
284
672
  You can use the following request classes to initialize the Genesis client:
285
673
 
286
674
  ```ruby
287
- # Transactions
675
+ # Financial
288
676
  ## Cards
289
677
  GenesisRuby::Api::Requests::Financial::Cards::Authorize
290
678
  GenesisRuby::Api::Requests::Financial::Cards::Authorize3d
@@ -294,6 +682,17 @@ GenesisRuby::Api::Requests::Financial::Cards::Sale3d
294
682
  # Web Payment Form
295
683
  ## Create
296
684
  GenesisRuby::Api::Requests::Wpf::Create
685
+ GenesisRuby::Api::Requests::Wpf::Reconcile
686
+
687
+ # References
688
+ GenesisRuby::Api::Requests::Financial::Capture
689
+ GenesisRuby::Api::Requests::Financial::Void
690
+ GenesisRuby::Api::Requests::Financial::Refund
691
+
692
+ # Non Financial
693
+ ## Reconcile
694
+ GenesisRuby::Api::Requests::NonFinancial::Reconcile::Transaction
695
+ GenesisRuby::Api::Requests::NonFinancial::Reconcile::DateRange
297
696
  ```
298
697
 
299
698
  ### Manual initialization
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.2
data/genesis_ruby.gemspec CHANGED
@@ -13,10 +13,13 @@ Gem::Specification.new do |spec|
13
13
  spec.license = 'MIT'
14
14
  spec.required_ruby_version = '>= 2.7.0'
15
15
 
16
- spec.metadata['homepage_uri'] = spec.homepage
17
- spec.metadata['source_code_uri'] = 'https://github.com/GenesisGateway/genesis_ruby'
18
- spec.metadata['changelog_uri'] = 'https://github.com/GenesisGateway/genesis_ruby/CHANGELOG.md'
16
+ spec.metadata['homepage_uri'] = spec.homepage
17
+ spec.metadata['source_code_uri'] = 'https://github.com/GenesisGateway/genesis_ruby'
18
+ spec.metadata['changelog_uri'] = 'https://github.com/GenesisGateway/genesis_ruby/blob/main/CHANGELOG.md'
19
+ spec.metadata['documentation_uri'] = 'https://github.com/GenesisGateway/genesis_ruby/blob/main/README.md'
19
20
 
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
20
23
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
21
24
  f.match(%r{^(bin|test|spec|features|sig)/|\.(?:git|pronto|rspec|rubocop)})
22
25
  end
@@ -28,7 +31,7 @@ Gem::Specification.new do |spec|
28
31
  spec.add_runtime_dependency 'net-http', '~> 0.3.2'
29
32
  spec.add_runtime_dependency 'nokogiri', '~> 1.14'
30
33
 
31
- spec.add_development_dependency 'bundler'
34
+ spec.add_development_dependency 'bundler', '~> 2.1'
32
35
  spec.add_development_dependency 'faker', '~> 2.22'
33
36
  spec.add_development_dependency 'faraday-retry', '~> 2.0'
34
37
  spec.add_development_dependency 'pronto', '~> 0.11'
@@ -16,7 +16,7 @@ module GenesisRuby
16
16
  DD_MM_YYYY_L_SLASHES = '%d/%m/%Y'.freeze
17
17
 
18
18
  # Zulu timestamp
19
- YYYY_MM_DD_H_I_S_ZULU = '%Y-%m-%dT%H:%M:%S%z'.freeze
19
+ YYYY_MM_DD_H_I_S_ZULU = '%Y-%m-%dT%H:%M:%SZ'.freeze
20
20
 
21
21
  # Modified Zulu timestamp
22
22
  YYYY_MM_DD_H_I_S = '%Y-%m-%d %H:%M:%S'.freeze