samurai 0.2.3 → 0.2.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.
@@ -0,0 +1,86 @@
1
+ <% sandbox ||= false %>
2
+ <% payment_method ||= OpenStruct.new %>
3
+ <form action="<%= Samurai.site %>/payment_methods" method="POST">
4
+ <fieldset>
5
+ <input name="redirect_url" type="hidden" value="<%= redirect_url %>" />
6
+ <input name="merchant_key" type="hidden" value="<%= Samurai.options[:merchant_key] %>" />
7
+ <input name="sandbox" type="hidden" value="<%= sandbox %>" />
8
+ </fieldset>
9
+
10
+ <fieldset>
11
+ <div class="field-group">
12
+ <p>
13
+ <label for="credit_card_first_name">First name</label><br>
14
+ <input id="credit_card_first_name" name="credit_card[first_name]" size="30" type="text" value="<%= payment_method.first_name %>" />
15
+ </p>
16
+ <p>
17
+ <label for="credit_card_last_name">Last name</label><br>
18
+ <input id="credit_card_last_name" name="credit_card[last_name]" size="30" type="text" value="<%= payment_method.last_name %>" />
19
+ </p>
20
+ </div>
21
+
22
+ <p>
23
+ <label for="credit_card_address_1">Address 1</label><br>
24
+ <input class="span-6" id="credit_card_address_1" name="credit_card[address_1]" size="30" type="text" value="<%= payment_method.address_1 %>" />
25
+ </p>
26
+ <p>
27
+ <label for="credit_card_address_2">Address 2</label><br>
28
+ <input class="span-6" id="credit_card_address_2" name="credit_card[address_2]" size="30" type="text" value="<%= payment_method.address_2 %>" />
29
+ </p>
30
+
31
+ <div class="field-group">
32
+ <p>
33
+ <label for="credit_card_city">City</label><br>
34
+ <input id="credit_card_city" name="credit_card[city]" size="30" type="text" value="<%= payment_method.city %>" />
35
+ </p>
36
+ <p>
37
+ <label for="credit_card_state">State</label><br>
38
+ <input class="span-1" id="credit_card_state" name="credit_card[state]" size="30" type="text" value="<%= payment_method.state %>" />
39
+ </p>
40
+ <p>
41
+ <label for="credit_card_zip">Zip</label><br>
42
+ <input class="span-2" id="credit_card_zip" name="credit_card[zip]" size="30" type="text" value="<%= payment_method.zip %>" />
43
+ </p>
44
+ </div>
45
+ </fieldset>
46
+
47
+ <fieldset>
48
+ <div class="field-group">
49
+ <p>
50
+ <label for="credit_card_card_number">Card Number</label><br>
51
+ <input id="credit_card_card_number" name="credit_card[card_number]" size="30" type="text" value="<%= payment_method.card_number %>" />
52
+ </p>
53
+ <p>
54
+ <label for="credit_card_cvv">CVV</label><br>
55
+ <input class="span-1" id="credit_card_cvv" name="credit_card[cvv]" size="30" type="text" value="<%= payment_method.cvv %>" />
56
+ </p>
57
+ <p>
58
+ <label for="credit_card_expiry_month">Expires on</label><br>
59
+ <select id="credit_card_expiry_month" name="credit_card[expiry_month]">
60
+ <option value="1" <%= 'selected' if payment_method.expiry_month.to_s=='1' %>>01</option>
61
+ <option value="2" <%= 'selected' if payment_method.expiry_month.to_s=='2' %>>02</option>
62
+ <option value="3" <%= 'selected' if payment_method.expiry_month.to_s=='3' %>>03</option>
63
+ <option value="4" <%= 'selected' if payment_method.expiry_month.to_s=='4' %>>04</option>
64
+ <option value="5" <%= 'selected' if payment_method.expiry_month.to_s=='5' %>>05</option>
65
+ <option value="6" <%= 'selected' if payment_method.expiry_month.to_s=='6' %>>06</option>
66
+ <option value="7" <%= 'selected' if payment_method.expiry_month.to_s=='7' %>>07</option>
67
+ <option value="8" <%= 'selected' if payment_method.expiry_month.to_s=='8' %>>08</option>
68
+ <option value="9" <%= 'selected' if payment_method.expiry_month.to_s=='9' %>>09</option>
69
+ <option value="10" <%= 'selected' if payment_method.expiry_month.to_s=='10' %>>10</option>
70
+ <option value="11" <%= 'selected' if payment_method.expiry_month.to_s=='11' %>>11</option>
71
+ <option value="12" <%= 'selected' if payment_method.expiry_month.to_s=='12' %>>12</option>
72
+ </select>
73
+ <select id="credit_card_expiry_year" name="credit_card[expiry_year]">
74
+ <option value="2011" <%= 'selected' if payment_method.expiry_year.to_s=='2011' %>>2011</option>
75
+ <option value="2012" <%= 'selected' if payment_method.expiry_year.to_s=='2012' %>>2012</option>
76
+ <option value="2013" <%= 'selected' if payment_method.expiry_year.to_s=='2013' %>>2013</option>
77
+ <option value="2014" <%= 'selected' if payment_method.expiry_year.to_s=='2014' %>>2014</option>
78
+ <option value="2015" <%= 'selected' if payment_method.expiry_year.to_s=='2015' %>>2015</option>
79
+ <option value="2016" <%= 'selected' if payment_method.expiry_year.to_s=='2016' %>>2016</option>
80
+ </select>
81
+ </p>
82
+ </div>
83
+ </fieldset>
84
+
85
+ <button type='submit' class='button blue'>Submit Payment</button>
86
+ </form>
@@ -0,0 +1,36 @@
1
+ <h3><%= transaction.errors.empty? ? 'Successful' : 'Failed' %> <%= transaction.transaction_type.titleize %> Transaction</h3>
2
+ <h4>Reference ID: <%= transaction.reference_id %></h4>
3
+
4
+ <% if transaction.errors.any? %>
5
+ <div id="error_explanation">
6
+ <h4>This transaction could not be processed:</h4>
7
+ <ul>
8
+ <% transaction.errors.full_messages.each do |msg| %>
9
+ <li><%= msg %></li>
10
+ <% end %>
11
+ </ul>
12
+ </div>
13
+ <% end %>
14
+
15
+ <p>
16
+ <strong>Amount:</strong>
17
+ <%= transaction.amount %> (<%= transaction.currency_code %>)
18
+ </p>
19
+
20
+ <p>
21
+ <strong>Credit Card:</strong>
22
+ <em>XXXX XXXX XXXX</em> <%= transaction.payment_method.last_four_digits %>
23
+ (<%= "%02d" % transaction.payment_method.expiry_month %> / <%= "%04d" % transaction.payment_method.expiry_year %>)
24
+ </p>
25
+
26
+ <p><strong>Date / Time:</strong> <%= transaction.created_at %></p>
27
+ <p>
28
+ <strong>Descriptor:</strong> <%= transaction.descriptor %><br>
29
+ <strong>Billing Reference:</strong> <%= transaction.billing_reference %><br>
30
+ <strong>Customer Reference: </strong> <%= transaction.customer_reference %><br>
31
+ <strong>Custom Data: </strong> <%= transaction.custom %><br>
32
+ </p>
33
+
34
+ <p>
35
+ <strong>AVS Response:</strong> <%= transaction.processor_response.avs_result_code || 'None' %>
36
+ </p>
@@ -0,0 +1,46 @@
1
+ <% authenticity_token ||= '' %>
2
+ <% transaction ||= OpenStruct.new %>
3
+ <form accept-charset="UTF-8" action="<%= post_url %>" class="new_transaction" id="new_transaction" method="post">
4
+ <%= authenticity_token %>
5
+ <input id="processor_token" name="processor_token" type="hidden" value="<%= processor_token %>"/>
6
+ <input id="payment_method_token" name="payment_method_token" type="hidden" value="<%= payment_method.payment_method_token %>"/>
7
+ <input id="transaction_custom" name="transaction[custom]" type="hidden" value="" />
8
+
9
+ <p>
10
+ <label for="transaction_type">Transaction type</label><br/>
11
+ <select id="transaction_type" name="transaction_type">
12
+ <option value="purchase">Purchase</option>
13
+ <option value="authorize">Authorize Only</option>
14
+ </select>
15
+ </p>
16
+
17
+ <div class="field-group">
18
+ <p>
19
+ <label for="amount">Amount</label><br/>
20
+ <input id="amount" name="amount" size="30" type="text" value="<%= transaction.amount %>"/>
21
+ </p>
22
+ <p>
23
+ <label for="transaction_currency_code">Currency code</label><br/>
24
+ <input class="span-1" id="transaction_currency_code" name="transaction[currency_code]" size="30" type="text" value="<%= transaction.currency_code %>"/>
25
+ </p>
26
+ </div>
27
+
28
+ <div class="field-group">
29
+ <p>
30
+ <label for="transaction_billing_reference">Billing Reference</label><br/>
31
+ <input id="transaction_billing_reference" name="transaction[billing_reference]" size="30" type="text" value="<%= transaction.billing_reference %>"/>
32
+ </p>
33
+ <p>
34
+ <label for="transaction_customer_reference">Customer Reference</label><br/>
35
+ <input id="transaction_customer_reference" name="transaction[customer_reference]" size="30" type="text" value="<%= transaction.customer_reference %>"/>
36
+ </p>
37
+ </div>
38
+ <p>
39
+ <label for="transaction_descriptor">Description</label><br/>
40
+ <input id="transaction_descriptor" name="transaction[descriptor]" size="30" type="text" value="<%= transaction.descriptor %>"/>
41
+ </p>
42
+
43
+ <p>
44
+ <input class="button red" name="commit" type="submit" value="Submit Transaction"/>
45
+ </p>
46
+ </form>
data/lib/samurai/base.rb CHANGED
@@ -10,5 +10,15 @@ class Samurai::Base < ActiveResource::Base
10
10
  self.user = Samurai.merchant_key
11
11
  self.password = Samurai.merchant_password
12
12
  end
13
-
13
+
14
+ protected
15
+
16
+ def load_attributes_from_response(response)
17
+ super.tap { |instance| instance.process_response_errors }
18
+ end
19
+
20
+ def process_response_errors
21
+ # Do nothing by default, subclasses may override this to process specific error messages
22
+ end
23
+
14
24
  end
@@ -26,4 +26,14 @@ class Samurai::PaymentMethod < Samurai::Base
26
26
  def custom_json_data
27
27
  @custom_data ||= self.custom && (JSON.parse(self.custom) rescue {}).symbolize_keys
28
28
  end
29
+
30
+
31
+ require 'pathname'
32
+ def self.form_html
33
+ File.read(form_partial_path)
34
+ end
35
+ def self.form_partial_path
36
+ Pathname.new(__FILE__).dirname.join('..', '..', 'app', 'views', 'application', '_payment_method_form.html.erb')
37
+ end
38
+
29
39
  end
@@ -0,0 +1,8 @@
1
+ class Samurai::ProcessorResponse < Samurai::Base
2
+
3
+ def avs_result_code
4
+ avs_result_code_message = self.messages.find {|m| m.context=='processor.avs_result_code' || m.context=='gateway.avs_result_code' }
5
+ avs_result_code_message && avs_result_code_message.key
6
+ end
7
+
8
+ end
@@ -26,7 +26,7 @@ class Samurai::Transaction < Samurai::Base
26
26
  def credit(amount = nil, options = {})
