spook_and_pay 0.2.6.alpha → 0.2.7.alpha

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5b1ff796137c7a459d6b8757e56e8c9ea52b76e3
4
- data.tar.gz: 8b3dc5f18685220533a8718177c945f0ba7eaa76
3
+ metadata.gz: 0bd84aa5f8a08e720cb7eb6140911be472d923ee
4
+ data.tar.gz: c9345a68d16c46d723812c9934f561c3ce5513ec
5
5
  SHA512:
6
- metadata.gz: 168c68ae8c2a3fe771938fe39dc87d06134d83494ec9e863a0a2e0f91d795b2f6d3f15f57833c3277df9f2b1e7705a1182b7bf22b3858c94611def2482f33c8c
7
- data.tar.gz: bdf338598dcc6f21327bad76f9c87b91e6b28dd9c7e288ae5ddaca8dfe8133580177935b0265b4fdf55b5d6abf34b0657142b748c681c5dcff6296b5774c4c46
6
+ metadata.gz: 045d465056dce7c1025c4c04b7dca6e4f504b2203c86f3ea52b86f40ede6b919db556c312fe25b5477e47304846eb48e294ee94c9e3edaecec46354ea0d48106
7
+ data.tar.gz: 7b9e0f4368ce879baf32b3a20f4b41ba1d1f3164ae3a44f69d83ffb7c0b6ab4a8835281da3aa67c9a80171a8f8a70dc7144a7d0473baf327c851b2286c3ac5c1
@@ -6,6 +6,14 @@ 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
10
+ # invalid details or has expired.
11
+ class InvalidCardError < StandardError
12
+ def to_s
13
+ "The action cannot be performed, this card is invalid or expired."
14
+ end
15
+ end
16
+
9
17
  # The basic attributes of the credit card.
10
18
  attr_reader :provider, :id, :raw
11
19
 
@@ -60,12 +68,58 @@ module SpookAndPay
60
68
  end
61
69
  end
62
70
 
71
+ # Checks to see if funds can be credited to a card. Depends on the
72
+ # gateway/provider supporting crediting and having a valid card.
73
+ #
74
+ # @return [true, false]
75
+ def can_credit?
76
+ provider.supports_credit? and valid? and !expired?
77
+ end
78
+
79
+ # Checks to see if this card can be authorized against the specified
80
+ # gateway.
81
+ #
82
+ # @return [true, false]
83
+ def can_authorize?
84
+ provider.supports_authorize? and valid? and !expired?
85
+ end
86
+
87
+ # Checks to see if this card can be used for a purchase against the
88
+ # underlying gateway.
89
+ #
90
+ # @return [true, false]
91
+ def can_purchase?
92
+ provider.supports_purchase? and valid? and !expired?
93
+ end
94
+
95
+ # Checks to see if the provider/gateway supports the deletion of credit
96
+ # card details.
97
+ #
98
+ # @return [true, false]
99
+ def can_delete?
100
+ provider.supports_delete?
101
+ end
102
+
103
+ # Credits the specified amount to the card.
104
+ #
105
+ # @param [String, Numeric] amount
106
+ # @return SpookAndPay::Result
107
+ # @raises SpookAndPay::Providers::Base::NotSupportedError
108
+ # @raises SpookAndPay::CreditCard::InvalidCardError
109
+ def credit!(amount)
110
+ verify_action
111
+ provider.credit_via_credit_card(self, amount)
112
+ end
113
+
63
114
  # Authorizes a payment of the specified amount. This generates a new
64
115
  # transaction that must be later settled.
65
116
  #
66
117
  # @param [String, Numeric] amount
67
118
  # @return SpookAndPay::Result
119
+ # @raises SpookAndPay::Providers::Base::NotSupportedError
120
+ # @raises SpookAndPay::CreditCard::InvalidCardError
68
121
  def authorize!(amount)
122
+ verify_action
69
123
  provider.authorize_via_credit_card(self, amount)
70
124
  end
71
125
 
@@ -73,13 +127,17 @@ module SpookAndPay
73
127
  #
74
128
  # @param [String, Numeric] amount
75
129
  # @return SpookAndPay::Result
