Skip to content

Commit

Permalink
Updated to supported latest edge PaymentMethods (very edge)
Browse files Browse the repository at this point in the history
  • Loading branch information
BDQ committed Feb 24, 2010
1 parent 0bcbdaa commit fb0ac7b
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 66 deletions.
53 changes: 53 additions & 0 deletions app/models/paypal_account.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
class PaypalAccount < ActiveRecord::Base
has_many :payments, :as => :source

def finalize!(payment)
authorization = find_authorization

ppx_response = p.payment_method.capture((100 * payment.amount).to_i, authorization.transaction_id)
if ppx_response.success?
payment = authorization.paypal_payment

transaction = PaypalTxn.new(:payment => payment,
:amount => ppx_response.params["gross_amount"].to_f,
:message => ppx_response.params["message"],
:payment_status => ppx_response.params["payment_status"],
:pending_reason => ppx_response.params["pending_reason"],
:transaction_id => ppx_response.params["transaction_id"],
:transaction_type => ppx_response.params["transaction_type"],
:payment_type => ppx_response.params["payment_type"],
:ack => ppx_response.params["ack"],
:token => ppx_response.params["token"],
:avs_response => ppx_response.avs_result["code"],
:cvv_response => ppx_response.cvv_result["code"])

payment.paypal_txns << transaction

payment.save
else
gateway_error(ppx_response)
end


end


private
def find_authorization(payment)
#find the transaction associated with the original authorization/capture
txns.find(:first,
:conditions => {:pending_reason => "authorization", :payment_status => "Pending"},
:order => 'created_at DESC')
end

def find_capture(payment)
#find the transaction associated with the original authorization/capture
txns.find(:first,
:conditions => {:payment_status => "Completed"},
:order => 'created_at DESC')
end

def can_capture?(payment)
find_capture.nil?
end
end
23 changes: 0 additions & 23 deletions app/models/paypal_payment.rb

This file was deleted.

8 changes: 6 additions & 2 deletions app/models/paypal_txn.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
class PaypalTxn < ActiveRecord::Base
belongs_to :paypal_payment
class PaypalTxn < Transaction
enumerable_constant :txn_type, :constants => [:authorize, :capture, :purchase, :void, :credit]

def txn_type_name
TxnType.from_value(txn_type)
end
end
3 changes: 3 additions & 0 deletions app/views/checkouts/payment/_paypalexpress.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<a href="<%= paypal_payment_order_checkout_url @order, :payment_method_id => payment_method %>" style="text-align: center;">
<img src="https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif" align="left" style="margin-right:7px;"/>
</a>
3 changes: 0 additions & 3 deletions app/views/shared/_paypal_express_payment.html.erb

This file was deleted.

2 changes: 1 addition & 1 deletion db/migrate/20100122120551_create_paypal_txns.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class CreatePaypalTxns < ActiveRecord::Migration
def self.up
create_table :paypal_txns do |t|
create_table :paypal_txns do |t|
t.references :paypal_payment
t.decimal :gross_amount, :precision => 8, :scale => 2
t.string :payment_status
Expand Down
14 changes: 14 additions & 0 deletions db/migrate/20100224133156_create_paypal_accounts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class CreatePaypalAccounts < ActiveRecord::Migration
def self.up
create_table :paypal_accounts do |t|
t.string :email
t.string :payer_id
t.string :payer_country
t.string :payer_status
end
end

def self.down
drop_table :paypal_accounts
end
end
26 changes: 26 additions & 0 deletions db/migrate/20100224181116_make_paypal_txn_sti.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
class MakePaypalTxnSti < ActiveRecord::Migration
def self.up
add_column :transactions, :payment_status, :string
add_column :transactions, :message, :string
add_column :transactions, :pending_reason, :string
add_column :transactions, :transaction_id, :string
add_column :transactions, :transaction_type, :string
add_column :transactions, :payment_type, :string
add_column :transactions, :token, :string

#to-do migrate existing ppx_txns

drop_table :paypal_txns

end

def self.down
remove_column :transactions, :payment_status
remove_column :transactions, :message
remove_column :transactions, :pending_reason
remove_column :transactions, :transaction_id
remove_column :transactions, :transaction_type
remove_column :transactions, :payment_type
remove_column :transactions, :token
end
end
100 changes: 63 additions & 37 deletions lib/spree/paypal_express.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Spree::PaypalExpress

def paypal_checkout
load_object
opts = all_opts(@order, 'checkout')
opts = all_opts(@order, params[:payment_method_id], 'checkout')
opts.merge!(address_options(@order))
gateway = paypal_gateway

Expand All @@ -16,12 +16,12 @@ def paypal_checkout
return
end

redirect_to (gateway.redirect_url_for response.token)
redirect_to (gateway.redirect_url_for response.token, :review => review)
end

def paypal_payment
load_object
opts = all_opts(@order, 'payment')
opts = all_opts(@order,params[:payment_method_id], 'payment')
opts.merge!(address_options(@order))
gateway = paypal_gateway

Expand All @@ -32,23 +32,28 @@ def paypal_payment
return
end

redirect_to (gateway.redirect_url_for response.token)
redirect_to (gateway.redirect_url_for response.token, :review => review)
end

def paypal_confirm
load_object

opts = { :token => params[:token], :payer_id => params[:PayerID] }.merge all_opts(@order)
opts = { :token => params[:token], :payer_id => params[:PayerID] }.merge all_opts(@order, params[:payment_method_id])
gateway = paypal_gateway

@ppx_details = gateway.details_for params[:token]

if @ppx_details.success?
# now save the updated order info
@order.checkout.email = @ppx_details.email

PaypalAccount.create(:email => @ppx_details.params["payer"],
:payer_id => @ppx_details.params["payer_id"],
:payer_country => @ppx_details.params["payer_country"],
:payer_status => @ppx_details.params["payer_status"])

@order.checkout.special_instructions = @ppx_details.params["note"]

@order.update_attribute(:user, current_user)
#@order.update_attribute(:user, current_user)

ship_address = @ppx_details.address
order_ship_address = Address.new :firstname => @ppx_details.params["first_name"],
Expand All @@ -71,17 +76,21 @@ def paypal_confirm

@order.checkout.ship_address = order_ship_address
@order.checkout.save
render :partial => "shared/paypal_express_confirm", :layout => true

if review
render :partial => "shared/paypal_express_confirm", :layout => true
else
paypal_finish
end
else
gateway_error(@ppx_details)
end
end

def paypal_finish
load_object
#order = Order.find_by_number(params[:id])

opts = { :token => params[:token], :payer_id => params[:PayerID] }.merge all_opts(@order)
opts = { :token => params[:token], :payer_id => params[:PayerID] }.merge all_opts(@order, params[:payment_method_id])
gateway = paypal_gateway

if Spree::Config[:auto_capture]
Expand All @@ -91,23 +100,26 @@ def paypal_finish
end

if ppx_auth_response.success?
paypal_account = PaypalAccount.find_by_payer_id(params[:PayerID])

payment = @order.checkout.payments.create(:amount => ppx_auth_response.params["gross_amount"].to_f,
:source => paypal_account,
:payment_method_id => params[:payment_method_id])

PaypalTxn.create(:payment => payment,
:txn_type => PaypalTxn::TxnType::AUTHORIZE,
:amount => ppx_auth_response.params["gross_amount"].to_f,
:message => ppx_auth_response.params["message"],
:payment_status => ppx_auth_response.params["payment_status"],
:pending_reason => ppx_auth_response.params["pending_reason"],
:transaction_id => ppx_auth_response.params["transaction_id"],
:transaction_type => ppx_auth_response.params["transaction_type"],
:payment_type => ppx_auth_response.params["payment_type"],
:response_code => ppx_auth_response.params["ack"],
:token => ppx_auth_response.params["token"],
:avs_response => ppx_auth_response.avs_result["code"],
:cvv_response => ppx_auth_response.cvv_result["code"])

payment = @order.paypal_payments.create(:amount => ppx_auth_response.params["gross_amount"].to_f)

transaction = PaypalTxn.new(:paypal_payment => payment,
:gross_amount => ppx_auth_response.params["gross_amount"].to_f,
:message => ppx_auth_response.params["message"],
:payment_status => ppx_auth_response.params["payment_status"],
:pending_reason => ppx_auth_response.params["pending_reason"],
:transaction_id => ppx_auth_response.params["transaction_id"],
:transaction_type => ppx_auth_response.params["transaction_type"],
:payment_type => ppx_auth_response.params["payment_type"],
:ack => ppx_auth_response.params["ack"],
:token => ppx_auth_response.params["token"],
:avs_response => ppx_auth_response.avs_result["code"],
:cvv_response => ppx_auth_response.cvv_result["code"])

