activemerchant 1.16.0 → 1.17.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 +15 -1
- data/CONTRIBUTORS +8 -0
- data/lib/active_merchant/billing/credit_card.rb +100 -18
- data/lib/active_merchant/billing/gateways/authorize_net.rb +31 -2
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +46 -36
- data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
- data/lib/active_merchant/billing/gateways/epay.rb +1 -1
- data/lib/active_merchant/billing/gateways/iridium.rb +3 -3
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +270 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +5 -5
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +6 -3
- data/lib/active_merchant/billing/gateways/paypal_express.rb +22 -15
- data/lib/active_merchant/billing/gateways/quickpay.rb +96 -22
- data/lib/active_merchant/billing/integrations/payflow_link.rb +21 -0
- data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +58 -0
- data/lib/active_merchant/billing/integrations/payflow_link/notification.rb +78 -0
- data/lib/active_merchant/version.rb +1 -1
- metadata +23 -18
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG
CHANGED
@@ -1,6 +1,20 @@
|
|
1
1
|
= ActiveMerchant CHANGELOG
|
2
2
|
|
3
|
-
== Version 1.
|
3
|
+
== Version 1.17.0 (August 23, 2011)
|
4
|
+
|
5
|
+
* Add Payflow Link integration [jduff]
|
6
|
+
* Add CardSave gateway [MrJaba/jduff]]
|
7
|
+
* Quickpay: Support protocal version 4 and fraud parameters [anderslemke/jduff]
|
8
|
+
* Authorize.net: Add status_recurring [mm1/jduff]
|
9
|
+
* Paypal Express: Support specifying :items with purchase [sivabudh/jduff]
|
10
|
+
* ePay: Add Sweden and Norway to supported countries [ePay/jduff]
|
11
|
+
* Brainreee: Support passing merchant_account_id parameter [braintreeps/jduff]
|
12
|
+
* Paypal Express: Remove deprecated Address field in favor of ShipToAddress[jduff]
|
13
|
+
* Add Optimal Payments gateway [jamie/jduff]
|
14
|
+
* Documentation improvements [dasch/nhemsley/jstorimer/jduff]
|
15
|
+
* Authorize.Net: Pass through first name, last name, and zip for refunds. [ntalbott]
|
16
|
+
|
17
|
+
== Version 1.16.0 (July 18, 2011)
|
4
18
|
|
5
19
|
* Bogus: Support referenced transactions for #authorize, #purchase, #recurring and
|
6
20
|
#credit [dasch/jduff]
|
data/CONTRIBUTORS
CHANGED
@@ -4,22 +4,34 @@ require 'active_merchant/billing/expiry_date'
|
|
4
4
|
|
5
5
|
module ActiveMerchant #:nodoc:
|
6
6
|
module Billing #:nodoc:
|
7
|
-
#
|
8
|
-
#
|
9
|
-
# but doesn't support the .save method as its not backed by a database.
|
7
|
+
# A +CreditCard+ object represents a physical credit card, and is capable of validating the various
|
8
|
+
# data associated with these.
|
10
9
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
10
|
+
# At the moment, the following credit card types are supported:
|
11
|
+
#
|
12
|
+
# * Visa
|
13
|
+
# * MasterCard
|
14
|
+
# * Discover
|
15
|
+
# * American Express
|
16
|
+
# * Diner's Club
|
17
|
+
# * JCB
|
18
|
+
# * Switch
|
19
|
+
# * Solo
|
20
|
+
# * Dankort
|
21
|
+
# * Maestro
|
22
|
+
# * Forbrugsforeningen
|
23
|
+
# * Laser
|
24
|
+
#
|
25
|
+
# For testing purposes, use the 'bogus' credit card type. This skips the vast majority of
|
26
|
+
# validations, allowing you to focus on your core concerns until you're ready to be more concerned
|
27
|
+
# with the details of particular credit cards or your gateway.
|
14
28
|
#
|
15
29
|
# == Testing With CreditCard
|
16
30
|
# Often when testing we don't care about the particulars of a given card type. When using the 'test'
|
17
|
-
# mode in your Gateway, there are six different valid card numbers: 1, 2, 3, 'success', 'fail',
|
31
|
+
# mode in your {Gateway}, there are six different valid card numbers: 1, 2, 3, 'success', 'fail',
|
18
32
|
# and 'error'.
|
19
33
|
#
|
20
|
-
|
21
|
-
# For details, see CreditCardMethods#valid_number?
|
22
|
-
#++
|
34
|
+
# For details, see {CreditCardMethods::ClassMethods#valid_number?}
|
23
35
|
#
|
24
36
|
# == Example Usage
|
25
37
|
# cc = CreditCard.new(
|
@@ -38,44 +50,102 @@ module ActiveMerchant #:nodoc:
|
|
38
50
|
include CreditCardMethods
|
39
51
|
include Validateable
|
40
52
|
|
41
|
-
## Attributes
|
42
|
-
|
43
53
|
cattr_accessor :require_verification_value
|
44
54
|
self.require_verification_value = true
|
45
55
|
|
46
|
-
#
|
47
|
-
|
56
|
+
# Returns or sets the credit card number.
|
57
|
+
#
|
58
|
+
# @return [String]
|
59
|
+
attr_accessor :number
|
60
|
+
|
61
|
+
# Returns or sets the expiry month for the card.
|
62
|
+
#
|
63
|
+
# @return [Integer]
|
64
|
+
attr_accessor :month
|
65
|
+
|
66
|
+
# Returns or sets the expiry year for the card.
|
67
|
+
#
|
68
|
+
# @return [Integer]
|
69
|
+
attr_accessor :year
|
70
|
+
|
71
|
+
# Returns or sets the credit card type.
|
72
|
+
#
|
73
|
+
# Valid card types are
|
74
|
+
#
|
75
|
+
# * +'visa'+
|
76
|
+
# * +'master'+
|
77
|
+
# * +'discover'+
|
78
|
+
# * +'american_express'+
|
79
|
+
# * +'diners_club'+
|
80
|
+
# * +'jcb'+
|
81
|
+
# * +'switch'+
|
82
|
+
# * +'solo'+
|
83
|
+
# * +'dankort'+
|
84
|
+
# * +'maestro'+
|
85
|
+
# * +'forbrugsforeningen'+
|
86
|
+
# * +'laser'+
|
87
|
+
#
|
88
|
+
# Or, if you wish to test your implementation, +'bogus'+.
|
89
|
+
#
|
90
|
+
# @return (String) the credit card type
|
91
|
+
attr_accessor :type
|
92
|
+
|
93
|
+
# Returns or sets the first name of the card holder.
|
94
|
+
#
|
95
|
+
# @return [String]
|
96
|
+
attr_accessor :first_name
|
97
|
+
|
98
|
+
# Returns or sets the last name of the card holder.
|
99
|
+
#
|
100
|
+
# @return [String]
|
101
|
+
attr_accessor :last_name
|
48
102
|
|
49
103
|
# Required for Switch / Solo cards
|
50
104
|
attr_accessor :start_month, :start_year, :issue_number
|
51
105
|
|
52
|
-
#
|
53
|
-
#
|
106
|
+
# Returns or sets the card verification value.
|
107
|
+
#
|
108
|
+
# This attribute is optional but recommended. The verification value is
|
109
|
+
# a {card security code}[http://en.wikipedia.org/wiki/Card_security_code]. If provided,
|
110
|
+
# the gateway will attempt to validate the value.
|
111
|
+
#
|
112
|
+
# @return [String] the verification value
|
54
113
|
attr_accessor :verification_value
|
55
114
|
|
56
115
|
alias_method :brand, :type
|
57
|
-
|
116
|
+
|
58
117
|
# Provides proxy access to an expiry date object
|
118
|
+
#
|
119
|
+
# @return [ExpiryDate]
|
59
120
|
def expiry_date
|
60
121
|
ExpiryDate.new(@month, @year)
|
61
122
|
end
|
62
123
|
|
124
|
+
# Returns whether the credit card has expired.
|
125
|
+
#
|
126
|
+
# @return +true+ if the card has expired, +false+ otherwise
|
63
127
|
def expired?
|
64
128
|
expiry_date.expired?
|
65
129
|
end
|
66
130
|
|
131
|
+
# Returns whether either the +first_name+ or the +last_name+ attributes has been set.
|
67
132
|
def name?
|
68
133
|
first_name? || last_name?
|
69
134
|
end
|
70
135
|
|
136
|
+
# Returns whether the +first_name+ attribute has been set.
|
71
137
|
def first_name?
|
72
138
|
@first_name.present?
|
73
139
|
end
|
74
140
|
|
141
|
+
# Returns whether the +last_name+ attribute has been set.
|
75
142
|
def last_name?
|
76
143
|
@last_name.present?
|
77
144
|
end
|
78
145
|
|
146
|
+
# Returns the full name of the card holder.
|
147
|
+
#
|
148
|
+
# @return [String] the full name of the card holder
|
79
149
|
def name
|
80
150
|
[@first_name, @last_name].compact.join(' ')
|
81
151
|
end
|
@@ -90,7 +160,16 @@ module ActiveMerchant #:nodoc:
|
|
90
160
|
!@verification_value.blank?
|
91
161
|
end
|
92
162
|
|
93
|
-
#
|
163
|
+
# Returns a display-friendly version of the card number.
|
164
|
+
#
|
165
|
+
# All but the last 4 numbers are replaced with an "X", and hyphens are
|
166
|
+
# inserted in order to improve legibility.
|
167
|
+
#
|
168
|
+
# @example
|
169
|
+
# credit_card = CreditCard.new(:number => "2132542376824338")
|
170
|
+
# credit_card.display_number # "XXXX-XXXX-XXXX-4338"
|
171
|
+
#
|
172
|
+
# @return [String] a display-friendly version of the card number
|
94
173
|
def display_number
|
95
174
|
self.class.mask(number)
|
96
175
|
end
|
@@ -99,6 +178,9 @@ module ActiveMerchant #:nodoc:
|
|
99
178
|
self.class.last_digits(number)
|
100
179
|
end
|
101
180
|
|
181
|
+
# Validates the credit card details.
|
182
|
+
#
|
183
|
+
# Any validation errors are added to the {#errors} attribute.
|
102
184
|
def validate
|
103
185
|
validate_essential_attributes
|
104
186
|
|
@@ -19,7 +19,7 @@ module ActiveMerchant #:nodoc:
|
|
19
19
|
#
|
20
20
|
# Automated Recurring Billing (ARB) is an optional service for submitting and managing recurring, or subscription-based, transactions.
|
21
21
|
#
|
22
|
-
# To use recurring, update_recurring, and
|
22
|
+
# To use recurring, update_recurring, cancel_recurring and status_recurring ARB must be enabled for your account.
|
23
23
|
#
|
24
24
|
# Information about ARB is available on the {Authorize.Net website}[http://www.authorize.net/solutions/merchantsolutions/merchantservices/automatedrecurringbilling/].
|
25
25
|
# Information about the ARB API is available at the {Authorize.Net Integration Center}[http://developer.authorize.net/]
|
@@ -55,7 +55,8 @@ module ActiveMerchant #:nodoc:
|
|
55
55
|
RECURRING_ACTIONS = {
|
56
56
|
:create => 'ARBCreateSubscription',
|
57
57
|
:update => 'ARBUpdateSubscription',
|
58
|
-
:cancel => 'ARBCancelSubscription'
|
58
|
+
:cancel => 'ARBCancelSubscription',
|
59
|
+
:status => 'ARBGetSubscriptionStatus'
|
59
60
|
}
|
60
61
|
|
61
62
|
# Creates a new AuthorizeNetGateway
|
@@ -149,12 +150,20 @@ module ActiveMerchant #:nodoc:
|
|
149
150
|
# ==== Options
|
150
151
|
#
|
151
152
|
# * <tt>:card_number</tt> -- The credit card number the refund is being issued to. (REQUIRED)
|
153
|
+
# * <tt>:first_name</tt> -- The first name of the account being refunded.
|
154
|
+
# * <tt>:last_name</tt> -- The last name of the account being refunded.
|
155
|
+
# * <tt>:zip</tt> -- The postal code of the account being refunded.
|
152
156
|
def refund(money, identification, options = {})
|
153
157
|
requires!(options, :card_number)
|
154
158
|
|
155
159
|
post = { :trans_id => identification,
|
156
160
|
:card_num => options[:card_number]
|
157
161
|
}
|
162
|
+
|
163
|
+
post[:first_name] = options[:first_name] if options[:first_name]
|
164
|
+
post[:last_name] = options[:last_name] if options[:last_name]
|
165
|
+
post[:zip] = options[:zip] if options[:zip]
|
166
|
+
|
158
167
|
add_invoice(post, options)
|
159
168
|
add_duplicate_window(post)
|
160
169
|
|
@@ -234,6 +243,19 @@ module ActiveMerchant #:nodoc:
|
|
234
243
|
recurring_commit(:cancel, request)
|
235
244
|
end
|
236
245
|
|
246
|
+
# Get Subscription Status of a recurring payment.
|
247
|
+
#
|
248
|
+
# This transaction gets the status of an existing Automated Recurring Billing (ARB) subscription. Your account must have ARB enabled.
|
249
|
+
#
|
250
|
+
# ==== Parameters
|
251
|
+
#
|
252
|
+
# * <tt>subscription_id</tt> -- A string containing the +subscription_id+ of the recurring payment already in place
|
253
|
+
# for a given credit card. (REQUIRED)
|
254
|
+
def status_recurring(subscription_id)
|
255
|
+
request = build_recurring_request(:status, :subscription_id => subscription_id)
|
256
|
+
recurring_commit(:status, request)
|
257
|
+
end
|
258
|
+
|
237
259
|
private
|
238
260
|
|
239
261
|
def commit(action, money, parameters)
|
@@ -447,6 +469,13 @@ module ActiveMerchant #:nodoc:
|
|
447
469
|
xml.target!
|
448
470
|
end
|
449
471
|
|
472
|
+
# Builds body for ARBGetSubscriptionStatusRequest
|
473
|
+
def build_arb_status_subscription_request(xml, options)
|
474
|
+
xml.tag!('subscriptionId', options[:subscription_id])
|
475
|
+
|
476
|
+
xml.target!
|
477
|
+
end
|
478
|
+
|
450
479
|
# Adds subscription information
|
451
480
|
def add_arb_subscription(xml, options)
|
452
481
|
xml.tag!('subscription') do
|
@@ -158,36 +158,10 @@ module ActiveMerchant #:nodoc:
|
|
158
158
|
end
|
159
159
|
|
160
160
|
def create_transaction(transaction_type, money, credit_card_or_vault_id, options)
|
161
|
-
|
162
|
-
|
163
|
-
:order_id => options[:order_id],
|
164
|
-
:customer => {
|
165
|
-
:id => options[:store] == true ? "" : options[:store],
|
166
|
-
:email => options[:email]
|
167
|
-
},
|
168
|
-
:options => {
|
169
|
-
:store_in_vault => options[:store] ? true : false,
|
170
|
-
:submit_for_settlement => options[:submit_for_settlement]
|
171
|
-
}
|
172
|
-
}
|
173
|
-
if credit_card_or_vault_id.is_a?(String) || credit_card_or_vault_id.is_a?(Integer)
|
174
|
-
parameters[:customer_id] = credit_card_or_vault_id
|
175
|
-
else
|
176
|
-
parameters[:customer].merge!(
|
177
|
-
:first_name => credit_card_or_vault_id.first_name,
|
178
|
-
:last_name => credit_card_or_vault_id.last_name
|
179
|
-
)
|
180
|
-
parameters[:credit_card] = {
|
181
|
-
:number => credit_card_or_vault_id.number,
|
182
|
-
:cvv => credit_card_or_vault_id.verification_value,
|
183
|
-
:expiration_month => credit_card_or_vault_id.month.to_s.rjust(2, "0"),
|
184
|
-
:expiration_year => credit_card_or_vault_id.year.to_s
|
185
|
-
}
|
186
|
-
end
|
187
|
-
parameters[:billing] = map_address(options[:billing_address]) if options[:billing_address]
|
188
|
-
parameters[:shipping] = map_address(options[:shipping_address]) if options[:shipping_address]
|
161
|
+
transaction_params = create_transaction_parameters(money, credit_card_or_vault_id, options)
|
162
|
+
|
189
163
|
commit do
|
190
|
-
result = Braintree::Transaction.send(transaction_type,
|
164
|
+
result = Braintree::Transaction.send(transaction_type, transaction_params)
|
191
165
|
response_params, response_options, avs_result, cvv_result = {}, {}, {}, {}
|
192
166
|
if result.success?
|
193
167
|
response_params[:braintree_transaction] = transaction_hash(result.transaction)
|
@@ -201,7 +175,7 @@ module ActiveMerchant #:nodoc:
|
|
201
175
|
:postal_match => result.transaction.avs_postal_code_response_code
|
202
176
|
}
|
203
177
|
response_options[:cvv_result] = result.transaction.cvv_response_code
|
204
|
-
message = result.transaction.processor_response_code
|
178
|
+
message = "#{result.transaction.processor_response_code} #{result.transaction.processor_response_text}"
|
205
179
|
else
|
206
180
|
message = message_from_result(result)
|
207
181
|
end
|
@@ -279,13 +253,49 @@ module ActiveMerchant #:nodoc:
|
|
279
253
|
}
|
280
254
|
|
281
255
|
{
|
282
|
-
"order_id"
|
283
|
-
"status"
|
284
|
-
"customer_details"
|
285
|
-
"billing_details"
|
286
|
-
"shipping_details"
|
287
|
-
"vault_customer"
|
256
|
+
"order_id" => transaction.order_id,
|
257
|
+
"status" => transaction.status,
|
258
|
+
"customer_details" => customer_details,
|
259
|
+
"billing_details" => billing_details,
|
260
|
+
"shipping_details" => shipping_details,
|
261
|
+
"vault_customer" => vault_customer,
|
262
|
+
"merchant_account_id" => transaction.merchant_account_id
|
263
|
+
}
|
264
|
+
end
|
265
|
+
|
266
|
+
def create_transaction_parameters(money, credit_card_or_vault_id, options)
|
267
|
+
parameters = {
|
268
|
+
:amount => amount(money).to_s,
|
269
|
+
:order_id => options[:order_id],
|
270
|
+
:customer => {
|
271
|
+
:id => options[:store] == true ? "" : options[:store],
|
272
|
+
:email => options[:email]
|
273
|
+
},
|
274
|
+
:options => {
|
275
|
+
:store_in_vault => options[:store] ? true : false,
|
276
|
+
:submit_for_settlement => options[:submit_for_settlement]
|
277
|
+
}
|
288
278
|
}
|
279
|
+
if options.has_key?(:merchant_account_id)
|
280
|
+
parameters[:merchant_account_id] = options[:merchant_account_id]
|
281
|
+
end
|
282
|
+
if credit_card_or_vault_id.is_a?(String) || credit_card_or_vault_id.is_a?(Integer)
|
283
|
+
parameters[:customer_id] = credit_card_or_vault_id
|
284
|
+
else
|
285
|
+
parameters[:customer].merge!(
|
286
|
+
:first_name => credit_card_or_vault_id.first_name,
|
287
|
+
:last_name => credit_card_or_vault_id.last_name
|
288
|
+
)
|
289
|
+
parameters[:credit_card] = {
|
290
|
+
:number => credit_card_or_vault_id.number,
|
291
|
+
:cvv => credit_card_or_vault_id.verification_value,
|
292
|
+
:expiration_month => credit_card_or_vault_id.month.to_s.rjust(2, "0"),
|
293
|
+
:expiration_year => credit_card_or_vault_id.year.to_s
|
294
|
+
}
|
295
|
+
end
|
296
|
+
parameters[:billing] = map_address(options[:billing_address]) if options[:billing_address]
|
297
|
+
parameters[:shipping] = map_address(options[:shipping_address]) if options[:shipping_address]
|
298
|
+
parameters
|
289
299
|
end
|
290
300
|
end
|
291
301
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class CardSaveGateway < IridiumGateway
|
4
|
+
#CardSave lets you handle failovers on payments by providing 3 gateways in case one happens to be down
|
5
|
+
#URLS = ['https://gw1.cardsaveonlinepayments.com:4430/','https://gw2.cardsaveonlinepayments.com:4430/','https://gw3.cardsaveonlinepayments.com:4430/']
|
6
|
+
|
7
|
+
self.money_format = :cents
|
8
|
+
self.default_currency = 'GBP'
|
9
|
+
self.supported_cardtypes = [ :visa, :switch, :maestro, :master, :solo, :american_express, :jcb ]
|
10
|
+
self.supported_countries = [ 'GB' ]
|
11
|
+
self.homepage_url = 'http://www.cardsave.net/'
|
12
|
+
self.display_name = 'CardSave'
|
13
|
+
|
14
|
+
def initialize(options={})
|
15
|
+
super
|
16
|
+
@test_url = 'https://gw1.cardsaveonlinepayments.com:4430/'
|
17
|
+
@live_url = 'https://gw1.cardsaveonlinepayments.com:4430/'
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
@@ -8,7 +8,7 @@ module ActiveMerchant #:nodoc:
|
|
8
8
|
self.money_format = :cents
|
9
9
|
self.supported_cardtypes = [:dankort, :forbrugsforeningen, :visa, :master,
|
10
10
|
:american_express, :diners_club, :jcb, :maestro]
|
11
|
-
self.supported_countries = ['DK']
|
11
|
+
self.supported_countries = ['DK', 'SE', 'NO']
|
12
12
|
self.homepage_url = 'http://epay.dk/'
|
13
13
|
self.display_name = 'ePay'
|
14
14
|
|
@@ -7,8 +7,6 @@ module ActiveMerchant #:nodoc:
|
|
7
7
|
# login to the Iridium Merchant Management System. Instead, you will
|
8
8
|
# use the API username and password you were issued separately.
|
9
9
|
class IridiumGateway < Gateway
|
10
|
-
TEST_URL = 'https://gw1.iridiumcorp.net/'
|
11
|
-
LIVE_URL = 'https://gw1.iridiumcorp.net/'
|
12
10
|
|
13
11
|
# The countries the gateway supports merchants from as 2 digit ISO country codes
|
14
12
|
self.supported_countries = ['GB', 'ES']
|
@@ -37,6 +35,8 @@ module ActiveMerchant #:nodoc:
|
|
37
35
|
def initialize(options = {})
|
38
36
|
requires!(options, :login, :password)
|
39
37
|
@options = options
|
38
|
+
@test_url = 'https://gw1.iridiumcorp.net/'
|
39
|
+
@live_url = 'https://gw1.iridiumcorp.net/'
|
40
40
|
super
|
41
41
|
end
|
42
42
|
|
@@ -172,7 +172,7 @@ module ActiveMerchant #:nodoc:
|
|
172
172
|
|
173
173
|
def commit(request, options)
|
174
174
|
requires!(options, :action)
|
175
|
-
response = parse(ssl_post(test? ?
|
175
|
+
response = parse(ssl_post(test? ? @test_url : @live_url, request,
|
176
176
|
{"SOAPAction" => "https://www.thepaymentgateway.net/#{options[:action]}",
|
177
177
|
"Content-Type" => "text/xml; charset=utf-8" }))
|
178
178
|
|