activemerchant 1.30.0 → 1.31.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +10 -0
- data/CONTRIBUTORS +9 -1
- data/README.md +2 -0
- data/lib/active_merchant/billing/check.rb +0 -4
- data/lib/active_merchant/billing/credit_card.rb +0 -4
- data/lib/active_merchant/billing/gateway.rb +1 -1
- data/lib/active_merchant/billing/gateways/cyber_source.rb +3 -3
- data/lib/active_merchant/billing/gateways/evo_ca.rb +308 -0
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +10 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +6 -4
- data/lib/active_merchant/billing/gateways/paymill.rb +161 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +15 -11
- data/lib/active_merchant/billing/gateways/worldpay.rb +4 -1
- data/lib/active_merchant/version.rb +1 -1
- metadata +52 -104
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
= ActiveMerchant CHANGELOG
|
2
2
|
|
3
|
+
== Version 1.31.0 (February 20, 2013)
|
4
|
+
|
5
|
+
* Worldpay: XML encoding is required to be ISO-8859-1 [dougal]
|
6
|
+
* Worldpay: Add card code for more supported card types [dougal]
|
7
|
+
* Ogone: Add action option [pwoestelandt]
|
8
|
+
* PayPal Express gateway: Add support for BuyerEmailOptInEnable [chrisrbnelson]
|
9
|
+
* Add Paymill gateway [duff]
|
10
|
+
* Add EVO Canada gateway [alexdunae]
|
11
|
+
* Fixed credit card and check interface, used correct method for checking payment type [jduff]
|
12
|
+
|
3
13
|
== Version 1.30.0 (February 13, 2013)
|
4
14
|
|
5
15
|
* Add FirstData Global Gateway e4 [frobcode]
|
data/CONTRIBUTORS
CHANGED
@@ -370,9 +370,17 @@ Pin gateway (February 2013)
|
|
370
370
|
|
371
371
|
* Myles Eftos (madpilot)
|
372
372
|
|
373
|
-
Merchant Warrior
|
373
|
+
Merchant Warrior (February 2013)
|
374
374
|
|
375
375
|
* Ben Bruscella (benbruscella)
|
376
376
|
* Дмитрий Василец (pronix)
|
377
377
|
* Kirill Shirinkin (Fodoj)
|
378
378
|
* Nathaniel Talbott (ntalbott)
|
379
|
+
|
380
|
+
Paymill (February 2013)
|
381
|
+
|
382
|
+
* Duff O'Melia (duff)
|
383
|
+
|
384
|
+
EVO Canada (February 2013)
|
385
|
+
|
386
|
+
* Alex Dunae (alexdunae)
|
data/README.md
CHANGED
@@ -94,6 +94,7 @@ The [ActiveMerchant Wiki](http://github.com/Shopify/active_merchant/wikis) conta
|
|
94
94
|
* [Efsnet](http://www.concordefsnet.com/) - US
|
95
95
|
* [Elavon MyVirtualMerchant](http://www.elavon.com) - US, CA
|
96
96
|
* [ePay](http://www.epay.dk/) - DK, SE, NO
|
97
|
+
* [EVO Canada](http://www.evocanada.com/) - CA
|
97
98
|
* [eWAY](http://www.eway.com.au/) - AU
|
98
99
|
* [eWay Rapid 3.0](http://www.eway.com.au/) - AU
|
99
100
|
* [E-xact](http://www.e-xact.com) - CA, US
|
@@ -132,6 +133,7 @@ The [ActiveMerchant Wiki](http://github.com/Shopify/active_merchant/wikis) conta
|
|
132
133
|
* [PayGate PayXML](http://paygate.co.za/) - US, ZA
|
133
134
|
* [PayJunction](http://www.payjunction.com/) - US
|
134
135
|
* [PaymentExpress](http://www.paymentexpress.com/) - AU, MY, NZ, SG, ZA, UK, US
|
136
|
+
* [Paymill](https://www.paymill.com) - AT, BE, CH, CZ, DE, DK, EE, ES, FI, FR, GB, HU, IE, IS, IT, LI, LU, LV, NL, NO, PL, PT, SE, SI, TR
|
135
137
|
* [PayPal Express Checkout](https://www.paypal.com/cgi-bin/webscr?cmd=xpt/merchant/ExpressCheckoutIntro-outside) - US, CA, SG, AU
|
136
138
|
* [PayPal Payflow Pro](https://www.paypal.com/cgi-bin/webscr?cmd=_payflow-pro-overview-outside) - US, CA, SG, AU
|
137
139
|
* [PayPal Website Payments Pro (UK)](https://www.paypal.com/uk/cgi-bin/webscr?cmd=_wp-pro-overview-outside) - UK
|
@@ -45,10 +45,6 @@ module ActiveMerchant #:nodoc:
|
|
45
45
|
'check'
|
46
46
|
end
|
47
47
|
|
48
|
-
def check?
|
49
|
-
true
|
50
|
-
end
|
51
|
-
|
52
48
|
# Routing numbers may be validated by calculating a checksum and dividing it by 10. The
|
53
49
|
# formula is:
|
54
50
|
# (3(d1 + d4 + d7) + 7(d2 + d5 + d8) + 1(d3 + d6 + d9))mod 10 = 0
|
@@ -254,7 +254,7 @@ module ActiveMerchant #:nodoc:
|
|
254
254
|
def build_purchase_request(money, payment_method_or_reference, options)
|
255
255
|
xml = Builder::XmlMarkup.new :indent => 2
|
256
256
|
add_payment_method_or_subscription(xml, money, payment_method_or_reference, options)
|
257
|
-
if(payment_method_or_reference
|
257
|
+
if card_brand(payment_method_or_reference) == 'check'
|
258
258
|
add_check_service(xml)
|
259
259
|
else
|
260
260
|
add_purchase_service(xml, options)
|
@@ -308,7 +308,7 @@ module ActiveMerchant #:nodoc:
|
|
308
308
|
xml = Builder::XmlMarkup.new :indent => 2
|
309
309
|
add_address(xml, payment_method, options[:billing_address], options)
|
310
310
|
add_purchase_data(xml, options[:setup_fee] || 0, true, options)
|
311
|
-
if payment_method
|
311
|
+
if card_brand(payment_method) == 'check'
|
312
312
|
add_check(xml, payment_method)
|
313
313
|
add_check_payment_method(xml)
|
314
314
|
add_check_service(xml, options) if options[:setup_fee]
|
@@ -524,7 +524,7 @@ module ActiveMerchant #:nodoc:
|
|
524
524
|
if payment_method_or_reference.is_a?(String)
|
525
525
|
add_purchase_data(xml, money, true, options)
|
526
526
|
add_subscription(xml, options, payment_method_or_reference)
|
527
|
-
elsif payment_method_or_reference
|
527
|
+
elsif card_brand(payment_method_or_reference) == 'check'
|
528
528
|
add_address(xml, payment_method_or_reference, options[:billing_address], options)
|
529
529
|
add_purchase_data(xml, money, true, options)
|
530
530
|
add_check(xml, payment_method_or_reference)
|
@@ -0,0 +1,308 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
# === EVO Canada payment gateway.
|
4
|
+
#
|
5
|
+
# EVO returns two different identifiers for most transactions, the
|
6
|
+
# +authcode+ and the +transactionid+. Since +transactionid+ is used more
|
7
|
+
# often (i.e. for {#capture}, {#refund}, {#void} and {#update}) we store it in the
|
8
|
+
# Response#authorization attribute. The +authcode+ from the merchant
|
9
|
+
# account is accessible via {Response#params}.
|
10
|
+
#
|
11
|
+
# Two different but related response messages are also returned from EVO.
|
12
|
+
# The message indicated by EVO's <tt>response_code</tt> parameter is returned as
|
13
|
+
# {Response#message} (Those messages can be seen in the {MESSAGES} hash.)
|
14
|
+
# The other, shorter message is available via {Response#params}.
|
15
|
+
#
|
16
|
+
# It's recommended to save the contents of the {Response#params} in your
|
17
|
+
# transaction log for future reference.
|
18
|
+
#
|
19
|
+
# === Sample Use
|
20
|
+
#
|
21
|
+
# gateway = ActiveMerchant::Billing::EvoCaGateway.new(username: 'demo', password: 'password')
|
22
|
+
#
|
23
|
+
# response = gateway.authorize(1000, credit_card, options)
|
24
|
+
#
|
25
|
+
# puts response.authorization # the transactionid
|
26
|
+
# puts response.params['authcode'] # the authcode from the merchant account
|
27
|
+
# puts response.message # the 'pretty' response message
|
28
|
+
# puts response.params['responsetext'] # the 'terse' response message
|
29
|
+
#
|
30
|
+
# gateway.capture(1000, response.authorization)
|
31
|
+
# gateway.update(response.authorization, shipping_carrier: 'fedex')
|
32
|
+
# gateway.refund(500, response.authorization)
|
33
|
+
#
|
34
|
+
class EvoCaGateway < Gateway
|
35
|
+
self.test_url = 'https://secure.evoepay.com/api/transact.php'
|
36
|
+
self.live_url = 'https://secure.evoepay.com/api/transact.php'
|
37
|
+
|
38
|
+
self.supported_countries = ['CA']
|
39
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :jcb, :discover]
|
40
|
+
self.money_format = :dollars
|
41
|
+
self.homepage_url = 'http://www.evocanada.com/'
|
42
|
+
self.display_name = 'EVO Canada'
|
43
|
+
|
44
|
+
APPROVED, DECLINED, ERROR = 1, 2, 3
|
45
|
+
|
46
|
+
MESSAGES = {
|
47
|
+
100 => 'Transaction was approved',
|
48
|
+
200 => 'Transaction was declined by processor',
|
49
|
+
201 => 'Do not honor',
|
50
|
+
202 => 'Insufficient funds',
|
51
|
+
203 => 'Over limit',
|
52
|
+
204 => 'Transaction not allowed',
|
53
|
+
220 => 'Incorrect payment data',
|
54
|
+
221 => 'No such card issuer',
|
55
|
+
222 => 'No card number on file with issuer',
|
56
|
+
223 => 'Expired card',
|
57
|
+
224 => 'Invalid expiration date',
|
58
|
+
225 => 'Invalid card security code',
|
59
|
+
240 => 'Call issuer for futher information',
|
60
|
+
250 => 'Pick up card',
|
61
|
+
251 => 'Lost card',
|
62
|
+
252 => 'Stolen card',
|
63
|
+
253 => 'Fraudulant card',
|
64
|
+
260 => 'Declined with further instructions available',
|
65
|
+
261 => 'Declined - stop all recurring payments',
|
66
|
+
262 => 'Declined - stop this recurring program',
|
67
|
+
263 => 'Declined - updated cardholder data available',
|
68
|
+
264 => 'Declined - retry in a few days',
|
69
|
+
300 => 'Transaction was rejected by gateway',
|
70
|
+
400 => 'Transaction error returned by processor',
|
71
|
+
410 => 'Invalid merchant configuration',
|
72
|
+
411 => 'Merchant account is inactive',
|
73
|
+
420 => 'Communication error',
|
74
|
+
421 => 'Communication error with issuer',
|
75
|
+
430 => 'Duplicate transaction at processor',
|
76
|
+
440 => 'Processor format error',
|
77
|
+
441 => 'Invalid transaction information',
|
78
|
+
460 => 'Processor feature not available',
|
79
|
+
461 => 'Unsupported card type'
|
80
|
+
}
|
81
|
+
|
82
|
+
# This gateway requires that a valid username and password be passed
|
83
|
+
# in the +options+ hash.
|
84
|
+
#
|
85
|
+
# === Required Options
|
86
|
+
#
|
87
|
+
# * <tt>:username</tt>
|
88
|
+
# * <tt>:password</tt>
|
89
|
+
def initialize(options = {})
|
90
|
+
requires!(options, :username, :password)
|
91
|
+
super
|
92
|
+
end
|
93
|
+
|
94
|
+
# Transaction sales are submitted and immediately flagged for settlement.
|
95
|
+
# These transactions will automatically be settled.
|
96
|
+
#
|
97
|
+
# Payment source can be either a {CreditCard} or {Check}.
|
98
|
+
#
|
99
|
+
# === Additional Options
|
100
|
+
# In addition to the standard options, this gateway supports
|
101
|
+
#
|
102
|
+
# * <tt>:tracking_number</tt> - Shipping tracking number
|
103
|
+
# * <tt>:shipping_carrier</tt> - ups/fedex/dhl/usps
|
104
|
+
# * <tt>:po_number</tt> - Purchase order
|
105
|
+
# * <tt>:tax</tt> - Tax amount
|
106
|
+
# * <tt>:shipping</tt> - Shipping cost
|
107
|
+
def purchase(money, credit_card_or_check, options = {})
|
108
|
+
post = {}
|
109
|
+
add_invoice(post, options)
|
110
|
+
add_order(post, options)
|
111
|
+
add_paymentmethod(post, credit_card_or_check)
|
112
|
+
add_address(post, options)
|
113
|
+
add_customer_data(post, options)
|
114
|
+
commit('sale', money, post)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Transaction authorizations are authorized immediately but are not
|
118
|
+
# flagged for settlement. These transactions must be flagged for
|
119
|
+
# settlement using the _capture_ transaction type. Authorizations
|
120
|
+
# typically remain activate for three to seven business days.
|
121
|
+
#
|
122
|
+
# Payment source must be a {CreditCard}.
|
123
|
+
def authorize(money, credit_card, options = {})
|
124
|
+
post = {}
|
125
|
+
add_invoice(post, options)
|
126
|
+
add_order(post, options)
|
127
|
+
add_paymentmethod(post, credit_card)
|
128
|
+
add_address(post, options)
|
129
|
+
add_customer_data(post, options)
|
130
|
+
commit('auth', money, post)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Transaction captures flag existing _authorizations_ for settlement. Only
|
134
|
+
# authorizations can be captured. Captures can be submitted for an amount
|
135
|
+
# equal to or less than the original authorization.
|
136
|
+
#
|
137
|
+
# The <tt>authorization</tt> parameter is the transaction ID, retrieved
|
138
|
+
# from Response#authorization. See EvoCaGateway#purchase for the
|
139
|
+
# <tt>options</tt>.
|
140
|
+
def capture(money, authorization, options = {})
|
141
|
+
post = {
|
142
|
+
:amount => amount(money),
|
143
|
+
:transactionid => authorization
|
144
|
+
}
|
145
|
+
add_order(post, options)
|
146
|
+
commit('capture', money, post)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Transaction refunds will reverse a previously settled transaction. If
|
150
|
+
# the transaction has not been settled, it must be _voided_ instead of
|
151
|
+
# refunded.
|
152
|
+
#
|
153
|
+
# The <tt>identification</tt> parameter is the transaction ID, retrieved
|
154
|
+
# from {Response#authorization}.
|
155
|
+
def refund(money, identification)
|
156
|
+
post = {:transactionid => identification}
|
157
|
+
commit('refund', money, post)
|
158
|
+
end
|
159
|
+
|
160
|
+
# Transaction credits apply a negative amount to the cardholder's card.
|
161
|
+
# In most situations credits are disabled as transaction refunds should
|
162
|
+
# be used instead.
|
163
|
+
#
|
164
|
+
# Note that this is different from a {#refund} (which is usually what
|
165
|
+
# you'll be looking for).
|
166
|
+
def credit(money, credit_card, options = {})
|
167
|
+
post = {}
|
168
|
+
add_invoice(post, options)
|
169
|
+
add_order(post, options)
|
170
|
+
add_paymentmethod(post, credit_card)
|
171
|
+
add_address(post, options)
|
172
|
+
add_customer_data(post, options)
|
173
|
+
commit('credit', money, post)
|
174
|
+
end
|
175
|
+
|
176
|
+
# Transaction voids will cancel an existing sale or captured
|
177
|
+
# authorization. In addition, non-captured authorizations can be voided to
|
178
|
+
# prevent any future capture. Voids can only occur if the transaction has
|
179
|
+
# not been settled.
|
180
|
+
#
|
181
|
+
# The <tt>identification</tt> parameter is the transaction ID, retrieved
|
182
|
+
# from {Response#authorization}.
|
183
|
+
def void(identification)
|
184
|
+
post = {:transactionid => identification}
|
185
|
+
commit('void', nil, post)
|
186
|
+
end
|
187
|
+
|
188
|
+
# Transaction updates can be used to update previous transactions with
|
189
|
+
# specific order information, such as a tracking number and shipping
|
190
|
+
# carrier. See EvoCaGateway#purchase for <tt>options</tt>.
|
191
|
+
#
|
192
|
+
# The <tt>identification</tt> parameter is the transaction ID, retrieved
|
193
|
+
# from {Response#authorization}.
|
194
|
+
def update(identification, options)
|
195
|
+
post = {:transactionid => identification}
|
196
|
+
add_order(post, options)
|
197
|
+
commit('update', nil, post)
|
198
|
+
end
|
199
|
+
|
200
|
+
private
|
201
|
+
|
202
|
+
def add_customer_data(post, options)
|
203
|
+
post[:email] = options[:email]
|
204
|
+
post[:ipaddress] = options[:ip]
|
205
|
+
end
|
206
|
+
|
207
|
+
def add_address(post, options)
|
208
|
+
if address = options[:billing_address] || options[:address]
|
209
|
+
post[:firstname] = address[:first_name]
|
210
|
+
post[:lastname] = address[:last_name]
|
211
|
+
post[:address1] = address[:address1]
|
212
|
+
post[:address2] = address[:address2]
|
213
|
+
post[:company] = address[:company]
|
214
|
+
post[:phone] = address[:phone]
|
215
|
+
post[:city] = address[:city]
|
216
|
+
post[:state] = address[:state]
|
217
|
+
post[:zip] = address[:zip]
|
218
|
+
post[:country] = address[:country]
|
219
|
+
end
|
220
|
+
|
221
|
+
if address = options[:shipping_address]
|
222
|
+
post[:shipping_firstname] = address[:first_name]
|
223
|
+
post[:shipping_lastname] = address[:last_name]
|
224
|
+
post[:shipping_address1] = address[:address1]
|
225
|
+
post[:shipping_address2] = address[:address2]
|
226
|
+
post[:shipping_company] = address[:company]
|
227
|
+
post[:shipping_zip] = address[:zip]
|
228
|
+
post[:shipping_city] = address[:city]
|
229
|
+
post[:shipping_state] = address[:state]
|
230
|
+
post[:shipping_country] = address[:country]
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def add_order(post, options)
|
235
|
+
post[:orderid] = options[:order_id]
|
236
|
+
post[:tracking_number] = options[:tracking_number]
|
237
|
+
post[:shipping_carrier] = options[:shipping_carrier]
|
238
|
+
end
|
239
|
+
|
240
|
+
def add_invoice(post, options)
|
241
|
+
post[:orderdescription] = options[:description]
|
242
|
+
post[:ponumber] = options[:po_number]
|
243
|
+
post[:shipping] = amount(options[:shipping])
|
244
|
+
post[:tax] = amount(options[:tax])
|
245
|
+
end
|
246
|
+
|
247
|
+
def add_paymentmethod(post, payment)
|
248
|
+
if card_brand(payment)=='check'
|
249
|
+
post[:payment] = 'check'
|
250
|
+
post[:checkname] = payment.name
|
251
|
+
post[:checkaba] = payment.routing_number
|
252
|
+
post[:checkaccount] = payment.account_number
|
253
|
+
post[:account_holder_type] = payment.account_holder_type
|
254
|
+
post[:account_type] = payment.account_type
|
255
|
+
else
|
256
|
+
post[:payment] = 'creditcard'
|
257
|
+
post[:ccnumber] = payment.number
|
258
|
+
post[:ccexp] = "#{format(payment.month, :two_digits)}#{format(payment.year, :two_digits)}"
|
259
|
+
post[:cvv] = payment.verification_value
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
def parse(body)
|
264
|
+
fields = {}
|
265
|
+
CGI::parse(body).each do |k, v|
|
266
|
+
fields[k.to_s] = v.kind_of?(Array) ? v[0] : v
|
267
|
+
end
|
268
|
+
fields
|
269
|
+
end
|
270
|
+
|
271
|
+
def success?(response)
|
272
|
+
response['response'].to_i == APPROVED
|
273
|
+
end
|
274
|
+
|
275
|
+
def commit(action, money, parameters)
|
276
|
+
parameters[:amount] = amount(money) unless action == 'void'
|
277
|
+
|
278
|
+
data = ssl_post self.live_url, post_data(action, parameters)
|
279
|
+
response = parse(data)
|
280
|
+
message = message_from(response)
|
281
|
+
|
282
|
+
Response.new(success?(response), message, response,
|
283
|
+
:test => test?,
|
284
|
+
:authorization => response['transactionid'],
|
285
|
+
:avs_result => { :code => response['avsresponse'] },
|
286
|
+
:cvv_result => response['cvvresponse']
|
287
|
+
)
|
288
|
+
end
|
289
|
+
|
290
|
+
def message_from(response)
|
291
|
+
MESSAGES.fetch(response['response_code'].to_i, false) || response['message']
|
292
|
+
end
|
293
|
+
|
294
|
+
def post_data(action, parameters = {})
|
295
|
+
post = {:type => action}
|
296
|
+
|
297
|
+
if test?
|
298
|
+
post[:username] = 'demo'
|
299
|
+
post[:password] = 'password'
|
300
|
+
else
|
301
|
+
post[:username] = options[:username]
|
302
|
+
post[:password] = options[:password]
|
303
|
+
end
|
304
|
+
post.merge(parameters).collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" unless value.nil? }.compact.join("&")
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
@@ -27,6 +27,16 @@ module ActiveMerchant #:nodoc:
|
|
27
27
|
self.homepage_url = "http://www.firstdata.com"
|
28
28
|
self.display_name = "FirstData Global Gateway e4"
|
29
29
|
|
30
|
+
# Create a new FirstdataE4Gateway
|
31
|
+
#
|
32
|
+
# The gateway requires that a valid login and password be passed
|
33
|
+
# in the +options+ hash.
|
34
|
+
#
|
35
|
+
# ==== Options
|
36
|
+
#
|
37
|
+
# * <tt>:login</tt> -- The EXACT ID. Also known as the Gateway ID.
|
38
|
+
# (Found in your administration terminal settings)
|
39
|
+
# * <tt>:password</tt> -- The terminal password (not your account password)
|
30
40
|
def initialize(options = {})
|
31
41
|
requires!(options, :login, :password)
|
32
42
|
@options = options
|
@@ -154,23 +154,25 @@ module ActiveMerchant #:nodoc:
|
|
154
154
|
|
155
155
|
# Verify and transfer the specified amount.
|
156
156
|
def purchase(money, payment_source, options = {})
|
157
|
-
post
|
157
|
+
post = {}
|
158
|
+
action = options[:action] || 'SAL'
|
158
159
|
add_invoice(post, options)
|
159
160
|
add_payment_source(post, payment_source, options)
|
160
161
|
add_address(post, payment_source, options)
|
161
162
|
add_customer_data(post, options)
|
162
163
|
add_money(post, money, options)
|
163
|
-
commit(
|
164
|
+
commit(action, post)
|
164
165
|
end
|
165
166
|
|
166
167
|
# Complete a previously authorized transaction.
|
167
168
|
def capture(money, authorization, options = {})
|
168
|
-
post
|
169
|
+
post = {}
|
170
|
+
action = options[:action] || 'SAL'
|
169
171
|
add_authorization(post, reference_from(authorization))
|
170
172
|
add_invoice(post, options)
|
171
173
|
add_customer_data(post, options)
|
172
174
|
add_money(post, money, options)
|
173
|
-
commit(
|
175
|
+
commit(action, post)
|
174
176
|
end
|
175
177
|
|
176
178
|
# Cancels a previously authorized transaction.
|
@@ -0,0 +1,161 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class PaymillGateway < Gateway
|
4
|
+
self.supported_countries = %w(AT BE CH CZ DE DK EE ES FI FR GB HU IE
|
5
|
+
IS IT LI LU LV NL NO PL PT SE SI TR)
|
6
|
+
|
7
|
+
self.supported_cardtypes = [:visa, :master]
|
8
|
+
self.homepage_url = 'https://paymill.com'
|
9
|
+
self.display_name = 'Paymill'
|
10
|
+
self.money_format = :cents
|
11
|
+
self.default_currency = 'EUR'
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
requires!(options, :public_key, :private_key)
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
def purchase(money, credit_card, options = {})
|
19
|
+
MultiResponse.run do |r|
|
20
|
+
r.process { save_card(credit_card) }
|
21
|
+
r.process { purchase_with_token(money, r.authorization, options) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def authorize(money, credit_card, options = {})
|
26
|
+
MultiResponse.run do |r|
|
27
|
+
r.process { save_card(credit_card) }
|
28
|
+
r.process { authorize_with_token(money, r.authorization, options) }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def capture(money, authorization, options = {})
|
33
|
+
post = {}
|
34
|
+
|
35
|
+
add_amount(post, money, options)
|
36
|
+
post[:preauthorization] = preauth(authorization)
|
37
|
+
post[:description] = options[:description]
|
38
|
+
commit(:post, 'transactions', post)
|
39
|
+
end
|
40
|
+
|
41
|
+
def refund(money, authorization, options={})
|
42
|
+
post = {}
|
43
|
+
|
44
|
+
post[:amount] = amount(money)
|
45
|
+
post[:description] = options[:description]
|
46
|
+
commit(:post, "refunds/#{transaction_id(authorization)}", post)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def add_credit_card(post, credit_card)
|
52
|
+
post['account.number'] = credit_card.number
|
53
|
+
post['account.expiry.month'] = sprintf("%.2i", credit_card.month)
|
54
|
+
post['account.expiry.year'] = sprintf("%.4i", credit_card.year)
|
55
|
+
post['account.verification'] = credit_card.verification_value
|
56
|
+
end
|
57
|
+
|
58
|
+
def headers
|
59
|
+
{ 'Authorization' => ('Basic ' + Base64.strict_encode64("#{@options[:private_key]}:X").chomp) }
|
60
|
+
end
|
61
|
+
|
62
|
+
def commit(method, url, parameters=nil)
|
63
|
+
begin
|
64
|
+
raw_response = ssl_request(method, "https://api.paymill.com/v2/#{url}", post_data(parameters), headers)
|
65
|
+
rescue ResponseError => e
|
66
|
+
parsed = JSON.parse(e.response.body)
|
67
|
+
return Response.new(false, parsed['error'], parsed, {})
|
68
|
+
end
|
69
|
+
|
70
|
+
response_from(raw_response)
|
71
|
+
end
|
72
|
+
|
73
|
+
def response_from(raw_response)
|
74
|
+
parsed = JSON.parse(raw_response)
|
75
|
+
|
76
|
+
options = {
|
77
|
+
:authorization => authorization_from(parsed),
|
78
|
+
:test => (parsed['mode'] == 'test'),
|
79
|
+
}
|
80
|
+
|
81
|
+
Response.new(true, 'Transaction approved', parsed, options)
|
82
|
+
end
|
83
|
+
|
84
|
+
def authorization_from(parsed_response)
|
85
|
+
[
|
86
|
+
parsed_response['data']['id'],
|
87
|
+
parsed_response['data']['preauthorization'].try(:[], 'id')
|
88
|
+
].join(";")
|
89
|
+
end
|
90
|
+
|
91
|
+
def purchase_with_token(money, card_token, options)
|
92
|
+
post = {}
|
93
|
+
|
94
|
+
add_amount(post, money, options)
|
95
|
+
post[:token] = card_token
|
96
|
+
post[:description] = options[:description]
|
97
|
+
commit(:post, 'transactions', post)
|
98
|
+
end
|
99
|
+
|
100
|
+
def authorize_with_token(money, card_token, options)
|
101
|
+
post = {}
|
102
|
+
|
103
|
+
add_amount(post, money, options)
|
104
|
+
post[:token] = card_token
|
105
|
+
commit(:post, 'preauthorizations', post)
|
106
|
+
end
|
107
|
+
|
108
|
+
def save_card(credit_card)
|
109
|
+
post = {}
|
110
|
+
|
111
|
+
add_credit_card(post, credit_card)
|
112
|
+
post['channel.id'] = @options[:public_key]
|
113
|
+
post['jsonPFunction'] = 'jsonPFunction'
|
114
|
+
post['transaction.mode'] = (test? ? 'CONNECTOR_TEST' : 'LIVE')
|
115
|
+
|
116
|
+
begin
|
117
|
+
raw_response = ssl_request(:get, "#{save_card_url}?#{post_data(post)}", nil, {})
|
118
|
+
rescue ResponseError => e
|
119
|
+
return Response.new(false, e.response.body, e.response.body, {})
|
120
|
+
end
|
121
|
+
|
122
|
+
response_for_save_from(raw_response)
|
123
|
+
end
|
124
|
+
|
125
|
+
def response_for_save_from(raw_response)
|
126
|
+
parsed = JSON.parse(raw_response.sub(/jsonPFunction\(/, '').sub(/\)\z/, ''))
|
127
|
+
succeeded = parsed['transaction']['processing']['result'] == 'ACK'
|
128
|
+
|
129
|
+
options = { :test => test? }
|
130
|
+
if succeeded
|
131
|
+
options[:authorization] = parsed['transaction']['identification']['uniqueId']
|
132
|
+
end
|
133
|
+
|
134
|
+
message = parsed['transaction']['processing']['return']['message']
|
135
|
+
Response.new(succeeded, message, parsed, options)
|
136
|
+
end
|
137
|
+
|
138
|
+
def save_card_url
|
139
|
+
(test? ? 'https://test-token.paymill.de' : 'https://token-v2.paymill.de')
|
140
|
+
end
|
141
|
+
|
142
|
+
def post_data(params)
|
143
|
+
no_blanks = params.reject { |key, value| value.blank? }
|
144
|
+
no_blanks.map { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
|
145
|
+
end
|
146
|
+
|
147
|
+
def add_amount(post, money, options)
|
148
|
+
post[:amount] = amount(money)
|
149
|
+
post[:currency] = (options[:currency] || currency(money))
|
150
|
+
end
|
151
|
+
|
152
|
+
def preauth(authorization)
|
153
|
+
authorization.split(";").last
|
154
|
+
end
|
155
|
+
|
156
|
+
def transaction_id(authorization)
|
157
|
+
authorization.split(';').first
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -30,16 +30,16 @@ module ActiveMerchant #:nodoc:
|
|
30
30
|
self.supported_countries = ['US']
|
31
31
|
self.homepage_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=xpt/merchant/ExpressCheckoutIntro-outside'
|
32
32
|
self.display_name = 'PayPal Express Checkout'
|
33
|
-
|
33
|
+
|
34
34
|
def setup_authorization(money, options = {})
|
35
35
|
requires!(options, :return_url, :cancel_return_url)
|
36
|
-
|
36
|
+
|
37
37
|
commit 'SetExpressCheckout', build_setup_request('Authorization', money, options)
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
def setup_purchase(money, options = {})
|
41
41
|
requires!(options, :return_url, :cancel_return_url)
|
42
|
-
|
42
|
+
|
43
43
|
commit 'SetExpressCheckout', build_setup_request('Sale', money, options)
|
44
44
|
end
|
45
45
|
|
@@ -49,13 +49,13 @@ module ActiveMerchant #:nodoc:
|
|
49
49
|
|
50
50
|
def authorize(money, options = {})
|
51
51
|
requires!(options, :token, :payer_id)
|
52
|
-
|
52
|
+
|
53
53
|
commit 'DoExpressCheckoutPayment', build_sale_or_authorization_request('Authorization', money, options)
|
54
54
|
end
|
55
55
|
|
56
56
|
def purchase(money, options = {})
|
57
57
|
requires!(options, :token, :payer_id)
|
58
|
-
|
58
|
+
|
59
59
|
commit 'DoExpressCheckoutPayment', build_sale_or_authorization_request('Sale', money, options)
|
60
60
|
end
|
61
61
|
|
@@ -77,10 +77,10 @@ module ActiveMerchant #:nodoc:
|
|
77
77
|
|
78
78
|
xml.target!
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
def build_sale_or_authorization_request(action, money, options)
|
82
82
|
currency_code = options[:currency] || currency(money)
|
83
|
-
|
83
|
+
|
84
84
|
xml = Builder::XmlMarkup.new :indent => 2
|
85
85
|
xml.tag! 'DoExpressCheckoutPaymentReq', 'xmlns' => PAYPAL_NAMESPACE do
|
86
86
|
xml.tag! 'DoExpressCheckoutPaymentRequest', 'xmlns:n2' => EBAY_NAMESPACE do
|
@@ -141,7 +141,7 @@ module ActiveMerchant #:nodoc:
|
|
141
141
|
xml.tag! 'n2:AllowNote', options[:allow_note] ? '1' : '0'
|
142
142
|
end
|
143
143
|
xml.tag! 'n2:CallbackURL', options[:callback_url] unless options[:callback_url].blank?
|
144
|
-
|
144
|
+
|
145
145
|
add_payment_details(xml, with_money_default(money), currency_code, options)
|
146
146
|
if options[:shipping_options]
|
147
147
|
options[:shipping_options].each do |shipping_option|
|
@@ -155,16 +155,20 @@ module ActiveMerchant #:nodoc:
|
|
155
155
|
|
156
156
|
xml.tag! 'n2:CallbackTimeout', options[:callback_timeout] unless options[:callback_timeout].blank?
|
157
157
|
xml.tag! 'n2:CallbackVersion', options[:callback_version] unless options[:callback_version].blank?
|
158
|
+
|
159
|
+
if options.has_key?(:allow_buyer_optin)
|
160
|
+
xml.tag! 'n2:BuyerEmailOptInEnable', (options[:allow_buyer_optin] ? '1' : '0')
|
161
|
+
end
|
158
162
|
end
|
159
163
|
end
|
160
164
|
end
|
161
165
|
|
162
166
|
xml.target!
|
163
167
|
end
|
164
|
-
|
168
|
+
|
165
169
|
def build_reference_transaction_request(action, money, options)
|
166
170
|
currency_code = options[:currency] || currency(money)
|
167
|
-
|
171
|
+
|
168
172
|
# I am not sure why it's set like this for express gateway
|
169
173
|
# but I don't want to break the existing behavior
|
170
174
|
xml = Builder::XmlMarkup.new :indent => 2
|
@@ -16,6 +16,9 @@ module ActiveMerchant #:nodoc:
|
|
16
16
|
'master' => 'ECMC-SSL',
|
17
17
|
'discover' => 'DISCOVER-SSL',
|
18
18
|
'american_express' => 'AMEX-SSL',
|
19
|
+
'jcb' => 'JCB-SSL',
|
20
|
+
'maestro' => 'MAESTRO-SSL',
|
21
|
+
'laser' => 'LASER-SSL'
|
19
22
|
}
|
20
23
|
|
21
24
|
def initialize(options = {})
|
@@ -84,7 +87,7 @@ module ActiveMerchant #:nodoc:
|
|
84
87
|
|
85
88
|
def build_request
|
86
89
|
xml = Builder::XmlMarkup.new :indent => 2
|
87
|
-
xml.instruct!
|
90
|
+
xml.instruct! :xml, :encoding => 'ISO-8859-1'
|
88
91
|
xml.declare! :DOCTYPE, :paymentService, :PUBLIC, "-//WorldPay//DTD WorldPay PaymentService v1//EN", "http://dtd.wp3.rbsworldpay.com/paymentService_v1.dtd"
|
89
92
|
xml.tag! 'paymentService', 'version' => "1.4", 'merchantCode' => @options[:login] do
|
90
93
|
yield xml
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activemerchant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.31.0
|
4
5
|
prerelease:
|
5
|
-
version: 1.30.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Tobias Luetke
|
@@ -37,184 +37,129 @@ cert_chain:
|
|
37
37
|
Z1BvU1BxN25rK3MyRlFVQko5VVpGSzFsZ016aG8vNGZaZ3pKd2J1K2NPOFNO
|
38
38
|
dWFMUy9iagpoUGFTVHlWVTB5Q1Nudz09Ci0tLS0tRU5EIENFUlRJRklDQVRF
|
39
39
|
LS0tLS0K
|
40
|
-
date: 2013-02-
|
40
|
+
date: 2013-02-20 00:00:00.000000000 Z
|
41
41
|
dependencies:
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
|
-
|
43
|
+
name: activesupport
|
44
|
+
requirement: &70206840641520 !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
44
46
|
requirements:
|
45
47
|
- - ! '>='
|
46
48
|
- !ruby/object:Gem::Version
|
47
49
|
version: 2.3.14
|
48
|
-
none: false
|
49
|
-
name: activesupport
|
50
50
|
type: :runtime
|
51
51
|
prerelease: false
|
52
|
-
|
53
|
-
requirements:
|
54
|
-
- - ! '>='
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
version: 2.3.14
|
57
|
-
none: false
|
52
|
+
version_requirements: *70206840641520
|
58
53
|
- !ruby/object:Gem::Dependency
|
59
|
-
|
54
|
+
name: i18n
|
55
|
+
requirement: &70206840641100 !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
60
57
|
requirements:
|
61
58
|
- - ! '>='
|
62
59
|
- !ruby/object:Gem::Version
|
63
60
|
version: '0'
|
64
|
-
none: false
|
65
|
-
name: i18n
|
66
61
|
type: :runtime
|
67
62
|
prerelease: false
|
68
|
-
|
69
|
-
requirements:
|
70
|
-
- - ! '>='
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
version: '0'
|
73
|
-
none: false
|
63
|
+
version_requirements: *70206840641100
|
74
64
|
- !ruby/object:Gem::Dependency
|
75
|
-
|
65
|
+
name: money
|
66
|
+
requirement: &70206840640640 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
76
68
|
requirements:
|
77
69
|
- - ! '>='
|
78
70
|
- !ruby/object:Gem::Version
|
79
71
|
version: '0'
|
80
|
-
none: false
|
81
|
-
name: money
|
82
72
|
type: :runtime
|
83
73
|
prerelease: false
|
84
|
-
|
85
|
-
requirements:
|
86
|
-
- - ! '>='
|
87
|
-
- !ruby/object:Gem::Version
|
88
|
-
version: '0'
|
89
|
-
none: false
|
74
|
+
version_requirements: *70206840640640
|
90
75
|
- !ruby/object:Gem::Dependency
|
91
|
-
|
76
|
+
name: builder
|
77
|
+
requirement: &70206840640080 !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
92
79
|
requirements:
|
93
80
|
- - ! '>='
|
94
81
|
- !ruby/object:Gem::Version
|
95
82
|
version: 2.0.0
|
96
|
-
none: false
|
97
|
-
name: builder
|
98
83
|
type: :runtime
|
99
84
|
prerelease: false
|
100
|
-
|
101
|
-
requirements:
|
102
|
-
- - ! '>='
|
103
|
-
- !ruby/object:Gem::Version
|
104
|
-
version: 2.0.0
|
105
|
-
none: false
|
85
|
+
version_requirements: *70206840640080
|
106
86
|
- !ruby/object:Gem::Dependency
|
107
|
-
|
87
|
+
name: json
|
88
|
+
requirement: &70206840639440 !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
108
90
|
requirements:
|
109
91
|
- - ! '>='
|
110
92
|
- !ruby/object:Gem::Version
|
111
93
|
version: 1.5.1
|
112
|
-
none: false
|
113
|
-
name: json
|
114
94
|
type: :runtime
|
115
95
|
prerelease: false
|
116
|
-
|
117
|
-
requirements:
|
118
|
-
- - ! '>='
|
119
|
-
- !ruby/object:Gem::Version
|
120
|
-
version: 1.5.1
|
121
|
-
none: false
|
96
|
+
version_requirements: *70206840639440
|
122
97
|
- !ruby/object:Gem::Dependency
|
123
|
-
|
98
|
+
name: active_utils
|
99
|
+
requirement: &70206840638860 !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
124
101
|
requirements:
|
125
102
|
- - ! '>='
|
126
103
|
- !ruby/object:Gem::Version
|
127
104
|
version: 1.0.2
|
128
|
-
none: false
|
129
|
-
name: active_utils
|
130
105
|
type: :runtime
|
131
106
|
prerelease: false
|
132
|
-
|
133
|
-
requirements:
|
134
|
-
- - ! '>='
|
135
|
-
- !ruby/object:Gem::Version
|
136
|
-
version: 1.0.2
|
137
|
-
none: false
|
107
|
+
version_requirements: *70206840638860
|
138
108
|
- !ruby/object:Gem::Dependency
|
139
|
-
|
109
|
+
name: nokogiri
|
110
|
+
requirement: &70206840638080 !ruby/object:Gem::Requirement
|
111
|
+
none: false
|
140
112
|
requirements:
|
141
113
|
- - ! '>='
|
142
114
|
- !ruby/object:Gem::Version
|
143
115
|
version: '0'
|
144
|
-
none: false
|
145
|
-
name: nokogiri
|
146
116
|
type: :runtime
|
147
117
|
prerelease: false
|
148
|
-
|
149
|
-
requirements:
|
150
|
-
- - ! '>='
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: '0'
|
153
|
-
none: false
|
118
|
+
version_requirements: *70206840638080
|
154
119
|
- !ruby/object:Gem::Dependency
|
155
|
-
|
120
|
+
name: rake
|
121
|
+
requirement: &70206840637200 !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
156
123
|
requirements:
|
157
124
|
- - ! '>='
|
158
125
|
- !ruby/object:Gem::Version
|
159
126
|
version: '0'
|
160
|
-
none: false
|
161
|
-
name: rake
|
162
127
|
type: :development
|
163
128
|
prerelease: false
|
164
|
-
|
165
|
-
requirements:
|
166
|
-
- - ! '>='
|
167
|
-
- !ruby/object:Gem::Version
|
168
|
-
version: '0'
|
169
|
-
none: false
|
129
|
+
version_requirements: *70206840637200
|
170
130
|
- !ruby/object:Gem::Dependency
|
171
|
-
|
131
|
+
name: mocha
|
132
|
+
requirement: &70206840636380 !ruby/object:Gem::Requirement
|
133
|
+
none: false
|
172
134
|
requirements:
|
173
135
|
- - ~>
|
174
136
|
- !ruby/object:Gem::Version
|
175
137
|
version: 0.11.3
|
176
|
-
none: false
|
177
|
-
name: mocha
|
178
138
|
type: :development
|
179
139
|
prerelease: false
|
180
|
-
|
181
|
-
requirements:
|
182
|
-
- - ~>
|
183
|
-
- !ruby/object:Gem::Version
|
184
|
-
version: 0.11.3
|
185
|
-
none: false
|
140
|
+
version_requirements: *70206840636380
|
186
141
|
- !ruby/object:Gem::Dependency
|
187
|
-
|
142
|
+
name: rails
|
143
|
+
requirement: &70206840635740 !ruby/object:Gem::Requirement
|
144
|
+
none: false
|
188
145
|
requirements:
|
189
146
|
- - ! '>='
|
190
147
|
- !ruby/object:Gem::Version
|
191
148
|
version: 2.3.14
|
192
|
-
none: false
|
193
|
-
name: rails
|
194
149
|
type: :development
|
195
150
|
prerelease: false
|
196
|
-
|
197
|
-
requirements:
|
198
|
-
- - ! '>='
|
199
|
-
- !ruby/object:Gem::Version
|
200
|
-
version: 2.3.14
|
201
|
-
none: false
|
151
|
+
version_requirements: *70206840635740
|
202
152
|
- !ruby/object:Gem::Dependency
|
203
|
-
|
153
|
+
name: thor
|
154
|
+
requirement: &70206840684480 !ruby/object:Gem::Requirement
|
155
|
+
none: false
|
204
156
|
requirements:
|
205
157
|
- - ! '>='
|
206
158
|
- !ruby/object:Gem::Version
|
207
159
|
version: '0'
|
208
|
-
none: false
|
209
|
-
name: thor
|
210
160
|
type: :development
|
211
161
|
prerelease: false
|
212
|
-
|
213
|
-
requirements:
|
214
|
-
- - ! '>='
|
215
|
-
- !ruby/object:Gem::Version
|
216
|
-
version: '0'
|
217
|
-
none: false
|
162
|
+
version_requirements: *70206840684480
|
218
163
|
description: Active Merchant is a simple payment abstraction library used in and sponsored
|
219
164
|
by Shopify. It is written by Tobias Luetke, Cody Fauser, and contributors. The aim
|
220
165
|
of the project is to feel natural to Ruby users and to abstract as many parts as
|
@@ -261,6 +206,7 @@ files:
|
|
261
206
|
- lib/active_merchant/billing/gateways/efsnet.rb
|
262
207
|
- lib/active_merchant/billing/gateways/elavon.rb
|
263
208
|
- lib/active_merchant/billing/gateways/epay.rb
|
209
|
+
- lib/active_merchant/billing/gateways/evo_ca.rb
|
264
210
|
- lib/active_merchant/billing/gateways/eway.rb
|
265
211
|
- lib/active_merchant/billing/gateways/eway_managed.rb
|
266
212
|
- lib/active_merchant/billing/gateways/eway_rapid.rb
|
@@ -316,6 +262,7 @@ files:
|
|
316
262
|
- lib/active_merchant/billing/gateways/payflow_express_uk.rb
|
317
263
|
- lib/active_merchant/billing/gateways/payflow_uk.rb
|
318
264
|
- lib/active_merchant/billing/gateways/payment_express.rb
|
265
|
+
- lib/active_merchant/billing/gateways/paymill.rb
|
319
266
|
- lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb
|
320
267
|
- lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb
|
321
268
|
- lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb
|
@@ -512,21 +459,22 @@ rdoc_options: []
|
|
512
459
|
require_paths:
|
513
460
|
- lib
|
514
461
|
required_ruby_version: !ruby/object:Gem::Requirement
|
462
|
+
none: false
|
515
463
|
requirements:
|
516
464
|
- - ! '>='
|
517
465
|
- !ruby/object:Gem::Version
|
518
466
|
version: '0'
|
519
|
-
none: false
|
520
467
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
468
|
+
none: false
|
521
469
|
requirements:
|
522
470
|
- - ! '>='
|
523
471
|
- !ruby/object:Gem::Version
|
524
472
|
version: '0'
|
525
|
-
none: false
|
526
473
|
requirements: []
|
527
474
|
rubyforge_project: activemerchant
|
528
|
-
rubygems_version: 1.8.
|
475
|
+
rubygems_version: 1.8.11
|
529
476
|
signing_key:
|
530
477
|
specification_version: 3
|
531
478
|
summary: Framework and tools for dealing with credit card transactions.
|
532
479
|
test_files: []
|
480
|
+
has_rdoc:
|
metadata.gz.sig
CHANGED
Binary file
|