ecommerce 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- if request_seems_to_be_valid()
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
- if request_seems_to_be_valid()
29
- PaymentNotification.create!(:params => params,
30
- :cart_id => params[:invoice],
31
- :status => params[:payment_status].downcase,
32
- :transaction_id => params[:txn_id])
33
- else
34
- Rails.logger.warn("Something was wrong with this transaction! See PaymentNotification entry for cart_id #{params[:invoice]} and transaction_id #{params[:txn_id]}")
35
- end
36
- render :nothing => true
37
- end
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
@@ -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
@@ -1,7 +1,7 @@
1
1
  class Product < ActiveRecord::Base
2
2
  include ActionView::Helpers::NumberHelper
3
3
 
4
- validates_presence_of :name, :permalink
4
+ validates_presence_of :name, :permalink, :shipping_weight
5
5
 
6
6
  has_many :photos
7
7
 
@@ -0,0 +1,2 @@
1
+ :ruby
2
+ page_title("Your order has been received. Thank you!")
@@ -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(File.expand_path('../../ecommerce.yml', __FILE__)))[env]
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")
@@ -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
Binary file
@@ -1,3 +1,3 @@
1
1
  module Ecommerce
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -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.int :shipping_weight
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 :payment_notifications do |t|
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 :payment_notifications
55
+ drop_table :payment_handlers
56
56
  end
57
57
 
58
58
  end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe PaymentHandler do
4
+ pending "add some examples to (or delete) #{__FILE__}"
5
+ 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: 27
4
+ hash: 25
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
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-03 00:00:00 -07:00
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