Class: PaymentNotificationsController

Inherits:
ApplicationController
  • Object
show all
Defined in:
app/controllers/payment_notifications_controller.rb

Instance Method Summary collapse

Instance Method Details

#createObject



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'app/controllers/payment_notifications_controller.rb', line 5

def create
  if(Spree::Paypal::Config[:encryption] && (params[:secret] != Spree::Paypal::Config[:ipn_secret]))
    logger.info "PayPal_Website_Standard: attempt to send an IPN with invalid secret"
    raise Exception
  end
  
  @order = Order.find_by_number(params[:invoice])
  PaymentNotification.create!(:params => params, 
    :order_id => @order.id,
    :status => params[:payment_status], 
    :transaction_id => params[:txn_id])
  logger.info "PayPal_Website_Standard: processing payment notification for invoice #{params["invoice"]}, amount is #{params["mc_gross"]} #{params["mc_currency"]}"
  
  # this logging stuff won't live here for long...

  Order.transaction do
    # main part of hacks
    order = @order

    #create payment for this order
    payment = Payment.new
    
    # 1. Assume that if payment notification comes, it's exactly for the amount
    # sent to paypal (safe assumption -- cart can't be edited while on paypal)
    # 2. Can't use Order#total, as it's intercepted by spree-multi-currency
    # which might lead to lots of false "credit owed" payment states
    # (when they should be "complete")
    payment.amount = order.read_attribute(:total)
    logger.info "PayPal_Website_Standard: set payment.amount to #{payment.amount} based on order's total #{order.read_attribute(:total)}"
    
    payment.payment_method = Order.paypal_payment_method
    order.payments << payment
    payment.started_processing

    order.payment.complete
    logger.info("PayPal_Website_Standard: order #{order.number} (#{order.id}) -- completed payment")
    while order.state != "complete"
       order.next
       logger.info("PayPal_Website_Standard: advanced state of Order #{order.number} (#{order.id}). current state #{order.state}. thread #{Thread.current.to_s}. issuing callback")
       state_callback(:after) # that line will run all _not run before_ callbacks
    end
    order.update_totals
    order.update!
    logger.info("PayPal_Website_Standard: Order #{order.number} (#{order.id}) updated successfully, IPN complete")
  end
  
  render :nothing => true
end