spree_gateway 2.0.0 → 2.0.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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +14 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +22 -0
  5. data/Gemfile +14 -0
  6. data/LICENSE +26 -0
  7. data/README.md +68 -0
  8. data/Rakefile +14 -0
  9. data/Versionfile +12 -0
  10. data/app/controllers/spree/checkout_controller_decorator.rb +51 -0
  11. data/app/controllers/spree/skrill_status_controller.rb +39 -0
  12. data/app/models/spree/billing_integration/skrill/quick_checkout.rb +52 -0
  13. data/app/models/spree/gateway/authorize_net.rb +18 -0
  14. data/app/models/spree/gateway/authorize_net_cim.rb +134 -0
  15. data/app/models/spree/gateway/balanced_gateway.rb +68 -0
  16. data/app/models/spree/gateway/banwire.rb +16 -0
  17. data/app/models/spree/gateway/beanstream.rb +195 -0
  18. data/app/models/spree/gateway/braintree_gateway.rb +143 -0
  19. data/app/models/spree/gateway/card_save.rb +12 -0
  20. data/app/models/spree/gateway/data_cash.rb +12 -0
  21. data/app/models/spree/gateway/eway.rb +22 -0
  22. data/app/models/spree/gateway/fatzebra.rb +17 -0
  23. data/app/models/spree/gateway/klarna.rb +0 -0
  24. data/app/models/spree/gateway/linkpoint.rb +30 -0
  25. data/app/models/spree/gateway/moneris.rb +13 -0
  26. data/app/models/spree/gateway/pay_junction.rb +18 -0
  27. data/app/models/spree/gateway/pay_pal_gateway.rb +14 -0
  28. data/app/models/spree/gateway/payflow_pro.rb +19 -0
  29. data/app/models/spree/gateway/paymill.rb +15 -0
  30. data/app/models/spree/gateway/pin_gateway.rb +18 -0
  31. data/app/models/spree/gateway/sage_pay.rb +13 -0
  32. data/app/models/spree/gateway/samurai.rb +65 -0
  33. data/app/models/spree/gateway/secure_pay_au.rb +10 -0
  34. data/app/models/spree/gateway/stripe_gateway.rb +94 -0
  35. data/app/models/spree/gateway/usa_epay.rb +11 -0
  36. data/app/models/spree/gateway/worldpay.rb +96 -0
  37. data/app/models/spree/payment_decorator.rb +3 -0
  38. data/app/models/spree/skrill_transaction.rb +21 -0
  39. data/app/views/spree/admin/payments/source_forms/_quickcheckout.html.erb +8 -0
  40. data/app/views/spree/admin/payments/source_views/_quickcheckout.html.erb +39 -0
  41. data/app/views/spree/checkout/payment/_quickcheckout.html.erb +26 -0
  42. data/config/locales/bg.yml +11 -0
  43. data/config/locales/de.yml +11 -0
  44. data/config/locales/en.yml +11 -0
  45. data/config/locales/sv.yml +11 -0
  46. data/config/routes.rb +13 -0
  47. data/db/migrate/20111118164631_create_skrill_transactions.rb +14 -0
  48. data/db/migrate/20121017004102_update_braintree_payment_method_type.rb +9 -0
  49. data/db/migrate/20130213222555_update_stripe_payment_method_type.rb +9 -0
  50. data/db/migrate/20130415222802_update_balanced_payment_method_type.rb +9 -0
  51. data/db/migrate/20131008221012_update_paypal_payment_method_type.rb +9 -0
  52. data/lib/active_merchant/billing/skrill.rb +18 -0
  53. data/lib/generators/spree_gateway/install/install_generator.rb +28 -0
  54. data/lib/spree_gateway.rb +3 -0
  55. data/lib/spree_gateway/engine.rb +41 -0
  56. data/script/rails +5 -0
  57. data/spec/factories/payment_method_factory.rb +4 -0
  58. data/spec/models/gateway/authorize_net_cim_spec.rb +17 -0
  59. data/spec/models/gateway/authorize_net_spec.rb +17 -0
  60. data/spec/models/gateway/balanced_gateway_spec.rb +9 -0
  61. data/spec/models/gateway/banwire_spec.rb +9 -0
  62. data/spec/models/gateway/braintree_gateway_spec.rb +284 -0
  63. data/spec/models/gateway/eway_spec.rb +17 -0
  64. data/spec/models/gateway/fatzebra_spec.rb +47 -0
  65. data/spec/models/gateway/linkpoint_spec.rb +60 -0
  66. data/spec/models/gateway/pay_junction_spec.rb +17 -0
  67. data/spec/models/gateway/payflow_pro_spec.rb +17 -0
  68. data/spec/models/gateway/pin_gateway_spec.rb +57 -0
  69. data/spec/models/gateway/stripe_gateway_spec.rb +122 -0
  70. data/spec/models/gateway/usa_epay_spec.rb +38 -0
  71. data/spec/spec_helper.rb +34 -0
  72. data/spree_gateway.gemspec +26 -0
  73. metadata +91 -5
