ecommerce 0.0.2 → 0.0.3
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.
- data/app/controllers/cart_controller.rb +3 -1
- data/app/controllers/payment_notifications_controller.rb +13 -67
- data/app/models/cart.rb +6 -2
- data/app/models/payment_handler.rb +57 -0
- data/app/models/product.rb +1 -1
- data/app/views/cart/confirmation.haml +2 -0
- data/config/initializers/ecommerce-config.rb +1 -1
- data/config/routes.rb +1 -8
- data/ecommerce-0.0.2.gem +0 -0
- data/lib/ecommerce/version.rb +1 -1
- data/lib/generators/ecommerce/templates/migration.rb +3 -3
- data/spec/models/payment_handler_spec.rb +5 -0
- metadata +9 -4
@@ -10,7 +10,6 @@ class CartController < ApplicationController
|
|
10
10
|
def update
|
11
11
|
cart = find_cart()
|
12
12
|
|
13
|
-
|
14
13
|
if params.key?('quantity_total_update') && params.key?('cart_item')
|
15
14
|
# We are updating the total quantity of multiple items in teh cart. This is likely from teh cart page where
|
16
15
|
# the user has updated the quantity text fields and clicked 'Update Cart'
|
@@ -39,4 +38,7 @@ class CartController < ApplicationController
|
|
39
38
|
redirect_to :back
|
40
39
|
end
|
41
40
|
|
41
|
+
def confirmation
|
42
|
+
|
43
|
+
end
|
42
44
|
end
|
@@ -1,80 +1,26 @@
|
|
1
1
|
class PaymentNotificationsController < ApplicationController
|
2
|
+
|
2
3
|
# Paypal needs to be able to access this without passing the auth token
|
3
4
|
protect_from_forgery :except => [:create]
|
4
5
|
|
5
6
|
unloadable
|
6
7
|
|
7
|
-
# https://cms.paypal.com/cms_content/en_US/files/developer/PP_OrderMgmt_IntegrationGuide.pdf
|
8
|
-
SUCCESSFUL_PAYPAL_STATES = %w[instant echeck completed processed pending]
|
9
|
-
|
10
|
-
# For cart info, see:
|
11
|
-
# https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_Appx_websitestandard_htmlvariables
|
12
|
-
|
13
8
|
def index
|
14
|
-
|
15
|
-
pm = PaymentNotification.create!(:params => params,
|
16
|
-
:cart_id => params[:invoice],
|
17
|
-
:status => params[:payment_status].downcase,
|
18
|
-
:transaction_id => params[:txn_id])
|
19
|
-
render :text => pm.inspect
|
20
|
-
else
|
21
|
-
Rails.logger.warn("Something was wrong with this transaction! See PaymentNotification entry for cart_id #{params[:invoice]} and transaction_id #{params[:txn_id]}")
|
22
|
-
render :text => 'test failed'
|
23
|
-
end
|
9
|
+
create()
|
24
10
|
end
|
25
11
|
|
26
|
-
|
27
12
|
def create
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
protected
|
40
|
-
|
41
|
-
|
42
|
-
# TODO -- younker [2011-03-27 15:12]
|
43
|
-
# Move this into the payment notification model and do validations there (change request_seems_to_be_valid to pm.valid?)
|
44
|
-
def request_seems_to_be_valid()
|
45
|
-
# current_cart = find_cart()
|
46
|
-
txn_cart = Cart.find_by_id(params[:invoice])
|
47
|
-
|
48
|
-
# unless current_cart.id.eql?(txn_cart.id)
|
49
|
-
# Rails.logger.fatal("The user's current cart (#{current_cart.id}) does not match the cart for this transaction #{txn_cart.id}")
|
50
|
-
# return false
|
51
|
-
# end
|
52
|
-
|
53
|
-
# unless current_cart.total.eql?(txn_cart.total)
|
54
|
-
# Rails.logger.warn("The total for the current cart (#{current_cart.total}) does not equal the total for the transaction cart #{txn_cart.total}")
|
55
|
-
# return false
|
56
|
-
# end
|
57
|
-
|
58
|
-
# unless txn_cart.total.to_f.eql?(params[:payment_gross].to_f)
|
59
|
-
# Rails.logger.warn("The total for the current cart (#{txn_cart.total}) does not equal the payment_gross #{params[:payment_gross]}sent back from paypal")
|
60
|
-
# return false
|
61
|
-
# end
|
62
|
-
|
63
|
-
unless ECO['paypal']['email'].eql?(params[:receiver_email])
|
64
|
-
Rails.logger.warn("The receiver email from paypal (#{params[:receiver_email]}) does not match our ECO.paypal_email (#{ECO['paypal']['email']})")
|
65
|
-
return false
|
66
|
-
end
|
67
|
-
|
68
|
-
unless ECO['paypal']['secret'].eql?(params[:secret])
|
69
|
-
Rails.logger.warn("Our secret (#{ECO['paypal']['secret']}) does not match their secret (#{params[:secret]})")
|
70
|
-
return false
|
13
|
+
begin
|
14
|
+
pm = PaymentHandler.create!(:params => params)
|
15
|
+
if pm.accept?
|
16
|
+
head :accepted
|
17
|
+
else
|
18
|
+
Rails.logger.fatal("Failed Transaction for cart_id #{pm.cart_id}: #{pm.errors}")
|
19
|
+
head :bad_request
|
20
|
+
end
|
21
|
+
rescue => e
|
22
|
+
Rails.logger.fatal(e)
|
23
|
+
head :bad_request
|
71
24
|
end
|
72
|
-
|
73
|
-
if SUCCESSFUL_PAYPAL_STATES.detect{ |str| str.eql?(params[:payment_status].downcase) }.nil?
|
74
|
-
Rails.logger.warn("The payment state reported back from paypal (#{params[:payment_status].downcase}) does not indicate success")
|
75
|
-
return false
|
76
|
-
end
|
77
|
-
|
78
|
-
true
|
79
25
|
end
|
80
26
|
end
|
data/app/models/cart.rb
CHANGED
@@ -2,6 +2,9 @@ class Cart < ActiveRecord::Base
|
|
2
2
|
attr_reader :currency
|
3
3
|
include ActionView::Helpers::NumberHelper
|
4
4
|
|
5
|
+
# Needed to pass the order return path (order_confirmation_path) to paypal
|
6
|
+
include Rails.application.routes.url_helpers
|
7
|
+
|
5
8
|
has_many :cart_items
|
6
9
|
# Because 'has_many :cart_items, :as => :items' does not appear to work
|
7
10
|
def items ; self.cart_items ; end
|
@@ -78,9 +81,10 @@ class Cart < ActiveRecord::Base
|
|
78
81
|
:cert_id => ECO['paypal']['cert_id'],
|
79
82
|
:cmd => '_cart',
|
80
83
|
:upload => 1,
|
81
|
-
:weight => self.shipping_weight
|
84
|
+
:weight => self.shipping_weight,
|
85
|
+
:return => order_confirmation_path()
|
82
86
|
}
|
83
|
-
|
87
|
+
|
84
88
|
self.items.each_with_index do |item, index|
|
85
89
|
values.merge!({
|
86
90
|
"amount_#{index+1}" => item.unit_price,
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class PaymentHandler < ActiveRecord::Base
|
2
|
+
belongs_to :cart
|
3
|
+
|
4
|
+
attr_accessible :params, :cart_id, :status, :transaction_id
|
5
|
+
|
6
|
+
# convert params object to yaml when putting into the db and a hash when it comes out
|
7
|
+
serialize :params
|
8
|
+
|
9
|
+
after_create :set_purchase_date
|
10
|
+
|
11
|
+
# https://cms.paypal.com/cms_content/en_US/files/developer/PP_OrderMgmt_IntegrationGuide.pdf
|
12
|
+
SUCCESSFUL_PAYPAL_STATES = %w[instant echeck completed processed pending]
|
13
|
+
|
14
|
+
validates :params, :status, :presence => true
|
15
|
+
validates :cart_id, :transaction_id, :presence => true, :uniqueness => true
|
16
|
+
|
17
|
+
before_validation do
|
18
|
+
self.cart_id = self.params['invoice'] unless cart_id?
|
19
|
+
self.status = self.params['payment_status'].downcase unless status?
|
20
|
+
self.transaction_id = self.params['txn_id'] unless transaction_id?
|
21
|
+
end
|
22
|
+
|
23
|
+
# younker [2011-04-16 12:00]
|
24
|
+
# We want to create the entry even if it does not pass validation, otherwise we will not insert this into the db.
|
25
|
+
# That is why I removed this and created accept?
|
26
|
+
# validate do
|
27
|
+
# errors.add(:base, "Secret does not match") unless secrets_match?
|
28
|
+
# errors.add(:base, "Transaction state was invalid") unless valid_state?
|
29
|
+
# errors.add(:base, "Receiver email does not match our paypal email") unless emails_match?
|
30
|
+
# end
|
31
|
+
|
32
|
+
def accept?
|
33
|
+
errors.add(:base, " Secret does not match") unless secrets_match?
|
34
|
+
errors.add(:base, " Transaction state was invalid") unless valid_state?
|
35
|
+
errors.add(:base, " Receiver email does not match our paypal email") unless emails_match?
|
36
|
+
self.errors.empty?
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# checks to make sure this is valid are done in the payment_notification_controller.create()
|
42
|
+
def set_purchase_date
|
43
|
+
cart.update_attribute(:purchased_at, Time.now)
|
44
|
+
end
|
45
|
+
|
46
|
+
def secrets_match?
|
47
|
+
ECO['paypal']['secret'].eql?(self.params['secret'])
|
48
|
+
end
|
49
|
+
|
50
|
+
def valid_state?
|
51
|
+
SUCCESSFUL_PAYPAL_STATES.include?(self.status)
|
52
|
+
end
|
53
|
+
|
54
|
+
def emails_match?
|
55
|
+
ECO['paypal']['email'].eql?(self.params[:receiver_email])
|
56
|
+
end
|
57
|
+
end
|
data/app/models/product.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
env = Rails.env.present? ? Rails.env.to_s : 'test'
|
3
|
-
ECO = YAML.load(File.read(
|
3
|
+
ECO = YAML.load(File.read("#{Rails.root}/config/ecommerce.yml"))[env]
|
4
4
|
|
5
5
|
PAYPAL_CERT_PEM = File.read("#{Rails.root}/certs/paypal_cert.pem")
|
6
6
|
APP_CERT_PEM = File.read("#{Rails.root}/certs/app_cert.pem")
|
data/config/routes.rb
CHANGED
@@ -2,16 +2,9 @@ Rails.application.routes.draw do
|
|
2
2
|
match '/cart', :via => :get, :to => 'cart#index'
|
3
3
|
match '/cart', :via => :put, :to => 'cart#update'
|
4
4
|
match '/cart', :via => :delete, :to => 'cart#destroy'
|
5
|
-
|
6
|
-
|
7
|
-
# resources :cart, :except => [:update, :edit, :show, :create, :new] do
|
8
|
-
# collection do
|
9
|
-
# put :update
|
10
|
-
# end
|
11
|
-
# end
|
5
|
+
match '/order-confirmation', :via => :get, :to => 'cart#confirmation', :as => 'order_confirmation'
|
12
6
|
|
13
7
|
resources :payment_notifications
|
14
|
-
resources :order_confirmation
|
15
8
|
|
16
9
|
match '/products/search' => 'products#search'
|
17
10
|
resources :products do
|
data/ecommerce-0.0.2.gem
ADDED
Binary file
|
data/lib/ecommerce/version.rb
CHANGED
@@ -11,7 +11,7 @@ class CreateEcommerceTables < ActiveRecord::Migration
|
|
11
11
|
t.text :meta_description
|
12
12
|
t.text :meta_keywords
|
13
13
|
t.string :tags
|
14
|
-
t.
|
14
|
+
t.integer :shipping_weight
|
15
15
|
t.timestamps
|
16
16
|
end
|
17
17
|
|
@@ -37,7 +37,7 @@ class CreateEcommerceTables < ActiveRecord::Migration
|
|
37
37
|
end
|
38
38
|
|
39
39
|
# PayPal -- how they let us know when a payment has cleared
|
40
|
-
create_table :
|
40
|
+
create_table :payment_handlers do |t|
|
41
41
|
t.text :params
|
42
42
|
t.integer :cart_id
|
43
43
|
t.string :status
|
@@ -52,7 +52,7 @@ class CreateEcommerceTables < ActiveRecord::Migration
|
|
52
52
|
drop_table :photos
|
53
53
|
drop_table :carts
|
54
54
|
drop_table :cart_items
|
55
|
-
drop_table :
|
55
|
+
drop_table :payment_handlers
|
56
56
|
end
|
57
57
|
|
58
58
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ecommerce
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jason Younker
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-04-
|
18
|
+
date: 2011-04-16 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -72,8 +72,10 @@ files:
|
|
72
72
|
- app/helpers/products_helper.rb
|
73
73
|
- app/models/cart.rb
|
74
74
|
- app/models/cart_item.rb
|
75
|
+
- app/models/payment_handler.rb
|
75
76
|
- app/models/photo.rb
|
76
77
|
- app/models/product.rb
|
78
|
+
- app/views/cart/confirmation.haml
|
77
79
|
- app/views/cart/index.haml
|
78
80
|
- app/views/layouts/application.html.erb
|
79
81
|
- app/views/products/_form.html.haml
|
@@ -98,6 +100,7 @@ files:
|
|
98
100
|
- db/seeds.rb
|
99
101
|
- doc/README_FOR_APP
|
100
102
|
- ecommerce-0.0.1.gem
|
103
|
+
- ecommerce-0.0.2.gem
|
101
104
|
- ecommerce.gemspec
|
102
105
|
- lib/ecommerce.rb
|
103
106
|
- lib/ecommerce/ecommerce.rb
|
@@ -116,6 +119,7 @@ files:
|
|
116
119
|
- public/robots.txt
|
117
120
|
- public/stylesheets/.gitkeep
|
118
121
|
- script/rails
|
122
|
+
- spec/models/payment_handler_spec.rb
|
119
123
|
- spec/spec_helper.rb
|
120
124
|
- test/performance/browsing_test.rb
|
121
125
|
- test/test_helper.rb
|
@@ -155,6 +159,7 @@ signing_key:
|
|
155
159
|
specification_version: 3
|
156
160
|
summary: Very simple ecommerce framework
|
157
161
|
test_files:
|
162
|
+
- spec/models/payment_handler_spec.rb
|
158
163
|
- spec/spec_helper.rb
|
159
164
|
- test/performance/browsing_test.rb
|
160
165
|
- test/test_helper.rb
|