#142 PayPal Notifications
PayPal's IPN (Instant Payment Notification) service allows your app to get confirmation when an order is processed. In this episode I use IPN to mark a cart as purchased.
- Download:
- source codeProject Files in Zip (103 KB)
- mp4Full Size H.264 Video (14.2 MB)
- m4vSmaller H.264 Video (10.3 MB)
- webmFull Size VP8 Video (28.3 MB)
- ogvFull Size Theora Video (19.7 MB)
Note: As mentioned at the end of this episode, this code should not be used in production as-is due to security problems. I will address these in the next episode.
Resources
- Episode 141: PayPal Basics
- Nifty Generators
- Order Management Integration Guide (PDF)
- Full Episode Source Code
bash
script/generate nifty_scaffold payment_notification params:text cart_id:integer status:string transaction_id:string create rake db:migrate curl -d "txn_id=3XC103945N720211C&invoice=923204115&payment_status=Completed" http://localhost:3000/payment_notifications
payment_notifications_controller.rb
protect_from_forgery :except => [:create] def create PaymentNotification.create!(:params => params, :cart_id => params[:invoice], :status => params[:payment_status], :transaction_id => params[:txn_id]) render :nothing => true end
models/payment_notification.rb
belongs_to :cart serialize :params after_create :mark_cart_as_purchased private def mark_cart_as_purchased if status == "Completed" cart.update_attribute(:purchased_at, Time.now) end end
controllers/application.rb
def current_cart if session[:cart_id] @current_cart ||= Cart.find(session[:cart_id]) session[:cart_id] = nil if @current_cart.purchased_at end if session[:cart_id].nil? @current_cart = Cart.create! session[:cart_id] = @current_cart.id end @current_cart end
models/cart.rb
def paypal_url(return_url, notify_url) values = { :business => 'seller_1229899173_biz@railscasts.com', :cmd => '_cart', :upload => 1, :return => return_url, :invoice => id, :notify_url => notify_url } line_items.each_with_index do |item, index| values.merge!({ "amount_#{index+1}" => item.unit_price, "item_name_#{index+1}" => item.product.name, "item_number_#{index+1}" => item.id, "quantity_#{index+1}" => item.quantity }) end "https://www.sandbox.paypal.com/cgi-bin/webscr?" + values.to_query end
carts/show.html.erb
<%= link_to "Checkout", @cart.paypal_url(products_url, payment_notifications_url) %>