@@ -0,0 +1,3 @@
1
+ Spree::Payment.class_eval do
2
+ attr_accessible :source, :payment_method
3
+ end
@@ -0,0 +1,21 @@
1
+ module Spree
2
+ class SkrillTransaction < ActiveRecord::Base
3
+ has_many :payments, :as => :source
4
+
5
+ attr_accessible :email , :amount , :currency , :transaction_id , :customer_id, :payment_type
6
+
7
+ def actions
8
+ []
9
+ end
10
+
11
+ def self.create_from_postback(params)
12
+ SkrillTransaction.create(:email => params[:pay_from_email],
13
+ :amount => params[:mb_amount],
14
+ :currency => params[:mb_currency],
15
+ :transaction_id => params[:mb_transaction_id],
16
+ :customer_id => params[:customer_id],
17
+ :payment_type => params[:payment_type])
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,8 @@
1
+ <% content_for :head do %>
2
+ <script type="text/javascript">
3
+ jQuery(document).ready(function(){
4
+ $("label:contains('<%= payment_method.name %>')").hide();
5
+ $("label:contains('<%= payment_method.name %>') input").disable();
6
+ });
7
+ </script>
8
+ <% end %>
@@ -0,0 +1,39 @@
1
+ <fieldset>
2
+ <legend><%= Spree.t(:skrill) %></legend>
3
+
4
+ <table class="index">
5
+ <tr>
6
+ <th colspan="6"><%= Spree.t(:skrill_transaction) %></th>
7
+ </tr>
8
+ <tr>
9
+ <td><label><%= Spree.t(:email) %>:</label></td>
10
+ <td>
11
+ <%= payment.source.email %>
12
+ </td>
13
+ </tr>
14
+ <tr>
15
+ <td><label><%= Spree.t(:skrill_customer_id) %>:</label></td>
16
+ <td>
17
+ <%= payment.source.customer_id %>
18
+ </td>
19
+ </tr>
20
+ <tr>
21
+ <td><label><%= Spree.t(:skrill_transaction_id) %>:</label></td>
22
+ <td>
23
+ <%= payment.source.transaction_id %>
24
+ </td>
25
+ </tr>
26
+ <tr>
27
+ <td><label><%= Spree.t(:skrill_payment_type) %>:</label></td>
28
+ <td>
29
+ <%= payment.source.payment_type %>
30
+ </td>
31
+ </tr>
32
+ <tr>
33
+ <td><label><%= Spree.t(:skrill_payment_currency) %>:</label></td>
34
+ <td>
35
+ <%= payment.source.currency %>
36
+ </td>
37
+ </tr>
38
+ </table>
39
+ </fieldset>
@@ -0,0 +1,26 @@
1
+ <p data-hook="skrill_quick_checkout"></p>
2
+
3
+ <%
4
+ opts = {}
5
+ opts[:transaction_id] = "#{@order.number}"
6
+ opts[:amount] = @order.total
7
+ opts[:return_url] = skrill_return_order_checkout_url(@order, :token => @order.token,
8
+ :payment_method_id => payment_method.id)
9
+ opts[:cancel_url] = skrill_cancel_order_checkout_url(@order, :token => @order.token)
10
+ opts[:status_url] = skrill_status_update_url
11
+ opts[:payment_method_id] = payment_method.id
12
+ %>
13
+
14
+ <style>
15
+ iframe.skrill_frame{
16
+ border: 0px;
17
+ width: 500px;
18
+ height: 500px;
19
+ }
20
+ </style>
21
+
22
+ <fieldset id="skrill_payment__<%= payment_method.id %>" data-hook>
23
+ <legend><%= Spree.t(:payment_information) %></legend>
24
+ <iframe id="skrill_frame_<%= payment_method.id %>"
25
+ class="skrill_frame" src="<%= payment_method.redirect_url @order, opts %>"></iframe>
26
+ </fieldset>
@@ -0,0 +1,11 @@
1
+ ---
2
+ bg:
3
+ spree:
4
+ payment_has_been_cancelled: Плащането беше прекъснато.
5
+ complete_skrill_checkout: Моля довършете Вашето плащане със Skrill преди да продължите
6
+ skrill: Skrill
7
+ skrill_transaction: Транзакция
8
+ skrill_customer_id: Клиентски номер
9
+ skrill_transaction_id: Номер на транкцията
10
+ skrill_payment_type: Вид на плащане
11
+ skrill_payment_currency: Валута
@@ -0,0 +1,11 @@
1
+ ---
2
+ de:
3
+ spree:
4
+ payment_has_been_cancelled: Die Zahlung wurde abgebrochen.
5
+ complete_skrill_checkout: Bitte schliessen Sie die Skrill-Zahlung ab
6
+ skrill: Skrill
7
+ skrill_transaction: Transaktion
8
+ skrill_customer_id: Kunden ID
9
+ skrill_transaction_id: Transaktions ID
10
+ skrill_payment_type: Bezahlart
11
+ skrill_payment_currency: Währung
@@ -0,0 +1,11 @@
1
+ ---
2
+ en:
3
+ spree:
4
+ payment_has_been_cancelled: The payment has been cancelled.
5
+ complete_skrill_checkout: Please complete Skrill checkout before continuing
6
+ skrill: Skrill
7
+ skrill_transaction: Transaction
8
+ skrill_customer_id: Customer ID
9
+ skrill_transaction_id: Transaction ID
10
+ skrill_payment_type: Payment Type
11
+ skrill_payment_currency: Payment Currency
@@ -0,0 +1,11 @@
1
+ ---
2
+ sv:
3
+ spree:
4
+ payment_has_been_cancelled: Betalningen har avbrutits.
5
+ complete_skrill_checkout: Var god fyll i Skrill kassan innan du fortsätter
6
+ skrill: Skrill
7
+ skrill_transaction: Transaktion
8
+ skrill_customer_id: Kund ID
9
+ skrill_transaction_id: Transaktion ID
10
+ skrill_payment_type: Betalningstyp
11
+ skrill_payment_currency: Betalningsvaluta
data/config/routes.rb ADDED
@@ -0,0 +1,13 @@
1
+ Spree::Core::Engine.routes.draw do
2
+ # Add your extension routes here
3
+ resources :orders do
4
+ resource :checkout, :controller => 'checkout' do
5
+ member do
6
+ get :skrill_cancel
7
+ get :skrill_return
8
+ end
9
+ end
10
+ end
11
+
12
+ match '/skrill' => 'skrill_status#update', :via => :post, :as => :skrill_status_update
13
+ end
@@ -0,0 +1,14 @@
1
+ class CreateSkrillTransactions < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_skrill_transactions do |t|
4
+ t.string :email
5
+ t.float :amount
6
+ t.string :currency
7
+ t.integer :transaction_id
8
+ t.integer :customer_id
9
+ t.string :payment_type
10
+ t.timestamps
11
+ end
12
+ end
13
+ end
14
+
@@ -0,0 +1,9 @@
1
+ class UpdateBraintreePaymentMethodType < ActiveRecord::Migration
2
+ def up
3
+ Spree::PaymentMethod.where(:type => "Spree::Gateway::Braintree").update_all(:type => "Spree::Gateway::BraintreeGateway")
4
+ end
5
+
6
+ def down
7
+ Spree::PaymentMethod.where(:type => "Spree::Gateway::BraintreeGateway").update_all(:type => "Spree::Gateway::Braintree")
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class UpdateStripePaymentMethodType < ActiveRecord::Migration
2
+ def up
3
+ Spree::PaymentMethod.where(:type => "Spree::Gateway::Stripe").update_all(:type => "Spree::Gateway::StripeGateway")
4
+ end
5
+
6
+ def down
7
+ Spree::PaymentMethod.where(:type => "Spree::Gateway::StripeGateway").update_all(:type => "Spree::Gateway::Stripe")
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class UpdateBalancedPaymentMethodType < ActiveRecord::Migration
2
+ def up
3
+ Spree::PaymentMethod.where(:type => "Spree::Gateway::Balanced").update_all(:type => "Spree::Gateway::BalancedGateway")
4
+ end
5
+
6
+ def down
7
+ Spree::PaymentMethod.where(:type => "Spree::Gateway::BalancedGateway").update_all(:type => "Spree::Gateway::Balanced")
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class UpdatePaypalPaymentMethodType < ActiveRecord::Migration
2
+ def up
3
+ Spree::PaymentMethod.where(:type => "Spree::Gateway::PayPal").update_all(:type => "Spree::Gateway::PayPalGateway")
4
+ end
5
+
6
+ def down
7
+ Spree::PaymentMethod.where(:type => "Spree::Gateway::PayPalGateway").update_all(:type => "Spree::Gateway::PayPal")
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class Skrill < Gateway
4
+
5
+ def service_url
6
+ "https://www.moneybookers.com/app/payment.pl"
7
+ end
8
+
9
+ def payment_url(opts)
10
+ post = PostData.new
11
+ post.merge! opts
12
+
13
+ "#{service_url}?#{post.to_s}"
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,28 @@
1
+ module SpreeGateway
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ class_option :auto_run_migrations, type: :boolean, default: false
5
+
6
+ def add_migrations
7
+ run 'bundle exec rake railties:install:migrations FROM=spree_gateway'
8
+ end
9
+
10
+ def run_migrations
11
+ if running_migrations?
12
+ run 'bundle exec rake db:migrate'
13
+ else
14
+ puts "Skiping rake db:migrate, don't forget to run it!"
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def running_migrations?
21
+ options.auto_run_migrations? || begin
22
+ response = ask 'Would you like to run the migrations now? [Y/n]'
23
+ ['', 'y'].include? response.downcase
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ require 'spree_core'
2
+ require 'spree_gateway/engine'
3
+ require 'savon'
@@ -0,0 +1,41 @@
1
+ module SpreeGateway
2
+ class Engine < Rails::Engine
3
+ engine_name 'spree_gateway'
4
+
5
+ config.autoload_paths += %W(#{config.root}/lib)
6
+
7
+ # use rspec for tests
8
+ config.generators do |g|
9
+ g.test_framework :rspec
10
+ end
11
+
12
+ initializer "spree.gateway.payment_methods", :after => "spree.register.payment_methods" do |app|
13
+ app.config.spree.payment_methods << Spree::Gateway::AuthorizeNetCim
14
+ app.config.spree.payment_methods << Spree::Gateway::AuthorizeNet
15
+ app.config.spree.payment_methods << Spree::Gateway::CardSave
16
+ app.config.spree.payment_methods << Spree::Gateway::Eway
17
+ app.config.spree.payment_methods << Spree::Gateway::Fatzebra
18
+ app.config.spree.payment_methods << Spree::Gateway::Linkpoint
19
+ app.config.spree.payment_methods << Spree::Gateway::Moneris
20
+ app.config.spree.payment_methods << Spree::Gateway::PayJunction
21
+ app.config.spree.payment_methods << Spree::Gateway::PayPalGateway
22
+ app.config.spree.payment_methods << Spree::Gateway::SagePay
23
+ app.config.spree.payment_methods << Spree::Gateway::Beanstream
24
+ app.config.spree.payment_methods << Spree::Gateway::BraintreeGateway
25
+ app.config.spree.payment_methods << Spree::Gateway::StripeGateway
26
+ app.config.spree.payment_methods << Spree::Gateway::Samurai
27
+ app.config.spree.payment_methods << Spree::Gateway::Worldpay
28
+ app.config.spree.payment_methods << Spree::Gateway::Banwire
29
+ app.config.spree.payment_methods << Spree::Gateway::UsaEpay
30
+ app.config.spree.payment_methods << Spree::BillingIntegration::Skrill::QuickCheckout
31
+ app.config.spree.payment_methods << Spree::Gateway::BalancedGateway
32
+ app.config.spree.payment_methods << Spree::Gateway::DataCash
33
+ app.config.spree.payment_methods << Spree::Gateway::UsaEpay
34
+ app.config.spree.payment_methods << Spree::Gateway::PinGateway
35
+ app.config.spree.payment_methods << Spree::Gateway::Paymill
36
+ app.config.spree.payment_methods << Spree::Gateway::PayflowPro
37
+ app.config.spree.payment_methods << Spree::Gateway::SecurePayAU
38
+ end
39
+ end
40
+
41
+ end
data/script/rails ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ ENGINE_PATH = File.expand_path('../..', __FILE__)
5
+ load File.expand_path('../../spec/dummy/script/rails', __FILE__)
@@ -0,0 +1,4 @@
1
+ Factory.define(:skrill_quick_checkout, :class => BillingIntegration::Skrill::QuickCheckout) do |record|
2
+ record.name 'Skrill - Quick Checkout'
3
+ record.environment 'test'
4
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Gateway::AuthorizeNetCim do
4
+ let (:gateway) { Spree::Gateway::AuthorizeNetCim.new }
5
+
6
+ describe "options" do
7
+ it "should include :test => true when :test_mode is true" do
8
+ gateway.preferred_test_mode = true
9
+ gateway.options[:test].should == true
10
+ end
11
+
12
+ it "should not include :test when :test_mode is false" do
13
+ gateway.preferred_test_mode = false
14
+ gateway.options[:test].should be_nil
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Gateway::AuthorizeNet do
4
+ let (:gateway) { Spree::Gateway::AuthorizeNet.create!(:name => "Authorize.net") }
5
+
6
+ describe "options" do
7
+ it "should include :test => true when :test_mode is true" do
8
+ gateway.preferred_test_mode = true
9
+ gateway.options[:test].should == true
10
+ end
11
+
12
+ it "should not include :test when test_mode is false" do
13
+ gateway.preferred_test_mode = false
14
+ gateway.options[:test].should == false
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Gateway::BalancedGateway do
4
+ let(:gateway) { Spree::Gateway::BalancedGateway.create!(:name => "Balanced") }
5
+
6
+ it "should be Balanced gateway" do
7
+ gateway.provider_class.should == ::ActiveMerchant::Billing::BalancedGateway
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Gateway::Banwire do
4
+ let(:gateway) { Spree::Gateway::Banwire.create!(:name => "Banwire") }
5
+
6
+ it "should be Banwire gateway" do
7
+ gateway.provider_class.should == ::ActiveMerchant::Billing::BanwireGateway
8
+ end
9
+ end
@@ -0,0 +1,284 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Gateway::BraintreeGateway do
4
+
5
+ before(:each) do
6
+ Spree::Gateway.update_all :active => false
7
+ @gateway = Spree::Gateway::BraintreeGateway.create!(:name => "Braintree Gateway", :environment => "sandbox", :active => true)
8
+
9
+ @gateway.set_preference(:environment, "sandbox" )
10
+ @gateway.set_preference(:merchant_id, "zbn5yzq9t7wmwx42" )
11
+ @gateway.set_preference(:public_key, "ym9djwqpkxbv3xzt")
12
+ @gateway.set_preference(:private_key, "4ghghkyp2yy6yqc8")
13
+ @gateway.save!
14
+
15
+ with_payment_profiles_off do
16
+ @country = FactoryGirl.create(:country, :name => "United States", :iso_name => "UNITED STATES", :iso3 => "USA", :iso => "US", :numcode => 840)
17
+ @state = FactoryGirl.create(:state, :name => "Maryland", :abbr => "MD", :country => @country)
18
+ @address = FactoryGirl.create(:address,
19
+ :firstname => 'John',
20
+ :lastname => 'Doe',
21
+ :address1 => '1234 My Street',
22
+ :address2 => 'Apt 1',
23
+ :city => 'Washington DC',
24
+ :zipcode => '20123',
25
+ :phone => '(555)555-5555',
26
+ :state => @state,
27
+ :country => @country
28
+ )
29
+ @order = FactoryGirl.create(:order_with_totals, :bill_address => @address, :ship_address => @address)
30
+ @order.update!
31
+ @credit_card = FactoryGirl.create(:credit_card, :verification_value => '123', :number => '5105105105105100', :month => 9, :year => Time.now.year + 1, :first_name => 'John', :last_name => 'Doe', :cc_type => 'master')
32
+ @payment = FactoryGirl.create(:payment, :source => @credit_card, :order => @order, :payment_method => @gateway, :amount => 10.00)
33
+ @payment.payment_method.environment = "test"
34
+ end
35
+
36
+ end
37
+
38
+ describe 'merchant_account_id' do
39
+ context 'with merchant_account_id set on gateway' do
40
+ let(:merchant_account_id) { 'test' }
41
+
42
+ before do
43
+ @gateway.set_preference(:merchant_account_id, merchant_account_id)
44
+ end
45
+
46
+ it 'should have a perferred_merchant_account_id' do
47
+ @gateway.preferred_merchant_account_id.should == merchant_account_id
48
+ end
49
+
50
+ it 'should have a preferences[:merchant_account_id]' do
51
+ @gateway.preferences.keys.include?(:merchant_account_id).should be_true
52
+ end
53
+
54
+ it 'should adjust options to include merchant_account_id' do
55
+ options = {}
56
+ @gateway.should_receive(:adjust_billing_address).once
57
+ @gateway.send(:adjust_options_for_braintree, double, options)
58
+ options['merchant_account_id'].should == merchant_account_id
59
+ end
60
+ end
61
+ end
62
+
63
+ it "should be braintree gateway" do
64
+ @gateway.provider_class.should == ::ActiveMerchant::Billing::BraintreeBlueGateway
65
+ end
66
+
67
+ describe "preferences" do
68
+ it "should not include server + test_mode" do
69
+ lambda { @gateway.preferences.fetch(:server) }.should raise_error(StandardError)
70
+ end
71
+ end
72
+
73
+ describe "authorize" do
74
+ it "should return a success response with an authorization code" do
75
+ result = @gateway.authorize(500, @credit_card)
76
+
77
+ result.success?.should be_true
78
+ result.authorization.should match(/\A\w{6}\z/)
79
+
80
+
81
+ Braintree::Transaction::Status::Authorized.should == Braintree::Transaction.find(result.authorization).status
82
+ end
83
+
84
+ shared_examples "a valid credit card" do
85
+ it 'should work through the spree payment interface' do
86
+ Spree::Config.set :auto_capture => false
87
+ @payment.log_entries.size.should == 0
88
+ @payment.process!
89
+ @payment.log_entries.size.should == 1
90
+ @payment.response_code.should match /\A\w{6}\z/
91
+ @payment.state.should == 'pending'
92
+ transaction = ::Braintree::Transaction.find(@payment.response_code)
93
+ transaction.status.should == Braintree::Transaction::Status::Authorized
94
+ card_number = @credit_card.number[0..5] + "******" + @credit_card.number[-4..-1]
95
+ transaction.credit_card_details.masked_number.should == card_number
96
+ transaction.credit_card_details.expiration_date.should == "09/#{Time.now.year + 1}"
97
+ transaction.customer_details.first_name.should == 'John'
98
+ transaction.customer_details.last_name.should == 'Doe'
99
+ end
100
+ end
101
+
102
+ context "when the card is a mastercard" do
103
+ before do
104
+ @credit_card.number = '5105105105105100'
105
+ @credit_card.cc_type = 'master'
106
+ @credit_card.save
107
+ end
108
+
109
+ it_behaves_like "a valid credit card"
110
+ end
111
+
112
+ context "when the card is a visa" do
113
+ before do
114
+ @credit_card.number = '4111111111111111'
115
+ @credit_card.cc_type = 'visa'
116
+ @credit_card.save
117
+ end
118
+
119
+ it_behaves_like "a valid credit card"
120
+ end
121
+
122
+ context "when the card is an amex" do
123
+ before do
124
+ @credit_card.number = '378282246310005'
125
+ @credit_card.verification_value = '1234'
126
+ @credit_card.cc_type = 'american_express'
127
+ @credit_card.save
128
+ end
129
+
130
+ it_behaves_like "a valid credit card"
131
+ end
132
+
133
+ context "when the card is a JCB" do
134
+ before do
135
+ @credit_card.number = '3530111333300000'
136
+ @credit_card.cc_type = 'jcb'
137
+ @credit_card.save
138
+ end
139
+
140
+ it_behaves_like "a valid credit card"
141
+ end
142
+
143
+ context "when the card is a diners club" do
144
+ before do
145
+ @credit_card.number = '36050000000003'
146
+ @credit_card.cc_type = 'diners_club'
147
+ @credit_card.save
148
+ end
149
+
150
+ it_behaves_like "a valid credit card"
151
+ end
152
+ end
153
+
154
+ describe "capture" do
155
+
156
+ it " should capture a previous authorization" do
157
+ @payment.process!
158
+ assert_equal 1, @payment.log_entries.size
159
+ assert_match /\A\w{6}\z/, @payment.response_code
160
+ transaction = ::Braintree::Transaction.find(@payment.response_code)
161
+ transaction.status.should == Braintree::Transaction::Status::Authorized
162
+ capture_result = @gateway.capture(@payment,:ignored_arg_credit_card, :ignored_arg_options)
163
+ capture_result.success?.should be_true
164
+ transaction = ::Braintree::Transaction.find(@payment.response_code)
165
+ transaction.status.should == Braintree::Transaction::Status::SubmittedForSettlement
166
+ end
167
+
168
+ pending "raise an error if capture fails using spree interface" do
169
+ Spree::Config.set :auto_capture => false
170
+ @payment.log_entries.size.should == 0
171
+ @payment.process!
172
+ @payment.log_entries.size.should == 1
173
+ transaction = ::Braintree::Transaction.find(@payment.response_code)
174
+ transaction.status.should == Braintree::Transaction::Status::Authorized
175
+ @payment.payment_source.capture(@payment) # as done in PaymentsController#fire
176
+ # transaction = ::Braintree::Transaction.find(@payment.response_code)
177
+ # transaction.status.should == Braintree::Transaction::Status::SubmittedForSettlement
178
+ # lambda do
179
+ # @payment.payment_source.capture(@payment)
180
+ # end.should raise_error(Spree::Core::GatewayError, "Cannot submit for settlement unless status is authorized. (91507)")
181
+ end
182
+ end
183
+
184
+ describe 'purchase' do
185
+ it 'should return a success response with an authorization code' do
186
+ result = @gateway.purchase(500, @credit_card)
187
+ result.success?.should be_true
188
+ result.authorization.should match(/\A\w{6}\z/)
189
+ Braintree::Transaction::Status::SubmittedForSettlement.should == Braintree::Transaction.find(result.authorization).status
190
+ end
191
+
192
+ it 'should work through the spree payment interface with payment profiles' do
193
+ purchase_using_spree_interface
194
+ transaction = ::Braintree::Transaction.find(@payment.response_code)
195
+ transaction.credit_card_details.token.should_not be_nil
196
+ end
197
+
198
+ it 'should work through the spree payment interface without payment profiles' do
199
+ with_payment_profiles_off do
200
+ purchase_using_spree_interface(false)
201
+ transaction = ::Braintree::Transaction.find(@payment.response_code)
202
+ transaction.credit_card_details.token.should be_nil
203
+ end
204
+ end
205
+ end
206
+
207
+ describe "credit" do
208
+ pending "should work through the spree interface" do
209
+ @payment.amount += 100.00
210
+ purchase_using_spree_interface
211
+ credit_using_spree_interface
212
+ end
213
+ end
214
+
215
+ describe "void" do
216
+ pending "should work through the spree credit_card / payment interface" do
217
+ assert_equal 0, @payment.log_entries.size
218
+ @payment.process!
219
+ assert_equal 1, @payment.log_entries.size
220
+ @payment.response_code.should match(/\A\w{6}\z/)
221
+ transaction = Braintree::Transaction.find(@payment.response_code)
222
+ transaction.status.should == Braintree::Transaction::Status::SubmittedForSettlement
223
+ @credit_card.void(@payment)
224
+ transaction = Braintree::Transaction.find(transaction.id)
225
+ transaction.status.should == Braintree::Transaction::Status::Voided
226
+ end
227
+ end
228
+
229
+ describe "update_card_number" do
230
+ it "passes through gateway_payment_profile_id" do
231
+ credit_card = { 'token' => 'testing', 'last_4' => '1234', 'masked_number' => '5555**5555' }
232
+ @gateway.update_card_number(@payment.source, credit_card)
233
+ @payment.source.gateway_payment_profile_id.should == "testing"
234
+ end
235
+ end
236
+
237
+ def credit_using_spree_interface
238
+ @payment.log_entries.size.should == 1
239
+ @payment.source.credit(@payment) # as done in PaymentsController#fire
240
+ @payment.log_entries.size.should == 2
241
+ #Let's get the payment record associated with the credit
242
+ @payment = @order.payments.last
243
+ @payment.response_code.should match(/\A\w{6}\z/)
244
+ transaction = ::Braintree::Transaction.find(@payment.response_code)
245
+ transaction.type.should == Braintree::Transaction::Type::Credit
246
+ transaction.status.should == Braintree::Transaction::Status::SubmittedForSettlement
247
+ transaction.credit_card_details.masked_number.should == "510510******5100"
248
+ transaction.credit_card_details.expiration_date.should == "09/#{Time.now.year + 1}"
249
+ transaction.customer_details.first_name.should == "John"
250
+ transaction.customer_details.last_name.should == "Doe"
251
+ end
252
+
253
+ def purchase_using_spree_interface(profile=true)
254
+ Spree::Config.set :auto_capture => true
255
+ @payment.send(:create_payment_profile) if profile
256
+ @payment.log_entries.size == 0
257
+ @payment.process! # as done in PaymentsController#create
258
+ @payment.log_entries.size == 1
259
+ @payment.response_code.should match /\A\w{6}\z/
260
+ @payment.state.should == 'completed'
261
+ transaction = ::Braintree::Transaction.find(@payment.response_code)
262
+ Braintree::Transaction::Status::SubmittedForSettlement.should == transaction.status
263
+ transaction.credit_card_details.masked_number.should == "510510******5100"
264
+ transaction.credit_card_details.expiration_date.should == "09/#{Time.now.year + 1}"
265
+ transaction.customer_details.first_name.should == 'John'
266
+ transaction.customer_details.last_name.should == 'Doe'
267
+ end
268
+
269
+ def with_payment_profiles_off(&block)
270
+ Spree::Gateway::BraintreeGateway.class_eval do
271
+ def payment_profiles_supported?
272
+ false
273
+ end
274
+ end
275
+ yield
276
+ ensure
277
+ Spree::Gateway::BraintreeGateway.class_eval do
278
+ def payment_profiles_supported?
279
+ true
280
+ end
281
+ end
282
+ end
283
+
284
+ end