Added IPN support, initially only covers e-checks
This commit is contained in:
parent
1d4caea500
commit
038ae315b3
|
@ -0,0 +1 @@
|
||||||
|
*.swp
|
|
@ -1,8 +1,50 @@
|
||||||
class PaypalExpressCallbacksController < Admin::BaseController
|
class PaypalExpressCallbacksController < Spree::BaseController
|
||||||
def index
|
include ActiveMerchant::Billing::Integrations
|
||||||
render :text => "index"
|
skip_before_filter :verify_authenticity_token
|
||||||
end
|
|
||||||
def show
|
def notify
|
||||||
render :text => "text to render..."
|
@notification = Paypal::Notification.new(request.raw_post)
|
||||||
|
debugger
|
||||||
|
|
||||||
|
# we only care about eChecks (for now?)
|
||||||
|
if @notification.params["payment_type"] == "echeck" && @notification.acknowledge
|
||||||
|
case @notification.params["payment_status"]
|
||||||
|
when "Denied"
|
||||||
|
retrieve_details
|
||||||
|
create_txn PaypalTxn::TxnType::DENIED
|
||||||
|
|
||||||
|
when "Completed"
|
||||||
|
retrieve_details
|
||||||
|
create_txn PaypalTxn::TxnType::CAPTURE
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
render :nothing => true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def retrieve_details
|
||||||
|
@order = Order.find_by_number(@notification.params["invoice"])
|
||||||
|
@payment = @order.checkout.payments.find(:first,
|
||||||
|
:conditions => {"transactions.txn_type" => PaypalTxn::TxnType::AUTHORIZE,
|
||||||
|
"transactions.payment_type" => @notification.params["payment_type"]},
|
||||||
|
:joins => :transactions)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_txn(txn_type)
|
||||||
|
if @payment.can_finalize?
|
||||||
|
@payment.finalize!
|
||||||
|
PaypalTxn.create(:payment => @payment,
|
||||||
|
:txn_type => txn_type,
|
||||||
|
:amount => @notification.params["payment_gross"].to_f,
|
||||||
|
:payment_status => @notification.params["payment_status"],
|
||||||
|
:transaction_id => @notification.params["txn_id"],
|
||||||
|
:transaction_type => @notification.params["txn_type"],
|
||||||
|
:payment_type => @notification.params["payment_type"])
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class PaypalTxn < Transaction
|
class PaypalTxn < Transaction
|
||||||
enumerable_constant :txn_type, :constants => [:authorize, :capture, :purchase, :void, :credit]
|
enumerable_constant :txn_type, :constants => [:authorize, :capture, :purchase, :void, :credit, :denied, :unknown]
|
||||||
|
|
||||||
def txn_type_name
|
def txn_type_name
|
||||||
TxnType.from_value(txn_type)
|
TxnType.from_value(txn_type)
|
||||||
|
|
|
@ -4,7 +4,7 @@ map.resources :orders do |order|
|
||||||
order.resource :checkout, :member => {:paypal_checkout => :any, :paypal_payment => :any, :paypal_confirm => :any, :paypal_finish => :any}
|
order.resource :checkout, :member => {:paypal_checkout => :any, :paypal_payment => :any, :paypal_confirm => :any, :paypal_finish => :any}
|
||||||
end
|
end
|
||||||
|
|
||||||
map.resources :paypal_express_callbacks, :only => [:index]
|
map.paypal_notify "/paypal_notify", :controller => :paypal_express_callbacks, :action => :notify, :method => [:post, :get]
|
||||||
|
|
||||||
map.namespace :admin do |admin|
|
map.namespace :admin do |admin|
|
||||||
admin.resources :orders do |order|
|
admin.resources :orders do |order|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# aim to unpick this later
|
|
||||||
module Spree::PaypalExpress
|
module Spree::PaypalExpress
|
||||||
include ERB::Util
|
include ERB::Util
|
||||||
include ActiveMerchant::RequiresParameters
|
include ActiveMerchant::RequiresParameters
|
||||||
|
@ -7,13 +6,21 @@ module Spree::PaypalExpress
|
||||||
target.before_filter :redirect_to_paypal_express_form_if_needed, :only => [:update]
|
target.before_filter :redirect_to_paypal_express_form_if_needed, :only => [:update]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Outbound redirect to PayPal from Cart Page
|
||||||
|
# Not fully implmented or tested.
|
||||||
|
#
|
||||||
def paypal_checkout
|
def paypal_checkout
|
||||||
load_object
|
load_object
|
||||||
opts = all_opts(@order, params[:payment_method_id], 'checkout')
|
opts = all_opts(@order, params[:payment_method_id], 'checkout')
|
||||||
opts.merge!(address_options(@order))
|
opts.merge!(address_options(@order))
|
||||||
gateway = paypal_gateway
|
gateway = paypal_gateway
|
||||||
|
|
||||||
response = gateway.setup_authorization(opts[:money], opts)
|
if Spree::Config[:auto_capture]
|
||||||
|
response = gateway.setup_purchase(opts[:money], opts)
|
||||||
|
else
|
||||||
|
response = gateway.setup_authorization(opts[:money], opts)
|
||||||
|
end
|
||||||
|
|
||||||
unless response.success?
|
unless response.success?
|
||||||
gateway_error(response)
|
gateway_error(response)
|
||||||
redirect_to edit_order_url(@order)
|
redirect_to edit_order_url(@order)
|
||||||
|
@ -23,13 +30,20 @@ module Spree::PaypalExpress
|
||||||
redirect_to (gateway.redirect_url_for response.token, :review => payment_method.preferred_review)
|
redirect_to (gateway.redirect_url_for response.token, :review => payment_method.preferred_review)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Outbound redirect to PayPal from checkout payments step
|
||||||
|
#
|
||||||
def paypal_payment
|
def paypal_payment
|
||||||
load_object
|
load_object
|
||||||
opts = all_opts(@order,params[:payment_method_id], 'payment')
|
opts = all_opts(@order,params[:payment_method_id], 'payment')
|
||||||
opts.merge!(address_options(@order))
|
opts.merge!(address_options(@order))
|
||||||
gateway = paypal_gateway
|
gateway = paypal_gateway
|
||||||
|
|
||||||
response = gateway.setup_authorization(opts[:money], opts)
|
if Spree::Config[:auto_capture]
|
||||||
|
response = gateway.setup_purchase(opts[:money], opts)
|
||||||
|
else
|
||||||
|
response = gateway.setup_authorization(opts[:money], opts)
|
||||||
|
end
|
||||||
|
|
||||||
unless response.success?
|
unless response.success?
|
||||||
gateway_error(response)
|
gateway_error(response)
|
||||||
redirect_to edit_order_checkout_url(@order, :step => "payment")
|
redirect_to edit_order_checkout_url(@order, :step => "payment")
|
||||||
|
@ -39,6 +53,8 @@ module Spree::PaypalExpress
|
||||||
redirect_to (gateway.redirect_url_for response.token, :review => payment_method.preferred_review)
|
redirect_to (gateway.redirect_url_for response.token, :review => payment_method.preferred_review)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Inbound post from PayPal after (possible) successful completion
|
||||||
|
#
|
||||||
def paypal_confirm
|
def paypal_confirm
|
||||||
load_object
|
load_object
|
||||||
|
|
||||||
|
@ -92,6 +108,9 @@ module Spree::PaypalExpress
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Local call from A) Order Review Screen, or B) Automatically after paypal_confirm (no review).
|
||||||
|
# Completes checkout & order
|
||||||
|
#
|
||||||
def paypal_finish
|
def paypal_finish
|
||||||
load_object
|
load_object
|
||||||
|
|
||||||
|
@ -100,13 +119,23 @@ module Spree::PaypalExpress
|
||||||
|
|
||||||
if Spree::Config[:auto_capture]
|
if Spree::Config[:auto_capture]
|
||||||
ppx_auth_response = gateway.purchase((@order.total*100).to_i, opts)
|
ppx_auth_response = gateway.purchase((@order.total*100).to_i, opts)
|
||||||
txn_type = PaypalTxn::TxnType::CAPTURE
|
|
||||||
else
|
else
|
||||||
ppx_auth_response = gateway.authorize((@order.total*100).to_i, opts)
|
ppx_auth_response = gateway.authorize((@order.total*100).to_i, opts)
|
||||||
txn_type = PaypalTxn::TxnType::AUTHORIZE
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if ppx_auth_response.success?
|
if ppx_auth_response.success?
|
||||||
|
#confirm status
|
||||||
|
case ppx_auth_response.params["payment_status"]
|
||||||
|
when "Completed"
|
||||||
|
txn_type = PaypalTxn::TxnType::CAPTURE
|
||||||
|
when "Pending"
|
||||||
|
txn_type = PaypalTxn::TxnType::AUTHORIZE
|
||||||
|
else
|
||||||
|
txn_type = PaypalTxn::TxnType::UNKNOWN
|
||||||
|
Rails.logger.error "Unexpected response from PayPal Express"
|
||||||
|
Rails.logger.error ppx_auth_response.to_yaml
|
||||||
|
end
|
||||||
|
|
||||||
paypal_account = PaypalAccount.find_by_payer_id(params[:PayerID])
|
paypal_account = PaypalAccount.find_by_payer_id(params[:PayerID])
|
||||||
|
|
||||||
payment = @order.checkout.payments.create(:amount => ppx_auth_response.params["gross_amount"].to_f,
|
payment = @order.checkout.payments.create(:amount => ppx_auth_response.params["gross_amount"].to_f,
|
||||||
|
@ -136,13 +165,17 @@ module Spree::PaypalExpress
|
||||||
end
|
end
|
||||||
complete_checkout
|
complete_checkout
|
||||||
|
|
||||||
if Spree::Config[:auto_capture]
|
# even with auto_capture , an Auth might be returned / forced by PPX
|
||||||
|
if Spree::Config[:auto_capture] && txn_type == PaypalTxn::TxnType::CAPTURE
|
||||||
payment.finalize!
|
payment.finalize!
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
order_params = {}
|
order_params = {}
|
||||||
gateway_error(ppx_auth_response)
|
gateway_error(ppx_auth_response)
|
||||||
|
|
||||||
|
#Failed trying to complete pending payment!
|
||||||
|
redirect_to edit_order_checkout_url(@order, :step => "payment")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -173,11 +206,8 @@ module Spree::PaypalExpress
|
||||||
:background_color => "ffffff", # must be hex only, six chars
|
:background_color => "ffffff", # must be hex only, six chars
|
||||||
:header_background_color => "ffffff",
|
:header_background_color => "ffffff",
|
||||||
:header_border_color => "ffffff",
|
:header_border_color => "ffffff",
|
||||||
|
|
||||||
:allow_note => true,
|
:allow_note => true,
|
||||||
:locale => Spree::Config[:default_locale],
|
:locale => Spree::Config[:default_locale],
|
||||||
:notify_url => 'to be done', # this is a callback, not tried it yet
|
|
||||||
|
|
||||||
:req_confirm_shipping => false, # for security, might make an option later
|
:req_confirm_shipping => false, # for security, might make an option later
|
||||||
:user_action => user_action
|
:user_action => user_action
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue