nimbleshop_stripe 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/README.md +35 -0
  2. data/app/assets/images/nimbleshop_stripe/american_express.png +0 -0
  3. data/app/assets/images/nimbleshop_stripe/discover.png +0 -0
  4. data/app/assets/images/nimbleshop_stripe/mastercard.png +0 -0
  5. data/app/assets/images/nimbleshop_stripe/stripe.png +0 -0
  6. data/app/assets/images/nimbleshop_stripe/visa.png +0 -0
  7. data/app/controllers/nimbleshop_stripe/payments_controller.rb +38 -0
  8. data/app/controllers/nimbleshop_stripe/stripes_controller.rb +50 -0
  9. data/app/helpers/nimbleshop_stripe/exposed_helper.rb +26 -0
  10. data/app/models/nimbleshop_stripe/stripe.rb +31 -0
  11. data/app/views/nimbleshop_stripe/payments/_new.html.erb +118 -0
  12. data/app/views/nimbleshop_stripe/payments/_order_show_extra_info.html.erb +4 -0
  13. data/app/views/nimbleshop_stripe/payments/_payment_info_for_buyer.html.erb +6 -0
  14. data/app/views/nimbleshop_stripe/payments/_stripe_instructions.html.erb +47 -0
  15. data/app/views/nimbleshop_stripe/payments/_what_is_cvv.html.erb +25 -0
  16. data/app/views/nimbleshop_stripe/stripes/_edit.html.erb +31 -0
  17. data/app/views/nimbleshop_stripe/stripes/_form.html.erb +68 -0
  18. data/config/routes.rb +4 -0
  19. data/lib/nimbleshop_stripe/engine.rb +17 -0
  20. data/lib/nimbleshop_stripe/gateway.rb +9 -0
  21. data/lib/nimbleshop_stripe/processor.rb +134 -0
  22. data/lib/nimbleshop_stripe/util.rb +32 -0
  23. data/lib/nimbleshop_stripe.rb +8 -0
  24. data/lib/tasks/nimbleshop_stripe_tasks.rake +31 -0
  25. data/test/test_helper.rb +32 -0
  26. data/test/unit/payment_method_test.rb +21 -0
  27. data/test/unit/processor_test.rb +241 -0
  28. data/test/vcr_cassettes/authorize_net/authorize-failure.yml +38 -0
  29. data/test/vcr_cassettes/authorize_net/authorize-success.yml +38 -0
  30. data/test/vcr_cassettes/authorize_net/capture-failure.yml +38 -0
  31. data/test/vcr_cassettes/authorize_net/capture-success.yml +38 -0
  32. data/test/vcr_cassettes/authorize_net/purchase-failure.yml +38 -0
  33. data/test/vcr_cassettes/authorize_net/purchase-success.yml +38 -0
  34. data/test/vcr_cassettes/authorize_net/refund-failure.yml +38 -0
  35. data/test/vcr_cassettes/authorize_net/refund-success.yml +38 -0
  36. data/test/vcr_cassettes/authorize_net/void-authorize.yml +38 -0
  37. data/test/vcr_cassettes/authorize_net/void-failure.yml +38 -0
  38. data/test/vcr_cassettes/authorize_net/void-success.yml +38 -0
  39. metadata +120 -0
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # nimbleshop_authorizedotnet extension
2
+
3
+ This is stripe extension for [nimbleShop](http://www.nimbleShop.org) .
4
+
5
+ # Dependencies
6
+
7
+ This gem relies on a model called `PaymentMethod` and this model should
8
+ have a column called `metadata` of type `text`. Given below is an
9
+ example that would work
10
+
11
+ ```
12
+ class CreatePaymentMethods < ActiveRecord::Migration
13
+ def change
14
+ create_table :payment_methods do |t|
15
+ t.string :name
16
+ t.text :description
17
+ t.string :type
18
+ t.string :permalink, null: false
19
+ t.text :metadata
20
+
21
+ t.timestamps
22
+ end
23
+ add_index :payment_methods, :permalink, unique: true
24
+ end
25
+ end
26
+ ```
27
+
28
+
29
+ # Documentation
30
+
31
+ Documentation is available at [http://nimbleshop.org/authorizedotnet.html](http://nimbleshop.org/authorizedotnet.html) .
32
+
33
+ # License
34
+
35
+ This gem uses [MIT license](http://www.opensource.org/licenses/mit-license.php) .
@@ -0,0 +1,38 @@
1
+ module NimbleshopStripe
2
+
3
+ class PaymentsController < ::ActionController::Base
4
+
5
+ def create
6
+ order = Order.find_by_id!(session[:order_id])
7
+ token = params[:stripeToken]
8
+
9
+ address_attrs = order.final_billing_address.to_credit_card_attributes
10
+ creditcard_attrs = params[:creditcard].merge(address_attrs)
11
+ creditcard = Creditcard.new(creditcard_attrs)
12
+ creditcard.perform_validations = false
13
+
14
+ payment_method = NimbleshopStripe::Stripe.first
15
+ processor = NimbleshopStripe::Processor.new({order: order, payment_method: payment_method})
16
+
17
+ default_action = Shop.current.default_creditcard_action
18
+
19
+ if processor.send(default_action, token: token)
20
+ url = nimbleshop_simply.order_path(order)
21
+ @output = "window.location='#{url}'"
22
+ else
23
+ error = processor.errors.first
24
+ Rails.logger.info "Error: #{error}"
25
+ @output = "alert('#{error}')"
26
+ end
27
+
28
+ respond_to do |format|
29
+ format.js do
30
+ render js: @output
31
+ end
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -0,0 +1,50 @@
1
+ module NimbleshopStripe
2
+
3
+ # this line makes it possible to use this gem without nimbleshop_core
4
+ klass = defined?(::Admin::PaymentMethodsController) ? ::Admin::PaymentMethodsController : ActionController::Base
5
+
6
+ class StripesController < klass
7
+
8
+ before_filter :load_payment_method
9
+
10
+ def update
11
+ respond_to do |format|
12
+ if @payment_method.update_attributes(post_params[:stripe])
13
+ format.js {
14
+ flash[:notice] = 'Stripe record was successfully updated'
15
+ render js: "window.location = '/admin/payment_methods'"
16
+ }
17
+ else
18
+ msg = @payment_method.errors.full_messages.first
19
+ error = %Q[alert("#{msg}")]
20
+ format.js { render js: error }
21
+ end
22
+ end
23
+ end
24
+
25
+ def destroy
26
+ respond_to do |format|
27
+ if @payment_method.destroy
28
+ format.js {
29
+ flash[:notice] = 'Stripe record was successfully deleted'
30
+ render js: "window.location = '/admin/payment_methods'"
31
+ }
32
+ else
33
+ format.js { render js: 'Stripe record could not be deleted. Please try again later.' }
34
+ end
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def post_params
41
+ params.permit(stripe: [:mode, :ssl, :publishable_key, :secret_key, :business_name])
42
+ end
43
+
44
+ def load_payment_method
45
+ @payment_method = NimbleshopStripe::Stripe.first
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,26 @@
1
+ module NimbleshopStripe
2
+ module ExposedHelper
3
+
4
+ def nimbleshop_stripe_crud_form
5
+ return unless NimbleshopStripe::Stripe.first
6
+ render partial: '/nimbleshop_stripe/stripes/edit'
7
+ end
8
+
9
+ def nimbleshop_stripe_picture_on_admin_payment_methods
10
+ image_tag 'engines/nimbleshop_stripe/stripe.png', alt: 'stripe logo'
11
+ end
12
+
13
+ def nimbleshop_stripe_payment_form(order)
14
+ return unless NimbleshopStripe::Stripe.first
15
+ render partial: '/nimbleshop_stripe/payments/new', locals: { order: order }
16
+ end
17
+
18
+ def nimbleshop_stripe_icon_for_order_payment(order)
19
+ if payment_transaction = order.payment_transactions.last
20
+ cardtype = payment_transaction.metadata[:cardtype]
21
+ image_tag("engines/nimbleshop_stripe/#{cardtype}.png", height: '10px')
22
+ end
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,31 @@
1
+ module NimbleshopStripe
2
+ class Stripe < PaymentMethod
3
+
4
+ store_accessor :metadata, :publishable_key, :secret_key, :business_name, :mode, :ssl
5
+
6
+ before_save :set_mode, :set_ssl
7
+
8
+ validates_presence_of :publishable_key, :business_name, :secret_key
9
+
10
+ def use_ssl?
11
+ self.ssl == 'enabled'
12
+ end
13
+
14
+ def kapture!(order)
15
+ processor = NimbleshopAuthorizedotnet::Processor.new(order)
16
+ processor.kapture
17
+ order.kapture!
18
+ end
19
+
20
+ private
21
+
22
+ def set_mode
23
+ self.mode ||= 'test'
24
+ end
25
+
26
+ def set_ssl
27
+ self.ssl ||= 'disabled'
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,118 @@
1
+ <br />
2
+
3
+ <p>
4
+ <label class='radio'>
5
+ <%= radio_button_tag 'payment_choice', 'authorize-net', true %>
6
+ <label for='payment_choice'>
7
+ <%= image_tag('engines/nimbleshop_authorizedotnet/visa.png') %>
8
+ <%= image_tag('engines/nimbleshop_authorizedotnet/mastercard.png') %>
9
+ <%= image_tag('engines/nimbleshop_authorizedotnet/american_express.png') %>
10
+ <%= image_tag('engines/nimbleshop_authorizedotnet/discover.png') %>
11
+ </label>
12
+ </label>
13
+ </p>
14
+
15
+ <%= form_for @creditcard, url: nimbleshop_stripe.payment_path(format: :js), remote: true, html: { id: 'stripe-payment-form', class: 'form-horizontal' } do |f| %>
16
+ <div class='nimbleshop_stripe_umbrella'>
17
+ <% if @creditcard.errors.any? %>
18
+ <div class="alert alert-error">
19
+ <ul>
20
+ <% @creditcard.errors.full_messages.each do |msg| %>
21
+ <li><%= msg %></li>
22
+ <% end %>
23
+ </ul>
24
+ </div>
25
+ <% end %>
26
+
27
+ <fieldset>
28
+ <div class='control-group'>
29
+ <div class='controls'>
30
+ <input autocomplete="off" class="input-xlarge focus" id="creditcard_number" placeholder="Credit card number" size="30" type="text">
31
+ <% unless (NimbleshopStripe::Stripe.first.mode == 'production') %>
32
+ &nbsp;
33
+ <%= link_to 'Valid number', '#stripe-sandboxhelp', 'data-toggle' => "modal" %>
34
+ <% end %>
35
+ </div>
36
+ </div>
37
+
38
+ <div class='control-group'>
39
+ <div class='controls'>
40
+ <input autocomplete="off" id="creditcard_cvv" placeholder="CVV" size="30" type="text">
41
+ &nbsp;
42
+ <%= link_to 'What is this?', '#cvvhelp', 'data-toggle' => "modal" %>
43
+ </div>
44
+ </div>
45
+
46
+ <div class='control-group'>
47
+ <p style='padding-left:160px;'>
48
+ Expiration date
49
+ </p>
50
+ <div class='controls'>
51
+ <%= f.date_select :expires_on, discard_day: true, start_year: Date.today.year,
52
+ end_year: (Date.today.year + 10),
53
+ add_month_numbers: true,
54
+ order: [:day, :month, :year] %>
55
+ </div>
56
+ </div>
57
+ </fieldset>
58
+ </div>
59
+
60
+ <div class="form-actions">
61
+ <%= f.submit 'Submit', class: 'btn btn-primary', 'data-behavior' => 'stripe-submit-button' %>
62
+ </div>
63
+
64
+ <%= render '/nimbleshop_stripe/payments/stripe_instructions' %>
65
+ <%= render '/nimbleshop_stripe/payments/what_is_cvv' %>
66
+ <% end %>
67
+
68
+ <style>
69
+ #creditcard_expires_on_2i{
70
+ width: 130px;
71
+ }
72
+ #creditcard_expires_on_1i {
73
+ width: 100px;
74
+ }
75
+ </style>
76
+
77
+ <script type="text/javascript" src="https://js.stripe.com/v1/"></script>
78
+ <script type="text/javascript"> Stripe.setPublishableKey('<%=NimbleshopStripe::Stripe.first.publishable_key%>'); </script>
79
+ <script>
80
+ $(document).ready(function(){
81
+ $('#stripe-payment-form').submit(function(event){
82
+ $('[data-behavior~=stripe-submit-button]').attr('value', 'processing ...').attr('disabled', 'disabled');
83
+
84
+ var $this = $(this);
85
+
86
+ function stripeResponseHandler(status, response) {
87
+ if (response.error) {
88
+ $('[data-behavior~=stripe-submit-button]').attr('value', 'Submit').removeAttr('disabled');
89
+ alert(response.error.message);
90
+ } else {
91
+ var $form = $("#stripe-payment-form");
92
+ // token contains id, last4, and card type
93
+ var token = response['id'];
94
+ // insert the token into the form so it gets submitted to the server
95
+ $form.append("<input type='hidden' name='stripeToken' value='" + token + "'/>");
96
+
97
+ $.ajax({
98
+ type: 'POST',
99
+ url: $this.attr('action'),
100
+ data: $this.serializeArray()
101
+ });
102
+
103
+
104
+ }
105
+ }
106
+
107
+ Stripe.createToken({
108
+ number: $('#creditcard_number').val(),
109
+ cvc: $('#creditcard_cvv').val(),
110
+ exp_month: $('#creditcard_expires_on_2i').val(),
111
+ exp_year: $('#creditcard_expires_on_1i').val()
112
+ }, stripeResponseHandler);
113
+
114
+ // prevent the form from submitting with the default action
115
+ return false;
116
+ });
117
+ });
118
+ </script>
@@ -0,0 +1,4 @@
1
+ <tr>
2
+ <td> <%= transaction.created_at.to_s(:long) %> </td>
3
+ <td> <%= transaction.operation.titleize %> <%= number_to_currency((transaction.amount || 0) / 100) %> </td>
4
+ </tr>
@@ -0,0 +1,6 @@
1
+ <li>
2
+ Your credit card was charged <strong><%= number_to_currency(order.total_amount) %> </strong> .
3
+ </li>
4
+ <li>
5
+ In the credit card statement name of the company would appear as <strong><%= order.payment_method.business_name %></strong> .
6
+ </li>
@@ -0,0 +1,47 @@
1
+ <style>
2
+ #stripe-sandboxhelp li {
3
+ margin-top: 2px;
4
+ margin-bottom: 2px;
5
+ }
6
+ </style>
7
+
8
+ <% if !Rails.env.production? && NimbleshopStripe::Stripe.first %>
9
+ <div id='stripe-sandboxhelp' class='modal hide fade'>
10
+
11
+ <div class='modal-header'>
12
+ <%= link_to 'x', '#', class: 'close', 'data-dismiss' => 'modal' %>
13
+ <h3>Valid credit card numbers in Stripe Test mode</h3>
14
+ </div>
15
+ <div class="modal-body">
16
+ <p> The application is running Stripe in <strong>Test</strong> mode. You cannot make real payment. Here are the valid credit card numbers in test mode. </p>
17
+
18
+ <ul>
19
+ <li> Visa: 4242424242424242 </li>
20
+ <li> Visa: 4012888888881881 </li>
21
+ <li> Mastercard: 5555555555554444 </li>
22
+ <li> Mastercard: 5105105105105100 </li>
23
+ <li> American Express: 378282246310005 </li>
24
+ <li> American Express: 371449635398431 </li>
25
+ <li> Discover: 6011111111111117 </li>
26
+ <li> Discover: 6011000990139424 </li>
27
+ <li> JCB: 3530111333300000 </li>
28
+ <li> JCB: 3566002020360505 </li>
29
+ <li> Diners Club: 30569309025904 </li>
30
+ <li> Diners Club: 38520000023237 </li>
31
+ </ul>
32
+ <br />
33
+ <ul>
34
+ <li> Expiration date must be set to the present day or later. </li>
35
+ <li> Security code for American express must be any 4 digits. For all others use any 3 digits. </li>
36
+ </ul>
37
+ </div>
38
+ <div class="modal-footer">
39
+ <p>
40
+ <%= link_to 'More information', '' %> .
41
+ <small>
42
+ This message never appears when Stripe is running in live mode .
43
+ </small>
44
+ </p>
45
+ </div>
46
+ </div>
47
+ <% end %>
@@ -0,0 +1,25 @@
1
+ <div id='cvvhelp' class="modal hide fade" >
2
+ <div class='modal-header'>
3
+ <%= link_to 'x', '#', class: 'close', 'data-dismiss' => 'modal' %>
4
+ <h3>What is CVV ?</h3>
5
+ </div>
6
+ <div class="modal-body">
7
+ <p>
8
+ The <strong>CVV Number</strong>
9
+ stands for "<strong>C</strong>ard <strong>V</strong>erification <strong>V</strong>alue" .
10
+ It is a 3 digit number for VISA, MasterCard and Discover cards.
11
+ It is a 4 digit number for American Express credit cards.
12
+ </p>
13
+
14
+ <div class="modal_images">
15
+ <div class="modal_cvv_image">
16
+ <h4>For Visa, MasterCard and Discover credit cards</h4>
17
+ <%= image_tag 'https://www.paypalobjects.com/en_US/i/demo/cv_card.gif' %>
18
+ </div>
19
+ <div class="modal_cvv_image">
20
+ <h4>For American Express credit cards</h4>
21
+ <%= image_tag 'https://www.paypalobjects.com/en_US/i/demo/cv_amex_card.gif' %>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ </div>
@@ -0,0 +1,31 @@
1
+ <div class='payment-method-engine-well'>
2
+
3
+ <div>
4
+ <h2>Stripe</h2>
5
+ <div class="edit_link">
6
+ <%= link_to 'Edit', '#', class: 'nimbleshop-payment-method-edit', id: 'nimbleshop-stripe-payment-method-edit' %>
7
+ <%= link_to nimbleshop_stripe.stripe_path, class: 'nimbleshop-payment-method-delete',
8
+ confirm: 'Do you really want to delete Stripe payment method', method: :delete, remote: true do %>
9
+ <i class='icon-remove icon-white'></i>
10
+ <% end %>
11
+ </div>
12
+
13
+ <%= nimbleshop_stripe_picture_on_admin_payment_methods %>
14
+
15
+ <div class='clear'></div>
16
+ </div>
17
+
18
+ <%= render partial: '/nimbleshop_stripe/stripes/form' %>
19
+ </div>
20
+
21
+ <script>
22
+ $(function(){
23
+
24
+ $('#nimbleshop-stripe-payment-method-edit').toggle(function(){
25
+ $('#nimbleshop-stripe-form-well').show();
26
+ }, function(){
27
+ $('#nimbleshop-stripe-form-well').hide();
28
+ });
29
+
30
+ })
31
+ </script>
@@ -0,0 +1,68 @@
1
+ <div class='well nimbleshop-payment-method-form-well' id='nimbleshop-stripe-form-well' style='display:none;'>
2
+
3
+ <%= form_for NimbleshopStripe::Stripe.first, url: '/nimbleshop_stripe/stripe',
4
+ remote: true,
5
+ html: { method: 'put',
6
+ id: 'nimbleshop-stripe-form',
7
+ class: 'nimbleshop-payment-method-form form-horizontal'} do |f| %>
8
+
9
+ <fieldset>
10
+ <div class='control-group'>
11
+ <%= f.label :publishable_key, nil, class: 'control-label' %>
12
+ <div class='controls'>
13
+ <%= f.text_field :publishable_key, class: 'span6' %>
14
+ </div>
15
+ </div>
16
+
17
+ <div class='control-group'>
18
+ <%= f.label :secret_key, nil, class: 'control-label' %>
19
+ <div class='controls'>
20
+ <%= f.text_field :secret_key, class: 'span6' %>
21
+ </div>
22
+ </div>
23
+
24
+ <div class='control-group'>
25
+ <%= f.label :business_name, nil, class: 'control-label' %>
26
+ <%= link_to '?', '#', 'data-content' => 'Please enter the name of the company as it would appear in the credit card statement. If are not sure what name would appear in the credit card statements then consult your merchant account provider.',
27
+ 'data-original-title' => 'Business name' %>
28
+ <div class='controls'>
29
+ <%= f.text_field :business_name, class: 'span6' %>
30
+ </div>
31
+ </div>
32
+
33
+ <div class='control-group'>
34
+ <div class='controls'>
35
+ <label class='checkbox'>
36
+ <%= f.check_box :mode, {}, 'test', 'production' %> Enable test mode
37
+ <%= link_to '?', '#', class: 'help', 'data-content' => 'In the test mode real credit card numbers are not accepted.',
38
+ 'data-original-title' => 'Test mode' %>
39
+ </label>
40
+ </div>
41
+ </div>
42
+
43
+ <div class='control-group'>
44
+ <div class='controls'>
45
+ <label class='checkbox'>
46
+ <%= f.check_box :ssl, {}, 'enabled', 'disabled' %> Enable SSL requirement
47
+ <%= link_to '?', '#', class: 'help', 'data-content' => 'Enabling SSL requirement will force the payment page to be on SSL.',
48
+ 'data-original-title' => 'SSL requirement' %>
49
+ </label>
50
+ </div>
51
+ </div>
52
+
53
+ </fieldset>
54
+
55
+ <div class='form-actions'>
56
+ <%= f.submit('Submit', class: 'btn btn-primary') %>
57
+ &nbsp;
58
+ <%= link_to t(:cancel), nimbleshop_stripe.stripe_path, class: 'cancel btn' %>
59
+ </div>
60
+ <% end %>
61
+
62
+ </div>
63
+
64
+ <style>
65
+ .control-group a.help {
66
+ float: none;
67
+ }
68
+ </style>
data/config/routes.rb ADDED
@@ -0,0 +1,4 @@
1
+ NimbleshopStripe::Engine.routes.draw do
2
+ resource :stripe
3
+ resource :payment
4
+ end
@@ -0,0 +1,17 @@
1
+ module NimbleshopStripe
2
+ class Engine < ::Rails::Engine
3
+
4
+ isolate_namespace NimbleshopStripe
5
+
6
+ config.to_prepare do
7
+ ::NimbleshopStripe::Stripe
8
+ end
9
+
10
+ initializer 'nimbleshop_stripe.action_controller' do |app|
11
+ ActiveSupport.on_load :action_controller do
12
+ helper NimbleshopStripe::ExposedHelper
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ module NimbleshopStripe
2
+ module Gateway
3
+ def self.instance(payment_method)
4
+ ActiveMerchant::Billing::Gateway.logger = Rails.logger if payment_method.mode.to_s == 'test'
5
+
6
+ ActiveMerchant::Billing::StripeGateway.new( login: payment_method.secret_key )
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,134 @@
1
+ module NimbleshopStripe
2
+ class Processor < Processor::Base
3
+
4
+ attr_reader :order, :payment_method, :errors, :gateway
5
+
6
+ def initialize(options)
7
+ @errors = []
8
+ @order = options.fetch(:order)
9
+ @payment_method = options.fetch(:payment_method)
10
+ @gateway = ::NimbleshopStripe::Gateway.instance(payment_method)
11
+ ::Stripe.api_key = payment_method.secret_key
12
+ end
13
+
14
+ private
15
+
16
+ def set_active_merchant_mode # :nodoc:
17
+ ActiveMerchant::Billing::Base.mode = payment_method.mode.to_sym
18
+ end
19
+
20
+ def do_authorize(options = {})
21
+ #Stripe does not support authorize operation
22
+ do_purchase(options)
23
+ end
24
+
25
+ # Creates purchase for the order amount.
26
+ #
27
+ # === Options
28
+ #
29
+ # * <tt>:token</tt> -- token to be charged. This is a required field.
30
+ #
31
+ # This method returns false if purchase fails. Error messages are in <tt>errors</tt> array.
32
+ # If purchase succeeds then <tt>order.purchase</tt> is invoked.
33
+ #
34
+ def do_purchase(options = {})
35
+ options.symbolize_keys!
36
+ options.assert_valid_keys(:token)
37
+
38
+ token = options[:token]
39
+
40
+ response = gateway.purchase(order.total_amount_in_cents, token)
41
+ token_response = ::Stripe::Token.retrieve(token)
42
+
43
+ record_transaction(response, 'purchased',
44
+ fingerprint: token_response.card.fingerprint,
45
+ livemode: token_response.livemode,
46
+ card_number: "XXXX-XXXX-XXXX-#{token_response.card.last4}",
47
+ cardtype: token_response.card.type.downcase,
48
+ transaction_gid: token_response.id)
49
+
50
+ if response.success?
51
+ order.update_attributes(payment_method: payment_method)
52
+ order.purchase!
53
+ else
54
+ Rails.logger.info response.params['error']['message']
55
+ @errors << 'Credit card was declined. Please try again!'
56
+ return false
57
+ end
58
+ end
59
+
60
+ # Voids the previously authorized transaction.
61
+ #
62
+ # === Options
63
+ #
64
+ # * <tt>:transaction_gid</tt> -- transaction_gid is the transaction id returned by the gateway. This is a required field.
65
+ #
66
+ # This method returns false if void fails. Error messages are in <tt>errors</tt> array.
67
+ # If void succeeds then <tt>order.void</tt> is invoked.
68
+ #
69
+ def do_void(options = {})
70
+ options.symbolize_keys!
71
+ options.assert_valid_keys(:transaction_gid)
72
+ transaction_gid = options[:transaction_gid]
73
+
74
+ response = gateway.void(transaction_gid, {})
75
+ record_transaction(response, 'voided')
76
+
77
+ if response.success?
78
+ order.void
79
+ else
80
+ @errors << "Void operation failed"
81
+ false
82
+ end
83
+ end
84
+
85
+ # Refunds the given transaction.
86
+ #
87
+ # === Options
88
+ #
89
+ # * <tt>:transaction_gid</tt> -- transaction_gid is the transaction id returned by the gateway. This is a required field.
90
+ #
91
+ # This method returns false if refund fails. Error messages are in <tt>errors</tt> array.
92
+ # If refund succeeds then <tt>order.refund</tt> is invoked.
93
+ #
94
+ def do_refund(options = {})
95
+ options.symbolize_keys!
96
+ options.assert_valid_keys(:transaction_gid, :card_number)
97
+
98
+ transaction_gid = options[:transaction_gid]
99
+ card_number = options[:card_number]
100
+
101
+ response = gateway.refund(order.total_amount_in_cents, transaction_gid, card_number: card_number)
102
+ record_transaction(response, 'refunded')
103
+
104
+ if response.success?
105
+ order.refund
106
+ else
107
+ @errors << "Refund failed"
108
+ false
109
+ end
110
+
111
+ end
112
+
113
+ def record_transaction(response, operation, additional_options = {}) # :nodoc:
114
+ transaction_gid = additional_options.fetch(:transaction_gid)
115
+
116
+ options = { operation: 'capture',
117
+ params: response.params,
118
+ success: true,
119
+ metadata: additional_options,
120
+ transaction_gid: transaction_gid }
121
+
122
+ if response.success?
123
+ options.update(amount: order.total_amount_in_cents)
124
+ end
125
+
126
+ order.payment_transactions.create(options)
127
+ end
128
+
129
+ def valid_card?(creditcard) # :nodoc:
130
+ true
131
+ end
132
+
133
+ end
134
+ end