activemerchant 1.43.0 → 1.43.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|