swiss-activemerchant 1.0.1 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +38 -35
- data/lib/active_merchant/billing/gateways/axcessms.rb +42 -43
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +2 -2
- data/lib/active_merchant/billing/gateways/fluidpay.rb +5 -5
- data/lib/active_merchant/billing/gateways/klarna.rb +46 -46
- data/lib/active_merchant/billing/gateways/nmi.rb +1 -1
- data/lib/active_merchant/billing/gateways/paynetworx.rb +74 -73
- data/lib/active_merchant/billing/gateways/paypal_standard.rb +6 -6
- data/lib/active_merchant/billing/gateways/pixxels.rb +9 -9
- data/lib/active_merchant/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c66df163d153edf8a62f2395d9fae5f5c1b20a6795ff6fbb1f6f3cfc7482c43
|
4
|
+
data.tar.gz: b227b14b4ec4b26058de6fd0c90565cf1bb76e01d80b4a1e25b4553823cf774f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22cda31d6b255520c3c01309e1353b1616d66f62c009d8af8b400e99bb5d0b25e5d53670b4ce64ba3b482b8bac779b4b3fda215a4c1660bf58ef484ebf6b0e38
|
7
|
+
data.tar.gz: cc3136f9966f13cad62d10c1d6b7e9fa82191b952af2a26041fdae385bca0c638a6c93e2f68326810d4513c9fa8e2983a93c473e4b4250078d687c5656db3a3b
|
data/README.md
CHANGED
@@ -1,44 +1,21 @@
|
|
1
|
-
# Active Merchant
|
2
|
-
[![Build Status](https://github.com/activemerchant/active_merchant/workflows/CI/badge.svg?branch=master)](https://github.com/activemerchant/active_merchant/actions?query=workflow%3ACI)
|
3
|
-
[![Code Climate](https://codeclimate.com/github/activemerchant/active_merchant.svg)](https://codeclimate.com/github/activemerchant/active_merchant)
|
1
|
+
# Swiss Active Merchant
|
4
2
|
|
5
|
-
Active Merchant
|
6
|
-
Shopify's requirements for a simple and unified API to access dozens of different payment
|
7
|
-
gateways with very different internal APIs was the chief principle in designing the library.
|
8
|
-
|
9
|
-
It was developed for usage in Ruby on Rails web applications and integrates seamlessly
|
10
|
-
as a Rails plugin, but it also works excellently as a stand alone Ruby library.
|
11
|
-
|
12
|
-
Active Merchant has been in production use since June 2006 and is now used in most modern
|
13
|
-
Ruby applications which deal with financial transactions. It is maintained by the
|
14
|
-
[Shopify](http://www.shopify.com) and [Spreedly](https://spreedly.com) teams, with much help
|
15
|
-
from an ever-growing set of contributors.
|
16
|
-
|
17
|
-
See [GettingStarted.md](GettingStarted.md) if you want to learn more about using Active Merchant in your
|
18
|
-
applications.
|
19
|
-
|
20
|
-
If you'd like to contribute to Active Merchant, please start with our [Contribution Guide](https://github.com/activemerchant/active_merchant/wiki/Contributing).
|
3
|
+
Swiss Active Merchant stands as an expanded iteration of the Active Merchant gem, designed to offer an enriched experience in handling financial transactions within Ruby applications. Serving as an extension to the renowned Active Merchant, Swiss Active Merchant introduces additional payment gateways.
|
21
4
|
|
22
5
|
## Installation
|
23
6
|
|
24
|
-
### From Git
|
25
|
-
|
26
|
-
You can check out the latest source from git:
|
27
|
-
|
28
|
-
git clone git://github.com/activemerchant/active_merchant.git
|
29
|
-
|
30
7
|
### From RubyGems
|
31
8
|
|
32
9
|
Installation from RubyGems:
|
33
10
|
|
34
11
|
```console
|
35
|
-
gem install activemerchant
|
12
|
+
gem install swiss-activemerchant
|
36
13
|
```
|
37
14
|
|
38
15
|
Or, if you're using Bundler, just add the following to your Gemfile:
|
39
16
|
|
40
17
|
```ruby
|
41
|
-
gem 'activemerchant'
|
18
|
+
gem 'swiss-activemerchant'
|
42
19
|
```
|
43
20
|
|
44
21
|
## Usage
|
@@ -81,14 +58,6 @@ if credit_card.validate.empty?
|
|
81
58
|
end
|
82
59
|
```
|
83
60
|
|
84
|
-
## Contributing
|
85
|
-
|
86
|
-
For more in-depth documentation and tutorials, see [GettingStarted.md](GettingStarted.md) and the
|
87
|
-
[API documentation](http://www.rubydoc.info/github/activemerchant/active_merchant/).
|
88
|
-
|
89
|
-
Emerging ActiveMerchant 3DS conventions are documented in the [Contributing](https://github.com/activemerchant/active_merchant/wiki/Contributing#3ds-options)
|
90
|
-
guide and [Standardized 3DS Fields](https://github.com/activemerchant/active_merchant/wiki/Standardized-3DS-Fields) guide of the wiki.
|
91
|
-
|
92
61
|
## Supported Payment Gateways
|
93
62
|
|
94
63
|
The [ActiveMerchant Wiki](https://github.com/activemerchant/active_merchant/wikis) contains a [table of features supported by each gateway](https://github.com/activemerchant/active_merchant/wiki/Gateway-Feature-Matrix).
|
@@ -239,6 +208,40 @@ The [ActiveMerchant Wiki](https://github.com/activemerchant/active_merchant/wiki
|
|
239
208
|
* [Worldpay Global](http://www.worldpay.com/) - HK, GB, AU, AD, BE, CH, CY, CZ, DE, DK, ES, FI, FR, GI, GR, HU, IE, IL, IT, LI, LU, MC, MT, NL, NO, NZ, PL, PT, SE, SG, SI, SM, TR, UM, VA
|
240
209
|
* [Worldpay Online](https://online.worldpay.com/) - HK, US, GB, AU, AD, BE, CH, CY, CZ, DE, DK, ES, FI, FR, GI, GR, HU, IE, IL, IT, LI, LU, MC, MT, NL, NO, NZ, PL, PT, SE, SG, SI, SM, TR, UM, VA
|
241
210
|
* [Worldpay US](http://www.worldpay.com/us) - US
|
211
|
+
* [Pixxel](https://pixxles.com/) - GB
|
212
|
+
* [Paynetworx](https://paynetworx.com/) - US
|
213
|
+
* [Klarna](https://www.klarna.com/) - AD, AT, BE, BG, CA, CH, CZ, DE, DK, EE, ES, FI, FR, GB, GR, HR, HU, IE, IS, IT, LI, LT, LU, LV, MC, MT, NL, NO, PL, PT, RO, SE, SI, SK, US
|
214
|
+
* [Fluidpay](https://www.fluidpay.com/) - US, CA, GB, AU, DE, FR, ES, IT, JP, SG, HK, BR, MX
|
215
|
+
|
216
|
+
## Publishing Changes to RubyGems
|
217
|
+
|
218
|
+
If you make changes or improvements to this project, we encourage you to share these updates with the community. Follow the steps below to publish your changes to RubyGems:
|
219
|
+
|
220
|
+
1. Increment Version: Update the version number in the lib/your_gem/version.rb file.
|
221
|
+
|
222
|
+
```ruby
|
223
|
+
module YourGem
|
224
|
+
VERSION = 'x.x.x'
|
225
|
+
end
|
226
|
+
```
|
227
|
+
|
228
|
+
2. Build Gem: Build the gem using the following command:
|
229
|
+
|
230
|
+
```console
|
231
|
+
gem build activemerchant.gemspec
|
232
|
+
```
|
233
|
+
|
234
|
+
3. Push to RubyGems: Push the updated gem to RubyGems:
|
235
|
+
|
236
|
+
```console
|
237
|
+
gem push swiss-activemerchant-x.x.x.gem
|
238
|
+
```
|
239
|
+
|
240
|
+
4. Yank Previous Version: If necessary, yank the previous version to prevent installations:
|
241
|
+
|
242
|
+
```console
|
243
|
+
gem yank swiss-activemerchant -v x.x.x
|
244
|
+
```
|
242
245
|
|
243
246
|
## API stability policy
|
244
247
|
|
@@ -98,67 +98,67 @@ module ActiveMerchant #:nodoc:
|
|
98
98
|
private
|
99
99
|
|
100
100
|
def add_payment_method(post, payment_method, options)
|
101
|
-
post[
|
102
|
-
post[
|
103
|
-
post[
|
104
|
-
post[
|
105
|
-
post[
|
106
|
-
post[
|
101
|
+
post['createRegistration'] = true
|
102
|
+
post['card.number'] = payment_method.number
|
103
|
+
post['card.expiryMonth'] = format(payment_method.month, :two_digits)
|
104
|
+
post['card.expiryYear'] = format(payment_method.year, :four_digits)
|
105
|
+
post['card.cvv'] = payment_method.verification_value unless empty?(payment_method.verification_value)
|
106
|
+
post['card.holder'] = options[:billing_address][:name] if options[:billing_address].present?
|
107
107
|
end
|
108
108
|
|
109
109
|
def add_customer_details(post, options)
|
110
|
-
post[
|
111
|
-
post[
|
112
|
-
post[
|
113
|
-
post[
|
110
|
+
post['customer.email'] = options[:email]
|
111
|
+
post['customer.ip'] = options[:ip]
|
112
|
+
post['customer.browser.userAgent'] = options[:browser_details][:identity] if options[:browser_details].present?
|
113
|
+
post['shopperResultUrl'] = options[:redirect_links][:success_url] if options[:redirect_links].present?
|
114
114
|
|
115
115
|
if options[:billing_address].present?
|
116
|
-
post[
|
117
|
-
post[
|
118
|
-
post[
|
119
|
-
post[
|
120
|
-
post[
|
121
|
-
post[
|
116
|
+
post['billing.street1'] = options[:billing_address][:address1]
|
117
|
+
post['billing.street2'] = options[:billing_address][:address2]
|
118
|
+
post['billing.city'] = options[:billing_address][:city]
|
119
|
+
post['billing.postcode'] = options[:billing_address][:zip]
|
120
|
+
post['billing.state'] = options[:billing_address][:state]
|
121
|
+
post['billing.country'] = options[:billing_address][:country]
|
122
122
|
post['customer.phone'] = options[:billing_address][:phone]
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
126
126
|
def add_invoice_details(post, payment_code, amount, options)
|
127
|
-
post[
|
128
|
-
post[
|
129
|
-
post[
|
127
|
+
post['amount'] = localized_amount(amount, options[:currency])
|
128
|
+
post['currency'] = options[:currency]
|
129
|
+
post['paymentType'] = payment_code
|
130
130
|
end
|
131
131
|
|
132
132
|
def add_three_d_secure_data(post, amount, options)
|
133
|
-
post[
|
134
|
-
post[
|
135
|
-
post[
|
136
|
-
post[
|
137
|
-
post[
|
133
|
+
post['threeDSecure.challengeIndicator'] = options[:three_d_secure_data][:challengeIndicator]
|
134
|
+
post['threeDSecure.exemptionFlag'] = options[:three_d_secure_data][:exemptionFlag]
|
135
|
+
post['threeDSecure.verificationId'] = options[:three_d_secure_data][:verificationId]
|
136
|
+
post['threeDSecure.eci'] = options[:three_d_secure_data][:eci]
|
137
|
+
post['threeDSecure.xid'] = options[:three_d_secure_data][:xid]
|
138
138
|
end
|
139
139
|
|
140
140
|
def add_recurring_details(post, options)
|
141
|
-
post[
|
142
|
-
post[
|
143
|
-
post[
|
141
|
+
post['standingInstruction.type'] = 'RECURRING'
|
142
|
+
post['standingInstruction.mode'] = 'INITIAL'
|
143
|
+
post['standingInstruction.source'] = 'CIT'
|
144
144
|
end
|
145
145
|
|
146
146
|
def add_repeated_recurring_details(post, options)
|
147
|
-
post[
|
148
|
-
post[
|
149
|
-
post[
|
147
|
+
post['standingInstruction.type'] = 'RECURRING'
|
148
|
+
post['standingInstruction.mode'] = 'REPEATED'
|
149
|
+
post['standingInstruction.source'] = 'MIT'
|
150
150
|
end
|
151
151
|
|
152
|
-
def commit(action, params, method = :post, authorization=nil)
|
153
|
-
params = params.merge(
|
152
|
+
def commit(action, params, method = :post, authorization = nil)
|
153
|
+
params = params.merge('entityId' => @options[:entityId])
|
154
154
|
request_body = post_data(action, params)
|
155
155
|
request_endpoint = url(action, authorization)
|
156
|
-
raw_response =
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
156
|
+
raw_response = if method == :post
|
157
|
+
ssl_post(request_endpoint, request_body, headers)
|
158
|
+
else
|
159
|
+
request_endpoint += "?#{request_body}"
|
160
|
+
ssl_get(request_endpoint, headers)
|
161
|
+
end
|
162
162
|
response = JSON.parse(raw_response)
|
163
163
|
|
164
164
|
succeeded = success_from(response)
|
@@ -166,11 +166,11 @@ module ActiveMerchant #:nodoc:
|
|
166
166
|
succeeded,
|
167
167
|
message_from(succeeded, response),
|
168
168
|
response,
|
169
|
-
authorization: authorization_from(response, params[
|
169
|
+
authorization: authorization_from(response, params['paymentType']),
|
170
170
|
response_type: response_type(response.dig('result', 'code')),
|
171
171
|
test: test?,
|
172
172
|
response_http_code: @response_http_code,
|
173
|
-
request_endpoint
|
173
|
+
request_endpoint: request_endpoint,
|
174
174
|
request_method: method,
|
175
175
|
request_body: params
|
176
176
|
)
|
@@ -187,7 +187,7 @@ module ActiveMerchant #:nodoc:
|
|
187
187
|
when :capture, :refund, :void, :rebill, :confirm
|
188
188
|
"#{base_url}#{API_VERSION}/payments/#{split_authorization(authorization)}"
|
189
189
|
when :registration_token_purchase
|
190
|
-
|
190
|
+
"#{base_url}#{API_VERSION}/registrations/#{authorization}/payments"
|
191
191
|
end
|
192
192
|
end
|
193
193
|
|
@@ -201,7 +201,7 @@ module ActiveMerchant #:nodoc:
|
|
201
201
|
end
|
202
202
|
|
203
203
|
def authorization_from(response, payment_type)
|
204
|
-
authorization = response[
|
204
|
+
authorization = response['id'].present? ? response['id'] : 'Failed'
|
205
205
|
[authorization, payment_type].join('#')
|
206
206
|
end
|
207
207
|
|
@@ -223,7 +223,6 @@ module ActiveMerchant #:nodoc:
|
|
223
223
|
SUCCESS_CODES.include?(code)
|
224
224
|
end
|
225
225
|
|
226
|
-
|
227
226
|
def response_type(code)
|
228
227
|
if SUCCESS_CODES.include?(code)
|
229
228
|
0
|
@@ -401,7 +401,7 @@ module ActiveMerchant #:nodoc:
|
|
401
401
|
succeeded = success_from(action, response)
|
402
402
|
|
403
403
|
additional_data = {
|
404
|
-
request_endpoint
|
404
|
+
request_endpoint: request_endpoint,
|
405
405
|
request_method: method,
|
406
406
|
request_body: parse(request_body),
|
407
407
|
response_http_code: @response_http_code
|
@@ -416,7 +416,7 @@ module ActiveMerchant #:nodoc:
|
|
416
416
|
cvv_result = successful_response ? cvv_result(response) : nil
|
417
417
|
authorization = authorization_from(response) unless action == :unstore
|
418
418
|
body = action == :unstore ? { response_code: response.to_s } : response
|
419
|
-
response_code =
|
419
|
+
response_code = action == :refund && succeeded ? '10000' : response.dig('response_code')
|
420
420
|
|
421
421
|
Response.new(
|
422
422
|
succeeded,
|
@@ -10,7 +10,7 @@ module ActiveMerchant #:nodoc:
|
|
10
10
|
self.live_url = 'https://app.fluidpay.com'
|
11
11
|
self.default_currency = 'USD'
|
12
12
|
self.money_format = :dollars
|
13
|
-
self.supported_countries = [
|
13
|
+
self.supported_countries = %w[US CA GB AU DE FR ES IT JP SG HK BR MX]
|
14
14
|
self.supported_cardtypes = %i[visa master american_express discover diners_club jcb]
|
15
15
|
self.homepage_url = 'https://www.fluidpay.com/'
|
16
16
|
self.display_name = 'Fluidpay'
|
@@ -195,8 +195,8 @@ module ActiveMerchant #:nodoc:
|
|
195
195
|
end
|
196
196
|
|
197
197
|
def commit(action, params)
|
198
|
-
request_url = action ==
|
199
|
-
request_url = (request_url +
|
198
|
+
request_url = action == 'customer' ? "#{url}/api/vault/customer" : "#{url}/api/transaction"
|
199
|
+
request_url = (request_url + '/' + params[:transactionid] + '/' + action) if params[:transactionid].present?
|
200
200
|
raw_response = ssl_post(request_url, params.to_json, headers)
|
201
201
|
response = parse(raw_response)
|
202
202
|
succeeded = success_from(response)
|
@@ -241,14 +241,14 @@ module ActiveMerchant #:nodoc:
|
|
241
241
|
end
|
242
242
|
|
243
243
|
def success_from(response)
|
244
|
-
response[
|
244
|
+
response['msg'] == 'success'
|
245
245
|
end
|
246
246
|
|
247
247
|
def message_from(succeeded, response)
|
248
248
|
if succeeded
|
249
249
|
'Succeeded'
|
250
250
|
else
|
251
|
-
response[
|
251
|
+
response['msg']
|
252
252
|
end
|
253
253
|
end
|
254
254
|
|
@@ -9,7 +9,7 @@ module ActiveMerchant
|
|
9
9
|
self.display_name = 'Klarna'
|
10
10
|
self.homepage_url = 'https://www.klarna.com/'
|
11
11
|
|
12
|
-
def initialize(options={})
|
12
|
+
def initialize(options = {})
|
13
13
|
requires!(options, :login, :password, :zone)
|
14
14
|
@options = options
|
15
15
|
|
@@ -55,17 +55,17 @@ module ActiveMerchant
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
-
def purchase(amount, authorize_token, options={})
|
58
|
+
def purchase(amount, authorize_token, options = {})
|
59
59
|
post = {}
|
60
60
|
prepare_billing_address(post, options)
|
61
61
|
prepare_line_items(post, options)
|
62
62
|
prepare_order_data(post, options)
|
63
|
-
post[
|
63
|
+
post['order_amount'] = amount.to_f
|
64
64
|
|
65
65
|
customer_order(amount, authorize_token, post)
|
66
66
|
end
|
67
67
|
|
68
|
-
def authorize(amount, authorize_token, options={})
|
68
|
+
def authorize(amount, authorize_token, options = {})
|
69
69
|
response = Klarna.client(:payment).place_order(authorize_token, options)
|
70
70
|
|
71
71
|
if response.success?
|
@@ -76,7 +76,7 @@ module ActiveMerchant
|
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
-
def customer_order(amount, customer_token, options={})
|
79
|
+
def customer_order(amount, customer_token, options = {})
|
80
80
|
response = Klarna.client(:customer_token).place_order(customer_token, options)
|
81
81
|
|
82
82
|
if response.success?
|
@@ -87,8 +87,8 @@ module ActiveMerchant
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
-
def capture(amount, order_id, options={})
|
91
|
-
response = Klarna.client.capture(order_id, {captured_amount: amount, shipping_info: options[:shipping_info]})
|
90
|
+
def capture(amount, order_id, options = {})
|
91
|
+
response = Klarna.client.capture(order_id, { captured_amount: amount, shipping_info: options[:shipping_info] })
|
92
92
|
|
93
93
|
if response.success?
|
94
94
|
message = "Captured order with Klarna id: '#{order_id}' Capture id: '#{response['Capture-ID']}'"
|
@@ -98,12 +98,12 @@ module ActiveMerchant
|
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
|
-
def refund(amount, order_id, options={})
|
101
|
+
def refund(amount, order_id, options = {})
|
102
102
|
# Get the refunded line items for better customer communications
|
103
103
|
post = {}
|
104
104
|
prepare_line_items(post, options)
|
105
105
|
|
106
|
-
response = Klarna.client(:refund).create(order_id, {refunded_amount: amount})
|
106
|
+
response = Klarna.client(:refund).create(order_id, { refunded_amount: amount })
|
107
107
|
|
108
108
|
if response.success?
|
109
109
|
message = "Refunded order with Klarna id: #{order_id}"
|
@@ -113,7 +113,7 @@ module ActiveMerchant
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
-
def store(authorize_token, options={})
|
116
|
+
def store(authorize_token, options = {})
|
117
117
|
post = {}
|
118
118
|
prepare_billing_address(post, options)
|
119
119
|
prepare_customer_data(post, options)
|
@@ -121,7 +121,7 @@ module ActiveMerchant
|
|
121
121
|
response = Klarna.client(:payment).customer_token(authorize_token, post)
|
122
122
|
|
123
123
|
if response.success?
|
124
|
-
message =
|
124
|
+
message = 'Client token Created'
|
125
125
|
generate_success_response(response, message)
|
126
126
|
else
|
127
127
|
generate_failure_response(response)
|
@@ -132,14 +132,14 @@ module ActiveMerchant
|
|
132
132
|
response = Klarna.client(:customer_token).get(authorize_token)
|
133
133
|
|
134
134
|
if response.success?
|
135
|
-
message =
|
135
|
+
message = 'Client token details'
|
136
136
|
generate_success_response(response, message)
|
137
137
|
else
|
138
138
|
generate_failure_response(response)
|
139
139
|
end
|
140
140
|
end
|
141
141
|
|
142
|
-
|
142
|
+
alias credit refund
|
143
143
|
|
144
144
|
def get(order_id)
|
145
145
|
Klarna.client.get(order_id)
|
@@ -218,14 +218,14 @@ module ActiveMerchant
|
|
218
218
|
|
219
219
|
private
|
220
220
|
|
221
|
-
def generate_success_response(response, message, authorization=nil, fraud_status=nil)
|
221
|
+
def generate_success_response(response, message, authorization = nil, fraud_status = nil)
|
222
222
|
ActiveMerchant::Billing::Response.new(
|
223
223
|
true,
|
224
224
|
message,
|
225
225
|
response.body || {},
|
226
226
|
{
|
227
|
-
authorization
|
228
|
-
fraud_status
|
227
|
+
authorization: authorization,
|
228
|
+
fraud_status: fraud_status,
|
229
229
|
response_http_code: response.http_response&.code,
|
230
230
|
request_endpoint: response.request_endpoint,
|
231
231
|
request_method: response.request_method,
|
@@ -265,52 +265,52 @@ module ActiveMerchant
|
|
265
265
|
def prepare_line_items(post, options)
|
266
266
|
return unless options[:order_line_items].present?
|
267
267
|
|
268
|
-
post[
|
269
|
-
final_amount = item[
|
270
|
-
unit_price = item[
|
268
|
+
post['order_lines'] = options[:order_line_items].map do |item|
|
269
|
+
final_amount = item['final_amount'] ? item['final_amount'].to_f * 100 : nil
|
270
|
+
unit_price = item['price'] ? item['price'].to_f * 100 : nil
|
271
271
|
|
272
272
|
{
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
273
|
+
'name' => item['name'],
|
274
|
+
'quantity' => item['quantity'],
|
275
|
+
'total_amount' => final_amount,
|
276
|
+
'unit_price' => unit_price
|
277
277
|
}
|
278
278
|
end
|
279
279
|
end
|
280
280
|
|
281
281
|
def prepare_billing_address(post, options)
|
282
282
|
return unless options[:billing_address].present?
|
283
|
+
|
283
284
|
firstname, lastname = split_names(options[:billing_address][:name])
|
284
285
|
|
285
|
-
post[
|
286
|
-
post[
|
287
|
-
post[
|
288
|
-
post[
|
289
|
-
post[
|
290
|
-
post[
|
291
|
-
post[
|
292
|
-
post[
|
293
|
-
post[
|
294
|
-
post[
|
295
|
-
post[
|
286
|
+
post['billing_address'] = {}
|
287
|
+
post['billing_address']['given_name'] = firstname
|
288
|
+
post['billing_address']['family_name'] = lastname
|
289
|
+
post['billing_address']['email'] = options[:email]
|
290
|
+
post['billing_address']['street_address'] = options[:billing_address][:address1]
|
291
|
+
post['billing_address']['street_address2'] = options[:billing_address][:address2]
|
292
|
+
post['billing_address']['organization_name'] = options[:billing_address][:company]
|
293
|
+
post['billing_address']['city'] = options[:billing_address][:city]
|
294
|
+
post['billing_address']['region'] = options[:billing_address][:state]
|
295
|
+
post['billing_address']['postal_code'] = options[:billing_address][:zip]
|
296
|
+
post['billing_address']['country'] = options[:billing_address][:country]
|
296
297
|
end
|
297
298
|
|
298
|
-
|
299
299
|
def prepare_order_data(post, options)
|
300
|
-
post[
|
301
|
-
post[
|
302
|
-
post[
|
303
|
-
post[
|
304
|
-
post[
|
305
|
-
post[
|
300
|
+
post['auto_capture'] = true
|
301
|
+
post['intent'] = 'buy_and_tokenize'
|
302
|
+
post['purchase_country'] = options.dig(:billing_address, :country)
|
303
|
+
post['purchase_currency'] = options[:currency]
|
304
|
+
post['order_amount'] = options[:total]&.to_f
|
305
|
+
post['order_tax_amount'] = options[:tax]&.to_f
|
306
306
|
end
|
307
307
|
|
308
308
|
def prepare_customer_data(post, options)
|
309
|
-
post[
|
310
|
-
post[
|
311
|
-
post[
|
312
|
-
post[
|
313
|
-
post[
|
309
|
+
post['purchase_country'] = options.dig(:billing_address, :country)
|
310
|
+
post['purchase_currency'] = options[:currency]
|
311
|
+
post['intended_use'] = 'SUBSCRIPTION'
|
312
|
+
post['description'] = 'For Recurring Payments'
|
313
|
+
post['locale'] = options[:locale]
|
314
314
|
end
|
315
315
|
end
|
316
316
|
end
|
@@ -248,7 +248,7 @@ module ActiveMerchant #:nodoc:
|
|
248
248
|
end
|
249
249
|
|
250
250
|
if (descriptor = options[:descriptors])
|
251
|
-
post[:descriptor] =
|
251
|
+
post[:descriptor] = options[:descriptor]
|
252
252
|
post[:descriptor_phone] = descriptor[:descriptor_phone]
|
253
253
|
post[:descriptor_address] = descriptor[:descriptor_address]
|
254
254
|
post[:descriptor_city] = descriptor[:descriptor_city]
|
@@ -27,7 +27,7 @@ module ActiveMerchant
|
|
27
27
|
add_customer_data(post, options)
|
28
28
|
add_transaction_descriptor(post, options)
|
29
29
|
add_point_of_sale(post, options) if payment_method.is_a?(String)
|
30
|
-
commit(post,
|
30
|
+
commit(post, 'auth')
|
31
31
|
end
|
32
32
|
|
33
33
|
def purchase(amount, payment_method, options = {})
|
@@ -37,7 +37,7 @@ module ActiveMerchant
|
|
37
37
|
add_customer_data(post, options)
|
38
38
|
add_transaction_descriptor(post, options)
|
39
39
|
add_point_of_sale(post, options) if payment_method.is_a?(String)
|
40
|
-
commit(post,
|
40
|
+
commit(post, 'authcapture')
|
41
41
|
end
|
42
42
|
|
43
43
|
def refund(amount, authorization, options = {})
|
@@ -45,7 +45,7 @@ module ActiveMerchant
|
|
45
45
|
add_invoice(post, amount, options)
|
46
46
|
add_customer_data(post, options)
|
47
47
|
process_payment(post, authorization)
|
48
|
-
commit(post,
|
48
|
+
commit(post, 'refund')
|
49
49
|
end
|
50
50
|
|
51
51
|
def capture(amount, authorization, options = {})
|
@@ -53,7 +53,7 @@ module ActiveMerchant
|
|
53
53
|
add_invoice(post, amount, options)
|
54
54
|
add_customer_data(post, options)
|
55
55
|
process_payment(post, authorization)
|
56
|
-
commit(post,
|
56
|
+
commit(post, 'capture')
|
57
57
|
end
|
58
58
|
|
59
59
|
def void(authorization, options = {})
|
@@ -61,117 +61,113 @@ module ActiveMerchant
|
|
61
61
|
add_customer_data(post, options)
|
62
62
|
process_payment(post, authorization)
|
63
63
|
void_reasons(post, options)
|
64
|
-
commit(post,
|
64
|
+
commit(post, 'void')
|
65
65
|
end
|
66
66
|
|
67
67
|
private
|
68
68
|
|
69
69
|
def add_invoice(post, amount, options)
|
70
|
-
post[
|
71
|
-
post[
|
72
|
-
post[
|
70
|
+
post['Amount'] = {}
|
71
|
+
post['Amount']['Total'] = localized_amount(amount, options[:currency])
|
72
|
+
post['Amount']['Currency'] = options[:currency] || currency(amount)
|
73
73
|
end
|
74
74
|
|
75
75
|
def add_payment_method(post, payment_method, options)
|
76
|
-
post[
|
76
|
+
post['PaymentMethod'] = { 'Card' => {} }
|
77
77
|
|
78
78
|
if payment_method.is_a?(String)
|
79
|
-
post[
|
80
|
-
post[
|
79
|
+
post['PaymentMethod']['Card']['CardPresent'] = false
|
80
|
+
post['PaymentMethod']['Token'] = { 'TokenID' => payment_method }
|
81
81
|
else
|
82
|
-
post[
|
83
|
-
post[
|
84
|
-
card_info = post[
|
85
|
-
|
86
|
-
card_info[
|
87
|
-
card_info[
|
88
|
-
|
89
|
-
|
90
|
-
|
82
|
+
post['DataAction'] = 'token/add'
|
83
|
+
post['PaymentMethod']['Card']['CardPresent'] = true
|
84
|
+
card_info = post['PaymentMethod']['Card']
|
85
|
+
|
86
|
+
card_info['CVC'] = { 'CVC' => payment_method.verification_value } unless empty?(payment_method.verification_value)
|
87
|
+
card_info['PAN'] = {
|
88
|
+
'PAN' => payment_method.number,
|
89
|
+
'ExpMonth' => format(payment_method.month, :two_digits),
|
90
|
+
'ExpYear' => format(payment_method.year, :two_digits)
|
91
91
|
}
|
92
92
|
end
|
93
93
|
|
94
|
-
card_info = post[
|
94
|
+
card_info = post['PaymentMethod']['Card']
|
95
95
|
|
96
96
|
if options[:billing_address].present?
|
97
97
|
billing_address = options[:billing_address]
|
98
|
-
card_info[
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
98
|
+
card_info['BillingAddress'] = {
|
99
|
+
'Name' => billing_address[:name],
|
100
|
+
'Line1' => billing_address[:address1],
|
101
|
+
'Line2' => billing_address[:address2],
|
102
|
+
'City' => billing_address[:city],
|
103
|
+
'State' => billing_address[:state],
|
104
|
+
'PostalCode' => billing_address[:zip],
|
105
|
+
'Country' => billing_address[:country],
|
106
|
+
'Phone' => billing_address[:phone],
|
107
|
+
'Email' => options[:email]
|
108
108
|
}
|
109
109
|
end
|
110
110
|
|
111
111
|
if options[:three_d_secure].present?
|
112
|
-
secure_info = card_info[
|
113
|
-
secure_info[
|
114
|
-
secure_info[
|
115
|
-
secure_info[
|
112
|
+
secure_info = card_info['3DSecure'] = {}
|
113
|
+
secure_info['AuthenticationValue'] = options[:three_d_secure][:splitSdkServerTransId]
|
114
|
+
secure_info['ECommerceIndicator'] = options[:three_d_secure][:eci]
|
115
|
+
secure_info['3DSecureTransactionID'] = options[:three_d_secure][:authenticationValue]
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
119
119
|
def add_point_of_sale(post, options)
|
120
|
-
post[
|
121
|
-
post[
|
122
|
-
post[
|
123
|
-
post[
|
124
|
-
post[
|
125
|
-
post[
|
126
|
-
post[
|
127
|
-
post[
|
120
|
+
post['POS'] = {}
|
121
|
+
post['POS']['EntryMode'] = 'card-on-file'
|
122
|
+
post['POS']['Type'] = 'recurring'
|
123
|
+
post['POS']['Device'] = 'NA'
|
124
|
+
post['POS']['DeviceVersion'] = 'NA'
|
125
|
+
post['POS']['Application'] = 'Swiss CRM'
|
126
|
+
post['POS']['ApplicationVersion'] = API_VERSION
|
127
|
+
post['POS']['Timestamp'] = formated_timestamp
|
128
128
|
end
|
129
129
|
|
130
130
|
def add_customer_data(post, options)
|
131
|
-
post[
|
132
|
-
post[
|
133
|
-
post[
|
134
|
-
post[
|
131
|
+
post['Detail'] = {}
|
132
|
+
post['Detail']['MerchantData'] = {}
|
133
|
+
post['Detail']['MerchantData']['OrderNumber'] = options[:order_id]
|
134
|
+
post['Detail']['MerchantData']['CustomerID'] = options[:customer_id]
|
135
135
|
end
|
136
136
|
|
137
137
|
def add_transaction_descriptor(post, options)
|
138
138
|
return unless options[:descriptor]
|
139
139
|
|
140
|
-
post[
|
141
|
-
post[
|
142
|
-
post[
|
140
|
+
post['Attributes'] = {}
|
141
|
+
post['Attributes']['TransactionDescriptor'] = {}
|
142
|
+
post['Attributes']['TransactionDescriptor']['Prefix'] = split_descriptor(options[:descriptor])
|
143
143
|
end
|
144
144
|
|
145
145
|
def process_payment(post, authorization)
|
146
|
-
post[
|
146
|
+
post['TransactionID'], = split_authorization(authorization)
|
147
147
|
end
|
148
148
|
|
149
149
|
def void_reasons(post, options)
|
150
|
-
post[
|
151
|
-
post[
|
150
|
+
post['Reason'] = options[:reason] if options[:reason].present?
|
151
|
+
post['Detail']['MerchantData']['VoidReason'] = options[:void_reason] if options[:void_reason].present?
|
152
152
|
end
|
153
153
|
|
154
154
|
def commit(params, action)
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
request.body = params.to_json
|
161
|
-
response = http.request(request)
|
162
|
-
response_data = JSON.parse(response.body)
|
163
|
-
succeeded = success_from(response_data["ResponseText"])
|
155
|
+
request_body = params.to_json
|
156
|
+
request_endpoint = "#{url}#{action}"
|
157
|
+
response = ssl_post(request_endpoint, request_body, headers)
|
158
|
+
response_data = JSON.parse(response)
|
159
|
+
succeeded = success_from(response_data['ResponseText'])
|
164
160
|
Response.new(
|
165
161
|
succeeded,
|
166
|
-
response_data[
|
162
|
+
response_data['ResponseText'],
|
167
163
|
response_data,
|
168
164
|
authorization: authorization_from(response_data, action),
|
169
165
|
test: test?,
|
170
|
-
response_type: response_type(response_data[
|
171
|
-
response_http_code:
|
172
|
-
request_endpoint:
|
166
|
+
response_type: response_type(response_data['ResponseCode']),
|
167
|
+
response_http_code: @response_http_code,
|
168
|
+
request_endpoint: request_endpoint,
|
173
169
|
request_method: :post,
|
174
|
-
request_body:
|
170
|
+
request_body: request_body
|
175
171
|
)
|
176
172
|
end
|
177
173
|
|
@@ -184,19 +180,19 @@ module ActiveMerchant
|
|
184
180
|
end
|
185
181
|
|
186
182
|
def success_from(resonse_message)
|
187
|
-
resonse_message&.downcase&.include?(
|
183
|
+
resonse_message&.downcase&.include?('approved') ? true : false
|
188
184
|
end
|
189
185
|
|
190
186
|
def authorization_from(response, payment_type)
|
191
|
-
authorization = response[
|
187
|
+
authorization = response['TransactionID'].present? ? response['TransactionID'] : 'Failed'
|
192
188
|
[authorization, payment_type].join('#')
|
193
189
|
end
|
194
190
|
|
195
191
|
def headers
|
196
|
-
|
192
|
+
{
|
197
193
|
'Content-Type' => 'application/json',
|
198
|
-
|
199
|
-
|
194
|
+
'Request-ID' => @options[:request_id],
|
195
|
+
'Authorization' => "Basic #{basic_auth}"
|
200
196
|
}
|
201
197
|
end
|
202
198
|
|
@@ -220,7 +216,12 @@ module ActiveMerchant
|
|
220
216
|
|
221
217
|
def formated_timestamp
|
222
218
|
current_time = Time.now.utc
|
223
|
-
current_time.strftime(
|
219
|
+
current_time.strftime('%Y-%m-%dT%H:%M:%S')
|
220
|
+
end
|
221
|
+
|
222
|
+
def handle_response(response)
|
223
|
+
@response_http_code = response.code.to_i
|
224
|
+
response.body
|
224
225
|
end
|
225
226
|
end
|
226
227
|
end
|
@@ -98,7 +98,7 @@ module ActiveMerchant
|
|
98
98
|
|
99
99
|
def normalize_response(action, response)
|
100
100
|
if action == :create_order && response.present?
|
101
|
-
redirect_link = response['links'].find { |link| link['rel'] ==
|
101
|
+
redirect_link = response['links'].find { |link| link['rel'] == 'payer-action' }
|
102
102
|
response['_links'] = { 'redirect' => { 'href' => redirect_link['href'] } } if redirect_link
|
103
103
|
response['order_id'] = response['id']
|
104
104
|
end
|
@@ -132,7 +132,7 @@ module ActiveMerchant
|
|
132
132
|
end
|
133
133
|
|
134
134
|
def headers
|
135
|
-
|
135
|
+
{ 'Authorization' => "Bearer #{@access_token}", 'Content-Type' => 'application/json', 'PayPal-Request-Id' => @request_id }
|
136
136
|
end
|
137
137
|
|
138
138
|
def post_data(post)
|
@@ -152,7 +152,7 @@ module ActiveMerchant
|
|
152
152
|
end
|
153
153
|
|
154
154
|
def grant_type
|
155
|
-
|
155
|
+
'grant_type=client_credentials'
|
156
156
|
end
|
157
157
|
|
158
158
|
def success_from(response)
|
@@ -205,8 +205,8 @@ module ActiveMerchant
|
|
205
205
|
payment_source = post[:payment_source][:paypal] = {}
|
206
206
|
experience_context = payment_source[:experience_context] = {}
|
207
207
|
|
208
|
-
experience_context[:landing_page] =
|
209
|
-
experience_context[:user_action] =
|
208
|
+
experience_context[:landing_page] = 'LOGIN'
|
209
|
+
experience_context[:user_action] = 'PAY_NOW'
|
210
210
|
experience_context[:return_url] = redirect_links[:success_url] if redirect_links
|
211
211
|
experience_context[:cancel_url] = redirect_links[:failure_url] if redirect_links
|
212
212
|
when 'giropay'
|
@@ -241,7 +241,7 @@ module ActiveMerchant
|
|
241
241
|
end
|
242
242
|
|
243
243
|
def add_payment_intent(post)
|
244
|
-
post[:intent] =
|
244
|
+
post[:intent] = 'CAPTURE'
|
245
245
|
end
|
246
246
|
|
247
247
|
def add_refund_amount(post, amount, options)
|
@@ -113,14 +113,14 @@ module ActiveMerchant #:nodoc:
|
|
113
113
|
def add_three_ds_fields(post, options)
|
114
114
|
if (three_d_secure = options[:pixxel_three_d_secure])
|
115
115
|
post[:threeDSRef] = three_d_secure[:threeDSRef]
|
116
|
-
post[
|
116
|
+
post['threeDSResponse[threeDSMethodData]'] = three_d_secure[:threeDSMethodData]
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
120
|
def add_three_ds_level_2_fields(post, options)
|
121
121
|
if (three_d_secure = options[:pixxel_three_d_secure])
|
122
122
|
post[:threeDSRef] = three_d_secure[:threeDSRef]
|
123
|
-
post[
|
123
|
+
post['threeDSResponse[cres]'] = three_d_secure[:cres]
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
@@ -144,13 +144,13 @@ module ActiveMerchant #:nodoc:
|
|
144
144
|
end
|
145
145
|
|
146
146
|
def add_recurring_type(post)
|
147
|
-
post[:rtAgreementType] =
|
147
|
+
post[:rtAgreementType] = 'recurring'
|
148
148
|
end
|
149
149
|
|
150
150
|
def add_recurring_details(post, amount, options)
|
151
151
|
post[:amount] = amount.to_s
|
152
|
-
post[:type] =
|
153
|
-
post[:avscv2CheckRequired] =
|
152
|
+
post[:type] = '9'
|
153
|
+
post[:avscv2CheckRequired] = 'N'
|
154
154
|
end
|
155
155
|
|
156
156
|
def add_refund_details(post, amount, options)
|
@@ -163,7 +163,7 @@ module ActiveMerchant #:nodoc:
|
|
163
163
|
params[:merchantID] = @options[:merchant_id]
|
164
164
|
sorted_params = params.transform_keys(&:to_s).sort.to_h
|
165
165
|
|
166
|
-
sorted_params[
|
166
|
+
sorted_params['signature'] = get_signature(sorted_params)
|
167
167
|
raw_response = ssl_post(url, post_data(action, sorted_params), headers)
|
168
168
|
response = parse(raw_response)
|
169
169
|
succeeded = success_from(response)
|
@@ -208,7 +208,7 @@ module ActiveMerchant #:nodoc:
|
|
208
208
|
end
|
209
209
|
|
210
210
|
def parse(body)
|
211
|
-
Hash[CGI
|
211
|
+
Hash[CGI.parse(body).map { |k, v| [k.intern, v.first] }]
|
212
212
|
end
|
213
213
|
|
214
214
|
def success_from(response)
|
@@ -219,7 +219,7 @@ module ActiveMerchant #:nodoc:
|
|
219
219
|
if succeeded
|
220
220
|
'Succeeded'
|
221
221
|
else
|
222
|
-
response[:responseMessage] ==
|
222
|
+
response[:responseMessage] == '3DS authentication required' ? '3DS_REQUIRED' : response[:responseMessage]
|
223
223
|
end
|
224
224
|
end
|
225
225
|
|
@@ -252,7 +252,7 @@ module ActiveMerchant #:nodoc:
|
|
252
252
|
end
|
253
253
|
|
254
254
|
def get_signature(params)
|
255
|
-
signature = params.map { |k, v| "#{CGI
|
255
|
+
signature = params.map { |k, v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}" }.join('&')
|
256
256
|
signature += @options[:signature_key]
|
257
257
|
signature.gsub!(/(\r\n|\n\r|\r)/, "\n")
|
258
258
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: swiss-activemerchant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tobias Luetke
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -484,7 +484,7 @@ licenses:
|
|
484
484
|
- MIT
|
485
485
|
metadata:
|
486
486
|
allowed_push_host: https://rubygems.org
|
487
|
-
post_install_message:
|
487
|
+
post_install_message:
|
488
488
|
rdoc_options: []
|
489
489
|
require_paths:
|
490
490
|
- lib
|
@@ -499,8 +499,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
499
499
|
- !ruby/object:Gem::Version
|
500
500
|
version: '0'
|
501
501
|
requirements: []
|
502
|
-
rubygems_version: 3.
|
503
|
-
signing_key:
|
502
|
+
rubygems_version: 3.4.10
|
503
|
+
signing_key:
|
504
504
|
specification_version: 4
|
505
505
|
summary: Framework and tools for dealing with credit card transactions.
|
506
506
|
test_files: []
|