activemerchant 1.14.0 → 1.15.0
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.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +18 -0
- data/CONTRIBUTORS +4 -0
- data/README.rdoc +1 -0
- data/lib/active_merchant.rb +1 -1
- data/lib/active_merchant/billing/credit_card.rb +53 -42
- data/lib/active_merchant/billing/gateway.rb +6 -6
- data/lib/active_merchant/billing/gateways/authorize_net.rb +4 -2
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +1 -1
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +3 -3
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +1 -1
- data/lib/active_merchant/billing/gateways/bogus.rb +12 -0
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +77 -16
- data/lib/active_merchant/billing/gateways/eway.rb +0 -4
- data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +1 -1
- data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +1 -1
- data/lib/active_merchant/billing/gateways/orbital.rb +1 -1
- data/lib/active_merchant/billing/gateways/pay_junction.rb +1 -1
- data/lib/active_merchant/billing/gateways/payflow.rb +22 -8
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +10 -10
- data/lib/active_merchant/billing/gateways/payflow_express.rb +115 -36
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +1 -1
- data/lib/active_merchant/billing/gateways/qbms.rb +1 -1
- data/lib/active_merchant/billing/gateways/realex.rb +7 -20
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +5 -5
- data/lib/active_merchant/billing/gateways/viaklix.rb +1 -1
- data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +18 -10
- data/lib/active_merchant/billing/integrations/directebanking.rb +47 -0
- data/lib/active_merchant/billing/integrations/directebanking/helper.rb +90 -0
- data/lib/active_merchant/billing/integrations/directebanking/notification.rb +120 -0
- data/lib/active_merchant/billing/integrations/directebanking/return.rb +11 -0
- data/lib/active_merchant/billing/integrations/helper.rb +4 -4
- data/lib/active_merchant/billing/integrations/notification.rb +1 -1
- data/lib/active_merchant/common/post_data.rb +1 -1
- data/lib/active_merchant/common/posts_data.rb +1 -1
- data/lib/active_merchant/common/validateable.rb +20 -15
- data/lib/active_merchant/version.rb +1 -1
- metadata +20 -21
- metadata.gz.sig +0 -0
@@ -17,7 +17,7 @@ module ActiveMerchant #:nodoc:
|
|
17
17
|
# The name of the gateway
|
18
18
|
self.display_name = 'SecurePay'
|
19
19
|
|
20
|
-
|
20
|
+
class_attribute :request_timeout
|
21
21
|
self.request_timeout = 60
|
22
22
|
|
23
23
|
self.money_format = :cents
|
@@ -58,20 +58,20 @@ module ActiveMerchant #:nodoc:
|
|
58
58
|
commit :authorization, build_purchase_request(money, credit_card, options)
|
59
59
|
end
|
60
60
|
|
61
|
-
def capture(money, reference)
|
61
|
+
def capture(money, reference, options = {})
|
62
62
|
commit :capture, build_reference_request(money, reference)
|
63
63
|
end
|
64
64
|
|
65
|
-
def refund(money, reference)
|
65
|
+
def refund(money, reference, options = {})
|
66
66
|
commit :refund, build_reference_request(money, reference)
|
67
67
|
end
|
68
68
|
|
69
|
-
def credit(money, reference)
|
69
|
+
def credit(money, reference, options = {})
|
70
70
|
deprecated CREDIT_DEPRECATION_MESSAGE
|
71
71
|
refund(money, reference)
|
72
72
|
end
|
73
73
|
|
74
|
-
def void(reference)
|
74
|
+
def void(reference, options = {})
|
75
75
|
commit :void, build_reference_request(nil, reference)
|
76
76
|
end
|
77
77
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module ActiveMerchant #:nodoc:
|
2
2
|
module Billing #:nodoc:
|
3
3
|
class ViaklixGateway < Gateway
|
4
|
-
|
4
|
+
class_attribute :test_url, :live_url, :delimiter, :actions
|
5
5
|
|
6
6
|
self.test_url = 'https://demo.viaklix.com/process.asp'
|
7
7
|
self.live_url = 'https://www.viaklix.com/process.asp'
|
@@ -64,8 +64,7 @@ module ActiveMerchant #:nodoc:
|
|
64
64
|
|
65
65
|
|
66
66
|
def customer(params = {})
|
67
|
-
|
68
|
-
add_field(mappings[:customer][:name], full_name)
|
67
|
+
add_field(mappings[:customer][:name], full_name(params))
|
69
68
|
add_field(mappings[:customer][:email], params[:email])
|
70
69
|
end
|
71
70
|
|
@@ -79,13 +78,11 @@ module ActiveMerchant #:nodoc:
|
|
79
78
|
end
|
80
79
|
|
81
80
|
def shipping_address(params = {})
|
82
|
-
update_address(:shipping_address, params)
|
83
|
-
super(params.dup)
|
81
|
+
super(update_address(:shipping_address, params))
|
84
82
|
end
|
85
83
|
|
86
84
|
def billing_address(params = {})
|
87
|
-
update_address(:billing_address, params)
|
88
|
-
super(params.dup)
|
85
|
+
super(update_address(:billing_address, params))
|
89
86
|
end
|
90
87
|
|
91
88
|
def form_fields
|
@@ -121,15 +118,20 @@ module ActiveMerchant #:nodoc:
|
|
121
118
|
end
|
122
119
|
|
123
120
|
def update_address(address_type, params)
|
121
|
+
params = params.dup
|
124
122
|
address = params[:address1]
|
125
|
-
address
|
126
|
-
params[:
|
123
|
+
address = "#{address} #{params[:address2]}" if params[:address2].present?
|
124
|
+
address = "#{params[:company]} #{address}" if params[:company].present?
|
125
|
+
params[:address1] = address
|
126
|
+
|
127
127
|
params[:phone] = normalize_phone_number(params[:phone])
|
128
128
|
add_land_line_phone_for(address_type, params)
|
129
129
|
|
130
|
-
if address_type == :shipping_address
|
131
|
-
|
130
|
+
if address_type == :shipping_address
|
131
|
+
shipping_name = full_name(params) || fields[mappings[:customer][:name]]
|
132
|
+
add_field(mappings[:shipping_address][:name], shipping_name)
|
132
133
|
end
|
134
|
+
params
|
133
135
|
end
|
134
136
|
|
135
137
|
# Split a single phone number into the country code, area code and local number as best as possible
|
@@ -185,6 +187,12 @@ module ActiveMerchant #:nodoc:
|
|
185
187
|
def phone_code_for_country(country)
|
186
188
|
PHONE_CODES[country]
|
187
189
|
end
|
190
|
+
|
191
|
+
def full_name(params)
|
192
|
+
return if params[:name].blank? && params[:first_name].blank? && params[:last_name].blank?
|
193
|
+
|
194
|
+
params[:name] || "#{params[:first_name]} #{params[:last_name]}"
|
195
|
+
end
|
188
196
|
end
|
189
197
|
end
|
190
198
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
module Integrations #:nodoc:
|
4
|
+
module Directebanking
|
5
|
+
autoload :Return, File.dirname(__FILE__) + '/directebanking/return.rb'
|
6
|
+
autoload :Helper, File.dirname(__FILE__) + '/directebanking/helper.rb'
|
7
|
+
autoload :Notification, File.dirname(__FILE__) + '/directebanking/notification.rb'
|
8
|
+
|
9
|
+
# Supported countries:
|
10
|
+
# Germany - DE
|
11
|
+
# Austria - AT
|
12
|
+
# Belgium - BE
|
13
|
+
# Netherlands - NL
|
14
|
+
# Switzerland - CH
|
15
|
+
# Great Britain - GB
|
16
|
+
|
17
|
+
# Overwrite this if you want to change the directebanking test url
|
18
|
+
mattr_accessor :test_url
|
19
|
+
self.test_url = 'https://www.directebanking.com/payment/start'
|
20
|
+
|
21
|
+
# Overwrite this if you want to change the directebanking production url
|
22
|
+
mattr_accessor :production_url
|
23
|
+
self.production_url = 'https://www.directebanking.com/payment/start'
|
24
|
+
|
25
|
+
def self.service_url
|
26
|
+
mode = ActiveMerchant::Billing::Base.integration_mode
|
27
|
+
case mode
|
28
|
+
when :production
|
29
|
+
self.production_url
|
30
|
+
when :test
|
31
|
+
self.test_url
|
32
|
+
else
|
33
|
+
raise StandardError, "Integration mode set to an invalid value: #{mode}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.notification(post, options = {})
|
38
|
+
Notification.new(post, options)
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.return(post, options = {})
|
42
|
+
Return.new(post, options)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
module Integrations #:nodoc:
|
4
|
+
module Directebanking
|
5
|
+
class Helper < ActiveMerchant::Billing::Integrations::Helper
|
6
|
+
|
7
|
+
# All credentials are mandatory and need to be set
|
8
|
+
#
|
9
|
+
# credential1: User ID
|
10
|
+
# credential2: Project ID
|
11
|
+
# credential3: Project Password (Algorithm: SH1)
|
12
|
+
# credential4: Notification Password (Algorithm: SH1)
|
13
|
+
def initialize(order, account, options = {})
|
14
|
+
super
|
15
|
+
add_field('user_variable_0', order)
|
16
|
+
add_field('project_id', options[:credential2])
|
17
|
+
@project_password = options[:credential3]
|
18
|
+
end
|
19
|
+
|
20
|
+
SIGNATURE_FIELDS = [
|
21
|
+
:user_id,
|
22
|
+
:project_id,
|
23
|
+
:sender_holder,
|
24
|
+
:sender_account_number,
|
25
|
+
:sender_bank_code,
|
26
|
+
:sender_country_id,
|
27
|
+
:amount,
|
28
|
+
:currency_id,
|
29
|
+
:reason_1,
|
30
|
+
:reason_2,
|
31
|
+
:user_variable_0,
|
32
|
+
:user_variable_1,
|
33
|
+
:user_variable_2,
|
34
|
+
:user_variable_3,
|
35
|
+
:user_variable_4,
|
36
|
+
:user_variable_5
|
37
|
+
]
|
38
|
+
|
39
|
+
SIGNATURE_IGNORE_AT_METHOD_CREATION_FIELDS = [
|
40
|
+
:user_id,
|
41
|
+
:amount,
|
42
|
+
:project_id,
|
43
|
+
:currency_id,
|
44
|
+
:user_variable_0,
|
45
|
+
:user_variable_1,
|
46
|
+
:user_variable_2,
|
47
|
+
:user_variable_3
|
48
|
+
]
|
49
|
+
|
50
|
+
SIGNATURE_FIELDS.each do |key|
|
51
|
+
if !SIGNATURE_IGNORE_AT_METHOD_CREATION_FIELDS.include?(key)
|
52
|
+
mapping "#{key}".to_sym, "#{key.to_s}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Need to format the amount to have 2 decimal places
|
57
|
+
def amount=(money)
|
58
|
+
cents = money.respond_to?(:cents) ? money.cents : money
|
59
|
+
if money.is_a?(String) or cents.to_i <= 0
|
60
|
+
raise ArgumentError, 'money amount must be either a Money object or a positive integer in cents.'
|
61
|
+
end
|
62
|
+
add_field mappings[:amount], sprintf("%.2f", cents.to_f/100)
|
63
|
+
end
|
64
|
+
|
65
|
+
def generate_signature_string
|
66
|
+
# format of signature: user_id|project_id|sender_holder|sender_account_number|sender_bank_code| sender_country_id|amount|currency_id|reason_1|reason_2|user_variable_0|user_variable_1|user_variable_2|user_variable_3|user_variable_4|user_variable_5|project_password
|
67
|
+
SIGNATURE_FIELDS.map {|key| @fields[key.to_s]} * "|" + "|#{@project_password}"
|
68
|
+
end
|
69
|
+
|
70
|
+
def generate_signature
|
71
|
+
Digest::SHA1.hexdigest(generate_signature_string)
|
72
|
+
end
|
73
|
+
|
74
|
+
def form_fields
|
75
|
+
@fields.merge('hash' => generate_signature)
|
76
|
+
end
|
77
|
+
|
78
|
+
mapping :account, 'user_id'
|
79
|
+
mapping :amount, 'amount'
|
80
|
+
mapping :currency, 'currency_id'
|
81
|
+
mapping :description, 'reason_1'
|
82
|
+
|
83
|
+
mapping :return_url, 'user_variable_1'
|
84
|
+
mapping :cancel_return_url, 'user_variable_2'
|
85
|
+
mapping :notify_url, 'user_variable_3'
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
module Integrations #:nodoc:
|
4
|
+
module Directebanking
|
5
|
+
class Notification < ActiveMerchant::Billing::Integrations::Notification
|
6
|
+
|
7
|
+
def initialize(data, options)
|
8
|
+
if options[:credential4].nil?
|
9
|
+
raise ArgumentError, "You need to provide the notification password (SH1) as the option :credential4 to verify that the notification originated from Directebanking (Payment Networks AG)"
|
10
|
+
end
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
def complete?
|
15
|
+
status == 'Completed'
|
16
|
+
end
|
17
|
+
|
18
|
+
def item_id
|
19
|
+
params['user_variable_0']
|
20
|
+
end
|
21
|
+
|
22
|
+
def transaction_id
|
23
|
+
params['transaction']
|
24
|
+
end
|
25
|
+
|
26
|
+
# When was this payment received by the client.
|
27
|
+
def received_at
|
28
|
+
Time.parse(params['created']) if params['created']
|
29
|
+
end
|
30
|
+
|
31
|
+
# the money amount we received in X.2 decimal.
|
32
|
+
def gross
|
33
|
+
"%.2f" % params['amount'].to_f
|
34
|
+
end
|
35
|
+
|
36
|
+
def status
|
37
|
+
'Completed'
|
38
|
+
end
|
39
|
+
|
40
|
+
def currency
|
41
|
+
params['currency_id']
|
42
|
+
end
|
43
|
+
|
44
|
+
def test?
|
45
|
+
params['sender_bank_name'] == 'Testbank'
|
46
|
+
end
|
47
|
+
|
48
|
+
# for verifying the signature of the URL parameters
|
49
|
+
PAYMENT_HOOK_SIGNATURE_FIELDS = [
|
50
|
+
:transaction,
|
51
|
+
:user_id,
|
52
|
+
:project_id,
|
53
|
+
:sender_holder,
|
54
|
+
:sender_account_number,
|
55
|
+
:sender_bank_code,
|
56
|
+
:sender_bank_name,
|
57
|
+
:sender_bank_bic,
|
58
|
+
:sender_iban,
|
59
|
+
:sender_country_id,
|
60
|
+
:recipient_holder,
|
61
|
+
:recipient_account_number,
|
62
|
+
:recipient_bank_code,
|
63
|
+
:recipient_bank_name,
|
64
|
+
:recipient_bank_bic,
|
65
|
+
:recipient_iban,
|
66
|
+
:recipient_country_id,
|
67
|
+
:international_transaction,
|
68
|
+
:amount,
|
69
|
+
:currency_id,
|
70
|
+
:reason_1,
|
71
|
+
:reason_2,
|
72
|
+
:security_criteria,
|
73
|
+
:user_variable_0,
|
74
|
+
:user_variable_1,
|
75
|
+
:user_variable_2,
|
76
|
+
:user_variable_3,
|
77
|
+
:user_variable_4,
|
78
|
+
:user_variable_5,
|
79
|
+
:created
|
80
|
+
]
|
81
|
+
|
82
|
+
PAYMENT_HOOK_IGNORE_AT_METHOD_CREATION_FIELDS = [
|
83
|
+
:transaction,
|
84
|
+
:amount,
|
85
|
+
:currency_id,
|
86
|
+
:user_variable_0,
|
87
|
+
:user_variable_1,
|
88
|
+
:user_variable_2,
|
89
|
+
:user_variable_3,
|
90
|
+
:created
|
91
|
+
]
|
92
|
+
|
93
|
+
# Provide access to raw fields
|
94
|
+
PAYMENT_HOOK_SIGNATURE_FIELDS.each do |key|
|
95
|
+
if !PAYMENT_HOOK_IGNORE_AT_METHOD_CREATION_FIELDS.include?(key)
|
96
|
+
define_method(key.to_s) do
|
97
|
+
params[key.to_s]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def generate_signature_string
|
103
|
+
#format is: transaction|user_id|project_id|sender_holder|sender_account_number|sender_bank_code|sender_bank_name|sender_bank_bic|sender_iban|sender_country_id|recipient_holder|recipient_account_number|recipient_bank_code|recipient_bank_name|recipient_bank_bic|recipient_iban|recipient_country_id|international_transaction|amount|currency_id|reason_1|reason_2|security_criteria|user_variable_0|user_variable_1|user_variable_2|user_variable_3|user_variable_4|user_variable_5|created|notification_password
|
104
|
+
PAYMENT_HOOK_SIGNATURE_FIELDS.map {|key| params[key.to_s]} * "|" + "|#{@options[:credential4]}"
|
105
|
+
end
|
106
|
+
|
107
|
+
def generate_signature
|
108
|
+
Digest::SHA1.hexdigest(generate_signature_string)
|
109
|
+
end
|
110
|
+
|
111
|
+
def acknowledge
|
112
|
+
# signature_is_valid?
|
113
|
+
generate_signature.to_s == params['hash'].to_s
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -3,14 +3,14 @@ module ActiveMerchant #:nodoc:
|
|
3
3
|
module Integrations #:nodoc:
|
4
4
|
class Helper #:nodoc:
|
5
5
|
attr_reader :fields
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
class_attribute :service_url
|
7
|
+
class_attribute :mappings
|
8
|
+
class_attribute :country_format
|
9
9
|
self.country_format = :alpha2
|
10
10
|
|
11
11
|
# The application making the calls to the gateway
|
12
12
|
# Useful for things like the PayPal build notation (BN) id fields
|
13
|
-
|
13
|
+
class_attribute :application_id
|
14
14
|
self.application_id = 'ActiveMerchant'
|
15
15
|
|
16
16
|
def initialize(order, account, options = {})
|
@@ -6,7 +6,7 @@ module ActiveMerchant #:nodoc:
|
|
6
6
|
attr_accessor :raw
|
7
7
|
|
8
8
|
# set this to an array in the subclass, to specify which IPs are allowed to send requests
|
9
|
-
|
9
|
+
class_attribute :production_ips
|
10
10
|
|
11
11
|
def initialize(post, options = {})
|
12
12
|
@options = options
|
@@ -5,7 +5,7 @@ module ActiveMerchant #:nodoc:
|
|
5
5
|
base.superclass_delegating_accessor :ssl_strict
|
6
6
|
base.ssl_strict = true
|
7
7
|
|
8
|
-
base.
|
8
|
+
base.class_attribute :retry_safe
|
9
9
|
base.retry_safe = false
|
10
10
|
|
11
11
|
base.superclass_delegating_accessor :open_timeout
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module ActiveMerchant #:nodoc:
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
2
|
module Validateable #:nodoc:
|
3
3
|
def valid?
|
4
4
|
errors.clear
|
@@ -7,13 +7,13 @@ module ActiveMerchant #:nodoc:
|
|
7
7
|
validate if respond_to?(:validate, true)
|
8
8
|
|
9
9
|
errors.empty?
|
10
|
-
end
|
10
|
+
end
|
11
11
|
|
12
12
|
def initialize(attributes = {})
|
13
13
|
self.attributes = attributes
|
14
14
|
end
|
15
15
|
|
16
|
-
def errors
|
16
|
+
def errors
|
17
17
|
@errors ||= Errors.new(self)
|
18
18
|
end
|
19
19
|
|
@@ -22,46 +22,51 @@ module ActiveMerchant #:nodoc:
|
|
22
22
|
def attributes=(attributes)
|
23
23
|
unless attributes.nil?
|
24
24
|
for key, value in attributes
|
25
|
-
send("#{key}=", value )
|
25
|
+
send("#{key}=", value )
|
26
26
|
end
|
27
27
|
end
|
28
|
-
end
|
28
|
+
end
|
29
29
|
|
30
30
|
# This hash keeps the errors of the object
|
31
31
|
class Errors < HashWithIndifferentAccess
|
32
32
|
|
33
33
|
def initialize(base)
|
34
|
+
super() { |h, k| h[k] = [] ; h[k] }
|
34
35
|
@base = base
|
35
36
|
end
|
36
|
-
|
37
|
+
|
37
38
|
def count
|
38
39
|
size
|
39
40
|
end
|
40
41
|
|
41
|
-
|
42
|
-
|
42
|
+
def empty?
|
43
|
+
all? { |k, v| v && v.empty? }
|
44
|
+
end
|
45
|
+
|
46
|
+
# returns a specific fields error message.
|
47
|
+
# if more than one error is available we will only return the first. If no error is available
|
43
48
|
# we return an empty string
|
44
49
|
def on(field)
|
45
50
|
self[field].to_a.first
|
46
51
|
end
|
47
52
|
|
48
53
|
def add(field, error)
|
49
|
-
self[field] ||= []
|
50
54
|
self[field] << error
|
51
|
-
end
|
52
|
-
|
55
|
+
end
|
56
|
+
|
53
57
|
def add_to_base(error)
|
54
58
|
add(:base, error)
|
55
59
|
end
|
56
60
|
|
57
61
|
def each_full
|
58
|
-
full_messages.each { |msg| yield msg }
|
62
|
+
full_messages.each { |msg| yield msg }
|
59
63
|
end
|
60
64
|
|
61
65
|
def full_messages
|
62
66
|
result = []
|
63
67
|
|
64
|
-
self.each do |key, messages|
|
68
|
+
self.each do |key, messages|
|
69
|
+
next if messages.blank?
|
65
70
|
if key == 'base'
|
66
71
|
result << "#{messages.first}"
|
67
72
|
else
|
@@ -70,7 +75,7 @@ module ActiveMerchant #:nodoc:
|
|
70
75
|
end
|
71
76
|
|
72
77
|
result
|
73
|
-
end
|
74
|
-
end
|
78
|
+
end
|
79
|
+
end
|
75
80
|
end
|
76
81
|
end
|