an 0.0.1.rc2 → 0.0.1.rc3
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/README +17 -24
- data/an.gemspec +3 -2
- data/lib/an.rb +52 -42
- data/test/an.rb +43 -26
- metadata +18 -7
data/README
CHANGED
@@ -13,32 +13,25 @@ USAGE
|
|
13
13
|
|
14
14
|
$ gem install an
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
begin
|
35
|
-
gateway.sale(customer, invoice, card)
|
36
|
-
rescue AN::TransactionFailed => e
|
37
|
-
puts "%s: %s" % [e.reason_code, e.reason_text]
|
16
|
+
$ export AUTHORIZE_NET_URL=https://<login>:<key>@<url>
|
17
|
+
|
18
|
+
gateway = AN.connect
|
19
|
+
|
20
|
+
response = gateway.transact(
|
21
|
+
card_number: "4111111111111111",
|
22
|
+
card_code: "123",
|
23
|
+
expiration_date: "2015-01",
|
24
|
+
amount: "10.00",
|
25
|
+
invoice_number: SecureRandom.hex(10)
|
26
|
+
)
|
27
|
+
|
28
|
+
if resp.success?
|
29
|
+
# process the order, possibly storing
|
30
|
+
# parts of resp.to_hash
|
31
|
+
else
|
32
|
+
# display an error.
|
38
33
|
end
|
39
34
|
|
40
|
-
|
41
35
|
TODOS
|
42
36
|
|
43
37
|
ARB Integration
|
44
|
-
CIM Integration
|
data/an.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "an"
|
3
|
-
s.version = "0.0.1.
|
3
|
+
s.version = "0.0.1.rc3"
|
4
4
|
s.summary = "A thin Authorize.NET client."
|
5
5
|
s.description = "AN is a simplified client for integration with Authorize.NET."
|
6
6
|
s.authors = ["Cyril David"]
|
@@ -15,6 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
"test/*.*"
|
16
16
|
]
|
17
17
|
|
18
|
-
s.add_dependency "
|
18
|
+
s.add_dependency "mote"
|
19
|
+
s.add_dependency "xml-simple"
|
19
20
|
s.add_development_dependency "cutest"
|
20
21
|
end
|
data/lib/an.rb
CHANGED
@@ -9,14 +9,14 @@ class AN
|
|
9
9
|
#
|
10
10
|
# AUTHORIZE_NET_URL=https://login:key@api.authorize.net/xml/v1/request.api
|
11
11
|
#
|
12
|
-
# in the appropriate location (e.g. /etc/profile.d, ~/.bashrc, or
|
12
|
+
# in the appropriate location (e.g. /etc/profile.d, ~/.bashrc, or
|
13
13
|
# whatever you're most comfortable with.
|
14
14
|
#
|
15
15
|
# The TEST URL is https://apikey.authorize.net/xml/v1/request.api
|
16
16
|
def self.connect(url = ENV["AUTHORIZE_NET_URL"])
|
17
17
|
new(URI(url))
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
TEMPLATES = File.expand_path("../templates", File.dirname(__FILE__))
|
21
21
|
|
22
22
|
include Mote::Helpers
|
@@ -24,7 +24,7 @@ class AN
|
|
24
24
|
attr :url
|
25
25
|
attr :auth
|
26
26
|
attr :client
|
27
|
-
|
27
|
+
|
28
28
|
def initialize(uri)
|
29
29
|
@auth = { login: uri.user, transaction_key: uri.password }
|
30
30
|
@client = Client.new(uri)
|
@@ -41,16 +41,16 @@ class AN
|
|
41
41
|
def create_payment_profile(params)
|
42
42
|
call("createCustomerPaymentProfileRequest", params)
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
def create_profile_transaction(params)
|
46
46
|
call("createCustomerProfileTransactionRequest", params)
|
47
47
|
end
|
48
48
|
|
49
|
-
private
|
49
|
+
private
|
50
50
|
def call(api_call, params)
|
51
51
|
Response.new(post(payload(api_call, params)))
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
def post(xml)
|
55
55
|
client.post(xml, "Content-Type" => "text/xml")
|
56
56
|
end
|
@@ -58,71 +58,81 @@ private
|
|
58
58
|
def payload(api_call, params)
|
59
59
|
mote(File.join(TEMPLATES, "%s.mote" % api_call), params.merge(auth))
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
class Response
|
63
|
-
attr :data
|
64
|
-
|
65
63
|
OK = "Ok"
|
66
64
|
|
67
65
|
def initialize(xml)
|
68
|
-
@data = XmlSimple.xml_in(xml, forcearray: false)
|
66
|
+
@data = XmlSimple.xml_in(xml, forcearray: false)
|
69
67
|
end
|
70
68
|
|
71
|
-
def
|
72
|
-
data[
|
69
|
+
def [](key)
|
70
|
+
@data[key]
|
73
71
|
end
|
74
72
|
|
75
|
-
def
|
76
|
-
data["
|
73
|
+
def success?
|
74
|
+
@data["messages"]["resultCode"] == OK
|
77
75
|
end
|
78
76
|
|
79
|
-
def
|
80
|
-
data
|
77
|
+
def to_hash
|
78
|
+
@data
|
81
79
|
end
|
82
80
|
|
83
81
|
def profile_id
|
84
|
-
data["customerProfileId"]
|
82
|
+
@data["customerProfileId"]
|
85
83
|
end
|
86
84
|
|
87
85
|
def payment_profile_id
|
88
|
-
data["customerPaymentProfileId"]
|
86
|
+
@data["customerPaymentProfileId"]
|
89
87
|
end
|
90
88
|
|
91
|
-
def
|
92
|
-
|
93
|
-
|
94
|
-
|
89
|
+
def authorization
|
90
|
+
response = @data["validationDirectResponse"] || @data["directResponse"]
|
91
|
+
|
92
|
+
AuthorizationResponse.new(response) if response
|
95
93
|
end
|
96
94
|
end
|
97
95
|
|
98
|
-
class
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
requested_amount balance_on_card].freeze
|
113
|
-
|
114
|
-
attr :fields
|
96
|
+
class AuthorizationResponse
|
97
|
+
FIELDS = {
|
98
|
+
1 => "responseCode",
|
99
|
+
3 => "messageCode",
|
100
|
+
4 => "messageDescription",
|
101
|
+
5 => "authCode",
|
102
|
+
6 => "avsResultCode",
|
103
|
+
7 => "transId",
|
104
|
+
38 => "transHash",
|
105
|
+
39 => "cvvResultCode",
|
106
|
+
40 => "cavvResultCode",
|
107
|
+
51 => "accountNumber",
|
108
|
+
52 => "accountType"
|
109
|
+
}
|
115
110
|
|
116
111
|
def initialize(data, delimiter = ",")
|
117
|
-
@
|
112
|
+
@list = data.split(delimiter)
|
113
|
+
@data = {}
|
114
|
+
|
115
|
+
FIELDS.each do |index, field|
|
116
|
+
# The FIELDS hash is using a 1-based index in order
|
117
|
+
# to match the ordering number in the AIM documentation.
|
118
|
+
@data[field] = @list[index - 1]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def to_hash
|
123
|
+
@data
|
124
|
+
end
|
125
|
+
|
126
|
+
def [](key)
|
127
|
+
@data[key]
|
118
128
|
end
|
119
129
|
|
120
130
|
def success?
|
121
|
-
|
131
|
+
@data["responseCode"] == "1" && @data["messageCode"] == "1"
|
122
132
|
end
|
123
133
|
|
124
134
|
def transaction_id
|
125
|
-
|
135
|
+
@data["transId"]
|
126
136
|
end
|
127
137
|
end
|
128
138
|
|
data/test/an.rb
CHANGED
@@ -4,22 +4,39 @@ setup do
|
|
4
4
|
AN.connect
|
5
5
|
end
|
6
6
|
|
7
|
-
test "AIM basic transaction" do |gateway|
|
8
|
-
resp = gateway.transact(
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
|
15
|
-
:first_name => "John",
|
16
|
-
:last_name => "Doe",
|
17
|
-
:address => "12345 foobar street",
|
18
|
-
:zip => "90210"
|
19
|
-
})
|
7
|
+
test "AIM most basic transaction" do |gateway|
|
8
|
+
resp = gateway.transact(
|
9
|
+
card_number: "4111111111111111",
|
10
|
+
card_code: "123",
|
11
|
+
expiration_date: "2015-01",
|
12
|
+
amount: "10.00",
|
13
|
+
invoice_number: SecureRandom.hex(10)
|
14
|
+
)
|
20
15
|
|
21
16
|
assert resp.success?
|
22
|
-
assert resp.
|
17
|
+
assert resp["transactionResponse"].kind_of?(Hash)
|
18
|
+
assert_equal "XXXX1111", resp["transactionResponse"]["accountNumber"]
|
19
|
+
assert_equal "Visa", resp["transactionResponse"]["accountType"]
|
20
|
+
end
|
21
|
+
|
22
|
+
test "AIM transaction with billing info" do |gateway|
|
23
|
+
resp = gateway.transact(
|
24
|
+
card_number: "4111111111111111",
|
25
|
+
card_code: "123",
|
26
|
+
expiration_date: "2015-01",
|
27
|
+
amount: "10.00",
|
28
|
+
invoice_number: SecureRandom.hex(10),
|
29
|
+
description: "Aeutsahoesuhtaeu",
|
30
|
+
first_name: "John",
|
31
|
+
last_name: "Doe",
|
32
|
+
address: "12345 foobar street",
|
33
|
+
zip: "90210"
|
34
|
+
)
|
35
|
+
|
36
|
+
assert resp.success?
|
37
|
+
assert resp["transactionResponse"].kind_of?(Hash)
|
38
|
+
assert_equal "XXXX1111", resp["transactionResponse"]["accountNumber"]
|
39
|
+
assert_equal "Visa", resp["transactionResponse"]["accountType"]
|
23
40
|
end
|
24
41
|
|
25
42
|
# CIM (Customer Information Manager)
|
@@ -33,9 +50,9 @@ scope do
|
|
33
50
|
resp = gateway.create_profile(reference_id: reference_id,
|
34
51
|
customer_id: customer_id,
|
35
52
|
email: "foo@bar.com")
|
36
|
-
|
53
|
+
|
37
54
|
assert resp.success?
|
38
|
-
assert_equal reference_id, resp
|
55
|
+
assert_equal reference_id, resp["refId"]
|
39
56
|
assert resp.profile_id
|
40
57
|
|
41
58
|
# After a successful response in the background process, you
|
@@ -64,13 +81,13 @@ scope do
|
|
64
81
|
# By default the validation method used is liveMode which returns an
|
65
82
|
# AIM-like payment response string related to the credit card details
|
66
83
|
# passed as part of creating the payment profile.
|
67
|
-
assert resp.success?
|
84
|
+
assert resp.success?
|
68
85
|
assert resp.payment_profile_id
|
69
|
-
assert resp.
|
70
|
-
|
71
|
-
assert_equal "XXXX1111", resp.
|
72
|
-
assert_equal "Visa", resp.
|
73
|
-
|
86
|
+
assert resp.authorization.success?
|
87
|
+
|
88
|
+
assert_equal "XXXX1111", resp.authorization["accountNumber"]
|
89
|
+
assert_equal "Visa", resp.authorization["accountType"]
|
90
|
+
|
74
91
|
# The payment profile id should then be saved together with the user.
|
75
92
|
# You may also do a one-to-many setup similar to amazon where they can
|
76
93
|
# add multiple credit cards. If that's the case, simply use the
|
@@ -89,10 +106,10 @@ scope do
|
|
89
106
|
description: "Jan - Feb",
|
90
107
|
purchase_order_number: "001"
|
91
108
|
})
|
92
|
-
|
109
|
+
|
93
110
|
assert resp.success?
|
94
|
-
assert resp.
|
95
|
-
assert_equal "XXXX1111", resp.
|
96
|
-
assert_equal "Visa", resp.
|
111
|
+
assert resp.authorization.success?
|
112
|
+
assert_equal "XXXX1111", resp.authorization["accountNumber"]
|
113
|
+
assert_equal "Visa", resp.authorization["accountType"]
|
97
114
|
end
|
98
115
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: an
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.1.
|
4
|
+
version: 0.0.1.rc3
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,8 +12,8 @@ cert_chain: []
|
|
12
12
|
date: 2012-02-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
16
|
-
requirement: &
|
15
|
+
name: mote
|
16
|
+
requirement: &2151853740 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,21 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2151853740
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: xml-simple
|
27
|
+
requirement: &2151853160 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2151853160
|
25
36
|
- !ruby/object:Gem::Dependency
|
26
37
|
name: cutest
|
27
|
-
requirement: &
|
38
|
+
requirement: &2151852500 !ruby/object:Gem::Requirement
|
28
39
|
none: false
|
29
40
|
requirements:
|
30
41
|
- - ! '>='
|
@@ -32,7 +43,7 @@ dependencies:
|
|
32
43
|
version: '0'
|
33
44
|
type: :development
|
34
45
|
prerelease: false
|
35
|
-
version_requirements: *
|
46
|
+
version_requirements: *2151852500
|
36
47
|
description: AN is a simplified client for integration with Authorize.NET.
|
37
48
|
email:
|
38
49
|
- me@cyrildavid.com
|
@@ -66,7 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
77
|
version: 1.3.1
|
67
78
|
requirements: []
|
68
79
|
rubyforge_project:
|
69
|
-
rubygems_version: 1.8.
|
80
|
+
rubygems_version: 1.8.16
|
70
81
|
signing_key:
|
71
82
|
specification_version: 3
|
72
83
|
summary: A thin Authorize.NET client.
|