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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -0
- data/Gemfile.lock +24 -25
- data/README.md +401 -2
- data/VERSION +1 -1
- data/genesis_ruby.gemspec +7 -4
- data/lib/genesis_ruby/api/constants/date_time_formats.rb +1 -1
- data/lib/genesis_ruby/api/constants/transactions/parameters/refund/bank_account_types.rb +27 -0
- data/lib/genesis_ruby/api/notification.rb +156 -0
- data/lib/genesis_ruby/api/requests/base/financials/credit_card.rb +0 -2
- data/lib/genesis_ruby/api/requests/base/reference.rb +29 -0
- data/lib/genesis_ruby/api/requests/financial/capture.rb +30 -0
- data/lib/genesis_ruby/api/requests/financial/cards/threeds/v2/method_continue.rb +145 -0
- data/lib/genesis_ruby/api/requests/financial/refund.rb +48 -0
- data/lib/genesis_ruby/api/requests/financial/void.rb +28 -0
- data/lib/genesis_ruby/api/requests/non_financial/reconcile/date_range.rb +95 -0
- data/lib/genesis_ruby/api/requests/non_financial/reconcile/transaction.rb +37 -0
- data/lib/genesis_ruby/api/requests/wpf/reconcile.rb +33 -0
- data/lib/genesis_ruby/api/response.rb +6 -5
- data/lib/genesis_ruby/builder.rb +3 -2
- data/lib/genesis_ruby/builders/form.rb +44 -0
- data/lib/genesis_ruby/dependencies.rb +8 -0
- data/lib/genesis_ruby/network/adapter/base_adapter.rb +10 -0
- data/lib/genesis_ruby/network/adapter/net_http_adapter.rb +30 -8
- data/lib/genesis_ruby/network/base_network.rb +16 -0
- data/lib/genesis_ruby/network/net_http.rb +5 -0
- data/lib/genesis_ruby/utils/common.rb +8 -1
- data/lib/genesis_ruby/utils/options/api_config.rb +15 -12
- data/lib/genesis_ruby/utils/options/network_adapter_config.rb +3 -4
- data/lib/genesis_ruby/utils/threeds/v2.rb +21 -0
- data/lib/genesis_ruby/version.rb +1 -1
- data/lib/genesis_ruby.rb +5 -2
- metadata +20 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8cc160e0cdb5cb22dd4726e2471a9d85ba199c4ee2bdd2e8cbd57b057657ce8
|
4
|
+
data.tar.gz: 824dc704419375ffd6276a45d757f1b45e40f6e5d542462d73b18c207392df9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
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.
|
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.
|
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.
|
46
|
+
nokogiri (1.15.5)
|
47
47
|
mini_portile2 (~> 2.8.2)
|
48
48
|
racc (~> 1.4)
|
49
|
-
octokit (
|
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.
|
53
|
+
parser (3.2.2.4)
|
54
54
|
ast (~> 2.4.1)
|
55
55
|
racc
|
56
|
-
pronto (0.11.
|
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, <
|
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.
|
68
|
-
racc (1.7.
|
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
|
74
|
-
regexp_parser (2.8.
|
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.
|
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.
|
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.
|
100
|
+
rubocop-ast (1.30.0)
|
102
101
|
parser (>= 3.2.1.0)
|
103
|
-
rubocop-capybara (2.
|
102
|
+
rubocop-capybara (2.19.0)
|
104
103
|
rubocop (~> 1.41)
|
105
|
-
rubocop-factory_bot (2.
|
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.
|
111
|
-
rubocop (~> 1.
|
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.
|
126
|
+
thor (1.3.0)
|
128
127
|
tilt (2.3.0)
|
129
|
-
unicode-display_width (2.
|
130
|
-
uri (0.
|
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
|
-
|
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
|
-
#
|
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.
|
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']
|
17
|
-
spec.metadata['source_code_uri']
|
18
|
-
spec.metadata['changelog_uri']
|
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:%
|
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
|