rack-payment 0.1.0 → 0.1.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/lib/rack-payment.rb
CHANGED
@@ -2,6 +2,7 @@ $LOAD_PATH.unshift File.dirname(__FILE__)
|
|
2
2
|
|
3
3
|
%w( active_merchant rack bigdecimal forwardable ostruct erb ).each {|lib| require lib }
|
4
4
|
|
5
|
+
require 'rack-payment/callable_hash'
|
5
6
|
require 'rack-payment/payment'
|
6
7
|
require 'rack-payment/request'
|
7
8
|
require 'rack-payment/response'
|
@@ -33,6 +33,9 @@ module Rack #:nodoc:
|
|
33
33
|
def address() address1 end
|
34
34
|
def address=(value) self.address1=(value) end
|
35
35
|
|
36
|
+
def full_name() name end
|
37
|
+
def full_name=(value) self.name=(value) end
|
38
|
+
|
36
39
|
# Returns a hash that can be passed to a Gateway#authorize call
|
37
40
|
def active_merchant_hash
|
38
41
|
{
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# A Hash that you can call, like an OpenStruct, but you can still
|
2
|
+
# call [] on it.
|
3
|
+
#
|
4
|
+
# >> hash = CallableHash.new :foo => 'bar'
|
5
|
+
#
|
6
|
+
# >> hash.foo
|
7
|
+
# => 'bar'
|
8
|
+
#
|
9
|
+
# >> hash[:foo]
|
10
|
+
# => 'bar'
|
11
|
+
class CallableHash < Hash
|
12
|
+
|
13
|
+
def initialize hash
|
14
|
+
hash.each {|key, value| self[key] = value }
|
15
|
+
end
|
16
|
+
|
17
|
+
def method_missing name, *args
|
18
|
+
if self[name]
|
19
|
+
self[name]
|
20
|
+
else
|
21
|
+
super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Override type so, if there's a :type or 'type' key in this Hash, we
|
26
|
+
# return that value. Else we return the actual object type.
|
27
|
+
def type
|
28
|
+
return self[:type] if self[:type]
|
29
|
+
return self['type'] if self['type']
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
# Override zip so, if there's a :zip or 'zip' key in this Hash, we
|
34
|
+
# return that value. Else we return the actual object zip.
|
35
|
+
def zip
|
36
|
+
return self[:zip] if self[:zip]
|
37
|
+
return self['zip'] if self['zip']
|
38
|
+
super
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/lib/rack-payment/helper.rb
CHANGED
@@ -175,7 +175,11 @@ module Rack #:nodoc:
|
|
175
175
|
# By default, the form will POST to the current URL (action='')
|
176
176
|
#
|
177
177
|
# You can pass a different URL for the form action
|
178
|
-
def form
|
178
|
+
def form options = nil
|
179
|
+
options ||= {}
|
180
|
+
post_to = (options[:post_to] ||= '') # the url/path to post to
|
181
|
+
auth_token = options[:auth_token] # if not nil, we include the authenticity_token in the form
|
182
|
+
|
179
183
|
view = ::File.dirname(__FILE__) + '/views/credit-card-and-billing-info-form.html.erb'
|
180
184
|
erb = ::File.read view
|
181
185
|
html = ''
|
@@ -218,6 +222,74 @@ module Rack #:nodoc:
|
|
218
222
|
end
|
219
223
|
}.join
|
220
224
|
end
|
225
|
+
|
226
|
+
def credit_card_values
|
227
|
+
%w( first_name last_name number cvv type expiration_month expiration_year ).inject({}) do |all, attribute|
|
228
|
+
all[attribute.to_sym] = credit_card[attribute.to_sym]
|
229
|
+
all
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def billing_address_values
|
234
|
+
%w( name address1 city state zip country ).inject({}) do |all, attribute|
|
235
|
+
all[attribute.to_sym] = billing_address[attribute.to_sym]
|
236
|
+
all
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
# @return Hash of HTML fields with their values set
|
241
|
+
def fields values = nil
|
242
|
+
values ||= {}
|
243
|
+
values[:credit_card] = credit_card_values.merge( values[:credit_card] || {} )
|
244
|
+
values[:billing_address] = billing_address_values.merge( values[:billing_address] || {} )
|
245
|
+
|
246
|
+
CallableHash.new({
|
247
|
+
:credit_card => CallableHash.new({
|
248
|
+
:first_name => input_tag( :credit_card, :first_name, values[:credit_card][:first_name], :autofocus => true),
|
249
|
+
:last_name => input_tag( :credit_card, :last_name, values[:credit_card][:last_name]),
|
250
|
+
:number => input_tag( :credit_card, :number, values[:credit_card][:number], :autocomplete => 'off'),
|
251
|
+
:cvv => input_tag( :credit_card, :cvv, values[:credit_card][:cvv], :autocomplete => 'off'),
|
252
|
+
:type => select_tag( :credit_card, :type, values[:credit_card][:type]),
|
253
|
+
:expiration_month => select_tag( :credit_card, :expiration_month, values[:credit_card][:expiration_month]),
|
254
|
+
:expiration_year => select_tag( :credit_card, :expiration_year, values[:credit_card][:expiration_year])
|
255
|
+
}),
|
256
|
+
|
257
|
+
:billing_address => CallableHash.new({
|
258
|
+
:name => input_tag(:billing_address, :name, values[:billing_address][:name]),
|
259
|
+
:address1 => input_tag(:billing_address, :address1, values[:billing_address][:address1]),
|
260
|
+
:city => input_tag(:billing_address, :city, values[:billing_address][:city]),
|
261
|
+
:state => input_tag(:billing_address, :state, values[:billing_address][:state]),
|
262
|
+
:zip => input_tag(:billing_address, :zip, values[:billing_address][:zip]),
|
263
|
+
:country => input_tag(:billing_address, :country, values[:billing_address][:country])
|
264
|
+
})
|
265
|
+
})
|
266
|
+
end
|
267
|
+
|
268
|
+
def select_tag object, property, value = nil, options = nil
|
269
|
+
attributes = { :type => 'text', :id => "#{object}_#{property}", :name => "#{object}[#{property}]" }
|
270
|
+
attributes.merge!(options) if options
|
271
|
+
|
272
|
+
case property
|
273
|
+
when :type
|
274
|
+
options = options_for_credit_card_type(value)
|
275
|
+
when :expiration_month
|
276
|
+
options = options_for_expiration_month(value)
|
277
|
+
when :expiration_year
|
278
|
+
options = options_for_expiration_year(value)
|
279
|
+
end
|
280
|
+
|
281
|
+
"<select #{ attributes.map {|name, value| "#{name}='#{value}'" }.join(' ') }>#{ options }</select>"
|
282
|
+
end
|
283
|
+
|
284
|
+
# Returns the HTML for an <input /> element
|
285
|
+
# @return String
|
286
|
+
def input_tag object, property, value = nil, options = nil
|
287
|
+
attributes = { :type => 'text', :id => "#{object}_#{property}", :name => "#{object}[#{property}]" }
|
288
|
+
attributes[:value] = value if value.present?
|
289
|
+
attributes.merge!(options) if options
|
290
|
+
|
291
|
+
"<input #{ attributes.map {|name, value| "#{name}='#{value}'" }.join(' ') } />"
|
292
|
+
end
|
221
293
|
end
|
222
294
|
|
223
295
|
end
|
data/lib/rack-payment/request.rb
CHANGED
@@ -183,8 +183,20 @@ module Rack #:nodoc:
|
|
183
183
|
payment.errors = errors
|
184
184
|
new_env = env.clone
|
185
185
|
new_env['REQUEST_METHOD'] = 'GET'
|
186
|
+
|
187
|
+
# Rails keeps track of its own Request/Response.
|
188
|
+
#
|
189
|
+
# If we're using Rails, we need to delete these variables
|
190
|
+
# to trick Rails into thinking that this is a new request.
|
191
|
+
#
|
192
|
+
# Kind of icky!
|
193
|
+
new_env.delete 'action_controller.rescue.request'
|
194
|
+
new_env.delete 'action_controller.rescue.response'
|
195
|
+
|
186
196
|
new_env['PATH_INFO'] = on_success if request.path_info == express_ok_path # if express, we render on_success
|
187
|
-
app.call(new_env)
|
197
|
+
resp = app.call(new_env)
|
198
|
+
puts resp.inspect
|
199
|
+
resp
|
188
200
|
end
|
189
201
|
end
|
190
202
|
|
@@ -203,7 +215,7 @@ module Rack #:nodoc:
|
|
203
215
|
|
204
216
|
def credit_card_and_billing_info_response
|
205
217
|
css_file = ::File.dirname(__FILE__) + '/views/credit-card-and-billing-info-form.css'
|
206
|
-
form_html = payment.form built_in_form_path, :inline_css => ::File.read(css_file)
|
218
|
+
form_html = payment.form :post_to => built_in_form_path, :inline_css => ::File.read(css_file)
|
207
219
|
layout = ::File.dirname(__FILE__) + '/views/layout.html'
|
208
220
|
html = ::File.read(layout)
|
209
221
|
html = html.sub 'CONTENT', form_html
|
@@ -1,6 +1,5 @@
|
|
1
1
|
<%
|
2
|
-
|
3
|
-
# TODO use helper for select options for expiration
|
2
|
+
@fields = fields # so we don't recreate the fields abunchof times
|
4
3
|
%>
|
5
4
|
|
6
5
|
<div class='rack-payment'>
|
@@ -16,37 +15,33 @@
|
|
16
15
|
<% end %>
|
17
16
|
|
18
17
|
<form action='<%= post_to %>' method='post'>
|
19
|
-
|
18
|
+
<% if auth_token %>
|
19
|
+
<input name='authenticity_token' type='hidden' value='<%= auth_token %>' />
|
20
|
+
<% end %>
|
20
21
|
<fieldset>
|
21
22
|
<legend>Credit Card</legend>
|
22
23
|
|
23
24
|
<div class='group'>
|
24
25
|
<label for='credit_card_first_name'>First Name</label>
|
25
|
-
|
26
|
+
<%= @fields.credit_card.first_name %>
|
26
27
|
|
27
28
|
<label for='credit_card_last_name'>Last Name</label>
|
28
|
-
|
29
|
+
<%= @fields.credit_card.last_name %>
|
29
30
|
|
30
31
|
<label for='credit_card_number'>Card Number</label>
|
31
|
-
|
32
|
+
<%= @fields.credit_card.number %>
|
32
33
|
</div>
|
33
34
|
|
34
35
|
<div class='group'>
|
35
36
|
<label for='credit_card_type'>Card Type</label>
|
36
|
-
|
37
|
-
<%= options_for_credit_card_type credit_card.type %>
|
38
|
-
</select>
|
37
|
+
<%= @fields.credit_card.type %>
|
39
38
|
|
40
39
|
<label for='credit_card_cvv'>CVV</label>
|
41
|
-
|
40
|
+
<%= @fields.credit_card.cvv %>
|
42
41
|
|
43
42
|
<label for='credit_card_expiration_month'>Expiration</label>
|
44
|
-
|
45
|
-
|
46
|
-
</select>
|
47
|
-
<select id='credit_card_expiration_year' name='credit_card[expiration_year]'>
|
48
|
-
<%= options_for_expiration_year credit_card.year %>
|
49
|
-
</select>
|
43
|
+
<%= @fields.credit_card.expiration_month %>
|
44
|
+
<%= @fields.credit_card.expiration_year %>
|
50
45
|
|
51
46
|
</div>
|
52
47
|
</fieldset>
|
@@ -56,24 +51,24 @@
|
|
56
51
|
|
57
52
|
<div class='group'>
|
58
53
|
<label for='billing_address_name'>Full Name</label>
|
59
|
-
|
54
|
+
<%= @fields.billing_address.name %>
|
60
55
|
|
61
56
|
<label for='billing_address_address1'>Address</label>
|
62
|
-
|
57
|
+
<%= @fields.billing_address.address1 %>
|
63
58
|
|
64
59
|
<label for='billing_address_city'>City</label>
|
65
|
-
|
60
|
+
<%= @fields.billing_address.city %>
|
66
61
|
</div>
|
67
62
|
|
68
63
|
<div class='group'>
|
69
64
|
<label for='billing_address_state'>State</label>
|
70
|
-
|
65
|
+
<%= @fields.billing_address.state %>
|
71
66
|
|
72
67
|
<label for='billing_address_country'>Country</label>
|
73
|
-
|
68
|
+
<%= @fields.billing_address.country %>
|
74
69
|
|
75
70
|
<label for='billing_address_zip'>Zip</label>
|
76
|
-
|
71
|
+
<%= @fields.billing_address.zip %>
|
77
72
|
</div>
|
78
73
|
</fieldset>
|
79
74
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-payment
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- remi
|
@@ -36,6 +36,7 @@ files:
|
|
36
36
|
- lib/rack-payment/test.rb
|
37
37
|
- lib/rack-payment/payment.rb
|
38
38
|
- lib/rack-payment/response.rb
|
39
|
+
- lib/rack-payment/callable_hash.rb
|
39
40
|
- lib/rack-payment/helper.rb
|
40
41
|
- lib/rack-payment/billing_address.rb
|
41
42
|
- lib/rack-payment/methods.rb
|