genesis_ruby 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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