130
+ # @raises SpookAndPay::Providers::Base::NotSupportedError
131
+ # @raises SpookAndPay::CreditCard::InvalidCardError
76
132
  def purchase!(amount)
133
+ verify_action
77
134
  provider.purchase_via_credit_card(self, amount)
78
135
  end
79
136
 
80
137
  # Deletes the credit card from the provider's vault.
81
138
  #
82
- # @return [true, false]
139
+ # @return SpookAndPay::Result
140
+ # @raises SpookAndPay::Providers::Base::NotSupportedError
83
141
  def delete!
84
142
  provider.delete_credit_card(self)
85
143
  end
@@ -98,5 +156,17 @@ module SpookAndPay
98
156
  def expired?
99
157
  expired
100
158
  end
159
+
160
+ private
161
+
162
+
163
+ # A helper method which validates any actions — authorize, credit etc. —
164
+ # and where the card is expired or has invalid details, raises an error.
165
+ #
166
+ # @return nil
167
+ # @raises SpookAndPay::CreditCard::InvalidCardError
168
+ def verify_action
169
+ raise InvalidCardError if expired? or !valid?
170
+ end
101
171
  end
102
172
  end
@@ -118,7 +118,7 @@ module SpookAndPay
118
118
  # @param [SpookAndPay::Transaction, String] id
119
119
  # @return SpookAndPay::Result
120
120
  def capture_transaction(id)
121
- raise NotImplementedError
121
+ check_support('capture')
122
122
  end
123
123
 
124
124
  # Refunds the amount of money captured in a transaction.
@@ -129,7 +129,16 @@ module SpookAndPay
129
129
  # @param [SpookAndPay::Transaction, String] id
130
130
  # @return SpookAndPay::Result
131
131
  def refund_transaction(id)
132
- raise NotImplementedError
132
+ check_support('refund')
133
+ end
134
+
135
+ # Checks to see if purchasing is supported. This is dependent on the payment
136
+ # provider. The default implementation simply returns true. Specific
137
+ # implementations should over-ride this method.
138
+ #
139
+ # @return [true, false]
140
+ def supports_purchase?
141
+ true
133
142
  end
134
143
 
135
144
  # Checks to see if voiding is supported. This is dependent on the payment
@@ -141,6 +150,51 @@ module SpookAndPay
141
150
  true
142
151
  end
143
152
 
153
+ # Checks to see if crediting is supported. This is dependent on the payment
154
+ # provider. The default implementation simply returns true. Specific
155
+ # implementations should over-ride this method.
156
+ #
157
+ # @return [true, false]
158
+ def supports_credit?
159
+ true
160
+ end
161
+
162
+ # Checks to see if refunding is supported. This is dependent on the payment
163
+ # provider. The default implementation simply returns true. Specific
164
+ # implementations should over-ride this method.
165
+ #
166
+ # @return [true, false]
167
+ def supports_refund?
168
+ true
169
+ end
170
+
171
+ # Checks to see if capturing is supported. This is dependent on the payment
172
+ # provider. The default implementation simply returns true. Specific
173
+ # implementations should over-ride this method.
174
+ #
175
+ # @return [true, false]
176
+ def supports_capture?
177
+ true
178
+ end
179
+
180
+ # Checks to see if authorizing is supported. This is dependent on the payment
181
+ # provider. The default implementation simply returns true. Specific
182
+ # implementations should over-ride this method.
183
+ #
184
+ # @return [true, false]
185
+ def supports_authorize?
186
+ true
187
+ end
188
+
189
+ # Checks to see if the deletion of payment details is supported. This is
190
+ # dependent on the payment provider. The default implementation simply
191
+ # returns true. Specific implementations should over-ride this method.
192
+ #
193
+ # @return [true, false]
194
+ def supports_delete?
195
+ true
196
+ end
197
+
144
198
  # Voids an authorization.
145
199
  #
146
200
  # This should not be called directly. Instead, use the #void! method
@@ -151,7 +205,7 @@ module SpookAndPay
151
205
  # @api private
152
206
  # @abstract Subclass to implement
153
207
  def void_transaction(id)
