spook_and_pay 0.3.1.alpha → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/spook_and_pay/credit_card.rb +13 -5
- data/lib/spook_and_pay/providers/base.rb +67 -34
- data/lib/spook_and_pay/providers/spreedly.rb +31 -15
- data/lib/spook_and_pay/transaction.rb +20 -7
- metadata +8 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb962e2e5cb48aa5da0423021039c2e37f0d54cf
|
4
|
+
data.tar.gz: e247fc0540cd4656aab4f18edc31d9c4c853d349
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25de0492cbc31f34355c366cf2b55f4196ec0fa4914beea0b78f5a5d85d203026ebf6680cfc991b241b01f44760c8facdc2f3d838c7db05d18ed0af18e151b0e
|
7
|
+
data.tar.gz: 9a6240d5ad254c9fb48db134967f7d47e716f2b14f9784d3ad512946ff9ad78c408478d08c16d7b66be2fc9915e272978c21306ea9192a58f321b87f865f744e
|
@@ -6,7 +6,7 @@ module SpookAndPay
|
|
6
6
|
# This module adds the ::attr_erroring_reader to this class
|
7
7
|
extend SpookAndPay::ErroringReader
|
8
8
|
|
9
|
-
# An error raised when trying to perform an action on a card that has
|
9
|
+
# An error raised when trying to perform an action on a card that has
|
10
10
|
# invalid details or has expired.
|
11
11
|
class InvalidCardError < StandardError
|
12
12
|
def to_s
|
@@ -48,8 +48,8 @@ module SpookAndPay
|
|
48
48
|
FIELDS.each {|f| instance_variable_set(:"@#{f}", vals[f]) if vals.has_key?(f)}
|
49
49
|
end
|
50
50
|
|
51
|
-
# A getter which takes the card number stored and generates a nice masked
|
52
|
-
# version. It also handles the case where the number isn't available and
|
51
|
+
# A getter which takes the card number stored and generates a nice masked
|
52
|
+
# version. It also handles the case where the number isn't available and
|
53
53
|
# just returns nil instead.
|
54
54
|
#
|
55
55
|
# @return String
|
@@ -68,7 +68,7 @@ module SpookAndPay
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
# Checks to see if funds can be credited to a card. Depends on the
|
71
|
+
# Checks to see if funds can be credited to a card. Depends on the
|
72
72
|
# gateway/provider supporting crediting and having a valid card.
|
73
73
|
#
|
74
74
|
# @return [true, false]
|
@@ -84,7 +84,7 @@ module SpookAndPay
|
|
84
84
|
provider.supports_authorize? and valid? and !expired?
|
85
85
|
end
|
86
86
|
|
87
|
-
# Checks to see if this card can be used for a purchase against the
|
87
|
+
# Checks to see if this card can be used for a purchase against the
|
88
88
|
# underlying gateway.
|
89
89
|
#
|
90
90
|
# @return [true, false]
|
@@ -157,6 +157,14 @@ module SpookAndPay
|
|
157
157
|
expired
|
158
158
|
end
|
159
159
|
|
160
|
+
# Retains the credit card within the payment provider's vault.
|
161
|
+
#
|
162
|
+
# @return SpookAndPay::Result
|
163
|
+
# @raises SpookAndPay::Providers::Base::NotSupportedError
|
164
|
+
def retain!
|
165
|
+
provider.retain_credit_card(self)
|
166
|
+
end
|
167
|
+
|
160
168
|
private
|
161
169
|
|
162
170
|
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module SpookAndPay
|
2
2
|
module Providers
|
3
3
|
# The abstract class from which other Provider classes should inherit. This
|
4
|
-
# class is intended to behave more as a template than anything else. It
|
4
|
+
# class is intended to behave more as a template than anything else. It
|
5
5
|
# provides very little in the way of actual implementation.
|
6
6
|
#
|
7
|
-
# To implement a provider all of the public methods of this class —
|
7
|
+
# To implement a provider all of the public methods of this class —
|
8
8
|
# excluding #initialize — must be implemented.
|
9
9
|
#
|
10
|
-
# Some features may not be supported by a provider, in which case the
|
10
|
+
# Some features may not be supported by a provider, in which case the
|
11
11
|
# `NotSupportedError` should be raised in lieu of a real implementation.
|
12
12
|
class Base
|
13
13
|
# A hash which maps between the fields for a credit card and the actual
|
@@ -17,8 +17,8 @@ module SpookAndPay
|
|
17
17
|
FORM_FIELD_NAMES = {}.freeze
|
18
18
|
|
19
19
|
# An error used when validating the contents of an options hash. Since
|
20
|
-
# many of the methods on the provider classes take additional arguments
|
21
|
-
# as a Hash, it's important to make sure we give good errors when they
|
20
|
+
# many of the methods on the provider classes take additional arguments
|
21
|
+
# as a Hash, it's important to make sure we give good errors when they
|
22
22
|
# are missing.
|
23
23
|
class InvalidOptionsError < StandardError
|
24
24
|
def initialize(errors)
|
@@ -80,14 +80,14 @@ module SpookAndPay
|
|
80
80
|
raise NotImplementedError
|
81
81
|
end
|
82
82
|
|
83
|
-
# Returns a hash containing the details necessary for making a
|
84
|
-
# submission. If you know what you're doing, you can use this directly,
|
83
|
+
# Returns a hash containing the details necessary for making a
|
84
|
+
# submission. If you know what you're doing, you can use this directly,
|
85
85
|
# but otherwise you should be using the form helpers.
|
86
86
|
#
|
87
87
|
# The details generated by this method are for submitting card details to
|
88
88
|
# the provider for storage. Billing etc has to be handled via a separate
|
89
89
|
# step after submission.
|
90
|
-
#
|
90
|
+
#
|
91
91
|
# The arguments for this are specific to each provider implementation,
|
92
92
|
# but they all return a Hash with the same keys, like so:
|
93
93
|
# {
|
@@ -95,9 +95,9 @@ module SpookAndPay
|
|
95
95
|
# :hidden_fields => {...},
|
96
96
|
# :field_names => {...}
|
97
97
|
# }
|
98
|
-
#
|
99
|
-
# Where :url is the target URL, :hidden_fields should be embedded in a
|
100
|
-
# form as they are and :field_names provide the mapping between known
|
98
|
+
#
|
99
|
+
# Where :url is the target URL, :hidden_fields should be embedded in a
|
100
|
+
# form as they are and :field_names provide the mapping between known
|
101
101
|
# keys like :number and :cvv to the input names required by the provider.
|
102
102
|
def prepare_payment_submission(*args)
|
103
103
|
raise NotImplementedError
|
@@ -132,70 +132,90 @@ module SpookAndPay
|
|
132
132
|
check_support('refund')
|
133
133
|
end
|
134
134
|
|
135
|
-
#
|
136
|
-
#
|
135
|
+
# Partially refunds the amount of money captured in a transaction.
|
136
|
+
#
|
137
|
+
# This should not be called directly. Instead, use the #partial_refund! method
|
138
|
+
# provided by a Transaction instance.
|
139
|
+
#
|
140
|
+
# @param [SpookAndPay::Transaction, String] id
|
141
|
+
# @return SpookAndPay::Result
|
142
|
+
def partially_refund_transaction(id)
|
143
|
+
check_support('partial_refund')
|
144
|
+
end
|
145
|
+
|
146
|
+
# Checks to see if purchasing is supported. This is dependent on the payment
|
147
|
+
# provider. The default implementation simply returns true. Specific
|
137
148
|
# implementations should over-ride this method.
|
138
|
-
#
|
149
|
+
#
|
139
150
|
# @return [true, false]
|
140
151
|
def supports_purchase?
|
141
152
|
true
|
142
153
|
end
|
143
154
|
|
144
|
-
# Checks to see if voiding is supported. This is dependent on the payment
|
145
|
-
# provider. The default implementation simply returns true. Specific
|
155
|
+
# Checks to see if voiding is supported. This is dependent on the payment
|
156
|
+
# provider. The default implementation simply returns true. Specific
|
146
157
|
# implementations should over-ride this method.
|
147
|
-
#
|
158
|
+
#
|
148
159
|
# @return [true, false]
|
149
160
|
def supports_void?
|
150
161
|
true
|
151
162
|
end
|
152
163
|
|
153
|
-
# Checks to see if crediting is supported. This is dependent on the payment
|
154
|
-
# provider. The default implementation simply returns true. Specific
|
164
|
+
# Checks to see if crediting is supported. This is dependent on the payment
|
165
|
+
# provider. The default implementation simply returns true. Specific
|
155
166
|
# implementations should over-ride this method.
|
156
|
-
#
|
167
|
+
#
|
157
168
|
# @return [true, false]
|
158
169
|
def supports_credit?
|
159
170
|
true
|
160
171
|
end
|
161
172
|
|
162
|
-
# Checks to see if refunding is supported. This is dependent on the payment
|
163
|
-
# provider. The default implementation simply returns true. Specific
|
173
|
+
# Checks to see if refunding is supported. This is dependent on the payment
|
174
|
+
# provider. The default implementation simply returns true. Specific
|
164
175
|
# implementations should over-ride this method.
|
165
|
-
#
|
176
|
+
#
|
166
177
|
# @return [true, false]
|
167
178
|
def supports_refund?
|
168
179
|
true
|
169
180
|
end
|
170
181
|
|
171
|
-
# Checks to see if
|
172
|
-
# provider. The default implementation simply returns true.
|
182
|
+
# Checks to see if partial refunding is supported. This is dependent on
|
183
|
+
# the payment provider. The default implementation simply returns true.
|
184
|
+
# Specific implementations should over-ride this method.
|
185
|
+
#
|
186
|
+
# @return [true, false]
|
187
|
+
def supports_partial_refund?
|
188
|
+
true
|
189
|
+
end
|
190
|
+
|
191
|
+
# Checks to see if capturing is supported. This is dependent on the payment
|
192
|
+
# provider. The default implementation simply returns true. Specific
|
173
193
|
# implementations should over-ride this method.
|
174
|
-
#
|
194
|
+
#
|
175
195
|
# @return [true, false]
|
176
196
|
def supports_capture?
|
177
197
|
true
|
178
198
|
end
|
179
199
|
|
180
|
-
# Checks to see if authorizing is supported. This is dependent on the payment
|
181
|
-
# provider. The default implementation simply returns true. Specific
|
200
|
+
# Checks to see if authorizing is supported. This is dependent on the payment
|
201
|
+
# provider. The default implementation simply returns true. Specific
|
182
202
|
# implementations should over-ride this method.
|
183
|
-
#
|
203
|
+
#
|
184
204
|
# @return [true, false]
|
185
205
|
def supports_authorize?
|
186
206
|
true
|
187
207
|
end
|
188
208
|
|
189
209
|
# Checks to see if the deletion of payment details is supported. This is
|
190
|
-
# dependent on the payment provider. The default implementation simply
|
210
|
+
# dependent on the payment provider. The default implementation simply
|
191
211
|
# returns true. Specific implementations should over-ride this method.
|
192
|
-
#
|
212
|
+
#
|
193
213
|
# @return [true, false]
|
194
214
|
def supports_delete?
|
195
215
|
true
|
196
216
|
end
|
197
217
|
|
198
|
-
# Voids an authorization.
|
218
|
+
# Voids an authorization.
|
199
219
|
#
|
200
220
|
# This should not be called directly. Instead, use the #void! method
|
201
221
|
# provided by a Transaction instance.
|
@@ -263,13 +283,26 @@ module SpookAndPay
|
|
263
283
|
check_support('delete')
|
264
284
|
end
|
265
285
|
|
286
|
+
# Retains a credit card within the provider's vault.
|
287
|
+
#
|
288
|
+
# This should not be called directly. Instead, use the #retain! method
|
289
|
+
# provided by a CreditCard instance.
|
290
|
+
#
|
291
|
+
# @param [SpookAndPay::CreditCard, String] id
|
292
|
+
# @return SpookAndPay::Result
|
293
|
+
# @api private
|
294
|
+
# @abstract Subclass to implement
|
295
|
+
def retain_credit_card(id)
|
296
|
+
check_support('retain')
|
297
|
+
end
|
298
|
+
|
266
299
|
private
|
267
300
|
|
268
|
-
# Checks to see if a particular action is defined as being supported and
|
301
|
+
# Checks to see if a particular action is defined as being supported and
|
269
302
|
# raises the appropriate error.
|
270
303
|
#
|
271
304
|
# The basic semantics is this; if someone implementing a provider says an
|
272
|
-
# action is supported via a #supports_*? predicate, this method should
|
305
|
+
# action is supported via a #supports_*? predicate, this method should
|
273
306
|
# never be called, so we raise NotImplementedError. Otherwise they are
|
274
307
|
# saying it's not supported and the appropriate response is to raise a
|
275
308
|
# NotSupportedError.
|
@@ -11,7 +11,7 @@ module SpookAndPay
|
|
11
11
|
:cvv => "credit_card[verification_value]"
|
12
12
|
}.freeze
|
13
13
|
|
14
|
-
# The which refers to a specific gateway.
|
14
|
+
# The which refers to a specific gateway.
|
15
15
|
#
|
16
16
|
# @attr_reader String
|
17
17
|
attr_reader :gateway_token
|
@@ -37,7 +37,7 @@ module SpookAndPay
|
|
37
37
|
@gateway_token = config[:gateway_token]
|
38
38
|
@currency_code = config[:currency_code] || 'AUD'
|
39
39
|
@spreedly = ::Spreedly::Environment.new(
|
40
|
-
config[:environment_key],
|
40
|
+
config[:environment_key],
|
41
41
|
config[:access_secret],
|
42
42
|
:currency_code => currency_code
|
43
43
|
)
|
@@ -77,7 +77,7 @@ module SpookAndPay
|
|
77
77
|
case opts[:execute]
|
78
78
|
when :authorize then card.authorize!(opts[:amount])
|
79
79
|
when :purchase then card.purchase!(opts[:amount])
|
80
|
-
|
80
|
+
else SpookAndPay::Result.new(true, nil, :credit_card => card)
|
81
81
|
end
|
82
82
|
else
|
83
83
|
SpookAndPay::Result.new(false, nil, :credit_card => card, :errors => extract_card_errors(card.raw))
|
@@ -109,12 +109,17 @@ module SpookAndPay
|
|
109
109
|
coerce_result(result)
|
110
110
|
end
|
111
111
|
|
112
|
+
def partially_refund_transaction(id, amount)
|
113
|
+
result = spreedly.refund_transaction(transaction_id(id), :amount => (amount.to_f * 100).to_i)
|
114
|
+
coerce_result(result)
|
115
|
+
end
|
116
|
+
|
112
117
|
def void_transaction(id)
|
113
118
|
result = spreedly.void_transaction(transaction_id(id))
|
114
119
|
coerce_result(result)
|
115
120
|
end
|
116
121
|
|
117
|
-
# This is a nasty little trick that makes the spreedly gateway class
|
122
|
+
# This is a nasty little trick that makes the spreedly gateway class
|
118
123
|
# store the characteristics XML fragment from the server.
|
119
124
|
#
|
120
125
|
# @todo In later versions this might not be necessary. When updating the
|
@@ -162,9 +167,19 @@ module SpookAndPay
|
|
162
167
|
coerce_result(result)
|
163
168
|
end
|
164
169
|
|
170
|
+
# Calls the retain action on the provider's vault.
|
171
|
+
#
|
172
|
+
# @param [SpookAndPay::CreditCard, Integer, String] id
|
173
|
+
# @return SpookAndPay::Result
|
174
|
+
# @api private
|
175
|
+
def retain_credit_card(id)
|
176
|
+
result = spreedly.retain_payment_method(credit_card_id(id))
|
177
|
+
coerce_result(result)
|
178
|
+
end
|
179
|
+
|
165
180
|
private
|
166
181
|
|
167
|
-
# Retrieves the gateway from Spreedly and then inspects the response to
|
182
|
+
# Retrieves the gateway from Spreedly and then inspects the response to
|
168
183
|
# see what features it supports. This is a helper for the #supports_*?
|
169
184
|
# predicates.
|
170
185
|
#
|
@@ -197,7 +212,7 @@ module SpookAndPay
|
|
197
212
|
# A mapping from the names used by Spreedly to the names SpookAndPay uses
|
198
213
|
# internally.
|
199
214
|
CARD_FIELDS = {
|
200
|
-
"full_name" => :name,
|
215
|
+
"full_name" => :name,
|
201
216
|
"number" => :number,
|
202
217
|
"year" => :expiration_year,
|
203
218
|
"month" => :expiration_month,
|
@@ -216,12 +231,12 @@ module SpookAndPay
|
|
216
231
|
#
|
217
232
|
# @param Spreedly::CreditCard result
|
218
233
|
# @return Array<SpookAndPay::SubmissionError>
|
219
|
-
# @todo If the Spreedly API behaves later, the check for first/last
|
234
|
+
# @todo If the Spreedly API behaves later, the check for first/last
|
220
235
|
# name might not be needed anymore.
|
221
236
|
def extract_card_errors(result)
|
222
|
-
# This gnarly bit of code transforms errors on the first_name or
|
237
|
+
# This gnarly bit of code transforms errors on the first_name or
|
223
238
|
# last_name attributes into an error on full_name. This is because
|
224
|
-
# Spreedly accepts input for full_name, but propogates errors to the
|
239
|
+
# Spreedly accepts input for full_name, but propogates errors to the
|
225
240
|
# separate attributes.
|
226
241
|
errors = result.errors.map do |e|
|
227
242
|
case e[:attribute]
|
@@ -243,7 +258,7 @@ module SpookAndPay
|
|
243
258
|
end
|
244
259
|
end
|
245
260
|
|
246
|
-
# Extracts/coerces errors from a Spreedly transaction into
|
261
|
+
# Extracts/coerces errors from a Spreedly transaction into
|
247
262
|
# SubmissionError instances.
|
248
263
|
#
|
249
264
|
# @param Spreedly::Transaction result
|
@@ -288,11 +303,12 @@ module SpookAndPay
|
|
288
303
|
fields = {}
|
289
304
|
|
290
305
|
fields[:type], status = case transaction
|
291
|
-
when ::Spreedly::Authorization
|
292
|
-
when ::Spreedly::Purchase
|
293
|
-
when ::Spreedly::Capture
|
294
|
-
when ::Spreedly::Refund
|
295
|
-
when ::Spreedly::Void
|
306
|
+
when ::Spreedly::Authorization then [:authorize, :authorized]
|
307
|
+
when ::Spreedly::Purchase then [:purchase, :settled]
|
308
|
+
when ::Spreedly::Capture then [:capture, :settled]
|
309
|
+
when ::Spreedly::Refund then [:credit, :refunded]
|
310
|
+
when ::Spreedly::Void then [:void, :voided]
|
311
|
+
when ::Spreedly::RetainPaymentMethod then [:retain, :retained]
|
296
312
|
end
|
297
313
|
|
298
314
|
if transaction.respond_to?(:amount)
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module SpookAndPay
|
2
|
-
# A simple class representing an interaction with a provider. Each
|
3
|
-
# interaction has an ID, a type and may be successful or not. It is
|
2
|
+
# A simple class representing an interaction with a provider. Each
|
3
|
+
# interaction has an ID, a type and may be successful or not. It is
|
4
4
|
# read-only.
|
5
5
|
class Transaction
|
6
6
|
# Basic attributes
|
7
7
|
attr_reader :provider, :id, :status, :raw
|
8
8
|
|
9
|
-
# Extra set of fields which may or may not be present depending on the
|
9
|
+
# Extra set of fields which may or may not be present depending on the
|
10
10
|
# provider.
|
11
11
|
FIELDS = [:created_at, :updated_at, :amount, :credit_card, :type].freeze
|
12
12
|
attr_reader *FIELDS
|
@@ -37,7 +37,7 @@ module SpookAndPay
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
# As a bare minimum the transaction captures the transaction ID, it's
|
40
|
+
# As a bare minimum the transaction captures the transaction ID, it's
|
41
41
|
# status and the raw response from the provider. Optionally, it can receive
|
42
42
|
# other fields via the opts hash.
|
43
43
|
#
|
@@ -60,7 +60,7 @@ module SpookAndPay
|
|
60
60
|
FIELDS.each {|f| instance_variable_set(:"@#{f}", opts[f]) if opts.has_key?(f)}
|
61
61
|
end
|
62
62
|
|
63
|
-
# Implements value comparison i.e. if class and ID match, they are the
|
63
|
+
# Implements value comparison i.e. if class and ID match, they are the
|
64
64
|
# same.
|
65
65
|
#
|
66
66
|
# @param Class other
|
@@ -127,7 +127,20 @@ module SpookAndPay
|
|
127
127
|
provider.refund_transaction(self)
|
128
128
|
end
|
129
129
|
|
130
|
-
#
|
130
|
+
# Refunds the transaction. The related credit card will be credited for
|
131
|
+
# the amount specified. It will only succeed for purchases or captured
|
132
|
+
# authorizations.
|
133
|
+
#
|
134
|
+
# @param Numeric amount
|
135
|
+
# @return SpookAndPay::Result
|
136
|
+
# @raises SpookAndPay::Transaction::InvalidActionError
|
137
|
+
# @raises SpookAndPay::Providers::Base::NotSupportedError
|
138
|
+
def partial_refund!(amount)
|
139
|
+
raise InvalidActionError.new(id, :partial_refund, status) unless settled?
|
140
|
+
provider.partially_refund_transaction(self, amount)
|
141
|
+
end
|
142
|
+
|
143
|
+
# Captures an authorized transaction. Will only capture the amount
|
131
144
|
# authorized and will fail if the transaction is already captured.
|
132
145
|
#
|
133
146
|
# @return SpookAndPay::Result
|
@@ -138,7 +151,7 @@ module SpookAndPay
|
|
138
151
|
provider.capture_transaction(self)
|
139
152
|
end
|
140
153
|
|
141
|
-
# Voids a transaction. Can only be done when the transaction is in the
|
154
|
+
# Voids a transaction. Can only be done when the transaction is in the
|
142
155
|
# authorized status. Otherwise it must be refunded.
|
143
156
|
#
|
144
157
|
# @return SpookAndPay::Result
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spook_and_pay
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luke Sutton
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2015-11-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: braintree
|
@@ -43,14 +43,14 @@ dependencies:
|
|
43
43
|
name: rack
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- -
|
46
|
+
- - ">="
|
47
47
|
- !ruby/object:Gem::Version
|
48
48
|
version: 1.4.0
|
49
49
|
type: :runtime
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- -
|
53
|
+
- - ">="
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: 1.4.0
|
56
56
|
- !ruby/object:Gem::Dependency
|
@@ -81,20 +81,6 @@ dependencies:
|
|
81
81
|
- - '='
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: 0.11.0
|
84
|
-
- !ruby/object:Gem::Dependency
|
85
|
-
name: debugger
|
86
|
-
requirement: !ruby/object:Gem::Requirement
|
87
|
-
requirements:
|
88
|
-
- - '='
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
version: 1.6.1
|
91
|
-
type: :development
|
92
|
-
prerelease: false
|
93
|
-
version_requirements: !ruby/object:Gem::Requirement
|
94
|
-
requirements:
|
95
|
-
- - '='
|
96
|
-
- !ruby/object:Gem::Version
|
97
|
-
version: 1.6.1
|
98
84
|
description:
|
99
85
|
email:
|
100
86
|
- lukeandben@spookandpuff.com
|
@@ -126,17 +112,17 @@ require_paths:
|
|
126
112
|
- lib
|
127
113
|
required_ruby_version: !ruby/object:Gem::Requirement
|
128
114
|
requirements:
|
129
|
-
- -
|
115
|
+
- - ">="
|
130
116
|
- !ruby/object:Gem::Version
|
131
117
|
version: '0'
|
132
118
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
119
|
requirements:
|
134
|
-
- -
|
120
|
+
- - ">="
|
135
121
|
- !ruby/object:Gem::Version
|
136
|
-
version:
|
122
|
+
version: '0'
|
137
123
|
requirements: []
|
138
124
|
rubyforge_project:
|
139
|
-
rubygems_version: 2.
|
125
|
+
rubygems_version: 2.4.8
|
140
126
|
signing_key:
|
141
127
|
specification_version: 4
|
142
128
|
summary: A library for handling online payments using services providing transparent
|