catarse_paypal_express 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +0 -2
  3. data/.rspec +2 -0
  4. data/.travis.yml +13 -0
  5. data/Gemfile +2 -126
  6. data/Gemfile.lock +88 -477
  7. data/README.md +3 -12
  8. data/app/assets/javascripts/catarse_paypal_express.js +6 -0
  9. data/app/assets/javascripts/catarse_paypal_express/paypal_form.js +19 -0
  10. data/app/assets/javascripts/catarse_paypal_express/user_document.js +111 -0
  11. data/app/controllers/catarse_paypal_express/paypal_express_controller.rb +113 -0
  12. data/app/views/catarse_paypal_express/paypal_express/review.html.slim +13 -0
  13. data/catarse_paypal_express.gemspec +4 -3
  14. data/config/initializers/active_merchant.rb +2 -0
  15. data/config/initializers/register.rb +5 -0
  16. data/config/locales/en.yml +7 -1
  17. data/config/locales/pt.yml +6 -0
  18. data/config/routes.rb +11 -5
  19. data/lib/catarse_paypal_express/version.rb +1 -1
  20. data/spec/controllers/catarse_paypal_express/paypal_express_controller_spec.rb +304 -0
  21. data/spec/fixtures/ipn_data.txt +1 -0
  22. data/spec/spec_helper.rb +12 -26
  23. data/spec/support/payment_engines.rb +3 -0
  24. data/test/dummy/README.rdoc +261 -0
  25. data/test/dummy/Rakefile +7 -0
  26. data/test/dummy/app/assets/javascripts/application.js +15 -0
  27. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  28. data/test/dummy/app/controllers/application_controller.rb +3 -0
  29. data/test/dummy/app/helpers/application_helper.rb +2 -0
  30. data/test/dummy/app/mailers/.gitkeep +0 -0
  31. data/test/dummy/app/models/.gitkeep +0 -0
  32. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  33. data/test/dummy/config.ru +4 -0
  34. data/test/dummy/config/application.rb +58 -0
  35. data/test/dummy/config/boot.rb +10 -0
  36. data/test/dummy/config/database.yml +52 -0
  37. data/test/dummy/config/environment.rb +5 -0
  38. data/test/dummy/config/environments/development.rb +37 -0
  39. data/test/dummy/config/environments/production.rb +67 -0
  40. data/test/dummy/config/environments/test.rb +37 -0
  41. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  42. data/test/dummy/config/initializers/inflections.rb +15 -0
  43. data/test/dummy/config/initializers/mime_types.rb +5 -0
  44. data/test/dummy/config/initializers/secret_token.rb +7 -0
  45. data/test/dummy/config/initializers/session_store.rb +8 -0
  46. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  47. data/test/dummy/config/locales/en.yml +5 -0
  48. data/test/dummy/config/routes.rb +4 -0
  49. data/test/dummy/lib/assets/.gitkeep +0 -0
  50. data/test/dummy/log/.gitkeep +0 -0
  51. data/test/dummy/public/404.html +26 -0
  52. data/test/dummy/public/422.html +26 -0
  53. data/test/dummy/public/500.html +25 -0
  54. data/test/dummy/public/favicon.ico +0 -0
  55. data/test/dummy/script/rails +6 -0
  56. metadata +112 -34
  57. data/app/controllers/catarse_paypal_express/payment/paypal_express_controller.rb +0 -119
  58. data/lib/catarse_paypal_express/processors.rb +0 -5
  59. data/lib/catarse_paypal_express/processors/paypal.rb +0 -26
  60. data/spec/controllers/catarse_paypal_express/payment/paypal_express_controller_spec.rb +0 -177
  61. data/spec/lib/processors/paypal_spec.rb +0 -33
@@ -1,119 +0,0 @@
1
- require 'catarse_paypal_express/processors'
2
-
3
- module CatarsePaypalExpress::Payment
4
- class PaypalExpressController < ApplicationController
5
- skip_before_filter :verify_authenticity_token, :only => [:notifications]
6
- skip_before_filter :detect_locale, :only => [:notifications]
7
- skip_before_filter :set_locale, :only => [:notifications]
8
-
9
- before_filter :setup_gateway
10
-
11
- SCOPE = "projects.backers.checkout"
12
-
13
-
14
- def notifications
15
- backer = Backer.find params[:id]
16
- response = @@gateway.details_for(backer.payment_token)
17
- if response.params['transaction_id'] == params['txn_id']
18
- build_notification(backer, response.params)
19
- render status: 200, nothing: true
20
- else
21
- render status: 404, nothing: true
22
- end
23
- rescue
24
- render status: 404, nothing: true
25
- end
26
-
27
- def pay
28
- backer = current_user.backs.find params[:id]
29
- begin
30
- response = @@gateway.setup_purchase(backer.price_in_cents, {
31
- ip: request.remote_ip,
32
- return_url: payment_success_paypal_express_url(id: backer.id),
33
- cancel_return_url: payment_cancel_paypal_express_url(id: backer.id),
34
- currency_code: 'BRL',
35
- description: t('paypal_description', scope: SCOPE, :project_name => backer.project.name, :value => backer.display_value),
36
- notify_url: payment_notifications_paypal_express_url(id: backer.id)
37
- })
38
-
39
- backer.update_attribute :payment_method, 'PayPal'
40
- backer.update_attribute :payment_token, response.token
41
-
42
- build_notification(backer, response.params)
43
-
44
- if response.params['correlation_id']
45
- backer.update_attribute :payment_id, response.params['correlation_id']
46
- end
47
-
48
- redirect_to @@gateway.redirect_url_for(response.token)
49
- rescue Exception => e
50
- Airbrake.notify({ :error_class => "Paypal Error", :error_message => "Paypal Error: #{e.inspect}", :parameters => params}) rescue nil
51
- Rails.logger.info "-----> #{e.inspect}"
52
- paypal_flash_error
53
- return redirect_to main_app.new_project_backer_path(backer.project)
54
- end
55
- end
56
-
57
- def success
58
- backer = current_user.backs.find params[:id]
59
- begin
60
- details = @@gateway.details_for(backer.payment_token)
61
- response = @@gateway.purchase(backer.price_in_cents, {
62
- ip: request.remote_ip,
63
- token: backer.payment_token,
64
- payer_id: details.payer_id
65
- })
66
-
67
- build_notification(backer, details.params)
68
-
69
- if details.params['transaction_id']
70
- backer.update_attribute :payment_id, details.params['transaction_id']
71
- end
72
-
73
- session[:thank_you_id] = backer.project.id
74
- session[:_payment_token] = backer.payment_token
75
-
76
- paypal_flash_success
77
- redirect_to main_app.thank_you_path
78
- rescue Exception => e
79
- Airbrake.notify({ :error_class => "Paypal Error", :error_message => "Paypal Error: #{e.message}", :parameters => params}) rescue nil
80
- Rails.logger.info "-----> #{e.inspect}"
81
- paypal_flash_error
82
- return redirect_to main_app.new_project_backer_path(backer.project)
83
- end
84
- end
85
-
86
- def cancel
87
- backer = current_user.backs.find params[:id]
88
- flash[:failure] = t('paypal_cancel', scope: SCOPE)
89
- redirect_to main_app.new_project_backer_path(backer.project)
90
- end
91
-
92
- private
93
-
94
- def build_notification(backer, data)
95
- processor = CatarsePaypalExpress::Processors::Paypal.new
96
- processor.process!(backer, data)
97
- end
98
-
99
- def paypal_flash_error
100
- flash[:failure] = t('paypal_error', scope: SCOPE)
101
- end
102
-
103
- def paypal_flash_success
104
- flash[:success] = t('success', scope: SCOPE)
105
- end
106
-
107
- def setup_gateway
108
- if ::Configuration[:paypal_username] and ::Configuration[:paypal_password] and ::Configuration[:paypal_signature]
109
- @@gateway ||= ActiveMerchant::Billing::PaypalExpressGateway.new({
110
- :login => ::Configuration[:paypal_username],
111
- :password => ::Configuration[:paypal_password],
112
- :signature => ::Configuration[:paypal_signature]
113
- })
114
- else
115
- puts "[PayPal] An API Certificate or API Signature is required to make requests to PayPal"
116
- end
117
- end
118
- end
119
- end
@@ -1,5 +0,0 @@
1
- require 'catarse_paypal_express/processors/paypal'
2
- module CatarsePaypalExpress
3
- module Processors
4
- end
5
- end
@@ -1,26 +0,0 @@
1
- module CatarsePaypalExpress
2
- module Processors
3
- class Paypal
4
-
5
- def process!(backer, data)
6
- status = data["checkout_status"] || "pending"
7
-
8
- notification = backer.payment_notifications.new({
9
- status: status,
10
- extra_data: data
11
- })
12
-
13
- notification.save!
14
-
15
- backer.confirm! if success_payment?(status)
16
- end
17
-
18
- protected
19
-
20
- def success_payment?(status)
21
- status == 'PaymentActionCompleted'
22
- end
23
-
24
- end
25
- end
26
- end
@@ -1,177 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe CatarsePaypalExpress::Payment::PaypalExpressController do
4
- before do
5
- Configuration.create!(name: "paypal_username", value: "usertest_api1.teste.com")
6
- Configuration.create!(name: "paypal_password", value: "HVN4PQBGZMHKFVGW")
7
- Configuration.create!(name: "paypal_signature", value: "AeL-u-Ox.N6Jennvu1G3BcdiTJxQAWdQcjdpLTB9ZaP0-Xuf-U0EQtnS")
8
- ActiveMerchant::Billing::PaypalExpressGateway.any_instance.stub(:details_for).and_return({})
9
- Airbrake.stub(:notify).and_return({})
10
- end
11
-
12
- let(:current_user) { Factory(:user) }
13
-
14
- context 'when receive a notification' do
15
- it 'and not found the backer, should return 404' do
16
- post :notifications, { id: 1, use_route: 'catarse_paypal_express'}
17
- response.status.should eq(404)
18
- end
19
-
20
- it 'and the transaction ID not match, should return 404' do
21
- backer = Factory(:backer, payment_id: '1234')
22
- post :notifications, { id: backer.id, txn_id: 123, use_route: 'catarse_paypal_express' }
23
- response.status.should eq(404)
24
- end
25
-
26
- it 'should create a payment_notification' do
27
- success_payment_response = mock()
28
- success_payment_response.stubs(:params).returns({ 'transaction_id' => '1234', "checkout_status" => "PaymentActionCompleted" })
29
- success_payment_response.stubs(:success?).returns(true)
30
- ActiveMerchant::Billing::PaypalExpressGateway.any_instance.stub(:details_for).and_return(success_payment_response)
31
-
32
- backer = Factory(:backer, payment_id: '1234')
33
- backer.payment_notifications.should be_empty
34
-
35
- post :notifications, { id: backer.id, txn_id: 1234 , use_route: 'catarse_paypal_express' }
36
- backer.reload
37
-
38
- backer.payment_notifications.should_not be_empty
39
- end
40
-
41
- it 'and the transaction ID match, should update the payment status if successful' do
42
- success_payment_response = mock()
43
- success_payment_response.stubs(:params).returns({ 'transaction_id' => '1234', "checkout_status" => "PaymentActionCompleted" })
44
- success_payment_response.stubs(:success?).returns(true)
45
- ActiveMerchant::Billing::PaypalExpressGateway.any_instance.stub(:details_for).and_return(success_payment_response)
46
- backer = Factory(:backer, payment_id: '1234', confirmed: false)
47
-
48
- post :notifications, { id: backer.id, txn_id: 1234, use_route: 'catarse_paypal_express' }
49
-
50
- backer.reload
51
- response.status.should eq(200)
52
- backer.confirmed.should be_true
53
- end
54
- end
55
-
56
- context 'setup purchase' do
57
- context 'when have some failures' do
58
- it 'user not logged in, should redirect' do
59
- pending 'problems with external application routes'
60
- #get :pay, {locale: 'en', use_route: 'catarse_paypal_express' }
61
- #response.status.should eq(302)
62
- end
63
-
64
- it 'backer not belongs to current_user should 404' do
65
- backer = Factory(:backer)
66
- session[:user_id] = current_user.id
67
-
68
- lambda {
69
- get :pay, { id: backer.id, locale: 'en', use_route: 'catarse_paypal_express' }
70
- }.should raise_exception ActiveRecord::RecordNotFound
71
- end
72
-
73
- it 'raise a exepction because invalid data and should be redirect and set the flash message' do
74
- ActiveMerchant::Billing::PaypalExpressGateway.any_instance.stub(:setup_purchase).and_raise(StandardError)
75
- session[:user_id] = current_user.id
76
- backer = Factory(:backer, user: current_user)
77
-
78
- get :pay, { id: backer.id, locale: 'en', use_route: 'catarse_paypal_express' }
79
- flash[:failure].should == I18n.t('paypal_error', scope: CatarsePaypalExpress::Payment::PaypalExpressController::SCOPE)
80
- response.should be_redirect
81
- end
82
- end
83
-
84
- context 'when successul' do
85
- before do
86
- success_response = mock()
87
- success_response.stub(:token).and_return('ABCD')
88
- success_response.stub(:params).and_return({ 'correlation_id' => '123' })
89
- ActiveMerchant::Billing::PaypalExpressGateway.any_instance.stub(:setup_purchase).and_return(success_response)
90
- end
91
-
92
- it 'should create a payment_notification' do
93
- session[:user_id] = current_user.id
94
- backer = Factory(:backer, user: current_user)
95
-
96
- get :pay, { id: backer.id, locale: 'en', use_route: 'catarse_paypal_express' }
97
- backer.reload
98
-
99
- backer.payment_notifications.should_not be_empty
100
- backer.payment_notifications.first.status == 'pending'
101
- end
102
-
103
- it 'payment method, token and id should be persisted ' do
104
- session[:user_id] = current_user.id
105
- backer = Factory(:backer, user: current_user)
106
-
107
- get :pay, { id: backer.id, locale: 'en', use_route: 'catarse_paypal_express' }
108
- backer.reload
109
-
110
- backer.payment_method.should == 'PayPal'
111
- backer.payment_token.should == 'ABCD'
112
- backer.payment_id.should == '123'
113
-
114
- response.should be_redirect
115
- end
116
- end
117
- end
118
-
119
- context 'when cancel the paypal purchase' do
120
- it 'should show for user the flash message' do
121
- session[:user_id] = current_user.id
122
- backer = Factory(:backer, user: current_user, payment_token: 'TOKEN')
123
-
124
- get :cancel, { id: backer.id, locale: 'en', use_route: 'catarse_paypal_express' }
125
- flash[:failure].should == I18n.t('paypal_cancel', scope: CatarsePaypalExpress::Payment::PaypalExpressController::SCOPE)
126
- response.should be_redirect
127
- end
128
- end
129
-
130
- context 'paypal returning to success route' do
131
- context 'when paypal purchase is ok' do
132
- before(:each) do
133
- fake_success_purchase = mock()
134
- fake_success_purchase.stub(:success?).and_return(true)
135
- ActiveMerchant::Billing::PaypalExpressGateway.any_instance.stub(:purchase).and_return(fake_success_purchase)
136
-
137
- fake_success_details = mock()
138
- fake_success_details.stub(:payer_id).and_return('123')
139
- fake_success_details.stub(:params).and_return({'transaction_id' => '12345', "checkout_status" => "PaymentActionCompleted"})
140
- ActiveMerchant::Billing::PaypalExpressGateway.any_instance.stub(:details_for).and_return(fake_success_details)
141
- end
142
-
143
- it 'should update the backer and redirect to thank_you' do
144
- session[:user_id] = current_user.id
145
- backer = Factory(:backer, user: current_user, payment_token: 'TOKEN')
146
- backer.payment_notifications.should be_empty
147
-
148
- get :success, { id: backer.id, locale: 'en', use_route: 'catarse_paypal_express' }
149
- backer.reload
150
-
151
- backer.payment_notifications.should_not be_empty
152
- backer.confirmed.should be_true
153
- backer.payment_id.should == '12345'
154
- session[:thank_you_id].should == backer.project.id
155
- session[:_payment_token].should == backer.payment_token
156
-
157
- response.should redirect_to('/thank_you')
158
- end
159
- end
160
- context 'when paypal purchase raise a error' do
161
- before do
162
- ActiveMerchant::Billing::PaypalExpressGateway.any_instance.stub(:purchase).and_raise(StandardError)
163
- end
164
-
165
- it 'should be redirect and show a flash message' do
166
- session[:user_id] = current_user.id
167
- backer = Factory(:backer, user: current_user)
168
-
169
- get :success, { id: backer.id, locale: 'en', use_route: 'catarse_paypal_express' }
170
-
171
- flash[:failure].should == I18n.t('paypal_error', scope: CatarsePaypalExpress::Payment::PaypalExpressController::SCOPE)
172
- response.should be_redirect
173
- end
174
- end
175
- end
176
-
177
- end
@@ -1,33 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe CatarsePaypalExpress::Processors::Paypal do
4
- context "process paypal details_for response" do
5
- let(:backer) { Factory(:backer, confirmed: false) }
6
-
7
- it "should create a new payment_notifications for backer" do
8
- backer.payment_notifications.should be_empty
9
- subject.process!(backer, paypal_details_response)
10
- backer.payment_notifications.should_not be_empty
11
- end
12
-
13
- it "should fill status based on checkout_status" do
14
- subject.process!(backer, paypal_details_response)
15
- backer.payment_notifications.first.status.should == 'PaymentActionCompleted'
16
- end
17
-
18
- it "should fill extra_data with all response data" do
19
- subject.process!(backer, paypal_details_response)
20
- backer.payment_notifications.first.extra_data.should == paypal_details_response
21
- end
22
-
23
- it "should confirm backer when checkout status is completed" do
24
- subject.process!(backer, paypal_details_response)
25
- backer.confirmed.should be_true
26
- end
27
-
28
- it "should not confirm when checkout status is not completed" do
29
- subject.process!(backer, paypal_details_response.merge!({"checkout_status" => "just_another_status"}) )
30
- backer.confirmed.should be_false
31
- end
32
- end
33
- end