154
- raise NotImplementedError
208
+ check_support('void')
155
209
  end
156
210
 
157
211
  # Authorizes a payment against a credit card
@@ -165,7 +219,21 @@ module SpookAndPay
165
219
  # @api private
166
220
  # @abstract Subclass to implement
167
221
  def authorize_via_credit_card(id, amount)
168
- raise NotImplementedError
222
+ check_support('authorize')
223
+ end
224
+
225
+ # Credits funds to a credit card
226
+ #
227
+ # This should not be called directly. Instead, use the #authorize! method
228
+ # provided by a CreditCard instance.
229
+ #
230
+ # @param [SpookAndPay::CreditCard, String] id
231
+ # @param [String, Numeric] amount in dollars
232
+ # @return SpookAndPay::Result
233
+ # @api private
234
+ # @abstract Subclass to implement
235
+ def credit_via_credit_card(id, amount)
236
+ check_support('credit')
169
237
  end
170
238
 
171
239
  # Creates a purchase against a credit card.
@@ -179,7 +247,7 @@ module SpookAndPay
179
247
  # @api private
180
248
  # @abstract Subclass to implement
181
249
  def purchase_via_credit_card(id, amount)
182
- raise NotImplementedError
250
+ check_support('purchase')
183
251
  end
184
252
 
185
253
  # Removes payment details from the provider's vault.
@@ -192,11 +260,32 @@ module SpookAndPay
192
260
  # @api private
193
261
  # @abstract Subclass to implement
194
262
  def delete_credit_card(id)
195
- raise NotImplementedError
263
+ check_support('delete')
196
264
  end
197
265
 
198
266
  private
199
267
 
268
+ # Checks to see if a particular action is defined as being supported and
269
+ # raises the appropriate error.
270
+ #
271
+ # The basic semantics is this; if someone implementing a provider says an
272
+ # action is supported via a #supports_*? predicate, this method should
273
+ # never be called, so we raise NotImplementedError. Otherwise they are
274
+ # saying it's not supported and the appropriate response is to raise a
275
+ # NotSupportedError.
276
+ #
277
+ # @param String action
278
+ # @return nil
279
+ # @raises NotSupportedError
280
+ # @raises NotImplementedError
281
+ def check_support(action)
282
+ if send(:"supports_#{action}?")
283
+ raise NotImplementedError
284
+ else
285
+ raise NotSupportedError
286
+ end
287
+ end
288
+
200
289
  # Extracts the credit card id from it's argument. This is is to help with
201
290
  # methods that accept either a card instance of an id.
202
291
  #
@@ -49,11 +49,17 @@ module SpookAndPay
49
49
  # @param Hash opts
50
50
  # @return Hash
51
51
  def prepare_payment_submission(redirect_url, opts = {})
