spree_gateway 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
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