activemerchant 1.43.0 → 1.43.1
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +2 -2
- data.tar.gz.sig +0 -0
- data/CHANGELOG +10 -0
- data/lib/active_merchant/billing/gateway.rb +17 -4
- data/lib/active_merchant/billing/gateways/app55.rb +1 -2
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +2 -1
- data/lib/active_merchant/billing/gateways/card_stream.rb +1 -2
- data/lib/active_merchant/billing/gateways/certo_direct.rb +1 -1
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +7 -3
- data/lib/active_merchant/billing/gateways/secure_pay.rb +1 -0
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +1 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +19 -7
- data/lib/active_merchant/billing/gateways/transnational.rb +1 -0
- data/lib/active_merchant/billing/gateways/webpay.rb +4 -12
- data/lib/active_merchant/billing/integrations/helper.rb +2 -2
- data/lib/active_merchant/billing/integrations/klarna.rb +71 -0
- data/lib/active_merchant/billing/integrations/klarna/helper.rb +123 -0
- data/lib/active_merchant/billing/integrations/klarna/notification.rb +103 -0
- data/lib/active_merchant/billing/integrations/mollie_ideal/helper.rb +2 -2
- data/lib/active_merchant/version.rb +1 -1
- metadata +5 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be737ebc9d332b9571aa148cd1eadaa48f6c5c3f
|
4
|
+
data.tar.gz: 55cab3d2d0d61c1035cb2e11b121929824074ff9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c1e115e510ea12a1c8e44da02b38ceb03153aaaeabc7cce59bf80d03931a072d851bdc0a616a49341d6bbb4840eaaf4ab81acd5ebc9882edb0723fb955faa12
|
7
|
+
data.tar.gz: a7e0a9e90bf568dbcf53f72a9d9bdc7bed4b7db666c950325bc5cff411731437d143966340090b4f599042ce2a48df02babfa1d9c60b2de0a171199a6b20ad73
|
checksums.yaml.gz.sig
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
�5�DS��ɴ��Ѭ[1]�H�5(\d!8lI �)٬"�7�t���� �G1�J)&�Ĩ�;.�3gh8�Y6��(Wwg�T�+���,��)t`_N����G�|
|
2
|
+
��`|�ͳy���m,+[h�o��!K6��(�O�Ug2�
|
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
= ActiveMerchant CHANGELOG
|
2
2
|
|
3
|
+
== Version 1.43.1 (May 1, 2014)
|
4
|
+
|
5
|
+
* Merchant Warrior: Scrub names [duff]
|
6
|
+
* Validate Gateway.supported_countries [rwdaigle]
|
7
|
+
* Stripe: Add recurring flag support [bslobodin]
|
8
|
+
* Stripe: Use localized amounts for currencies w/o minor units [bslobodin]
|
9
|
+
* WebPay: Leverage fixes to Stripe to remove duplicate code [bslobodin]
|
10
|
+
* Klarna: Miscellanenous fixes [edward]
|
11
|
+
* Mollie iDEAL: Use order's description [wvanbergen]
|
12
|
+
|
3
13
|
== Version 1.43.0 (April 24, 2014)
|
4
14
|
|
5
15
|
* PagSeguro: New offsite integration [celsodantas]
|
@@ -82,10 +82,6 @@ module ActiveMerchant #:nodoc:
|
|
82
82
|
# The default currency for the transactions if no currency is provided
|
83
83
|
class_attribute :default_currency
|
84
84
|
|
85
|
-
# The countries of merchants the gateway supports
|
86
|
-
class_attribute :supported_countries
|
87
|
-
self.supported_countries = []
|
88
|
-
|
89
85
|
# The supported card types for the gateway
|
90
86
|
class_attribute :supported_cardtypes
|
91
87
|
self.supported_cardtypes = []
|
@@ -116,6 +112,23 @@ module ActiveMerchant #:nodoc:
|
|
116
112
|
result.to_s.downcase
|
117
113
|
end
|
118
114
|
|
115
|
+
def self.supported_countries=(country_codes)
|
116
|
+
country_codes.each do |country_code|
|
117
|
+
unless ActiveMerchant::Country.find(country_code)
|
118
|
+
raise ActiveMerchant::InvalidCountryCodeError, "No country could be found for the country #{country_code}"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
@supported_countries = country_codes.dup
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.supported_countries
|
125
|
+
@supported_countries ||= []
|
126
|
+
end
|
127
|
+
|
128
|
+
def supported_countries
|
129
|
+
self.class.supported_countries
|
130
|
+
end
|
131
|
+
|
119
132
|
def card_brand(source)
|
120
133
|
self.class.card_brand(source)
|
121
134
|
end
|
@@ -4,7 +4,7 @@ module ActiveMerchant #:nodoc:
|
|
4
4
|
self.test_url = 'https://sandbox.app55.com/v1/'
|
5
5
|
self.live_url = 'https://api.app55.com/v1/'
|
6
6
|
|
7
|
-
self.supported_countries = ['AU', 'BR', 'CA', 'CH', 'CL', 'CN', 'CO', 'CZ', 'DK', '
|
7
|
+
self.supported_countries = ['AU', 'BR', 'CA', 'CH', 'CL', 'CN', 'CO', 'CZ', 'DK', 'GB', 'HK', 'HU', 'ID', 'IS', 'JP', 'KE', 'KR', 'MX', 'MY', 'NO', 'NZ', 'PH', 'PL', 'TH', 'TW', 'US', 'VN', 'ZA']
|
8
8
|
self.supported_cardtypes = [:visa, :master, :american_express, :jcb, :maestro, :solo]
|
9
9
|
self.default_currency = 'UKP'
|
10
10
|
self.money_format = :dollars
|
@@ -182,4 +182,3 @@ module ActiveMerchant #:nodoc:
|
|
182
182
|
end
|
183
183
|
end
|
184
184
|
end
|
185
|
-
|
@@ -7,7 +7,8 @@ module ActiveMerchant #:nodoc:
|
|
7
7
|
include BraintreeCommon
|
8
8
|
|
9
9
|
self.display_name = 'Braintree (Orange Platform)'
|
10
|
-
|
10
|
+
self.supported_countries = ["US"]
|
11
|
+
|
11
12
|
self.live_url = self.test_url = 'https://secure.braintreepaymentgateway.com/api/transact.php'
|
12
13
|
|
13
14
|
def add_processor(post, options)
|
@@ -4,7 +4,7 @@ module ActiveMerchant #:nodoc:
|
|
4
4
|
self.test_url = self.live_url = 'https://gateway.cardstream.com/direct/'
|
5
5
|
self.money_format = :cents
|
6
6
|
self.default_currency = 'GBP'
|
7
|
-
self.supported_countries = ['GB', '
|
7
|
+
self.supported_countries = ['GB', 'US', 'CH', 'SE', 'SG', 'NO', 'JP', 'IS', 'HK', 'NL', 'CZ', 'CA', 'AU']
|
8
8
|
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover, :jcb, :maestro, :solo, :switch]
|
9
9
|
self.homepage_url = 'http://www.cardstream.com/'
|
10
10
|
self.display_name = 'CardStream'
|
@@ -218,4 +218,3 @@ module ActiveMerchant #:nodoc:
|
|
218
218
|
end
|
219
219
|
end
|
220
220
|
end
|
221
|
-
|
@@ -4,7 +4,7 @@ module ActiveMerchant #:nodoc:
|
|
4
4
|
self.live_url = self.test_url = "https://secure.certodirect.com/gateway/process/v2"
|
5
5
|
|
6
6
|
self.supported_countries = [
|
7
|
-
"BE", "BG", "CZ", "DK", "DE", "EE", "IE", "
|
7
|
+
"BE", "BG", "CZ", "DK", "DE", "EE", "IE", "ES", "FR",
|
8
8
|
"IT", "CY", "LV", "LT", "LU", "HU", "MT", "NL", "AT", "PL",
|
9
9
|
"PT", "RO", "SI", "SK", "FI", "SE", "GB"
|
10
10
|
]
|
@@ -60,7 +60,7 @@ module ActiveMerchant #:nodoc:
|
|
60
60
|
|
61
61
|
def store(creditcard, options = {})
|
62
62
|
post = {
|
63
|
-
'cardName' => creditcard.name,
|
63
|
+
'cardName' => scrub_name(creditcard.name),
|
64
64
|
'cardNumber' => creditcard.number,
|
65
65
|
'cardExpiryMonth' => format(creditcard.month, :two_digits),
|
66
66
|
'cardExpiryYear' => format(creditcard.year, :two_digits)
|
@@ -77,7 +77,7 @@ module ActiveMerchant #:nodoc:
|
|
77
77
|
def add_address(post, options)
|
78
78
|
return unless(address = (options[:billing_address] || options[:address]))
|
79
79
|
|
80
|
-
post['customerName'] = address[:name]
|
80
|
+
post['customerName'] = scrub_name(address[:name])
|
81
81
|
post['customerCountry'] = address[:country]
|
82
82
|
post['customerState'] = address[:state]
|
83
83
|
post['customerCity'] = address[:city]
|
@@ -103,11 +103,15 @@ module ActiveMerchant #:nodoc:
|
|
103
103
|
|
104
104
|
def add_creditcard(post, creditcard)
|
105
105
|
post['paymentCardNumber'] = creditcard.number
|
106
|
-
post['paymentCardName'] = creditcard.name
|
106
|
+
post['paymentCardName'] = scrub_name(creditcard.name)
|
107
107
|
post['paymentCardExpiry'] = creditcard.expiry_date.expiration.strftime("%m%y")
|
108
108
|
post['paymentCardCSC'] = creditcard.verification_value if creditcard.verification_value?
|
109
109
|
end
|
110
110
|
|
111
|
+
def scrub_name(name)
|
112
|
+
name.gsub(/[^a-zA-Z\. -]/, '')
|
113
|
+
end
|
114
|
+
|
111
115
|
def add_amount(post, money, options)
|
112
116
|
currency = (options[:currency] || currency(money))
|
113
117
|
|
@@ -21,6 +21,9 @@ module ActiveMerchant #:nodoc:
|
|
21
21
|
'unchecked' => 'P'
|
22
22
|
}
|
23
23
|
|
24
|
+
# Source: https://support.stripe.com/questions/which-zero-decimal-currencies-does-stripe-support
|
25
|
+
CURRENCIES_WITHOUT_FRACTIONS = ['BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VUV', 'XAF', 'XOF', 'XPF']
|
26
|
+
|
24
27
|
self.supported_countries = %w(US CA GB AU IE FR NL BE DE ES)
|
25
28
|
self.default_currency = 'USD'
|
26
29
|
self.money_format = :cents
|
@@ -59,7 +62,8 @@ module ActiveMerchant #:nodoc:
|
|
59
62
|
end
|
60
63
|
|
61
64
|
def capture(money, authorization, options = {})
|
62
|
-
post = {
|
65
|
+
post = {}
|
66
|
+
add_amount(post, money, options)
|
63
67
|
add_application_fee(post, options)
|
64
68
|
|
65
69
|
commit(:post, "charges/#{CGI.escape(authorization)}/capture", post, options)
|
@@ -70,7 +74,8 @@ module ActiveMerchant #:nodoc:
|
|
70
74
|
end
|
71
75
|
|
72
76
|
def refund(money, identification, options = {})
|
73
|
-
post = {
|
77
|
+
post = {}
|
78
|
+
add_amount(post, money, options)
|
74
79
|
post[:refund_application_fee] = true if options[:refund_application_fee]
|
75
80
|
|
76
81
|
MultiResponse.run(:first) do |r|
|
@@ -93,7 +98,8 @@ module ActiveMerchant #:nodoc:
|
|
93
98
|
def refund_application_fee(money, identification, options = {})
|
94
99
|
return Response.new(false, "Application fee id could not be found") unless identification
|
95
100
|
|
96
|
-
post = {
|
101
|
+
post = {}
|
102
|
+
add_amount(post, money, options)
|
97
103
|
options.merge!(:key => @fee_refund_api_key)
|
98
104
|
|
99
105
|
commit(:post, "application_fees/#{CGI.escape(identification)}/refund", post, options)
|
@@ -146,7 +152,7 @@ module ActiveMerchant #:nodoc:
|
|
146
152
|
|
147
153
|
def create_post_for_auth_or_purchase(money, creditcard, options)
|
148
154
|
post = {}
|
149
|
-
add_amount(post, money, options)
|
155
|
+
add_amount(post, money, options, true)
|
150
156
|
add_creditcard(post, creditcard, options)
|
151
157
|
add_customer(post, creditcard, options)
|
152
158
|
add_customer_data(post,options)
|
@@ -157,9 +163,10 @@ module ActiveMerchant #:nodoc:
|
|
157
163
|
post
|
158
164
|
end
|
159
165
|
|
160
|
-
def add_amount(post, money, options)
|
161
|
-
|
162
|
-
post[:
|
166
|
+
def add_amount(post, money, options, include_currency = false)
|
167
|
+
currency = options[:currency] || currency(money)
|
168
|
+
post[:amount] = localized_amount(money, currency)
|
169
|
+
post[:currency] = currency.downcase if include_currency
|
163
170
|
end
|
164
171
|
|
165
172
|
def add_application_fee(post, options)
|
@@ -221,6 +228,7 @@ module ActiveMerchant #:nodoc:
|
|
221
228
|
|
222
229
|
def add_flags(post, options)
|
223
230
|
post[:uncaptured] = true if options[:uncaptured]
|
231
|
+
post[:recurring] = true if (options[:eci] == 'recurring' || options[:recurring])
|
224
232
|
end
|
225
233
|
|
226
234
|
def fetch_application_fees(identification, options = {})
|
@@ -320,6 +328,10 @@ module ActiveMerchant #:nodoc:
|
|
320
328
|
}
|
321
329
|
}
|
322
330
|
end
|
331
|
+
|
332
|
+
def non_fractional_currency?(currency)
|
333
|
+
CURRENCIES_WITHOUT_FRACTIONS.include?(currency.to_s)
|
334
|
+
end
|
323
335
|
end
|
324
336
|
end
|
325
337
|
end
|
@@ -14,14 +14,15 @@ module ActiveMerchant #:nodoc:
|
|
14
14
|
self.display_name = 'WebPay'
|
15
15
|
|
16
16
|
def capture(money, authorization, options = {})
|
17
|
-
post = {
|
17
|
+
post = {}
|
18
|
+
add_amount(post, money, options)
|
18
19
|
add_application_fee(post, options)
|
19
20
|
commit(:post, "charges/#{CGI.escape(authorization)}/capture", post)
|
20
21
|
end
|
21
22
|
|
22
23
|
def refund(money, identification, options = {})
|
23
|
-
post = {
|
24
|
-
|
24
|
+
post = {}
|
25
|
+
add_amount(post, money, options)
|
25
26
|
MultiResponse.run do |r|
|
26
27
|
r.process { commit(:post, "charges/#{CGI.escape(identification)}/refund", post, options) }
|
27
28
|
|
@@ -36,15 +37,6 @@ module ActiveMerchant #:nodoc:
|
|
36
37
|
raise NotImplementedError.new
|
37
38
|
end
|
38
39
|
|
39
|
-
def localized_amount(money, currency = self.default_currency)
|
40
|
-
non_fractional_currency?(currency) ? (amount(money).to_f / 100).floor : amount(money)
|
41
|
-
end
|
42
|
-
|
43
|
-
def add_amount(post, money, options)
|
44
|
-
post[:currency] = (options[:currency] || currency(money)).downcase
|
45
|
-
post[:amount] = localized_amount(money, post[:currency].upcase)
|
46
|
-
end
|
47
|
-
|
48
40
|
def add_customer(post, creditcard, options)
|
49
41
|
post[:customer] = options[:customer] if options[:customer] && !creditcard.respond_to?(:number)
|
50
42
|
end
|
@@ -18,7 +18,7 @@ module ActiveMerchant #:nodoc:
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def initialize(order, account, options = {})
|
21
|
-
options.assert_valid_keys([:amount, :currency, :test, :credential2, :credential3, :credential4, :country, :account_name, :transaction_type, :authcode, :notify_url, :return_url, :redirect_param, :forward_url])
|
21
|
+
options.assert_valid_keys([:amount, :currency, :test, :credential2, :credential3, :credential4, :country, :account_name, :description, :transaction_type, :authcode, :notify_url, :return_url, :redirect_param, :forward_url])
|
22
22
|
@fields = {}
|
23
23
|
@raw_html_fields = []
|
24
24
|
@test = options[:test]
|
@@ -101,7 +101,7 @@ module ActiveMerchant #:nodoc:
|
|
101
101
|
def method_missing(method_id, *args)
|
102
102
|
method_id = method_id.to_s.gsub(/=$/, '').to_sym
|
103
103
|
# Return and do nothing if the mapping was not found. This allows
|
104
|
-
#
|
104
|
+
# for easy substitution of the different integrations
|
105
105
|
return if mappings[method_id].nil?
|
106
106
|
|
107
107
|
mapping = mappings[method_id]
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/klarna/helper.rb'
|
2
|
+
require File.dirname(__FILE__) + '/klarna/notification.rb'
|
3
|
+
require 'digest'
|
4
|
+
|
5
|
+
module ActiveMerchant #:nodoc:
|
6
|
+
module Billing #:nodoc:
|
7
|
+
module Integrations #:nodoc:
|
8
|
+
module Klarna
|
9
|
+
mattr_accessor :service_url
|
10
|
+
self.service_url = 'https://api.hostedcheckout.io/api/v1/checkout'
|
11
|
+
|
12
|
+
def self.notification(post_body, options = {})
|
13
|
+
Notification.new(post_body, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.return(query_string, options = {})
|
17
|
+
Return.new(query_string, options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.cart_items_payload(fields, cart_items)
|
21
|
+
check_required_fields!(fields)
|
22
|
+
|
23
|
+
payload = fields['purchase_country'].to_s +
|
24
|
+
fields['purchase_currency'].to_s +
|
25
|
+
fields['locale'].to_s
|
26
|
+
|
27
|
+
cart_items.each_with_index do |item, i|
|
28
|
+
payload << fields["cart_item-#{i}_type"].to_s +
|
29
|
+
fields["cart_item-#{i}_reference"].to_s +
|
30
|
+
fields["cart_item-#{i}_quantity"].to_s +
|
31
|
+
fields["cart_item-#{i}_unit_price"].to_s +
|
32
|
+
fields.fetch("cart_item-#{i}_discount_rate", '').to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
payload << fields['merchant_id'].to_s +
|
36
|
+
fields['merchant_terms_uri'].to_s +
|
37
|
+
fields['merchant_checkout_uri'].to_s +
|
38
|
+
fields['merchant_base_uri'].to_s +
|
39
|
+
fields['merchant_confirmation_uri'].to_s
|
40
|
+
|
41
|
+
payload
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.sign(fields, cart_items, shared_secret)
|
45
|
+
payload = cart_items_payload(fields, cart_items)
|
46
|
+
|
47
|
+
digest(payload, shared_secret)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.digest(payload, shared_secret)
|
51
|
+
Digest::SHA256.base64digest(payload + shared_secret.to_s)
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def self.check_required_fields!(fields)
|
57
|
+
%w(purchase_country
|
58
|
+
purchase_currency
|
59
|
+
locale
|
60
|
+
merchant_id
|
61
|
+
merchant_terms_uri
|
62
|
+
merchant_checkout_uri
|
63
|
+
merchant_base_uri
|
64
|
+
merchant_confirmation_uri).each do |required_field|
|
65
|
+
raise ArgumentError, "Missing required field #{required_field}" if fields[required_field].nil?
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
module Integrations #:nodoc:
|
4
|
+
module Klarna
|
5
|
+
class Helper < ActiveMerchant::Billing::Integrations::Helper
|
6
|
+
mapping :currency, 'purchase_currency'
|
7
|
+
mapping :cancel_return_url, ['merchant_terms_uri', 'merchant_checkout_uri', 'merchant_base_uri']
|
8
|
+
mapping :account, 'merchant_id'
|
9
|
+
mapping :customer, email: 'shipping_address_email'
|
10
|
+
|
11
|
+
def initialize(order, account, options = {})
|
12
|
+
super
|
13
|
+
@shared_secret = options[:credential2]
|
14
|
+
@order = order
|
15
|
+
|
16
|
+
add_field('platform_type', application_id)
|
17
|
+
add_field('test_mode', test?)
|
18
|
+
end
|
19
|
+
|
20
|
+
def notify_url(url)
|
21
|
+
url = append_order_query_param(url)
|
22
|
+
add_field('merchant_push_uri', url)
|
23
|
+
end
|
24
|
+
|
25
|
+
def return_url(url)
|
26
|
+
url = append_order_query_param(url)
|
27
|
+
add_field('merchant_confirmation_uri', url)
|
28
|
+
end
|
29
|
+
|
30
|
+
def line_item(item)
|
31
|
+
@line_items ||= []
|
32
|
+
@line_items << item
|
33
|
+
|
34
|
+
i = @line_items.size - 1
|
35
|
+
|
36
|
+
add_field("cart_item-#{i}_type", item.fetch(:type, ''))
|
37
|
+
add_field("cart_item-#{i}_reference", item.fetch(:reference, ''))
|
38
|
+
add_field("cart_item-#{i}_name", item.fetch(:name, ''))
|
39
|
+
add_field("cart_item-#{i}_quantity", item.fetch(:quantity, ''))
|
40
|
+
add_field("cart_item-#{i}_unit_price", tax_included_unit_price(item)).to_s
|
41
|
+
add_field("cart_item-#{i}_discount_rate", item.fetch(:discount_rate, ''))
|
42
|
+
add_field("cart_item-#{i}_tax_rate", tax_rate_for(item)).to_s
|
43
|
+
|
44
|
+
@fields
|
45
|
+
end
|
46
|
+
|
47
|
+
def billing_address(billing_fields)
|
48
|
+
country = billing_fields[:country]
|
49
|
+
|
50
|
+
add_field('purchase_country', country)
|
51
|
+
add_field('locale', guess_locale_based_on_country(country))
|
52
|
+
end
|
53
|
+
|
54
|
+
def shipping_address(shipping_fields)
|
55
|
+
add_field('shipping_address_given_name', shipping_fields[:first_name])
|
56
|
+
add_field('shipping_address_family_name', shipping_fields[:last_name])
|
57
|
+
|
58
|
+
street_address = [shipping_fields[:address1], shipping_fields[:address2]].compact.join(', ')
|
59
|
+
add_field('shipping_address_street_address', street_address)
|
60
|
+
|
61
|
+
add_field('shipping_address_postal_code', shipping_fields[:zip])
|
62
|
+
add_field('shipping_address_city', shipping_fields[:city])
|
63
|
+
add_field('shipping_address_country', shipping_fields[:country])
|
64
|
+
add_field('shipping_address_phone', shipping_fields[:phone])
|
65
|
+
end
|
66
|
+
|
67
|
+
def form_fields
|
68
|
+
sign_fields
|
69
|
+
|
70
|
+
super
|
71
|
+
end
|
72
|
+
|
73
|
+
def sign_fields
|
74
|
+
merchant_digest = Klarna.sign(@fields, @line_items, @shared_secret)
|
75
|
+
add_field('merchant_digest', merchant_digest)
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def append_order_query_param(url)
|
81
|
+
u = URI.parse(url)
|
82
|
+
params = Rack::Utils.parse_nested_query(u.query)
|
83
|
+
params["order"] = @order
|
84
|
+
u.query = params.to_query
|
85
|
+
|
86
|
+
u.to_s
|
87
|
+
end
|
88
|
+
|
89
|
+
def guess_locale_based_on_country(country_code)
|
90
|
+
case country_code
|
91
|
+
when /no/i
|
92
|
+
"nb-no"
|
93
|
+
when /fi/i
|
94
|
+
"fi-fi"
|
95
|
+
when /se/i
|
96
|
+
"sv-se"
|
97
|
+
else
|
98
|
+
"sv-se"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def tax_included_unit_price(item)
|
103
|
+
item.fetch(:unit_price, '').to_i + item.fetch(:tax_amount, '').to_i
|
104
|
+
end
|
105
|
+
|
106
|
+
def tax_rate_for(item)
|
107
|
+
subtotal_price = item.fetch(:unit_price, 0).to_f * item.fetch(:quantity, 0).to_i
|
108
|
+
tax_amount = item.fetch(:tax_amount, 0).to_f
|
109
|
+
|
110
|
+
tax_rate = tax_amount / subtotal_price
|
111
|
+
tax_rate = tax_rate.round(4)
|
112
|
+
|
113
|
+
percentage_to_two_decimal_precision_whole_number(tax_rate)
|
114
|
+
end
|
115
|
+
|
116
|
+
def percentage_to_two_decimal_precision_whole_number(percentage)
|
117
|
+
(percentage * 10000).to_i
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module ActiveMerchant #:nodoc:
|
5
|
+
module Billing #:nodoc:
|
6
|
+
module Integrations #:nodoc:
|
7
|
+
module Klarna
|
8
|
+
class Notification < ActiveMerchant::Billing::Integrations::Notification
|
9
|
+
def initialize(post, options = {})
|
10
|
+
super
|
11
|
+
@shared_secret = @options[:credential2]
|
12
|
+
end
|
13
|
+
|
14
|
+
def complete?
|
15
|
+
status == 'Completed'
|
16
|
+
end
|
17
|
+
|
18
|
+
def item_id
|
19
|
+
order
|
20
|
+
end
|
21
|
+
|
22
|
+
def transaction_id
|
23
|
+
params["reference"]
|
24
|
+
end
|
25
|
+
|
26
|
+
def received_at
|
27
|
+
params["completed_at"]
|
28
|
+
end
|
29
|
+
|
30
|
+
def payer_email
|
31
|
+
params["billing_address"]["email"]
|
32
|
+
end
|
33
|
+
|
34
|
+
def receiver_email
|
35
|
+
params["shipping_address"]["email"]
|
36
|
+
end
|
37
|
+
|
38
|
+
def currency
|
39
|
+
params["purchase_currency"].upcase
|
40
|
+
end
|
41
|
+
|
42
|
+
def gross
|
43
|
+
amount = Float(gross_cents) / 100
|
44
|
+
sprintf("%.2f", amount)
|
45
|
+
end
|
46
|
+
|
47
|
+
def gross_cents
|
48
|
+
params["cart"]["total_price_including_tax"]
|
49
|
+
end
|
50
|
+
|
51
|
+
def status
|
52
|
+
case params['status']
|
53
|
+
when 'checkout_complete'
|
54
|
+
'Completed'
|
55
|
+
else
|
56
|
+
params['status']
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def acknowledge(authcode = nil)
|
61
|
+
Verifier.new(@options[:authorization_header], @raw, @shared_secret).verify
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def order
|
67
|
+
query = Rack::Utils.parse_nested_query(@options[:query_string])
|
68
|
+
query["order"]
|
69
|
+
end
|
70
|
+
|
71
|
+
def parse(post)
|
72
|
+
@raw = post.to_s
|
73
|
+
@params = JSON.parse(post)
|
74
|
+
end
|
75
|
+
|
76
|
+
class Verifier
|
77
|
+
attr_reader :header, :payload, :digest, :shared_secret
|
78
|
+
def initialize(header, payload, shared_secret)
|
79
|
+
@header, @payload, @shared_secret = header, payload, shared_secret
|
80
|
+
|
81
|
+
@digest = extract_digest
|
82
|
+
end
|
83
|
+
|
84
|
+
def verify
|
85
|
+
digest_matches?
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def extract_digest
|
91
|
+
match = header.match(/^Klarna (?<digest>.+)$/)
|
92
|
+
match && match[:digest]
|
93
|
+
end
|
94
|
+
|
95
|
+
def digest_matches?
|
96
|
+
Klarna.digest(payload, shared_secret) == digest
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -10,7 +10,7 @@ module ActiveMerchant #:nodoc:
|
|
10
10
|
@token = account
|
11
11
|
@redirect_paramaters = {
|
12
12
|
:amount => options[:amount],
|
13
|
-
:description => options[:
|
13
|
+
:description => options[:description],
|
14
14
|
:issuer => options[:redirect_param],
|
15
15
|
:redirectUrl => options[:return_url],
|
16
16
|
:method => 'ideal',
|
@@ -23,7 +23,7 @@ module ActiveMerchant #:nodoc:
|
|
23
23
|
|
24
24
|
raise ArgumentError, "The redirect_param option needs to be set to the bank_id the customer selected." if options[:redirect_param].blank?
|
25
25
|
raise ArgumentError, "The return_url option needs to be set." if options[:return_url].blank?
|
26
|
-
raise ArgumentError, "The
|
26
|
+
raise ArgumentError, "The description option needs to be set." if options[:description].blank?
|
27
27
|
end
|
28
28
|
|
29
29
|
def credential_based_url
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activemerchant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.43.
|
4
|
+
version: 1.43.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tobias Luetke
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
ZJB9YPQZG+vWBdDSca3sUMtvFxpLUFwdKF5APSPOVnhbFJ3vSXY1ulP/R6XW9vnw
|
31
31
|
6kkQi2fHhU20ugMzp881Eixr+TjC0RvUerLG7g==
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2014-
|
33
|
+
date: 2014-05-01 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: activesupport
|
@@ -455,6 +455,9 @@ files:
|
|
455
455
|
- lib/active_merchant/billing/integrations/ipay88/helper.rb
|
456
456
|
- lib/active_merchant/billing/integrations/ipay88/notification.rb
|
457
457
|
- lib/active_merchant/billing/integrations/ipay88/return.rb
|
458
|
+
- lib/active_merchant/billing/integrations/klarna.rb
|
459
|
+
- lib/active_merchant/billing/integrations/klarna/helper.rb
|
460
|
+
- lib/active_merchant/billing/integrations/klarna/notification.rb
|
458
461
|
- lib/active_merchant/billing/integrations/liqpay.rb
|
459
462
|
- lib/active_merchant/billing/integrations/liqpay/helper.rb
|
460
463
|
- lib/active_merchant/billing/integrations/liqpay/notification.rb
|
metadata.gz.sig
CHANGED
Binary file
|