active_merchant_card_flex 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE. +20 -0
- data/README.md +0 -0
- data/Rakefile +23 -0
- data/active_merchant_card_flex.gemspec +28 -0
- data/lib/active_merchant/billing/gateways/card_flex.rb +250 -0
- data/lib/active_merchant_card_flex.rb +2 -0
- data/lib/active_merchant_card_flex/version.rb +3 -0
- data/test/fixtures.yml +2 -0
- data/test/remote/gateways/remote_cardflex_test.rb +102 -0
- data/test/test_helper.rb +217 -0
- data/test/unit/gateways/card_flex_test.rb +305 -0
- metadata +126 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/MIT-LICENSE.
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2005-2010 Tobias Luetke
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'bundler'
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
desc "Run the unit test suite"
|
7
|
+
task :default => 'test:units'
|
8
|
+
|
9
|
+
namespace :test do
|
10
|
+
Rake::TestTask.new(:units) do |t|
|
11
|
+
t.pattern = 'test/unit/**/*_test.rb'
|
12
|
+
t.ruby_opts << '-rubygems'
|
13
|
+
t.libs << 'test'
|
14
|
+
t.verbose = true
|
15
|
+
end
|
16
|
+
|
17
|
+
Rake::TestTask.new(:remote) do |t|
|
18
|
+
t.pattern = 'test/remote/**/*_test.rb'
|
19
|
+
t.ruby_opts << '-rubygems'
|
20
|
+
t.libs << 'test'
|
21
|
+
t.verbose = true
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "active_merchant_card_flex/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "active_merchant_card_flex"
|
7
|
+
s.version = ActiveMerchantCardFlex::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Stephen St. Martin"]
|
10
|
+
s.email = ["kuprishuz@gmail.com"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{CardFlex support for ActiveMerchant}
|
13
|
+
s.description = %q{Provide support for CardFlex's standard integration and stored profile tokenization integrations.'}
|
14
|
+
|
15
|
+
s.rubyforge_project = "active_merchant_card_flex"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency 'activemerchant', '> 1.10.0'
|
23
|
+
s.add_dependency 'activesupport', '> 2.3.5'
|
24
|
+
s.add_dependency 'money'
|
25
|
+
|
26
|
+
s.add_development_dependency 'actionpack'
|
27
|
+
s.add_development_dependency 'mocha'
|
28
|
+
end
|
@@ -0,0 +1,250 @@
|
|
1
|
+
module ActiveMerchant
|
2
|
+
module Billing
|
3
|
+
class CardFlexGateway < Gateway
|
4
|
+
cattr_accessor :gateway_url
|
5
|
+
|
6
|
+
self.display_name = 'CardFlex Inc'
|
7
|
+
self.gateway_url = 'https://post.cfinc.com/cgi-bin/process.cgi'
|
8
|
+
self.homepage_url = 'http://www.cardflexnow.com/'
|
9
|
+
self.default_currency = 'USD'
|
10
|
+
self.money_format = :dollars
|
11
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
12
|
+
self.supported_countries = ['US']
|
13
|
+
|
14
|
+
# Creates a new CardFlexGateway
|
15
|
+
#
|
16
|
+
# The gateway requires that a valid login and password be passed
|
17
|
+
# in the +options+ hash.
|
18
|
+
#
|
19
|
+
# ==== Options
|
20
|
+
#
|
21
|
+
# * <tt>:login</tt> -- The CardFlex Account ID (REQUIRED)
|
22
|
+
# * <tt>:password</tt> -- The CardFlex Merchant PIN. (REQUIRED)
|
23
|
+
# * <tt>:test</tt> -- +true+ or +false+. If true, perform transactions against the test server.
|
24
|
+
# Otherwise, perform transactions against the production server.
|
25
|
+
def initialize(options = {})
|
26
|
+
requires!(options, :login)
|
27
|
+
@options = options
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
# Performs an authorization, which reserves the funds on the customer's credit card, but does not
|
32
|
+
# charge the card.
|
33
|
+
#
|
34
|
+
# ==== Parameters
|
35
|
+
#
|
36
|
+
# * <tt>money</tt> -- The amount to be captured as a FLOAT value in dollars and cents. (REQUIRED)
|
37
|
+
# * <tt>creditcard_or_credit_card_id</tt> -- The CreditCard details for the transaction. (REQUIRED)
|
38
|
+
# * <tt>options</tt> -- A hash of optional parameters.
|
39
|
+
def authorize(money, creditcard_or_credit_card_id, options = {})
|
40
|
+
post = {}
|
41
|
+
post[:authonly] = 1
|
42
|
+
|
43
|
+
add_address(post, options)
|
44
|
+
add_invoice(post, options)
|
45
|
+
add_payment_source(post, creditcard_or_credit_card_id, options)
|
46
|
+
|
47
|
+
commit(post[:userprofileid] ? :profile_sale : :ns_quicksale_cc, money, post)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Captures the funds from an authorized transaction.
|
51
|
+
#
|
52
|
+
# ==== Parameters
|
53
|
+
#
|
54
|
+
# * <tt>money</tt> -- The amount to be captured as a FLOAT value in dollars and cents. (REQUIRED)
|
55
|
+
# * <tt>authorization</tt> -- The authorization returned from the previous authorize request. (REQUIRED)
|
56
|
+
# * <tt>options</tt> -- A hash of optional parameters
|
57
|
+
def capture(money, authorization, options = {})
|
58
|
+
post = {}
|
59
|
+
|
60
|
+
# remove last 4 digits of cc number as they are not required here
|
61
|
+
post[:postonly] = authorization[0...-4]
|
62
|
+
|
63
|
+
commit(post[:userprofileid] ? :profile_sale : :ns_quicksale_cc, money, post)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Credit a transaction.
|
67
|
+
#
|
68
|
+
# This transaction indicates to the gateway that
|
69
|
+
# money should flow from the merchant to the customer.
|
70
|
+
#
|
71
|
+
# ==== Parameters
|
72
|
+
#
|
73
|
+
# * <tt>:money</tt> -- The amount to be credited as a FLOAT value in dollars and cents (REQUIRED)
|
74
|
+
# * <tt>:creditcard_or_credit_card_id</tt> -- The creditcard or stored creditcard id the refund is being issued to. (REQUIRED)
|
75
|
+
# * <tt>options</tt> -- A hash of optional parameters
|
76
|
+
def credit(money, creditcard_or_credit_card_id, options = {})
|
77
|
+
post = {}
|
78
|
+
add_address(post, options)
|
79
|
+
add_invoice(post, options)
|
80
|
+
add_payment_source(post, creditcard_or_credit_card_id, options)
|
81
|
+
|
82
|
+
commit(post[:userprofileid] ? :profile_credit : :ns_credit, money, post)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Perform a purchase, which is essentially an authorization and capture in a single operation.
|
86
|
+
#
|
87
|
+
# ==== Parameters
|
88
|
+
#
|
89
|
+
# * <tt>money</tt> -- The amount to be purchased as a FLOAT value in dollars and cents. (REQUIRED)
|
90
|
+
# * <tt>creditcard_or_credit_card_id</tt> -- The CreditCard details for the transaction or ID of a stored credit card. (REQUIRED)
|
91
|
+
# * <tt>options</tt> -- A hash of optional parameters.
|
92
|
+
def purchase(money, creditcard_or_credit_card_id, options = {})
|
93
|
+
post = {}
|
94
|
+
add_address(post, options)
|
95
|
+
add_invoice(post, options)
|
96
|
+
add_payment_source(post, creditcard_or_credit_card_id, options)
|
97
|
+
|
98
|
+
commit(post[:userprofileid] ? :profile_sale : :ns_quicksale_cc, money, post)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Stores CreditCard details for later use.
|
102
|
+
#
|
103
|
+
# ==== Parameters
|
104
|
+
#
|
105
|
+
# * <tt>creditcard</tt> -- The CreditCard details to store. (REQUIRED)
|
106
|
+
# * <tt>options</tt> -- A hash of optional parameters
|
107
|
+
def store(creditcard, options = {})
|
108
|
+
post = {}
|
109
|
+
post[:accttype] = 1
|
110
|
+
add_address(post, options)
|
111
|
+
add_creditcard(post, creditcard)
|
112
|
+
|
113
|
+
commit(:profile_add, nil, post)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Removes stored CreditCard details.
|
117
|
+
#
|
118
|
+
# ==== Parameters
|
119
|
+
#
|
120
|
+
# * <tt>creditcard_id</tt> -- The ID of the CreditCard details to remove. (REQUIRED)
|
121
|
+
# * <tt>options</tt> -- A hash of optional parameters
|
122
|
+
def unstore(creditcard_id, options = {})
|
123
|
+
commit(:profile_delete, nil, options.merge(:userprofileid => creditcard_id.to_s[0...-4].to_i, :last4digits => creditcard_id.to_s[-4..-1].to_i))
|
124
|
+
end
|
125
|
+
|
126
|
+
# Void a previous transaction
|
127
|
+
#
|
128
|
+
# ==== Parameters
|
129
|
+
#
|
130
|
+
# * <tt>authorization</tt> - The authorization returned from the previous authorize request. (REQUIRED)
|
131
|
+
# * <tt>options</tt> -- A hash of optional parameters
|
132
|
+
def void(authorization, options = {})
|
133
|
+
commit(:ns_void, nil, options.merge(:historykeyid => authorization[0...-4], :last4digits => authorization[-4..-1]))
|
134
|
+
end
|
135
|
+
|
136
|
+
private
|
137
|
+
# adds a billing or shipping address for the charge
|
138
|
+
def add_address(post, options)
|
139
|
+
if address = options[:billing_address] || options[:address]
|
140
|
+
post[:ci_billaddr1] = address[:address1]
|
141
|
+
post[:ci_billaddr2] = address[:address2] if address[:address2]
|
142
|
+
post[:ci_billcity] = address[:city]
|
143
|
+
post[:ci_billstate] = address[:state]
|
144
|
+
post[:ci_billzip] = address[:zip]
|
145
|
+
post[:ci_billcountry] = address[:country]
|
146
|
+
end
|
147
|
+
|
148
|
+
if address = options[:shipping_address]
|
149
|
+
post[:ci_shipaddr1] = address[:address1]
|
150
|
+
post[:ci_shipaddr2] = address[:address2] if address[:address2]
|
151
|
+
post[:ci_shipcity] = address[:city]
|
152
|
+
post[:ci_shipstate] = address[:state]
|
153
|
+
post[:ci_shipzip] = address[:zip]
|
154
|
+
post[:ci_shipcountry] = address[:country]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# add a new credit card to the transaction
|
159
|
+
def add_creditcard(post, creditcard)
|
160
|
+
post[:ccname] = "#{creditcard.first_name} #{creditcard.last_name}"
|
161
|
+
post[:ccnum] = creditcard.number
|
162
|
+
post[:cvv2] = creditcard.verification_value if creditcard.verification_value?
|
163
|
+
post[:expmon] = creditcard.month
|
164
|
+
post[:expyear] = creditcard.year
|
165
|
+
end
|
166
|
+
|
167
|
+
# add order id to charge
|
168
|
+
def add_invoice(post, options)
|
169
|
+
post[:merchantordernumber] = options[:order_id] if options.has_key?(:order_id)
|
170
|
+
end
|
171
|
+
|
172
|
+
# determine if we are using a new credit card or stored one
|
173
|
+
def add_payment_source(post, credit_card_or_card_id, options)
|
174
|
+
if credit_card_or_card_id.is_a?(ActiveMerchant::Billing::CreditCard)
|
175
|
+
add_creditcard(post, credit_card_or_card_id)
|
176
|
+
else
|
177
|
+
post[:userprofileid] = credit_card_or_card_id[0...-4]
|
178
|
+
post[:last4digits] = credit_card_or_card_id[-4..-1]
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def commit(action, money, parameters)
|
183
|
+
parameters[:amount] = money unless money.nil?
|
184
|
+
response = parse(ssl_post(self.gateway_url, post_data(action, parameters)))
|
185
|
+
test_mode = @options[:test] || @options[:login] == "TEST0"
|
186
|
+
|
187
|
+
Response.new(response[:result] == "1", response[:message], response,
|
188
|
+
:avs_result => { :code => response[:avs_result] },
|
189
|
+
:authorization => response[:authorization],
|
190
|
+
:cvv_result => response[:cvv_result],
|
191
|
+
:test => test_mode
|
192
|
+
)
|
193
|
+
end
|
194
|
+
|
195
|
+
# parse response body into its components
|
196
|
+
def parse(body)
|
197
|
+
response = {}
|
198
|
+
|
199
|
+
# parse reponse body into a hash
|
200
|
+
body.gsub!("<html><body><plaintext>", "")
|
201
|
+
body.split("\r\n").each do |pair|
|
202
|
+
key,val = pair.split("=")
|
203
|
+
response[key.underscore.to_sym] = val if key && val
|
204
|
+
end
|
205
|
+
|
206
|
+
# split response from : delimited format
|
207
|
+
if response[:result] == "1"
|
208
|
+
approval_response = response[:accepted].split(":")
|
209
|
+
response[:message] = "Accepted"
|
210
|
+
response[:transaction_type] = approval_response[0]
|
211
|
+
response[:authorization_code] = approval_response[1]
|
212
|
+
response[:reference_number] = approval_response[2]
|
213
|
+
response[:batch_number] = approval_response[3]
|
214
|
+
response[:transaction_id] = approval_response[4]
|
215
|
+
response[:avs_result] = approval_response[5]
|
216
|
+
response[:auth_net_message] = approval_response[6]
|
217
|
+
response[:cvv_result] = approval_response[7]
|
218
|
+
response[:partial_auth] = approval_response[8]
|
219
|
+
|
220
|
+
# if a stored profile was added use its id for authorization otherwise
|
221
|
+
# use the historyid, and append the last4digits of the card number so
|
222
|
+
# that it does not have to be passed in, making it more compliant to
|
223
|
+
# ActiveMerchant
|
224
|
+
if response[:accountnumber]
|
225
|
+
response[:authorization] = "#{response[:transaction_type] == 'PROFILEADD' || response[:partial_auth] == 'DUPLICATE' ? response[:userprofileid] : response[:historyid]}#{response[:accountnumber][-4..-1]}"
|
226
|
+
end
|
227
|
+
else
|
228
|
+
decline_response = response[:reason].split(":")
|
229
|
+
response[:transaction_result] = decline_response[0]
|
230
|
+
response[:decline_code] = decline_response[1]
|
231
|
+
response[:message] = decline_response[2]
|
232
|
+
end
|
233
|
+
|
234
|
+
response
|
235
|
+
end
|
236
|
+
|
237
|
+
# format post data for transaction
|
238
|
+
def post_data(action, parameters = {})
|
239
|
+
post = {}
|
240
|
+
post[:action] = action
|
241
|
+
post[:usepost] = 1
|
242
|
+
post[:acctid] = @options[:test] ? 'TEST0' : @options[:login]
|
243
|
+
post[:merchantpin] = @options[:password] if @options[:password] && !@options[:test]
|
244
|
+
|
245
|
+
request = post.merge(parameters).map {|key,value| "#{key}=#{CGI.escape(value.to_s)}"}.join("&")
|
246
|
+
request
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
data/test/fixtures.yml
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class RemoteCardFlexTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@gateway = CardFlexGateway.new(fixtures(:card_flex))
|
7
|
+
@amount = 100
|
8
|
+
@credit_card = credit_card('5454545454545454')
|
9
|
+
@declined_card = credit_card('4111111111111112')
|
10
|
+
@options = {
|
11
|
+
:order_id => generate_unique_id,
|
12
|
+
:billing_address => address,
|
13
|
+
:description => 'Test purchase'
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_sucessful_purchase
|
18
|
+
assert response = @gateway.purchase(@amount, @credit_card, @options)
|
19
|
+
assert_success response
|
20
|
+
assert response.test?
|
21
|
+
assert_equal 'Accepted', response.message
|
22
|
+
assert response.authorization
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_unsuccessful_purchase
|
26
|
+
assert response = @gateway.purchase(@amount, @declined_card, @options)
|
27
|
+
assert_failure response
|
28
|
+
assert_equal 'Invalid account number', response.message
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_successful_credit
|
32
|
+
assert response = @gateway.credit(@amount, @credit_card, @options)
|
33
|
+
assert_success response
|
34
|
+
assert response.test?
|
35
|
+
assert_equal 'Accepted', response.message
|
36
|
+
assert response.authorization
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_authorize_and_capture
|
40
|
+
amount = @amount
|
41
|
+
assert auth = @gateway.authorize(amount, @credit_card, @options)
|
42
|
+
assert_success auth
|
43
|
+
assert_equal 'Accepted', auth.message
|
44
|
+
assert auth.authorization
|
45
|
+
|
46
|
+
assert capture = @gateway.capture(amount, auth.authorization)
|
47
|
+
assert_success capture
|
48
|
+
assert_equal 'Accepted', capture.message
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_failed_capture
|
52
|
+
authorization = "12345678910"
|
53
|
+
assert response = @gateway.capture(@amount, '1234567890')
|
54
|
+
assert_failure response
|
55
|
+
assert_equal 'ProcessPostTrans... could not load order (123456,)', response.message
|
56
|
+
|
57
|
+
assert response = @gateway.capture(@amount, '')
|
58
|
+
assert_failure response
|
59
|
+
assert_equal 'Missing account number', response.message
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_authorize_and_void
|
63
|
+
assert auth = @gateway.authorize(@amount, @credit_card, @options)
|
64
|
+
assert_success auth
|
65
|
+
assert_equal 'Accepted', auth.message
|
66
|
+
assert auth.authorization
|
67
|
+
|
68
|
+
assert void = @gateway.void(auth.authorization)
|
69
|
+
assert_success void
|
70
|
+
assert_equal 'Accepted', void.message
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_unsuccessful_void
|
74
|
+
assert void = @gateway.void('')
|
75
|
+
assert_failure void
|
76
|
+
assert_equal 'Invalid acct type', void.message
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_store_purchase_unstore
|
80
|
+
assert store = @gateway.store(@credit_card)
|
81
|
+
assert_success store
|
82
|
+
assert_equal 'Accepted', store.message
|
83
|
+
|
84
|
+
# wait a few seconds before charging a profile
|
85
|
+
sleep 10
|
86
|
+
assert purchase = @gateway.purchase(@amount, store.authorization, @options)
|
87
|
+
assert_success purchase
|
88
|
+
assert_equal 'Accepted', purchase.message
|
89
|
+
|
90
|
+
assert unstore = @gateway.unstore(store.authorization)
|
91
|
+
assert_success unstore
|
92
|
+
assert_equal 'Accepted', unstore.message
|
93
|
+
assert purchase_after_unstore = @gateway.purchase(@amount, store.authorization, @options)
|
94
|
+
assert_failure purchase_after_unstore
|
95
|
+
assert_equal 'Profile Not Found', purchase_after_unstore.message
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_unsuccessful_unstore
|
99
|
+
assert unstore = @gateway.unstore('123456789')
|
100
|
+
assert_failure unstore
|
101
|
+
end
|
102
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,217 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubygems'
|
6
|
+
require 'bundler'
|
7
|
+
Bundler.setup
|
8
|
+
rescue LoadError => e
|
9
|
+
puts "Error loading bundler (#{e.message}): \"gem install bundler\" for bundler support."
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'test/unit'
|
13
|
+
require 'money'
|
14
|
+
require 'mocha'
|
15
|
+
require 'yaml'
|
16
|
+
require 'active_merchant'
|
17
|
+
|
18
|
+
require 'active_support/core_ext/integer/time'
|
19
|
+
require 'active_support/core_ext/numeric/time'
|
20
|
+
|
21
|
+
begin
|
22
|
+
require 'active_support/core_ext/time/acts_like'
|
23
|
+
rescue LoadError
|
24
|
+
end
|
25
|
+
|
26
|
+
begin
|
27
|
+
gem 'actionpack'
|
28
|
+
rescue LoadError
|
29
|
+
raise StandardError, "The view tests need ActionPack installed as gem to run"
|
30
|
+
end
|
31
|
+
|
32
|
+
require 'action_controller'
|
33
|
+
require "action_view/template"
|
34
|
+
begin
|
35
|
+
require 'active_support/core_ext/module/deprecation'
|
36
|
+
require 'action_dispatch/testing/test_process'
|
37
|
+
rescue LoadError
|
38
|
+
require 'action_controller/test_process'
|
39
|
+
end
|
40
|
+
require 'active_merchant/billing/integrations/action_view_helper'
|
41
|
+
require 'active_merchant_card_flex'
|
42
|
+
|
43
|
+
ActiveMerchant::Billing::Base.mode = :test
|
44
|
+
|
45
|
+
if ENV['DEBUG_ACTIVE_MERCHANT'] == 'true'
|
46
|
+
require 'logger'
|
47
|
+
ActiveMerchant::Billing::Gateway.logger = Logger.new(STDOUT)
|
48
|
+
ActiveMerchant::Billing::Gateway.wiredump_device = STDOUT
|
49
|
+
end
|
50
|
+
|
51
|
+
# Test gateways
|
52
|
+
class SimpleTestGateway < ActiveMerchant::Billing::Gateway
|
53
|
+
end
|
54
|
+
|
55
|
+
class SubclassGateway < SimpleTestGateway
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
module ActiveMerchant
|
60
|
+
module Assertions
|
61
|
+
AssertionClass = RUBY_VERSION > '1.9' ? MiniTest::Assertion : Test::Unit::AssertionFailedError
|
62
|
+
|
63
|
+
def assert_field(field, value)
|
64
|
+
clean_backtrace do
|
65
|
+
assert_equal value, @helper.fields[field]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Allows the testing of you to check for negative assertions:
|
70
|
+
#
|
71
|
+
# # Instead of
|
72
|
+
# assert !something_that_is_false
|
73
|
+
#
|
74
|
+
# # Do this
|
75
|
+
# assert_false something_that_should_be_false
|
76
|
+
#
|
77
|
+
# An optional +msg+ parameter is available to help you debug.
|
78
|
+
def assert_false(boolean, message = nil)
|
79
|
+
message = build_message message, '<?> is not false or nil.', boolean
|
80
|
+
|
81
|
+
clean_backtrace do
|
82
|
+
assert_block message do
|
83
|
+
not boolean
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# A handy little assertion to check for a successful response:
|
89
|
+
#
|
90
|
+
# # Instead of
|
91
|
+
# assert_success response
|
92
|
+
#
|
93
|
+
# # DRY that up with
|
94
|
+
# assert_success response
|
95
|
+
#
|
96
|
+
# A message will automatically show the inspection of the response
|
97
|
+
# object if things go afoul.
|
98
|
+
def assert_success(response)
|
99
|
+
clean_backtrace do
|
100
|
+
assert response.success?, "Response failed: #{response.inspect}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# The negative of +assert_success+
|
105
|
+
def assert_failure(response)
|
106
|
+
clean_backtrace do
|
107
|
+
assert_false response.success?, "Response expected to fail: #{response.inspect}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def assert_valid(validateable)
|
112
|
+
clean_backtrace do
|
113
|
+
assert validateable.valid?, "Expected to be valid"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def assert_not_valid(validateable)
|
118
|
+
clean_backtrace do
|
119
|
+
assert_false validateable.valid?, "Expected to not be valid"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def assert_deprecation_warning(message, target)
|
124
|
+
target.expects(:deprecated).with(message)
|
125
|
+
yield
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
def clean_backtrace(&block)
|
130
|
+
yield
|
131
|
+
rescue AssertionClass => e
|
132
|
+
path = File.expand_path(__FILE__)
|
133
|
+
raise AssertionClass, e.message, e.backtrace.reject { |line| File.expand_path(line) =~ /#{path}/ }
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
module Fixtures
|
138
|
+
HOME_DIR = RUBY_PLATFORM =~ /mswin32/ ? ENV['HOMEPATH'] : ENV['HOME'] unless defined?(HOME_DIR)
|
139
|
+
LOCAL_CREDENTIALS = File.join(HOME_DIR.to_s, '.active_merchant/fixtures.yml') unless defined?(LOCAL_CREDENTIALS)
|
140
|
+
DEFAULT_CREDENTIALS = File.join(File.dirname(__FILE__), 'fixtures.yml') unless defined?(DEFAULT_CREDENTIALS)
|
141
|
+
|
142
|
+
private
|
143
|
+
def credit_card(number = '4242424242424242', options = {})
|
144
|
+
defaults = {
|
145
|
+
:number => number,
|
146
|
+
:month => 9,
|
147
|
+
:year => Time.now.year + 1,
|
148
|
+
:first_name => 'Longbob',
|
149
|
+
:last_name => 'Longsen',
|
150
|
+
:verification_value => '123',
|
151
|
+
:type => 'visa'
|
152
|
+
}.update(options)
|
153
|
+
|
154
|
+
Billing::CreditCard.new(defaults)
|
155
|
+
end
|
156
|
+
|
157
|
+
def check(options = {})
|
158
|
+
defaults = {
|
159
|
+
:name => 'Jim Smith',
|
160
|
+
:routing_number => '244183602',
|
161
|
+
:account_number => '15378535',
|
162
|
+
:account_holder_type => 'personal',
|
163
|
+
:account_type => 'checking',
|
164
|
+
:number => '1'
|
165
|
+
}.update(options)
|
166
|
+
|
167
|
+
Billing::Check.new(defaults)
|
168
|
+
end
|
169
|
+
|
170
|
+
def address(options = {})
|
171
|
+
{
|
172
|
+
:name => 'Jim Smith',
|
173
|
+
:address1 => '1234 My Street',
|
174
|
+
:address2 => 'Apt 1',
|
175
|
+
:company => 'Widgets Inc',
|
176
|
+
:city => 'Ottawa',
|
177
|
+
:state => 'ON',
|
178
|
+
:zip => 'K1C2N6',
|
179
|
+
:country => 'CA',
|
180
|
+
:phone => '(555)555-5555',
|
181
|
+
:fax => '(555)555-6666'
|
182
|
+
}.update(options)
|
183
|
+
end
|
184
|
+
|
185
|
+
def all_fixtures
|
186
|
+
@@fixtures ||= load_fixtures
|
187
|
+
end
|
188
|
+
|
189
|
+
def fixtures(key)
|
190
|
+
data = all_fixtures[key] || raise(StandardError, "No fixture data was found for '#{key}'")
|
191
|
+
|
192
|
+
data.dup
|
193
|
+
end
|
194
|
+
|
195
|
+
def load_fixtures
|
196
|
+
file = File.exists?(LOCAL_CREDENTIALS) ? LOCAL_CREDENTIALS : DEFAULT_CREDENTIALS
|
197
|
+
yaml_data = YAML.load(File.read(file))
|
198
|
+
symbolize_keys(yaml_data)
|
199
|
+
|
200
|
+
yaml_data
|
201
|
+
end
|
202
|
+
|
203
|
+
def symbolize_keys(hash)
|
204
|
+
return unless hash.is_a?(Hash)
|
205
|
+
|
206
|
+
hash.symbolize_keys!
|
207
|
+
hash.each{|k,v| symbolize_keys(v)}
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
Test::Unit::TestCase.class_eval do
|
213
|
+
include ActiveMerchant::Billing
|
214
|
+
include ActiveMerchant::Assertions
|
215
|
+
include ActiveMerchant::Utils
|
216
|
+
include ActiveMerchant::Fixtures
|
217
|
+
end
|
@@ -0,0 +1,305 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CardFlexTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@gateway = CardFlexGateway.new(fixtures(:card_flex))
|
6
|
+
@amount = 100
|
7
|
+
@credit_card = credit_card('5454545454545454')
|
8
|
+
@declined_card = credit_card('4111111111111112')
|
9
|
+
@options = {
|
10
|
+
:order_id => generate_unique_id,
|
11
|
+
:billing_address => address,
|
12
|
+
:description => 'Test purchase'
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_successful_purchase
|
17
|
+
@gateway.expects(:ssl_post).returns(successful_purchase_response)
|
18
|
+
assert response = @gateway.purchase(@amount, @credit_card, @options)
|
19
|
+
assert_instance_of Response, response
|
20
|
+
assert_success response
|
21
|
+
assert_equal '1921788665454', response.authorization
|
22
|
+
assert response.test?
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_unsuccessful_purchase
|
26
|
+
@gateway.expects(:ssl_post).returns(failed_purchase_response)
|
27
|
+
assert response = @gateway.purchase(@amount, @credit_card, @options)
|
28
|
+
assert_failure response
|
29
|
+
assert response.test?
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_authorization
|
33
|
+
@gateway.expects(:ssl_post).returns(successful_authorization_response)
|
34
|
+
assert response = @gateway.authorize(@amount, @credit_card, @options)
|
35
|
+
assert response.success?
|
36
|
+
assert_equal '1921799375454', response.authorization
|
37
|
+
assert response.test?
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_capture
|
41
|
+
@gateway.expects(:ssl_post).returns(successful_capture_response)
|
42
|
+
assert response = @gateway.capture(@amount, '1921799375454', @options)
|
43
|
+
assert response.success?
|
44
|
+
assert_equal '1921799405454', response.authorization
|
45
|
+
assert response.test?
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_credit
|
49
|
+
@gateway.expects(:ssl_post).returns(successful_credit_response)
|
50
|
+
assert_success @gateway.credit(@amount, @credit_card, @options)
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_void
|
54
|
+
@gateway.expects(:ssl_post).returns(successful_void_response)
|
55
|
+
assert response = @gateway.void('1921799375454')
|
56
|
+
assert response.success?
|
57
|
+
assert_equal '1921796055454', response.authorization
|
58
|
+
assert response.test?
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_store
|
62
|
+
@gateway.expects(:ssl_post).returns(successful_store_response)
|
63
|
+
assert response = @gateway.store(@credit_card)
|
64
|
+
assert response.success?
|
65
|
+
assert_equal '65567155454', response.authorization
|
66
|
+
assert response.test?
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_unstore
|
70
|
+
@gateway.expects(:ssl_post).returns(successful_unstore_response)
|
71
|
+
assert response = @gateway.unstore('65567155454')
|
72
|
+
assert response.success?
|
73
|
+
assert_equal nil, response.authorization
|
74
|
+
assert response.test?
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_successful_avs_check
|
78
|
+
@gateway.expects(:ssl_post).returns(successful_purchase_response.gsub('192178866:N::U', '192178866:Y::U'))
|
79
|
+
assert response = @gateway.purchase(@amount, @credit_card, @options)
|
80
|
+
assert_equal response.avs_result['code'], "Y"
|
81
|
+
assert_equal response.avs_result['message'], "Street address and 5-digit postal code match."
|
82
|
+
assert_equal response.avs_result['street_match'], "Y"
|
83
|
+
assert_equal response.avs_result['postal_match'], "Y"
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_unsuccessful_avs_check_with_bad_street_address
|
87
|
+
@gateway.expects(:ssl_post).returns(successful_purchase_response.gsub('192178866:N::U', '192178866:Z::U'))
|
88
|
+
assert response = @gateway.purchase(@amount, @credit_card, @options)
|
89
|
+
assert_equal response.avs_result['code'], "Z"
|
90
|
+
assert_equal response.avs_result['message'], "Street address does not match, but 5-digit postal code matches."
|
91
|
+
assert_equal response.avs_result['street_match'], "N"
|
92
|
+
assert_equal response.avs_result['postal_match'], "Y"
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_unsuccessful_avs_check_with_bad_zip
|
96
|
+
@gateway.expects(:ssl_post).returns(successful_purchase_response.gsub('192178866:N::U', '192178866:A::U'))
|
97
|
+
assert response = @gateway.purchase(@amount, @credit_card, @options)
|
98
|
+
assert_equal response.avs_result['code'], "A"
|
99
|
+
assert_equal response.avs_result['message'], "Street address matches, but 5-digit and 9-digit postal code do not match."
|
100
|
+
assert_equal response.avs_result['street_match'], "Y"
|
101
|
+
assert_equal response.avs_result['postal_match'], "N"
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_successful_cvv_check
|
105
|
+
@gateway.expects(:ssl_post).returns(successful_purchase_response.gsub('192178866:N::U', '192178866:N::M'))
|
106
|
+
assert response = @gateway.purchase(@amount, @credit_card, @options)
|
107
|
+
assert_equal response.cvv_result['code'], "M"
|
108
|
+
assert_equal response.cvv_result['message'], "Match"
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_unsuccessful_cvv_check
|
112
|
+
@gateway.expects(:ssl_post).returns(successful_purchase_response.gsub('192178866:N::U', '192178866:N::N'))
|
113
|
+
assert response = @gateway.purchase(@amount, @credit_card, @options)
|
114
|
+
assert_equal response.cvv_result['code'], "N"
|
115
|
+
assert_equal response.cvv_result['message'], "No Match"
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_supported_countries
|
119
|
+
assert_equal ['US'], CardFlexGateway.supported_countries
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_supported_card_types
|
123
|
+
assert_equal [:visa, :master, :american_express, :discover], CardFlexGateway.supported_cardtypes
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
def successful_purchase_response
|
128
|
+
<<-eos.gsub(/^ {6}/, '').gsub("\n", "\r\n")
|
129
|
+
<html><body><plaintext>
|
130
|
+
Accepted=AVSAUTH:TEST:::192178866:N::U
|
131
|
+
historyid=192178866
|
132
|
+
orderid=141639490
|
133
|
+
Accepted=AVSAUTH:TEST:::192178866:N::U
|
134
|
+
ACCOUNTNUMBER=************5454
|
135
|
+
authcode=TEST
|
136
|
+
AuthNo=AVSAUTH:TEST:::192178866:N::U
|
137
|
+
ENTRYMETHOD=KEYED
|
138
|
+
historyid=192178866
|
139
|
+
MERCHANTORDERNUMBER=d86139833ae6f675c21931d1ca68a674
|
140
|
+
orderid=141639490
|
141
|
+
PAYTYPE=MasterCard
|
142
|
+
recurid=0
|
143
|
+
refcode=192178866-TEST
|
144
|
+
result=1
|
145
|
+
Status=Accepted
|
146
|
+
transid=0
|
147
|
+
eos
|
148
|
+
end
|
149
|
+
|
150
|
+
def successful_authorization_response
|
151
|
+
<<-eos.gsub(/^ {6}/, '').gsub("\n", "\r\n")
|
152
|
+
<html><body><plaintext>
|
153
|
+
Accepted=AVSAUTH:TEST:::192179937:N::U
|
154
|
+
historyid=192179937
|
155
|
+
orderid=141640360
|
156
|
+
Accepted=AVSAUTH:TEST:::192179937:N::U
|
157
|
+
ACCOUNTNUMBER=************5454
|
158
|
+
authcode=TEST
|
159
|
+
AuthNo=AVSAUTH:TEST:::192179937:N::U
|
160
|
+
ENTRYMETHOD=KEYED
|
161
|
+
historyid=192179937
|
162
|
+
MERCHANTORDERNUMBER=dd9d22bc626a793e039975bdc3f70eda
|
163
|
+
orderid=141640360
|
164
|
+
PAYTYPE=MasterCard
|
165
|
+
recurid=0
|
166
|
+
refcode=192179937-TEST
|
167
|
+
result=1
|
168
|
+
Status=Accepted
|
169
|
+
transid=0
|
170
|
+
eos
|
171
|
+
end
|
172
|
+
|
173
|
+
def successful_credit_response
|
174
|
+
<<-eos.gsub(/^ {6}/, '').gsub("\n", "\r\n")
|
175
|
+
<html><body><plaintext>
|
176
|
+
Accepted=CREDIT:TEST:::192180043:::
|
177
|
+
historyid=192180043
|
178
|
+
orderid=141640416
|
179
|
+
Accepted=CREDIT:TEST:::192180043:::
|
180
|
+
ACCOUNTNUMBER=************5454
|
181
|
+
authcode=TEST
|
182
|
+
AuthNo=CREDIT:TEST:::192180043:::
|
183
|
+
ENTRYMETHOD=KEYED
|
184
|
+
historyid=192180043
|
185
|
+
MERCHANTORDERNUMBER=1fe19bf710c5800dcef50fa9572b8962
|
186
|
+
orderid=141640416
|
187
|
+
PAYTYPE=MasterCard
|
188
|
+
recurid=0
|
189
|
+
refcode=192180043-TEST
|
190
|
+
result=1
|
191
|
+
Status=Accepted
|
192
|
+
transid=0
|
193
|
+
eos
|
194
|
+
end
|
195
|
+
|
196
|
+
def successful_void_response
|
197
|
+
<<-eos.gsub(/^ {6}/, '').gsub("\n", "\r\n")
|
198
|
+
<html><body><plaintext>
|
199
|
+
Accepted=VOID:TEST:::192179605:::
|
200
|
+
historyid=192179605
|
201
|
+
orderid=141640067
|
202
|
+
Accepted=VOID:TEST:::192179605:::
|
203
|
+
ACCOUNTNUMBER=************5454
|
204
|
+
authcode=TEST
|
205
|
+
AuthNo=VOID:TEST:::192179605:::
|
206
|
+
ENTRYMETHOD=KEYED
|
207
|
+
historyid=192179605
|
208
|
+
MERCHANTORDERNUMBER=42ecde63168c401ccb02a40171aa0042
|
209
|
+
orderid=141640067
|
210
|
+
PAYTYPE=MasterCard
|
211
|
+
recurid=0
|
212
|
+
refcode=192179605-TEST
|
213
|
+
result=1
|
214
|
+
Status=Accepted
|
215
|
+
transid=0
|
216
|
+
eos
|
217
|
+
end
|
218
|
+
|
219
|
+
def successful_capture_response
|
220
|
+
<<-eos.gsub(/^ {6}/, '').gsub("\n", "\r\n")
|
221
|
+
<html><body><plaintext>
|
222
|
+
Accepted=AVSPOST:TEST:::192179940:::
|
223
|
+
historyid=192179940
|
224
|
+
orderid=141640360
|
225
|
+
Accepted=AVSPOST:TEST:::192179940:::
|
226
|
+
ACCOUNTNUMBER=************5454
|
227
|
+
authcode=TEST
|
228
|
+
AuthNo=AVSPOST:TEST:::192179940:::
|
229
|
+
ENTRYMETHOD=KEYED
|
230
|
+
historyid=192179940
|
231
|
+
MERCHANTORDERNUMBER=dd9d22bc626a793e039975bdc3f70eda
|
232
|
+
orderid=141640360
|
233
|
+
PAYTYPE=MasterCard
|
234
|
+
recurid=0
|
235
|
+
refcode=192179940-TEST
|
236
|
+
result=1
|
237
|
+
Status=Accepted
|
238
|
+
transid=192179937
|
239
|
+
eos
|
240
|
+
end
|
241
|
+
|
242
|
+
def successful_store_response
|
243
|
+
<<-eos.gsub(/^ {6}/, '').gsub("\n", "\r\n")
|
244
|
+
<html><body><plaintext>
|
245
|
+
Accepted=AVSAUTH:TEST:::192179530:N::U:DUPLICATE
|
246
|
+
historyid=192179530
|
247
|
+
orderid=141640000
|
248
|
+
Accepted=AVSAUTH:TEST:::192179530:N::U:DUPLICATE
|
249
|
+
ACCOUNTNUMBER=************5454
|
250
|
+
authcode=TEST
|
251
|
+
AuthNo=AVSAUTH:TEST:::192179530:N::U:DUPLICATE
|
252
|
+
DUPLICATE=1
|
253
|
+
ENTRYMETHOD=KEYED
|
254
|
+
historyid=192179530
|
255
|
+
orderid=141640000
|
256
|
+
PAYTYPE=MasterCard
|
257
|
+
recurid=0
|
258
|
+
refcode=192179530-TEST
|
259
|
+
result=1
|
260
|
+
Status=Accepted
|
261
|
+
transid=0
|
262
|
+
USERPROFILEID=6556715
|
263
|
+
eos
|
264
|
+
end
|
265
|
+
|
266
|
+
def successful_unstore_response
|
267
|
+
<<-eos.gsub(/^ {6}/, '').gsub("\n", "\r\n")
|
268
|
+
<html><body><plaintext>
|
269
|
+
Accepted=PROFILEDELETE:Success:::0:::
|
270
|
+
historyid=0
|
271
|
+
orderid=
|
272
|
+
Accepted=PROFILEDELETE:Success:::0:::
|
273
|
+
authcode=Success
|
274
|
+
AuthNo=PROFILEDELETE:Success:::0:::
|
275
|
+
historyid=0
|
276
|
+
refcode=
|
277
|
+
result=1
|
278
|
+
Status=Accepted
|
279
|
+
transid=0
|
280
|
+
USERPROFILEID=6556715
|
281
|
+
eos
|
282
|
+
end
|
283
|
+
|
284
|
+
def failed_purchase_response
|
285
|
+
<<-eos.gsub(/^ {6}/, '').gsub("\n", "\r\n")
|
286
|
+
<html><body><plaintext>
|
287
|
+
Declined=DECLINED:1101610001:Invalid account number:
|
288
|
+
historyid=192179887
|
289
|
+
orderid=141640315
|
290
|
+
ACCOUNTNUMBER=************1112
|
291
|
+
Declined=DECLINED:1101610001:Invalid account number:
|
292
|
+
ENTRYMETHOD=KEYED
|
293
|
+
historyid=192179887
|
294
|
+
MERCHANTORDERNUMBER=5b42749552174e683282b5b0ddcd6459
|
295
|
+
orderid=141640315
|
296
|
+
PAYTYPE=Visa
|
297
|
+
rcode=1101610001
|
298
|
+
Reason=DECLINED:1101610001:Invalid account number:
|
299
|
+
recurid=0
|
300
|
+
result=0
|
301
|
+
Status=Declined
|
302
|
+
transid=0
|
303
|
+
eos
|
304
|
+
end
|
305
|
+
end
|
metadata
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: active_merchant_card_flex
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Stephen St. Martin
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-06-16 00:00:00 -04:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: activemerchant
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 1.10.0
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ">"
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 2.3.5
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: money
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: actionpack
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: mocha
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
type: :development
|
70
|
+
version_requirements: *id005
|
71
|
+
description: Provide support for CardFlex's standard integration and stored profile tokenization integrations.'
|
72
|
+
email:
|
73
|
+
- kuprishuz@gmail.com
|
74
|
+
executables: []
|
75
|
+
|
76
|
+
extensions: []
|
77
|
+
|
78
|
+
extra_rdoc_files: []
|
79
|
+
|
80
|
+
files:
|
81
|
+
- .gitignore
|
82
|
+
- Gemfile
|
83
|
+
- MIT-LICENSE.
|
84
|
+
- README.md
|
85
|
+
- Rakefile
|
86
|
+
- active_merchant_card_flex.gemspec
|
87
|
+
- lib/active_merchant/billing/gateways/card_flex.rb
|
88
|
+
- lib/active_merchant_card_flex.rb
|
89
|
+
- lib/active_merchant_card_flex/version.rb
|
90
|
+
- test/fixtures.yml
|
91
|
+
- test/remote/gateways/remote_cardflex_test.rb
|
92
|
+
- test/test_helper.rb
|
93
|
+
- test/unit/gateways/card_flex_test.rb
|
94
|
+
has_rdoc: true
|
95
|
+
homepage: ""
|
96
|
+
licenses: []
|
97
|
+
|
98
|
+
post_install_message:
|
99
|
+
rdoc_options: []
|
100
|
+
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: "0"
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: "0"
|
115
|
+
requirements: []
|
116
|
+
|
117
|
+
rubyforge_project: active_merchant_card_flex
|
118
|
+
rubygems_version: 1.6.2
|
119
|
+
signing_key:
|
120
|
+
specification_version: 3
|
121
|
+
summary: CardFlex support for ActiveMerchant
|
122
|
+
test_files:
|
123
|
+
- test/fixtures.yml
|
124
|
+
- test/remote/gateways/remote_cardflex_test.rb
|
125
|
+
- test/test_helper.rb
|
126
|
+
- test/unit/gateways/card_flex_test.rb
|