27
27
  execute(:credit, {:amount => amount || self.amount}.reverse_merge(options))
28
28
  end
29
-
29
+
30
30
  private
31
31
 
32
32
  def execute(action, options = {})
@@ -34,7 +34,18 @@ class Samurai::Transaction < Samurai::Base
34
34
  # return the response, wrapped in a Samurai::Transaction
35
35
  Samurai::Transaction.new.load_attributes_from_response(resp)
36
36
  end
37
-
37
+
38
+ def process_response_errors
39
+ if self.processor_response && self.processor_response.messages
40
+ self.processor_response.messages.each do |message|
41
+ if message.subclass == 'error'
42
+ self.errors.add message.context.gsub(/\./, ' '), message.key
43
+ end
44
+ end
45
+ end
46
+ end
47
+ protected :process_response_errors
48
+
38
49
  # Builds an xml payload that represents the transaction data to submit to samurai.feefighters.com
39
50
  def self.transaction_payload(options = {})
40
51
  {
@@ -50,5 +61,19 @@ class Samurai::Transaction < Samurai::Base
50
61
  reject{ |k,v| v.nil? }.
51
62
  to_xml(:skip_instruct => true, :root => 'transaction', :dasherize => false)
52
63
  end
53
-
64
+
65
+ require 'pathname'
66
+ def self.form_html
67
+ File.read(form_partial_path)
68
+ end
69
+ def self.form_partial_path
70
+ Pathname.new(__FILE__).dirname.join('..', '..', 'app', 'views', 'application', '_transaction_form.html.erb')
71
+ end
72
+ def self.show_html
73
+ File.read(show_partial_path)
74
+ end
75
+ def self.show_partial_path
76
+ Pathname.new(__FILE__).dirname.join('..', '..', 'app', 'views', 'application', '_transaction.html.erb')
77
+ end
78
+
54
79
  end
@@ -1,3 +1,3 @@
1
1
  module Samurai
2
- VERSION = "0.2.3".freeze
2
+ VERSION = "0.2.4".freeze
3
3
  end
data/lib/samurai.rb CHANGED
@@ -39,3 +39,4 @@ require 'samurai/processor'
39
39
  require 'samurai/payment_method'
40
40
  require 'samurai/transaction'
41
41
  require 'samurai/message'
42
+ require 'samurai/processor_response'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: samurai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,12 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-08-04 00:00:00.000000000 -05:00
14
- default_executable:
13
+ date: 2011-08-09 00:00:00.000000000Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: activeresource
18
- requirement: &70154627048120 !ruby/object:Gem::Requirement
17
+ requirement: &70158124256520 !ruby/object:Gem::Requirement
19
18
  none: false
20
19
  requirements:
21
20
  - - ! '>='
@@ -23,10 +22,10 @@ dependencies:
23
22
  version: 2.2.2
24
23
  type: :runtime
25
24
  prerelease: false
26
- version_requirements: *70154627048120
25
+ version_requirements: *70158124256520
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: bundler
29
- requirement: &70154627047660 !ruby/object:Gem::Requirement
28
+ requirement: &70158124256060 !ruby/object:Gem::Requirement
30
29
  none: false
31
30
  requirements:
32
31
  - - ! '>='
@@ -34,10 +33,10 @@ dependencies:
34
33
  version: 1.0.0
35
34
  type: :development
36
35
  prerelease: false
37
- version_requirements: *70154627047660
36
+ version_requirements: *70158124256060
38
37
  - !ruby/object:Gem::Dependency
39
38
  name: rspec
40
- requirement: &70154627047200 !ruby/object:Gem::Requirement
39
+ requirement: &70158124255600 !ruby/object:Gem::Requirement
41
40
  none: false
42
41
  requirements:
43
42
  - - ! '>='
@@ -45,10 +44,10 @@ dependencies:
45
44
  version: 2.6.0
46
45
  type: :development
47
46
  prerelease: false
48
- version_requirements: *70154627047200
47
+ version_requirements: *70158124255600
49
48
  - !ruby/object:Gem::Dependency
50
49
  name: fakeweb
51
- requirement: &70154627046820 !ruby/object:Gem::Requirement
50
+ requirement: &70158124255220 !ruby/object:Gem::Requirement
52
51
  none: false
53
52
  requirements:
54
53
  - - ! '>='
@@ -56,10 +55,10 @@ dependencies:
56
55
  version: '0'
57
56
  type: :development
58
57
  prerelease: false
59
- version_requirements: *70154627046820
58
+ version_requirements: *70158124255220
60
59
  - !ruby/object:Gem::Dependency
61
60
  name: ruby-debug19
62
- requirement: &70154627046320 !ruby/object:Gem::Requirement
61
+ requirement: &70158124254720 !ruby/object:Gem::Requirement
63
62
  none: false
64
63
  requirements:
65
64
  - - ! '>='
@@ -67,7 +66,7 @@ dependencies:
67
66
  version: '0'
68
67
  type: :development
69
68
  prerelease: false
70
- version_requirements: *70154627046320
69
+ version_requirements: *70158124254720
71
70
  description: If you are an online merchant and using samurai.feefighters.com, this
72
71
  gem will make your life easy. Integrate with the samurai.feefighters.com portal
73
72
  and process transaction.
@@ -84,12 +83,16 @@ files:
84
83
  - Gemfile.lock
85
84
  - README.markdown
86
85
  - Rakefile
86
+ - app/views/application/_payment_method_form.html.erb
87
+ - app/views/application/_transaction.html.erb
88
+ - app/views/application/_transaction_form.html.erb
87
89
  - lib/samurai.rb
88
90
  - lib/samurai/base.rb
89
91
  - lib/samurai/cacheable_by_token.rb
90
92
  - lib/samurai/message.rb
91
93
  - lib/samurai/payment_method.rb
92
94
  - lib/samurai/processor.rb
95
+ - lib/samurai/processor_response.rb
93
96
  - lib/samurai/transaction.rb
94
97
  - lib/samurai/version.rb
95
98
  - samurai.gemspec
@@ -97,7 +100,6 @@ files:
97
100
  - test/spec/processor_spec.rb
98
101
  - test/spec/purchase_spec.rb
99
102
  - test/spec_helper.rb
100
- has_rdoc: true
101
103
  homepage: http://rubygems.org/gems/samurai
102
104
  licenses: []
103
105
  post_install_message:
@@ -118,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
120
  version: 1.3.5
119
121
  requirements: []
120
122
  rubyforge_project:
121
- rubygems_version: 1.6.2
123
+ rubygems_version: 1.8.7
122
124
  signing_key:
123
125
  specification_version: 3
124
126
  summary: Integration gem for samurai.feefighters.com