52
- {
52
+ config = {
53
53
  :url => spreedly.transparent_redirect_form_action,
54
54
  :field_names => self.class::FORM_FIELD_NAMES,
55
55
  :hidden_fields => {:redirect_url => redirect_url, :environment_key => spreedly.key}
56
56
  }
57
+
58
+ if opts[:token]
59
+ config[:hidden_fields][:payment_method_token] = opts[:token]
60
+ end
61
+
62
+ config
57
63
  end
58
64
 
59
65
  # Confirms the submission of payment details to Spreedly Core.
@@ -115,10 +121,30 @@ module SpookAndPay
115
121
  # spreedly gem, check it.
116
122
  ::Spreedly::Gateway.send(:field, :characteristics)
117
123
 
124
+ def supports_purchase?
125
+ check_support_for('supports_purchase')
126
+ end
127
+
118
128
  def supports_void?
119
- gateway = spreedly.find_gateway(gateway_token)
120
- node = Nokogiri::XML::DocumentFragment.parse(gateway.characteristics)
121
- node.xpath(".//supports_void").inner_html.strip == 'true'
129
+ check_support_for('supports_void')
130
+ end
131
+
132
+ def supports_credit?
133
+ false
134
+ end
135
+
136
+ def supports_capture?
137
+ check_support_for('supports_capture')
138
+ end
139
+
140
+ def supports_authorize?
141
+ check_support_for('supports_authorize')
142
+ end
143
+
144
+ def supports_delete?
145
+ # This does not check the gateway, since the redaction is specific to
146
+ # Spreedly's store, not the gateway.
147
+ true
122
148
  end
123
149
 
124
150
  def authorize_via_credit_card(id, amount)
@@ -138,6 +164,18 @@ module SpookAndPay
138
164
 
139
165
  private
140
166
 
167
+ # Retrieves the gateway from Spreedly and then inspects the response to
168
+ # see what features it supports. This is a helper for the #supports_*?
169
+ # predicates.
170
+ #
171
+ # @param String path
172
+ # @return [true, false]
173
+ def check_support_for(path)
174
+ gateway = spreedly.find_gateway(gateway_token)
175
+ node = Nokogiri::XML::DocumentFragment.parse(gateway.characteristics)
176
+ node.xpath(".//#{path}").inner_html.strip == 'true'
177
+ end
178
+
141
179
  # Takes the result of running a transaction against a Spreedly gateway
142
180
  # and coerces it into a SpookAndPay::Result
143
181
  #
@@ -96,7 +96,7 @@ module SpookAndPay
96
96
  #
97
97
  # @return [true, false]
98
98
  def can_refund?
99
- status == :settled
99
+ settled? and provider.supports_refund?
100
100
  end
101
101
 
102
102
  # A predicate for checking if a transaction can be captured. Only true if
@@ -104,7 +104,7 @@ module SpookAndPay
104
104
  #
105
105
  # @return [true, false]
106
106
  def can_capture?
107
- status == :authorized
107
+ authorized? and provider.supports_capture?
108
108
  end
109
109
 
110
110
  # A predicate for checking if a transaction can be voided. Only true if
@@ -112,7 +112,7 @@ module SpookAndPay
112
112
  #
113
113
  # @return [true, false]
114
114
  def can_void?
115
- (status == :authorized or status == :settling) and provider.supports_void?
115
+ (authorized? or settling?) and provider.supports_void?
116
116
  end
117
117
 
118
118
  # Refunds the transaction. The related credit card will be credited for
@@ -120,9 +120,10 @@ module SpookAndPay
120
120
  # authorizations.
121
121
  #
122
122
  # @return SpookAndPay::Result
123
- # @raises InvalidActionError
123
+ # @raises SpookAndPay::Transaction::InvalidActionError
124
+ # @raises SpookAndPay::Providers::Base::NotSupportedError
124
125
  def refund!
125
- raise InvalidActionError.new(id, :refund, status) unless can_refund?
126
+ raise InvalidActionError.new(id, :refund, status) unless settled?
126
127
  provider.refund_transaction(self)
127
128
  end
128
129
 
@@ -130,9 +131,10 @@ module SpookAndPay
130
131
  # authorized and will fail if the transaction is already captured.
131
132
  #
132
133
  # @return SpookAndPay::Result
133
- # @raises InvalidActionError
134
+ # @raises SpookAndPay::Transaction::InvalidActionError
135
+ # @raises SpookAndPay::Providers::Base::NotSupportedError
134
136
  def capture!
135
- raise InvalidActionError.new(id, :capture, status) unless can_capture?
137
+ raise InvalidActionError.new(id, :capture, status) unless authorized?
136
138
  provider.capture_transaction(self)
137
139
  end
138
140
 
@@ -140,9 +142,10 @@ module SpookAndPay
140
142
  # authorized status. Otherwise it must be refunded.
141
143
  #
142
144
  # @return SpookAndPay::Result
143
- # @raises InvalidActionError
145
+ # @raises SpookAndPay::Transaction::InvalidActionError
146
+ # @raises SpookAndPay::Providers::Base::NotSupportedError
144
147
  def void!
145
- raise InvalidActionError.new(id, :void, status) unless can_void?
148
+ raise InvalidActionError.new(id, :void, status) unless authorized? or settling?
146
149
  provider.void_transaction(self)
147
150
  end
148
151
  end
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.2.6.alpha
4
+ version: 0.2.7.alpha
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: 2013-12-03 00:00:00.000000000 Z
12
+ date: 2014-01-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: braintree