Skip to content

Instantly share code, notes, and snippets.

@Hates
Created November 6, 2014 18:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Hates/fb67e791c5d239efdbff to your computer and use it in GitHub Desktop.
Save Hates/fb67e791c5d239efdbff to your computer and use it in GitHub Desktop.
app/controllers/spree/paypal_controller_decorator.rb
Spree::PaypalController.class_eval do
def express
order = current_order || raise(ActiveRecord::RecordNotFound)
items = order.line_items.map(&method(:line_item))
additional_adjustments = order.all_adjustments.additional
tax_adjustments = additional_adjustments.tax
shipping_adjustments = additional_adjustments.shipping
additional_adjustments.eligible.each do |adjustment|
next if (shipping_adjustments).include?(adjustment)
items << {
:Name => adjustment.label,
:Quantity => 1,
:Amount => {
:currencyID => order.currency,
:value => adjustment.amount
}
}
end
# Because PayPal doesn't accept $0 items at all.
# See #10
# https://cms.paypal.com/uk/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_ECCustomizing
# "It can be a positive or negative value but not zero."
items.reject! do |item|
item[:Amount][:value].zero?
end
pp_request = provider.build_set_express_checkout(express_checkout_request_details(order, items))
begin
pp_response = provider.set_express_checkout(pp_request)
if pp_response.success?
redirect_to provider.express_checkout_url(pp_response, :useraction => 'commit')
else
flash[:error] = Spree.t('flash.generic_error', :scope => 'paypal', :reasons => pp_response.errors.map(&:long_message).join(" "))
redirect_to checkout_state_path(:payment)
end
rescue SocketError
flash[:error] = Spree.t('flash.connection_failed', :scope => 'paypal')
redirect_to checkout_state_path(:payment)
end
end
private
def payment_details items
# This retrieves the cost of shipping after promotions are applied
# For example, if shippng costs $10, and is free with a promotion, shipment_sum is now $10
shipment_sum = current_order.shipments.map(&:discounted_cost).sum
# This calculates the item sum based upon what is in the order total, but not for shipping
# or tax. This is the easiest way to determine what the items should cost, as that
# functionality doesn't currently exist in Spree core
item_sum = current_order.total - shipment_sum
if item_sum.zero?
# Paypal does not support no items or a zero dollar ItemTotal
# This results in the order summary being simply "Current purchase"
{
:OrderTotal => {
:currencyID => current_order.currency,
:value => current_order.total
}
}
else
{
:OrderTotal => {
:currencyID => current_order.currency,
:value => current_order.total
},
:ItemTotal => {
:currencyID => current_order.currency,
:value => item_sum
},
:ShippingTotal => {
:currencyID => current_order.currency,
:value => shipment_sum,
},
:ShipToAddress => address_options,
:PaymentDetailsItem => items,
:ShippingMethod => "Shipping Method Name Goes Here",
:PaymentAction => "Sale"
}
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment