fat_zebra 1.1.3 → 1.1.4
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.
- checksums.yaml +15 -0
- data/README.markdown +1 -1
- data/lib/fat_zebra/config.rb +39 -0
- data/lib/fat_zebra/errors.rb +1 -0
- data/lib/fat_zebra/gateway.rb +64 -142
- data/lib/fat_zebra/models/card.rb +1 -3
- data/lib/fat_zebra/models/purchase.rb +107 -14
- data/lib/fat_zebra/models/refund.rb +26 -0
- data/lib/fat_zebra/version.rb +1 -1
- data/lib/fat_zebra.rb +41 -1
- data/spec/config_spec.rb +37 -0
- data/spec/gateway_spec.rb +37 -22
- data/spec/models/purchase_spec.rb +18 -0
- metadata +50 -34
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YmU1MzgwMjdkYTJlMDM2OTc2MDEzZWVlODI3OTMzN2Y0MzAyZjRmZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ODBlZTlmNzY2MGQ2ZTY0MTI4MTJmOTcyY2VjMmFkMWYwMjM4ZWNjMQ==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MTA3ZDc2ZWIyZTcxNGZmMTg0ZDViMWRkNmI0NTQyNzdhODExNzdkMmI5NDg4
|
10
|
+
NzY1M2JiNGNlODNjNDk1YzE4ZTQzZDIxNWVhZWQ2ZTMxZGUwOGRkZTg1NTUy
|
11
|
+
OTI1Y2U5ODEzYmQzYWIyODNlNTA0MzlmMDY5NjBiN2Q1ZDQyYWY=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NjQ4NjIxOWJjMmQ0OWEwYzE4MzBiMTY0Y2ExZWUzNGQ0ZjFlNTIwZmQyMjlm
|
14
|
+
NjY0ZjExYTE0Y2MwZWExZGY3NWJiMWZlMTQxY2E4NDJlOTVkNDE2NDY2ZTA4
|
15
|
+
NDMxZjg5MDFlMTk2YTkyZDhjZjE5MjA2NDA4OTE4YzQwMWE2NjY=
|
data/README.markdown
CHANGED
@@ -0,0 +1,39 @@
|
|
1
|
+
module FatZebra
|
2
|
+
class Config
|
3
|
+
|
4
|
+
# Returns the config values in a hash
|
5
|
+
def config
|
6
|
+
@config ||= {}
|
7
|
+
end
|
8
|
+
|
9
|
+
[:username, :token, :test_mode, :sandbox, :options, :gateway].each do |attr|
|
10
|
+
define_method "#{attr}" do |value = nil|
|
11
|
+
if value.nil?
|
12
|
+
config[attr.to_s]
|
13
|
+
else
|
14
|
+
config[attr.to_s] = value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Validates the configuration
|
20
|
+
def validate!
|
21
|
+
@errors = []
|
22
|
+
|
23
|
+
@errors << "Username is required" if self.username.nil?
|
24
|
+
@errors << "Username must begin with TEST when using Sandbox Mode" if self.sandbox && !self.username.match(/\ATEST/)
|
25
|
+
@errors << "Token is required" if self.token.nil?
|
26
|
+
|
27
|
+
raise "The following errors were raised during configuration: #{@errors.join(", ")}}" unless @errors.empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.from_hash(hash)
|
31
|
+
c = new
|
32
|
+
hash.each do |key, value|
|
33
|
+
c.send key, value
|
34
|
+
end
|
35
|
+
|
36
|
+
c
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/fat_zebra/errors.rb
CHANGED
data/lib/fat_zebra/gateway.rb
CHANGED
@@ -4,14 +4,25 @@ module FatZebra
|
|
4
4
|
|
5
5
|
DEFAULT_OPTIONS = {:secure => true, :version => API_VERSION}
|
6
6
|
|
7
|
-
|
7
|
+
class << self
|
8
|
+
def configure(config)
|
9
|
+
g = Gateway.new(config.username, config.token, config.gateway || GATEWAY_SERVER)
|
10
|
+
g.options ||= {}
|
11
|
+
g.options[:test_mode] = config.test_mode
|
12
|
+
g.options.merge!(config.options || {})
|
13
|
+
|
14
|
+
g
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Initializes a new gateway object
|
8
19
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
20
|
+
# @param [String] merchants username
|
21
|
+
# @param [String] merchants token for authentication
|
22
|
+
# @param [String] the server for the gateway, defaults to 'gateway.fatzebra.com.au'
|
23
|
+
# @param [Hash] the options for the gateway connection (e.g. secure, version etc)
|
13
24
|
#
|
14
|
-
#
|
25
|
+
# @return FatZebra::Gateway instance
|
15
26
|
def initialize(username, token, gateway_server = GATEWAY_SERVER, options = {})
|
16
27
|
self.username = username
|
17
28
|
self.token = token
|
@@ -21,7 +32,7 @@ module FatZebra
|
|
21
32
|
require_field :username, :token, :gateway_server
|
22
33
|
end
|
23
34
|
|
24
|
-
#
|
35
|
+
# Performs a purchase transaction against the gateway
|
25
36
|
#
|
26
37
|
# amount - the amount as an integer e.g. (1.00 * 100).to_i
|
27
38
|
# card_data - a hash of the card data (example: {:card_holder => "John Smith", :number => "...", :expiry => "...", :cvv => "123"} or {:token => "abcdefg1"})
|
@@ -35,38 +46,8 @@ module FatZebra
|
|
35
46
|
#
|
36
47
|
# Returns a new FatZebra::Models::Response (purchase) object
|
37
48
|
def purchase(amount, card_data, reference, customer_ip, currency = "AUD")
|
38
|
-
|
39
|
-
|
40
|
-
warn "[DEPRECATED] please use {:card_token => \".....\"} instead of {:token => \".....\"}"
|
41
|
-
card_data[:card_token] ||= card_data.delete(:token)
|
42
|
-
end
|
43
|
-
|
44
|
-
if card_data.keys.include?(:number)
|
45
|
-
warn "[DEPRECATED] please use :card_number instead of :number"
|
46
|
-
card_data[:card_number] ||= card_data.delete(:number)
|
47
|
-
end
|
48
|
-
|
49
|
-
if card_data.keys.include?(:expiry)
|
50
|
-
warn "[DEPRECATED] please use :card_expiry instead of :expiry"
|
51
|
-
card_data[:card_expiry] ||= card_data.delete(:expiry)
|
52
|
-
end
|
53
|
-
|
54
|
-
params = {
|
55
|
-
:amount => amount,
|
56
|
-
:card_holder => card_data.delete(:card_holder),
|
57
|
-
:card_number => card_data.delete(:card_number),
|
58
|
-
:card_expiry => extract_date(card_data.delete(:card_expiry)),
|
59
|
-
:cvv => card_data.delete(:cvv),
|
60
|
-
:card_token => card_data.delete(:card_token),
|
61
|
-
:reference => reference,
|
62
|
-
:customer_ip => customer_ip,
|
63
|
-
:currency => currency
|
64
|
-
}
|
65
|
-
|
66
|
-
params.delete_if {|key, value| value.nil? } # If token is nil, remove, otherwise, remove card values
|
67
|
-
|
68
|
-
response = make_request(:post, "purchases", params)
|
69
|
-
FatZebra::Models::Response.new(response)
|
49
|
+
warn "[DEPRECATED] Gateway#purchase is deprecated, please use Purchase.create instead" unless options[:silence]
|
50
|
+
Models::Purchase.create(amount, card_data, reference, customer_ip, currency)
|
70
51
|
end
|
71
52
|
|
72
53
|
# Retrieves purchases specified by the options hash
|
@@ -80,36 +61,10 @@ module FatZebra
|
|
80
61
|
# - offset (defaults to 0) - for pagination
|
81
62
|
# - limit (defaults to 10) for pagination
|
82
63
|
# @return [Array<Purchase>] array of purchases
|
64
|
+
# @deprecated Please use Purchase.find(options) instead
|
83
65
|
def purchases(options = {})
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
# Format dates for the request
|
88
|
-
options[:from] = options[:from].strftime("%Y%m%dT%H%M") if options[:from]
|
89
|
-
options[:to] = options[:to].strftime("%Y%m%dT%H%M") if options[:to]
|
90
|
-
|
91
|
-
|
92
|
-
if id.nil?
|
93
|
-
response = make_request(:get, "purchases", options)
|
94
|
-
if response["successful"]
|
95
|
-
purchases = []
|
96
|
-
response["response"].each do |purchase|
|
97
|
-
purchases << FatZebra::Models::Purchase.new(purchase)
|
98
|
-
end
|
99
|
-
|
100
|
-
purchases.size == 1 ? purchases.first : purchases
|
101
|
-
else
|
102
|
-
# TODO: This should raise a defined exception
|
103
|
-
raise StandardError, "Unable to query purchases, #{response["errors"].inspect}"
|
104
|
-
end
|
105
|
-
else
|
106
|
-
response = make_request(:get, "purchases/#{id}.json")
|
107
|
-
if response["successful"]
|
108
|
-
FatZebra::Models::Purchase.new(response["response"])
|
109
|
-
else
|
110
|
-
raise StandardError, "Unable to query purchases, #{response["errors"].inspect}"
|
111
|
-
end
|
112
|
-
end
|
66
|
+
warn "[DEPRECATED] Gateway#purchases is deprecated, please use Purchase.find instead" unless options[:silence]
|
67
|
+
Models::Purchase.find(options)
|
113
68
|
end
|
114
69
|
|
115
70
|
# Public: Performs an authorization transaction against the gateway
|
@@ -137,29 +92,24 @@ module FatZebra
|
|
137
92
|
raise "Sorry we haven't compelted this functionality yet."
|
138
93
|
end
|
139
94
|
|
140
|
-
#
|
95
|
+
# Refunds a transaction
|
141
96
|
#
|
142
|
-
#
|
143
|
-
#
|
144
|
-
#
|
97
|
+
# @param [String] the ID of the original transaction to be refunded
|
98
|
+
# @param [Integer] the amount to be refunded, as an integer
|
99
|
+
# @param [String] the reference for the refund
|
145
100
|
#
|
146
|
-
#
|
101
|
+
# @return [Refund] refund result object
|
102
|
+
# @deprecated Please use Refund.create or Purchase#refund instead
|
147
103
|
def refund(transaction_id, amount, reference)
|
148
|
-
|
149
|
-
|
150
|
-
:amount => amount,
|
151
|
-
:reference => reference
|
152
|
-
}
|
153
|
-
|
154
|
-
response = make_request(:post, "refunds", params)
|
155
|
-
FatZebra::Models::Response.new(response, :refund)
|
104
|
+
warn "[DEPRECATED] Gateway#refund is deprecated, please use Refund.create or Purchase#refund instead`" unless options[:silence]
|
105
|
+
Models::Refund.create(transaction_id, amount, reference)
|
156
106
|
end
|
157
107
|
|
158
|
-
#
|
108
|
+
# Pings the Fat Zebra service
|
159
109
|
#
|
160
|
-
#
|
110
|
+
# @param [String] the data to be echoed back
|
161
111
|
#
|
162
|
-
#
|
112
|
+
# @return true if reply is valid, false if the request times out, or otherwise
|
163
113
|
def ping(nonce = SecureRandom.hex)
|
164
114
|
begin
|
165
115
|
response = RestClient.get(build_url("ping") + "?echo=#{nonce}")
|
@@ -171,52 +121,48 @@ module FatZebra
|
|
171
121
|
end
|
172
122
|
end
|
173
123
|
|
174
|
-
#
|
124
|
+
# Tokenizes a credit card
|
175
125
|
#
|
176
|
-
#
|
177
|
-
#
|
178
|
-
#
|
179
|
-
#
|
126
|
+
# @param [String] the credit card holder name
|
127
|
+
# @param [String] the card number
|
128
|
+
# @param [String] the credit card expiry date (mm/yyyy)
|
129
|
+
# @param [String] the card CVV
|
180
130
|
#
|
181
|
-
#
|
131
|
+
# @return Response
|
132
|
+
# @deprecated Please use Card.create instead
|
182
133
|
def tokenize(card_holder, card_number, expiry, cvv)
|
183
|
-
|
184
|
-
|
185
|
-
:card_number => card_number,
|
186
|
-
:card_expiry => expiry,
|
187
|
-
:cvv => cvv
|
188
|
-
}
|
189
|
-
|
190
|
-
response = make_request(:post, "credit_cards", params)
|
191
|
-
FatZebra::Models::Response.new(response, :card)
|
134
|
+
warn "[DEPRECATED] Gateway#tokenize is deprecated, please use Card.create instead" unless options[:silence]
|
135
|
+
Models::Card.create(card_holder, card_number, expiry, cvv)
|
192
136
|
end
|
193
137
|
|
194
|
-
# Public:
|
138
|
+
# Public: Performs the HTTP(s) request and returns a response object, handing errors etc
|
195
139
|
#
|
196
|
-
#
|
140
|
+
# method - the request method (:post or :get)
|
141
|
+
# resource - the resource for the request
|
142
|
+
# data - a hash of the data for the request
|
197
143
|
#
|
198
|
-
# Returns
|
199
|
-
def
|
200
|
-
|
201
|
-
FatZebra::Models::Response.new(response, :card)
|
202
|
-
end
|
144
|
+
# Returns hash of response data
|
145
|
+
def make_request(method, resource, data = nil)
|
146
|
+
resource = get_resource(resource, method, data)
|
203
147
|
|
204
|
-
|
205
|
-
|
206
|
-
|
148
|
+
if method == :post
|
149
|
+
data[:test] = options[:test_mode] if options[:test_mode]
|
150
|
+
payload = data.to_json
|
151
|
+
else
|
152
|
+
payload = {}
|
153
|
+
end
|
207
154
|
|
208
|
-
|
209
|
-
options[:from] = options[:from].strftime("%Y%m%dT%H%M") if options[:from]
|
210
|
-
options[:to] = options[:to].strftime("%Y%m%dT%H%M") if options[:to]
|
155
|
+
headers = options[:headers] || {}
|
211
156
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
records << FatZebra::Models::Card.new(record)
|
157
|
+
if method == :get
|
158
|
+
resource.send(method, headers) do |response, request, result, &block|
|
159
|
+
handle_response(response)
|
216
160
|
end
|
217
|
-
records
|
218
161
|
else
|
219
|
-
|
162
|
+
# Add in test flag is test mode...
|
163
|
+
resource.send(method, payload, headers) do |response, request, result, &block|
|
164
|
+
handle_response(response)
|
165
|
+
end
|
220
166
|
end
|
221
167
|
end
|
222
168
|
|
@@ -304,30 +250,6 @@ module FatZebra
|
|
304
250
|
RestClient::Resource.new(url, opts.merge(ssl_options))
|
305
251
|
end
|
306
252
|
|
307
|
-
# Public: Performs the HTTP(s) request and returns a response object, handing errors etc
|
308
|
-
#
|
309
|
-
# method - the request method (:post or :get)
|
310
|
-
# resource - the resource for the request
|
311
|
-
# data - a hash of the data for the request
|
312
|
-
#
|
313
|
-
# Returns hash of response data
|
314
|
-
def make_request(method, resource, data = nil)
|
315
|
-
resource = get_resource(resource, method, data)
|
316
|
-
|
317
|
-
payload = (method == :post) ? data.to_json : {}
|
318
|
-
headers = options[:headers] || {}
|
319
|
-
|
320
|
-
if method == :get
|
321
|
-
resource.send(method, headers) do |response, request, result, &block|
|
322
|
-
handle_response(response)
|
323
|
-
end
|
324
|
-
else
|
325
|
-
resource.send(method, payload, headers) do |response, request, result, &block|
|
326
|
-
handle_response(response)
|
327
|
-
end
|
328
|
-
end
|
329
|
-
end
|
330
|
-
|
331
253
|
def handle_response(response)
|
332
254
|
case response.code
|
333
255
|
when 201
|
@@ -1,19 +1,112 @@
|
|
1
1
|
module FatZebra
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
2
|
+
module Models
|
3
|
+
class Purchase < Base
|
4
|
+
attribute :id, :amount, :reference, :message, :authorization, :transaction_id, :card_number,
|
5
|
+
:card_holder, :card_expiry, :authorized, :successful, :card_token, :currency, :raw
|
6
|
+
|
7
|
+
# Refunds the current transaction
|
8
|
+
#
|
9
|
+
# @param [Integer] the amount to be refunded
|
10
|
+
# @param [String] the refund reference
|
11
|
+
#
|
12
|
+
# @return Response (Refund) object
|
13
|
+
def refund(amount, reference)
|
14
|
+
Refund.create(self.id, amount, reference)
|
9
15
|
end
|
10
16
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
17
|
+
class << self
|
18
|
+
# Performs a purchase transaction against the gateway
|
19
|
+
#
|
20
|
+
# @param [Integer] the amount as an integer e.g. (1.00 * 100).to_i
|
21
|
+
# @param [Hash] a hash of the card data (example: {:card_holder => "John Smith", :number => "...", :expiry => "...", :cvv => "123"} or {:token => "abcdefg1"})
|
22
|
+
# @param [String] the card holders name
|
23
|
+
# @param [String] the customers credit card number
|
24
|
+
# @param [Date] the customers card expiry date (as Date or string [mm/yyyy])
|
25
|
+
# @param [String] the credit card verification value (cvv, cav, csc etc)
|
26
|
+
# @param [String] a reference for the purchase
|
27
|
+
# @param [String] the customers IP address (for fraud prevention)
|
28
|
+
# @param [String] currency code ("AUD", "USD", etc)
|
29
|
+
#
|
30
|
+
# @return [Response] response (purchase) object
|
31
|
+
def create(amount, card_data, reference, customer_ip, currency = "AUD")
|
32
|
+
params = {
|
33
|
+
:amount => amount,
|
34
|
+
:card_holder => card_data.delete(:card_holder),
|
35
|
+
:card_number => card_data.delete(:number),
|
36
|
+
:card_expiry => extract_date(card_data.delete(:expiry)),
|
37
|
+
:cvv => card_data.delete(:cvv),
|
38
|
+
:card_token => card_data.delete(:token),
|
39
|
+
:reference => reference,
|
40
|
+
:customer_ip => customer_ip,
|
41
|
+
:currency => currency
|
42
|
+
}
|
43
|
+
|
44
|
+
params.delete_if {|key, value| value.nil? } # If token is nil, remove, otherwise, remove card values
|
45
|
+
|
46
|
+
response = FatZebra.gateway.make_request(:post, "purchases", params)
|
47
|
+
Response.new(response)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Retrieves purchases specified by the options hash
|
51
|
+
#
|
52
|
+
# @param [Hash] options for lookup
|
53
|
+
# includes:
|
54
|
+
# - id (unique purchase ID)
|
55
|
+
# - reference (merchant reference)
|
56
|
+
# - from (Date)
|
57
|
+
# - to (Date)
|
58
|
+
# - offset (defaults to 0) - for pagination
|
59
|
+
# - limit (defaults to 10) for pagination
|
60
|
+
# @return [Array<Purchase>] array of purchases
|
61
|
+
def find(options = {})
|
62
|
+
id = options.delete(:id)
|
63
|
+
options.merge!({:offets => 0, :limit => 10})
|
64
|
+
|
65
|
+
# Format dates for the request
|
66
|
+
options[:from] = options[:from].strftime("%Y%m%dT%H%M") if options[:from]
|
67
|
+
options[:to] = options[:to].strftime("%Y%m%dT%H%M") if options[:to]
|
68
|
+
|
69
|
+
|
70
|
+
if id.nil?
|
71
|
+
response = FatZebra.gateway.make_request(:get, "purchases", options)
|
72
|
+
if response["successful"]
|
73
|
+
purchases = []
|
74
|
+
response["response"].each do |purchase|
|
75
|
+
purchases << Purchase.new(purchase)
|
76
|
+
end
|
77
|
+
|
78
|
+
purchases.size == 1 ? purchases.first : purchases
|
79
|
+
else
|
80
|
+
# TODO: This should raise a defined exception
|
81
|
+
raise StandardError, "Unable to query purchases, #{response["errors"].inspect}"
|
82
|
+
end
|
83
|
+
else
|
84
|
+
response = FatZebra.gateway.make_request(:get, "purchases/#{id}.json")
|
85
|
+
if response["successful"]
|
86
|
+
Purchase.new(response["response"])
|
87
|
+
else
|
88
|
+
raise StandardError, "Unable to query purchases, #{response["errors"].inspect}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
# Private: Extracts the date value from a Date/DateTime value
|
95
|
+
#
|
96
|
+
# value - the string or date value to extract the value from
|
97
|
+
#
|
98
|
+
# Returns date string as MM/YYYY
|
99
|
+
def extract_date(value)
|
100
|
+
return nil if value.nil?
|
101
|
+
|
102
|
+
if value.is_a?(String)
|
103
|
+
return value
|
104
|
+
elsif value.respond_to?(:strftime)
|
105
|
+
return value.strftime("%m/%Y")
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
16
109
|
end
|
17
|
-
|
18
|
-
|
110
|
+
end
|
111
|
+
end
|
19
112
|
end
|
@@ -3,14 +3,40 @@ module FatZebra
|
|
3
3
|
class Refund < Base
|
4
4
|
attribute :amount, :reference, :refunded, :id, :message, :transaction_id, :original_transaction_id, :raw
|
5
5
|
|
6
|
+
# Returns the original transaction for this refund
|
7
|
+
#
|
8
|
+
# @return Purchase
|
6
9
|
def original_transaction
|
7
10
|
@original_transaction ||= Purchase.find(self.original_transaction_id)
|
8
11
|
end
|
9
12
|
|
13
|
+
# Indicates if the refund was successful or not
|
14
|
+
#
|
15
|
+
# @return Boolean
|
10
16
|
def successful
|
11
17
|
self.refunded == "Approved"
|
12
18
|
end
|
13
19
|
alias successful? successful
|
20
|
+
|
21
|
+
class << self
|
22
|
+
# Refunds a transaction
|
23
|
+
#
|
24
|
+
# @param [String] the ID of the original transaction to be refunded
|
25
|
+
# @param [Integer] the amount to be refunded, as an integer
|
26
|
+
# @param [String] the reference for the refund
|
27
|
+
#
|
28
|
+
# @return [Refund] refund result object
|
29
|
+
def create(transaction_id, amount, reference)
|
30
|
+
params = {
|
31
|
+
:transaction_id => transaction_id,
|
32
|
+
:amount => amount,
|
33
|
+
:reference => reference
|
34
|
+
}
|
35
|
+
|
36
|
+
response = FatZebra.gateway.make_request(:post, "refunds", params)
|
37
|
+
Response.new(response, :refund)
|
38
|
+
end
|
39
|
+
end
|
14
40
|
end
|
15
41
|
end
|
16
42
|
end
|
data/lib/fat_zebra/version.rb
CHANGED
data/lib/fat_zebra.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'securerandom'
|
2
2
|
require 'json'
|
3
3
|
require 'rest_client'
|
4
|
+
require 'fat_zebra/config'
|
4
5
|
require 'fat_zebra/errors'
|
5
6
|
require "fat_zebra/version"
|
6
7
|
require 'fat_zebra/constants'
|
@@ -9,4 +10,43 @@ require 'fat_zebra/models/base'
|
|
9
10
|
require 'fat_zebra/models/purchase'
|
10
11
|
require 'fat_zebra/models/refund'
|
11
12
|
require 'fat_zebra/models/card'
|
12
|
-
require 'fat_zebra/models/response'
|
13
|
+
require 'fat_zebra/models/response'
|
14
|
+
|
15
|
+
module FatZebra
|
16
|
+
extend self
|
17
|
+
extend Forwardable
|
18
|
+
|
19
|
+
attr_accessor :config
|
20
|
+
attr_accessor :_gateway
|
21
|
+
|
22
|
+
# Configure the Fat Zebra gateway
|
23
|
+
def configure(auth = nil, &block)
|
24
|
+
raise ArgumentError, "missing authentication parameters or block" unless auth || block_given?
|
25
|
+
|
26
|
+
if !auth
|
27
|
+
self.config = Config.new
|
28
|
+
if (block.arity > 0)
|
29
|
+
block.call(self.config)
|
30
|
+
else
|
31
|
+
self.config.instance_eval(&block)
|
32
|
+
end
|
33
|
+
else
|
34
|
+
self.config = Config.from_hash(auth)
|
35
|
+
end
|
36
|
+
|
37
|
+
self.config.validate!
|
38
|
+
|
39
|
+
self.configure_gateway
|
40
|
+
|
41
|
+
self.config
|
42
|
+
end
|
43
|
+
|
44
|
+
def configure_gateway
|
45
|
+
self._gateway = Gateway.configure(self.config)
|
46
|
+
end
|
47
|
+
|
48
|
+
def gateway
|
49
|
+
raise GatewayError.new("Please configure the Gateway before use. See FatZebra.configure { }") if self.config.nil?
|
50
|
+
self._gateway
|
51
|
+
end
|
52
|
+
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe FatZebra::Config do
|
4
|
+
it "should configure with a block" do
|
5
|
+
FatZebra.configure do
|
6
|
+
username "TEST"
|
7
|
+
token "TEST"
|
8
|
+
sandbox true
|
9
|
+
end
|
10
|
+
|
11
|
+
FatZebra.config.username.should == "TEST"
|
12
|
+
FatZebra.config.token.should == "TEST"
|
13
|
+
FatZebra.config.sandbox.should be_true
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should configure from a hash" do
|
17
|
+
config = FatZebra.configure(:username => "TEST", :token => "TEST", :sandbox => true)
|
18
|
+
config.username.should == 'TEST'
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should prepare a new gateway when configured" do
|
22
|
+
FatZebra.configure do
|
23
|
+
username "TEST"
|
24
|
+
token "TEST"
|
25
|
+
test_mode true
|
26
|
+
sandbox true
|
27
|
+
options :headers => {"A" => "B"}
|
28
|
+
end
|
29
|
+
|
30
|
+
FatZebra.gateway.should_not be_nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should raise an error when trying to access the gateway before it is configured" do
|
34
|
+
FatZebra.config = nil
|
35
|
+
lambda { FatZebra.gateway }.should raise_exception(FatZebra::GatewayError)
|
36
|
+
end
|
37
|
+
end
|
data/spec/gateway_spec.rb
CHANGED
@@ -8,7 +8,15 @@ describe FatZebra::Gateway do
|
|
8
8
|
before :each do
|
9
9
|
# Setup the gateway for testing
|
10
10
|
server = TEST_LOCAL == true ? "fatapi.dev" : "gateway.sandbox.fatzebra.com.au"
|
11
|
-
|
11
|
+
FatZebra.configure do
|
12
|
+
username TEST_USER
|
13
|
+
token TEST_TOKEN
|
14
|
+
sandbox true
|
15
|
+
test_mode true
|
16
|
+
gateway server
|
17
|
+
options :secure => !TEST_LOCAL, :silence => true # Silence keeps the warnings quiet for testing (deprecation warnings)
|
18
|
+
end
|
19
|
+
@gw = FatZebra.gateway
|
12
20
|
end
|
13
21
|
|
14
22
|
it "should require username and token are provided" do
|
@@ -24,22 +32,22 @@ describe FatZebra::Gateway do
|
|
24
32
|
end
|
25
33
|
|
26
34
|
it "should perform a purchase" do
|
27
|
-
result =
|
35
|
+
result = FatZebra::Models::Purchase.create(10000, {:card_holder => "Matthew Savage", :number => "5555555555554444", :expiry => "05/2013", :cvv => 123}, "TEST#{rand}", "1.2.3.4")
|
28
36
|
result.should be_successful
|
29
37
|
result.errors.should be_empty
|
30
38
|
end
|
31
39
|
|
32
40
|
it "should fetch a purchase" do
|
33
|
-
result =
|
34
|
-
purchase =
|
41
|
+
result = FatZebra::Models::Purchase.create(10000, {:card_holder => "Matthew Savage", :number => "5555555555554444", :expiry => "05/2013", :cvv => 123}, "TES#{rand}T", "1.2.3.4")
|
42
|
+
purchase = FatZebra::Models::Purchase.find(:id => result.purchase.id)
|
35
43
|
purchase.id.should == result.purchase.id
|
36
44
|
end
|
37
45
|
|
38
46
|
it "should fetch a purchase via reference" do
|
39
47
|
ref = "TES#{rand}T"
|
40
|
-
result =
|
48
|
+
result = FatZebra::Models::Purchase.create(10000, {:card_holder => "Matthew Savage", :number => "5555555555554444", :expiry => "05/2013", :cvv => 123}, ref, "1.2.3.4")
|
41
49
|
|
42
|
-
purchases =
|
50
|
+
purchases = FatZebra::Models::Purchase.find(:reference => ref)
|
43
51
|
purchases.id.should == result.purchase.id
|
44
52
|
end
|
45
53
|
|
@@ -56,16 +64,16 @@ describe FatZebra::Gateway do
|
|
56
64
|
it "should fetch purchases with a from date" do
|
57
65
|
start = Time.now
|
58
66
|
5.times do |i|
|
59
|
-
|
67
|
+
FatZebra::Models::Purchase.create(10000, {:card_holder => "Matthew Savage", :number => "5555555555554444", :expiry => "05/2013", :cvv => 123}, "TEST#{rand(1000)}-#{i}", "1.2.3.4")
|
60
68
|
end
|
61
69
|
|
62
|
-
purchases =
|
70
|
+
purchases = FatZebra::Models::Purchase.find(:from => start)
|
63
71
|
purchases.count.should >= 5
|
64
72
|
end
|
65
73
|
|
66
74
|
it "should refund a transaction" do
|
67
|
-
purchase =
|
68
|
-
result =
|
75
|
+
purchase = FatZebra::Models::Purchase.create(10000, {:card_holder => "Matthew Savage", :number => "5555555555554444", :expiry => "05/2013", :cvv => 123}, "TES#{rand}T", "1.2.3.4")
|
76
|
+
result = FatZebra::Models::Refund.create(purchase.result.id, 100, "REFUND-#{purchase.result.id}")
|
69
77
|
|
70
78
|
result.should be_successful
|
71
79
|
result.result.successful.should be_true
|
@@ -77,26 +85,33 @@ describe FatZebra::Gateway do
|
|
77
85
|
response.result.token.should_not be_nil
|
78
86
|
end
|
79
87
|
|
80
|
-
it "should fetch a tokenized card" do
|
81
|
-
|
82
|
-
|
88
|
+
# it "should fetch a tokenized card" do
|
89
|
+
# token = @gw.tokenize("M Smith", "5123456789012346", "05/2013", "123").result.token
|
90
|
+
# card_response = @gw.tokenized_card(token)
|
83
91
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
end
|
92
|
+
# card_response.should be_successful
|
93
|
+
# card_response.result.token.should == token
|
94
|
+
# card_response.result.card_number.should == "512345XXXXXX2346"
|
95
|
+
# end
|
88
96
|
|
89
|
-
it "should fetch all cards" do
|
90
|
-
|
97
|
+
# it "should fetch all cards" do
|
98
|
+
# cards = @gw.tokenized_cards
|
91
99
|
|
92
|
-
|
93
|
-
end
|
100
|
+
# cards.first.should be_instance_of(FatZebra::Models::Card)
|
101
|
+
# end
|
94
102
|
|
95
103
|
it "should perform a purchase with a tokenized card" do
|
96
104
|
token = @gw.tokenize("M Smith", "5123456789012346", "05/2013", "123").result.token
|
97
|
-
purchase = @gw.purchase(10000, {:
|
105
|
+
purchase = @gw.purchase(10000, {:token => token}, "TEST#{rand}}", "127.0.0.1")
|
98
106
|
|
99
107
|
purchase.should be_successful
|
100
108
|
purchase.result.successful.should be_true
|
101
109
|
end
|
110
|
+
|
111
|
+
it "should transact in USD" do
|
112
|
+
result = FatZebra::Models::Purchase.create(10000, {:card_holder => "Matthew Savage", :number => "5555555555554444", :expiry => "05/2013", :cvv => 123}, "TEST#{rand}", "1.2.3.4", 'USD')
|
113
|
+
result.should be_successful, result.raw
|
114
|
+
result.errors.should be_empty
|
115
|
+
result.result.currency.should == 'USD'
|
116
|
+
end
|
102
117
|
end
|
@@ -34,4 +34,22 @@ describe FatZebra::Models::Purchase do
|
|
34
34
|
r = FatZebra::Models::Purchase.new(response)
|
35
35
|
r.card_token.should == "a1bhj98j"
|
36
36
|
end
|
37
|
+
|
38
|
+
it "should return the currency code" do
|
39
|
+
response = {
|
40
|
+
"authorization" => "55355",
|
41
|
+
"id" => "001-P-12345AA",
|
42
|
+
"card_number" => "512345XXXXXX2346",
|
43
|
+
"card_holder" => "John Smith",
|
44
|
+
"card_expiry" => "10/2011",
|
45
|
+
"card_token" => "a1bhj98j",
|
46
|
+
"amount" => 349,
|
47
|
+
"authorized" => true,
|
48
|
+
"reference" => "ABC123",
|
49
|
+
"message" => "Approved",
|
50
|
+
"currency" => "USD"
|
51
|
+
}
|
52
|
+
r = FatZebra::Models::Purchase.new(response)
|
53
|
+
r.currency.should == "USD"
|
54
|
+
end
|
37
55
|
end
|
metadata
CHANGED
@@ -1,93 +1,113 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fat_zebra
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
5
|
-
prerelease:
|
4
|
+
version: 1.1.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Matthew Savage
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-11-12 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rspec
|
16
|
-
requirement:
|
17
|
-
none: false
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
18
16
|
requirements:
|
19
17
|
- - ! '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
|
-
version_requirements:
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
25
27
|
- !ruby/object:Gem::Dependency
|
26
28
|
name: rake
|
27
|
-
requirement:
|
28
|
-
none: false
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
29
30
|
requirements:
|
30
31
|
- - ! '>='
|
31
32
|
- !ruby/object:Gem::Version
|
32
33
|
version: '0'
|
33
34
|
type: :development
|
34
35
|
prerelease: false
|
35
|
-
version_requirements:
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
36
41
|
- !ruby/object:Gem::Dependency
|
37
42
|
name: yard
|
38
|
-
requirement:
|
39
|
-
none: false
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
40
44
|
requirements:
|
41
45
|
- - ! '>='
|
42
46
|
- !ruby/object:Gem::Version
|
43
47
|
version: '0'
|
44
48
|
type: :development
|
45
49
|
prerelease: false
|
46
|
-
version_requirements:
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
47
55
|
- !ruby/object:Gem::Dependency
|
48
56
|
name: yard-tomdoc
|
49
|
-
requirement:
|
50
|
-
none: false
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
51
58
|
requirements:
|
52
59
|
- - ! '>='
|
53
60
|
- !ruby/object:Gem::Version
|
54
61
|
version: '0'
|
55
62
|
type: :development
|
56
63
|
prerelease: false
|
57
|
-
version_requirements:
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
58
69
|
- !ruby/object:Gem::Dependency
|
59
70
|
name: ZenTest
|
60
|
-
requirement:
|
61
|
-
none: false
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
62
72
|
requirements:
|
63
73
|
- - ! '>='
|
64
74
|
- !ruby/object:Gem::Version
|
65
75
|
version: '0'
|
66
76
|
type: :development
|
67
77
|
prerelease: false
|
68
|
-
version_requirements:
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rest-client
|
71
|
-
requirement:
|
72
|
-
none: false
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
73
86
|
requirements:
|
74
87
|
- - ! '>='
|
75
88
|
- !ruby/object:Gem::Version
|
76
89
|
version: '0'
|
77
90
|
type: :runtime
|
78
91
|
prerelease: false
|
79
|
-
version_requirements:
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
80
97
|
- !ruby/object:Gem::Dependency
|
81
98
|
name: json
|
82
|
-
requirement:
|
83
|
-
none: false
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
84
100
|
requirements:
|
85
101
|
- - ! '>='
|
86
102
|
- !ruby/object:Gem::Version
|
87
103
|
version: '0'
|
88
104
|
type: :runtime
|
89
105
|
prerelease: false
|
90
|
-
version_requirements:
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
91
111
|
description: Provides integration with the Fat Zebra internet payment gateway (www.fatzebra.com.au),
|
92
112
|
including purchase, refund, auth, capture and recurring billing functionality.
|
93
113
|
email:
|
@@ -104,6 +124,7 @@ files:
|
|
104
124
|
- README.markdown
|
105
125
|
- Rakefile
|
106
126
|
- lib/fat_zebra.rb
|
127
|
+
- lib/fat_zebra/config.rb
|
107
128
|
- lib/fat_zebra/constants.rb
|
108
129
|
- lib/fat_zebra/errors.rb
|
109
130
|
- lib/fat_zebra/gateway.rb
|
@@ -113,6 +134,7 @@ files:
|
|
113
134
|
- lib/fat_zebra/models/refund.rb
|
114
135
|
- lib/fat_zebra/models/response.rb
|
115
136
|
- lib/fat_zebra/version.rb
|
137
|
+
- spec/config_spec.rb
|
116
138
|
- spec/gateway_spec.rb
|
117
139
|
- spec/models/purchase_spec.rb
|
118
140
|
- spec/models/refund_spec.rb
|
@@ -121,35 +143,29 @@ files:
|
|
121
143
|
- vendor/cacert.pem
|
122
144
|
homepage: ''
|
123
145
|
licenses: []
|
146
|
+
metadata: {}
|
124
147
|
post_install_message:
|
125
148
|
rdoc_options: []
|
126
149
|
require_paths:
|
127
150
|
- lib
|
128
151
|
required_ruby_version: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
152
|
requirements:
|
131
153
|
- - ! '>='
|
132
154
|
- !ruby/object:Gem::Version
|
133
155
|
version: '0'
|
134
|
-
segments:
|
135
|
-
- 0
|
136
|
-
hash: -2567456050335982654
|
137
156
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
|
-
none: false
|
139
157
|
requirements:
|
140
158
|
- - ! '>='
|
141
159
|
- !ruby/object:Gem::Version
|
142
160
|
version: '0'
|
143
|
-
segments:
|
144
|
-
- 0
|
145
|
-
hash: -2567456050335982654
|
146
161
|
requirements: []
|
147
162
|
rubyforge_project: fat_zebra
|
148
|
-
rubygems_version:
|
163
|
+
rubygems_version: 2.0.7
|
149
164
|
signing_key:
|
150
|
-
specification_version:
|
165
|
+
specification_version: 4
|
151
166
|
summary: Fat Zebra payments gem - integrate your ruby app with Fat Zebra
|
152
167
|
test_files:
|
168
|
+
- spec/config_spec.rb
|
153
169
|
- spec/gateway_spec.rb
|
154
170
|
- spec/models/purchase_spec.rb
|
155
171
|
- spec/models/refund_spec.rb
|