@@ -7,9 +7,12 @@ def express
77 items = order . line_items . map ( &method ( :line_item ) )
88
99 additional_adjustments = order . all_adjustments . additional
10- tax_adjustments = additional_adjustments . tax
1110 shipping_adjustments = additional_adjustments . shipping
1211
12+ # we remove taxes refunds (negative amounts) from taxes
13+ # because paypal doesn't accept negative taxes
14+ tax_adjustments , negative_tax_adjustments = split_tax_adjustments ( order )
15+
1316 additional_adjustments . eligible . each do |adjustment |
1417 next if ( tax_adjustments + shipping_adjustments ) . include? ( adjustment )
1518 items << {
@@ -87,8 +90,9 @@ def line_item(item)
8790 }
8891 end
8992
90- def express_checkout_request_details order , items
91- { :SetExpressCheckoutRequestDetails => {
93+ def express_checkout_request_details ( order , items )
94+ {
95+ :SetExpressCheckoutRequestDetails => {
9296 :InvoiceID => order . number ,
9397 :ReturnURL => confirm_paypal_url ( :payment_method_id => params [ :payment_method_id ] , :utm_nooverride => 1 ) ,
9498 :CancelURL => cancel_paypal_url ,
@@ -97,7 +101,8 @@ def express_checkout_request_details order, items
97101 :cppheaderimage => payment_method . preferred_logourl . present? ? payment_method . preferred_logourl : "" ,
98102 :NoShipping => 1 ,
99103 :PaymentDetails => [ payment_details ( items ) ]
100- } }
104+ }
105+ }
101106 end
102107
103108 def payment_method
@@ -108,15 +113,19 @@ def provider
108113 payment_method . provider
109114 end
110115
111- def payment_details items
116+ def payment_details ( items )
112117 # This retrieves the cost of shipping after promotions are applied
113118 # For example, if shippng costs $10, and is free with a promotion, shipment_sum is now $10
114119 shipment_sum = current_order . shipments . map ( &:discounted_cost ) . sum
115120
121+ tax_adjustments , negative_tax_adjustments = split_tax_adjustments ( current_order )
122+ negative_tax_adjustments_sum = negative_tax_adjustments . map ( &:amount ) . sum
123+ tax_adjustments_sum = tax_adjustments . map ( &:amount ) . sum
124+
116125 # This calculates the item sum based upon what is in the order total, but not for shipping
117126 # or tax. This is the easiest way to determine what the items should cost, as that
118127 # functionality doesn't currently exist in Spree core
119- item_sum = current_order . total - shipment_sum - current_order . additional_tax_total
128+ item_sum = current_order . total - shipment_sum - current_order . additional_tax_total + negative_tax_adjustments_sum
120129
121130 if item_sum . zero?
122131 # Paypal does not support no items or a zero dollar ItemTotal
@@ -143,7 +152,7 @@ def payment_details items
143152 } ,
144153 :TaxTotal => {
145154 :currencyID => current_order . currency ,
146- :value => current_order . additional_tax_total
155+ :value => tax_adjustments_sum
147156 } ,
148157 :ShipToAddress => address_options ,
149158 :PaymentDetailsItem => items ,
@@ -175,5 +184,11 @@ def completion_route(order)
175184 def address_required?
176185 payment_method . preferred_solution . eql? ( 'Sole' )
177186 end
187+
188+ def split_tax_adjustments ( order )
189+ @split_tax_adjustments ||= order . all_adjustments . additional . tax . partition do |a |
190+ a . amount >= 0
191+ end
192+ end
178193 end
179194end
0 commit comments