payment.paypal_txns << transaction

@order.save!
@checkout.reload
Expand Down Expand Up @@ -135,15 +147,16 @@ def paypal_capture(authorization)
if ppx_response.success?
payment = authorization.paypal_payment

transaction = PaypalTxn.new(:paypal_payment => payment,
:gross_amount => ppx_response.params["gross_amount"].to_f,
transaction = PaypalTxn.new(:payment => payment,
:txn_type => PaypalTxn::TxnType::CAPTURE,
:amount => ppx_response.params["gross_amount"].to_f,
:message => ppx_response.params["message"],
:payment_status => ppx_response.params["payment_status"],
:pending_reason => ppx_response.params["pending_reason"],
:transaction_id => ppx_response.params["transaction_id"],
:transaction_type => ppx_response.params["transaction_type"],
:payment_type => ppx_response.params["payment_type"],
:ack => ppx_response.params["ack"],
:response_code => ppx_response.params["ack"],
:token => ppx_response.params["token"],
:avs_response => ppx_response.avs_result["code"],
:cvv_response => ppx_response.cvv_result["code"])
Expand Down Expand Up @@ -185,6 +198,12 @@ def paypal_refund(authorization, amount=nil)

private
def fixed_opts
if Spree::Config[:paypal_express_local_confirm].nil?
user_action = "continue"
else
user_action = Spree::Config[:paypal_express_local_confirm] == "t" ? "continue" : "commit"
end

{ :description => "Goods from #{Spree::Config[:site_name]}", # site details...

#:page_style => "foobar", # merchant account can set named config
Expand All @@ -198,14 +217,15 @@ def fixed_opts
:notify_url => 'to be done', # this is a callback, not tried it yet

:req_confirm_shipping => false, # for security, might make an option later
:user_action => user_action

# WARNING -- don't use :ship_discount, :insurance_offered, :insurance since
# they've not been tested and may trigger some paypal bugs, eg not showing order
# see http://www.pdncommunity.com/t5/PayPal-Developer-Blog/Displaying-Order-Details-in-Express-Checkout/bc-p/92902#C851
}
end

def order_opts(order, stage)
def order_opts(order, payment_method, stage)
items = order.line_items.map do |item|
tax = paypal_variant_tax(item.price, item.variant)
price = (item.price * 100).to_i # convert for gateway
Expand All @@ -223,7 +243,7 @@ def order_opts(order, stage)
end


opts = { :return_url => request.protocol + request.host_with_port + "/orders/#{order.number}/checkout/paypal_confirm",
opts = { :return_url => request.protocol + request.host_with_port + "/orders/#{order.number}/checkout/paypal_confirm?payment_method_id=#{payment_method}",
:cancel_return_url => "http://" + request.host_with_port + "/orders/#{order.number}/edit",
:order_id => order.number,
:custom => order.number,
Expand Down Expand Up @@ -285,9 +305,8 @@ def address_options(order)
}
end

def all_opts(order, stage=nil)
opts = fixed_opts.merge(order_opts(order, stage))#.
# merge(paypal_site_options order) BQ
def all_opts(order, payment_method, stage=nil)
opts = fixed_opts.merge(order_opts(order, payment_method, stage))

if stage == "payment"
opts.merge! flat_rate_shipping_and_handling_options(order, stage)
Expand Down Expand Up @@ -334,9 +353,16 @@ def gateway_error(response)

# create the gateway from the supplied options
def paypal_gateway
integration = BillingIntegration.find(params[:integration_id]) if params.key? :integration_id
integration ||= BillingIntegration.current

integration = PaymentMethod.find(params[:payment_method_id])
gateway = integration.provider
end

# if you want to confirm the order on Paypal's site, then this needs to return false
def review
if Spree::Config[:paypal_express_review].nil?
true
else
Spree::Config[:paypal_express_review] == "t" ? true : false
end
end
end

0 comments on commit fb0ac7b

Please sign in to comment.