Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

The PaymentDetails & PaymentDetailsItem objects are common between ap…

…i calls. Should return the same stuff
  • Loading branch information...
commit 6a88aa4ffd39d79656ff30b6b9521f9241f9468e 1 parent dd91818
@dscataglini authored
View
19 lib/active_merchant/billing/gateways/paypal.rb
@@ -51,24 +51,7 @@ def build_sale_or_authorization_request(action, money, credit_card_or_referenced
xml.tag! 'n2:' + transaction_type + 'RequestDetails' do
xml.tag! 'n2:ReferenceID', reference_id if transaction_type == 'DoReferenceTransaction'
xml.tag! 'n2:PaymentAction', action
- xml.tag! 'n2:PaymentDetails' do
- xml.tag! 'n2:OrderTotal', localized_amount(money, currency_code), 'currencyID' => currency_code
-
- # All of the values must be included together and add up to the order total
- if [:subtotal, :shipping, :handling, :tax].all?{ |o| options.has_key?(o) }
- xml.tag! 'n2:ItemTotal', localized_amount(options[:subtotal], currency_code), 'currencyID' => currency_code
- xml.tag! 'n2:ShippingTotal', localized_amount(options[:shipping], currency_code),'currencyID' => currency_code
- xml.tag! 'n2:HandlingTotal', localized_amount(options[:handling], currency_code),'currencyID' => currency_code
- xml.tag! 'n2:TaxTotal', localized_amount(options[:tax], currency_code), 'currencyID' => currency_code
- end
-
- xml.tag! 'n2:NotifyURL', options[:notify_url]
- xml.tag! 'n2:OrderDescription', options[:description]
- xml.tag! 'n2:InvoiceID', options[:order_id]
- xml.tag! 'n2:ButtonSource', application_id.to_s.slice(0,32) unless application_id.blank?
-
- add_address(xml, 'n2:ShipToAddress', options[:shipping_address]) if options[:shipping_address]
- end
+ add_payment_details(xml, money, currency_code, options)
add_credit_card(xml, credit_card_or_referenced_id, billing_address, options) unless transaction_type == 'DoReferenceTransaction'
xml.tag! 'n2:IPAddress', options[:ip]
end
View
80 lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb
@@ -118,6 +118,17 @@ def credit(money, identification, options = {})
end
private
+ def build_request_wrapper(action)
+ xml = Builder::XmlMarkup.new :indent => 2
+ xml.tag! action + 'Req', 'xmlns' => PAYPAL_NAMESPACE do
+ xml.tag! action + 'Request', 'xmlns:n2' => EBAY_NAMESPACE do
+ xml.tag! 'n2:Version', API_VERSION
+ yield(xml)
+ end
+ end
+ xml.target!
+ end
+
def build_reauthorize_request(money, authorization, options)
xml = Builder::XmlMarkup.new
@@ -313,11 +324,78 @@ def add_address(xml, element, address)
xml.tag! 'n2:CityName', address[:city]
xml.tag! 'n2:StateOrProvince', address[:state].blank? ? 'N/A' : address[:state]
xml.tag! 'n2:Country', address[:country]
- xml.tag! 'n2:Phone', address[:phone]
+ xml.tag! 'n2:Phone', address[:phone] unless address[:phone].blank?
xml.tag! 'n2:PostalCode', address[:zip]
end
end
+ def add_payment_details_items_xml(xml, options, currency_code)
+ options[:items].each do |item|
+ xml.tag! 'n2:PaymentDetailsItem' do
+ xml.tag! 'n2:Name', item[:name]
+ xml.tag! 'n2:Number', item[:number]
+ xml.tag! 'n2:Quantity', item[:quantity]
+ if item[:amount]
+ xml.tag! 'n2:Amount', localized_amount(item[:amount], currency_code), 'currencyID' => currency_code
+ end
+ xml.tag! 'n2:Description', item[:description]
+ xml.tag! 'n2:ItemURL', item[:url]
+ xml.tag! 'n2:ItemCategory', item[:category] if item[:category]
+ end
+ end
+ end
+
+ def add_payment_details(xml, money, currency_code, options = {})
+ xml.tag! 'n2:PaymentDetails' do
+ xml.tag! 'n2:OrderTotal', localized_amount(money, currency_code), 'currencyID' => currency_code
+
+ # All of the values must be included together and add up to the order total
+ if [:subtotal, :shipping, :handling, :tax].all?{ |o| options.has_key?(o) }
+ xml.tag! 'n2:ItemTotal', localized_amount(options[:subtotal], currency_code), 'currencyID' => currency_code
+ xml.tag! 'n2:ShippingTotal', localized_amount(options[:shipping], currency_code),'currencyID' => currency_code
+ xml.tag! 'n2:HandlingTotal', localized_amount(options[:handling], currency_code),'currencyID' => currency_code
+ xml.tag! 'n2:TaxTotal', localized_amount(options[:tax], currency_code), 'currencyID' => currency_code
+ end
+
+ xml.tag! 'n2:InsuranceTotal', localized_amount(options[:insurance_total], currency_code),'currencyID' => currency_code unless options[:insurance_total].blank?
+ xml.tag! 'n2:ShippingDiscount', localized_amount(options[:shipping_discount], currency_code),'currencyID' => currency_code unless options[:shipping_discount].blank?
+ xml.tag! 'n2:InsuranceOptionOffered', options[:insurance_option_offered] if options.has_key?(:insurance_option_offered)
+
+ xml.tag! 'n2:OrderDescription', options[:description] unless options[:description].blank?
+
+ # Custom field Character length and limitations: 256 single-byte alphanumeric characters
+ xml.tag! 'n2:Custom', options[:custom] unless options[:custom].blank?
+
+ xml.tag! 'n2:InvoiceID', (options[:order_id] || options[:invoice_id]) unless (options[:order_id] || options[:invoice_id]).blank?
+ xml.tag! 'n2:ButtonSource', application_id.to_s.slice(0,32) unless application_id.blank?
+
+ # The notify URL applies only to DoExpressCheckoutPayment.
+ # This value is ignored when set in SetExpressCheckout or GetExpressCheckoutDetails
+ xml.tag! 'n2:NotifyURL', options[:notify_url] unless options[:notify_url].blank?
+
+ add_address(xml, 'n2:ShipToAddress', options[:shipping_address]) unless options[:shipping_address].blank?
+
+ add_payment_details_items_xml(xml, options, currency_code) unless options[:items].blank?
+
+ add_express_only_payment_details(xml, options) if options[:express_request]
+
+ # Any value other than Y – This is not a recurring transaction
+ # To pass Y in this field, you must have established a billing agreement with
+ # the buyer specifying the amount, frequency, and duration of the recurring payment.
+ # requires version 80.0 of the API
+ xml.tag! 'n2:Recurring', options[:recurring] unless options[:recurring].blank?
+ end
+ end
+
+ def add_express_only_payment_details(xml, options = {})
+ %w{NoteText SoftDescriptor TransactionId AllowedPaymentMethodType
+ PaymentRequestID PaymentAction}.each do |optional_text_field|
+ field_as_symbol = optional_text_field.underscore.to_sym
+ xml.tag! 'n2:' + optional_text_field, options[field_as_symbol] unless options[field_as_symbol].blank?
+ end
+ xml
+ end
+
def endpoint_url
URLS[test? ? :test : :live][@options[:signature].blank? ? :certificate : :signature]
end
View
78 lib/active_merchant/billing/gateways/paypal_express.rb
@@ -71,24 +71,7 @@ def build_sale_or_authorization_request(action, money, options)
xml.tag! 'n2:PaymentAction', action
xml.tag! 'n2:Token', options[:token]
xml.tag! 'n2:PayerID', options[:payer_id]
- xml.tag! 'n2:PaymentDetails' do
- xml.tag! 'n2:OrderTotal', localized_amount(money, currency_code), 'currencyID' => currency_code
-
- # All of the values must be included together and add up to the order total
- if [:subtotal, :shipping, :handling, :tax].all?{ |o| options.has_key?(o) }
- xml.tag! 'n2:ItemTotal', localized_amount(options[:subtotal], currency_code), 'currencyID' => currency_code
- xml.tag! 'n2:ShippingTotal', localized_amount(options[:shipping], currency_code),'currencyID' => currency_code
- xml.tag! 'n2:HandlingTotal', localized_amount(options[:handling], currency_code),'currencyID' => currency_code
- xml.tag! 'n2:TaxTotal', localized_amount(options[:tax], currency_code), 'currencyID' => currency_code
- end
-
- xml.tag! 'n2:NotifyURL', options[:notify_url]
- xml.tag! 'n2:ButtonSource', application_id.to_s.slice(0,32) unless application_id.blank?
- xml.tag! 'n2:InvoiceID', options[:order_id]
- xml.tag! 'n2:OrderDescription', options[:description]
-
- add_items_xml(xml, options, currency_code) if options[:items]
- end
+ add_payment_details(xml, money, currency_code, options)
end
end
end
@@ -98,7 +81,10 @@ def build_sale_or_authorization_request(action, money, options)
def build_setup_request(action, money, options)
currency_code = options[:currency] || currency(money)
-
+ options[:payment_action] = action
+ options[:express_request] = true
+ options[:shipping_address] ||= options[:address]
+
xml = Builder::XmlMarkup.new :indent => 2
xml.tag! 'SetExpressCheckoutReq', 'xmlns' => PAYPAL_NAMESPACE do
xml.tag! 'SetExpressCheckoutRequest', 'xmlns:n2' => EBAY_NAMESPACE do
@@ -137,28 +123,8 @@ def build_setup_request(action, money, options)
xml.tag! 'n2:AllowNote', options[:allow_note] ? '1' : '0'
end
xml.tag! 'n2:CallbackURL', options[:callback_url] unless options[:callback_url].blank?
-
- xml.tag! 'n2:PaymentDetails' do
- xml.tag! 'n2:OrderTotal', amount(money).to_f.zero? ? localized_amount(100, currency_code) : localized_amount(money, currency_code), 'currencyID' => currency_code
- # All of the values must be included together and add up to the order total
- if [:subtotal, :shipping, :handling, :tax].all? { |o| options.has_key?(o) }
- xml.tag! 'n2:ItemTotal', localized_amount(options[:subtotal], currency_code), 'currencyID' => currency_code
- xml.tag! 'n2:ShippingTotal', localized_amount(options[:shipping], currency_code), 'currencyID' => currency_code
- xml.tag! 'n2:HandlingTotal', localized_amount(options[:handling], currency_code), 'currencyID' => currency_code
- xml.tag! 'n2:TaxTotal', localized_amount(options[:tax], currency_code), 'currencyID' => currency_code
- end
-
- xml.tag! 'n2:OrderDescription', options[:description]
- xml.tag! 'n2:InvoiceID', options[:order_id]
-
- add_address(xml, 'n2:ShipToAddress', options[:shipping_address] || options[:address])
-
- add_items_xml(xml, options, currency_code) if options[:items]
-
- xml.tag! 'n2:PaymentAction', action
- xml.tag! 'n2:Custom', options[:custom] unless options[:custom].blank?
- end
-
+
+ add_payment_details(xml, with_money_default(money), currency_code, options)
if options[:shipping_options]
options[:shipping_options].each do |shipping_option|
xml.tag! 'n2:FlatRateShippingOptions' do
@@ -180,7 +146,9 @@ def build_setup_request(action, money, options)
def build_reference_transaction_request(action, money, options)
currency_code = options[:currency] || currency(money)
-
+
+ # I am not sure why it's set like this for express gateway
+ # but I don't want to break the existing behavior
xml = Builder::XmlMarkup.new :indent => 2
xml.tag! 'DoReferenceTransactionReq', 'xmlns' => PAYPAL_NAMESPACE do
xml.tag! 'DoReferenceTransactionRequest', 'xmlns:n2' => EBAY_NAMESPACE do
@@ -189,13 +157,7 @@ def build_reference_transaction_request(action, money, options)
xml.tag! 'n2:ReferenceID', options[:reference_id]
xml.tag! 'n2:PaymentAction', action
xml.tag! 'n2:PaymentType', options[:payment_type] || 'Any'
- xml.tag! 'n2:PaymentDetails' do
- xml.tag! 'n2:OrderTotal', amount(money).to_f.zero? ? localized_amount(100, currency_code) : localized_amount(money, currency_code), 'currencyID' => currency_code
- xml.tag! 'n2:OrderDescription', options[:description]
- xml.tag! 'n2:InvoiceID', options[:invoice_id]
- xml.tag! 'n2:ButtonSource', 'ActiveMerchant'
- xml.tag! 'n2:NotifyURL', ''
- end
+ add_payment_details(xml, with_money_default(money), currency_code, options)
xml.tag! 'n2:IPAddress', options[:ip]
end
end
@@ -208,22 +170,8 @@ def build_response(success, message, response, options = {})
PaypalExpressResponse.new(success, message, response, options)
end
- private
-
- def add_items_xml(xml, options, currency_code)
- options[:items].each do |item|
- xml.tag! 'n2:PaymentDetailsItem' do
- xml.tag! 'n2:Name', item[:name]
- xml.tag! 'n2:Number', item[:number]
- xml.tag! 'n2:Quantity', item[:quantity]
- if item[:amount]
- xml.tag! 'n2:Amount', localized_amount(item[:amount], currency_code), 'currencyID' => currency_code
- end
- xml.tag! 'n2:Description', item[:description]
- xml.tag! 'n2:ItemURL', item[:url]
- xml.tag! 'n2:ItemCategory', item[:category] if item[:category]
- end
- end
+ def with_money_default(money)
+ amount(money).to_f.zero? ? 100 : money
end
end
end
View
76 test/unit/gateways/paypal/paypal_common_api_test.rb
@@ -0,0 +1,76 @@
+require 'test_helper'
+require 'active_merchant/billing/gateway'
+require File.expand_path(File.dirname(__FILE__) + '/../../../../lib/active_merchant/billing/gateways/paypal/paypal_common_api')
@dscataglini Owner

this is the change that will fix the warning.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+require 'nokogiri'
+
+class CommonPaypalGateway < ActiveMerchant::Billing::Gateway
+ include ActiveMerchant::Billing::PaypalCommonAPI
+ def currency(code); 'USD'; end
+ def localized_amount(num, code); num; end
+ def commit(a, b); end
+end
+
+class PaypalCommonApiTest < Test::Unit::TestCase
+ def setup
+ Base.mode = :test
+ CommonPaypalGateway.pem_file = nil
+
+ @gateway = CommonPaypalGateway.new(
+ :login => 'cody',
+ :password => 'test',
+ :pem => 'PEM'
+ )
+
+ @address = { :address1 => '1234 My Street',
+ :address2 => 'Apt 1',
+ :company => 'Widgets Inc',
+ :city => 'Ottawa',
+ :state => 'ON',
+ :zip => 'K1C2N6',
+ :country => 'Canada',
+ :phone => '(555)555-5555'
+ }
+ end
+
+ def xml_builder
+ Builder::XmlMarkup.new
+ end
+
+ def wrap_xml(&block)
+ REXML::Document.new(@gateway.send(:build_request_wrapper, 'Action', &block))
+ end
+
+ def test_add_payment_details_adds_express_only_payment_details_when_necessary
+ options = {:express_request => true}
+ @gateway.expects(:add_express_only_payment_details)
+ @gateway.send(:add_payment_details, xml_builder, 100, 'USD', options)
+ end
+
+ def test_add_payment_details_adds_items_details
+ options = {:items => [1]}
+ @gateway.expects(:add_payment_details_items_xml)
+ @gateway.send(:add_payment_details, xml_builder, 100, 'USD', options)
+ end
+
+ def test_add_payment_details_adds_address
+ options = {:shipping_address => @address}
+ @gateway.expects(:add_address)
+ @gateway.send(:add_payment_details, xml_builder, 100, 'USD', options)
+ end
+
+ def test_add_payment_details_adds_items_details_elements
+ options = {:items => [{:name => 'foo'}]}
+ request = wrap_xml do |xml|
+ @gateway.send(:add_payment_details, xml, 100, 'USD', options)
+ end
+ assert_equal 'foo', REXML::XPath.first(request, '//n2:PaymentDetails/n2:PaymentDetailsItem/n2:Name').text
+ end
+
+ def test_add_express_only_payment_details_adds_non_blank_fields
+ request = wrap_xml do |xml|
+ @gateway.send(:add_express_only_payment_details, xml, {:payment_action => 'Sale', :payment_request_id => ''})
+ end
+ assert_equal 'Sale', REXML::XPath.first(request, '//n2:PaymentAction').text
+ assert_nil REXML::XPath.first(request, '//n2:PaymentRequestID')
+ end
+end
View
13 test/unit/gateways/paypal_express_test.rb
@@ -329,6 +329,7 @@ def test_items_are_included_if_specified_in_build_sale_or_authorization_request
end
def test_build_reference_transaction_test
+ PaypalExpressGateway.application_id = 'ActiveMerchant_FOO'
xml = REXML::Document.new(@gateway.send(:build_reference_transaction_request, 'Sale', 2000, {
:reference_id => "ref_id",
:payment_type => 'Any',
@@ -343,7 +344,7 @@ def test_build_reference_transaction_test
assert_equal '20.00', REXML::XPath.first(xml, '//DoReferenceTransactionReq/DoReferenceTransactionRequest/n2:DoReferenceTransactionRequestDetails/n2:PaymentDetails/n2:OrderTotal').text
assert_equal 'Description', REXML::XPath.first(xml, '//DoReferenceTransactionReq/DoReferenceTransactionRequest/n2:DoReferenceTransactionRequestDetails/n2:PaymentDetails/n2:OrderDescription').text
assert_equal 'invoice_id', REXML::XPath.first(xml, '//DoReferenceTransactionReq/DoReferenceTransactionRequest/n2:DoReferenceTransactionRequestDetails/n2:PaymentDetails/n2:InvoiceID').text
- assert_equal 'ActiveMerchant', REXML::XPath.first(xml, '//DoReferenceTransactionReq/DoReferenceTransactionRequest/n2:DoReferenceTransactionRequestDetails/n2:PaymentDetails/n2:ButtonSource').text
+ assert_equal 'ActiveMerchant_FOO', REXML::XPath.first(xml, '//DoReferenceTransactionReq/DoReferenceTransactionRequest/n2:DoReferenceTransactionRequestDetails/n2:PaymentDetails/n2:ButtonSource').text
assert_equal '127.0.0.1', REXML::XPath.first(xml, '//DoReferenceTransactionReq/DoReferenceTransactionRequest/n2:DoReferenceTransactionRequestDetails/n2:IPAddress').text
end
@@ -415,6 +416,16 @@ def test_allow_guest_checkout
assert_equal 'Billing', REXML::XPath.first(xml, '//n2:LandingPage').text
end
+ def test_build_setup_request_money_defaults_money_to_100
+ xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', nil, {}))
+ assert_equal '1.00', REXML::XPath.first(xml, '//n2:OrderTotal').text
+ end
+
+ def test_build_reference_transaction_request_defaults_money_to_100
+ xml = REXML::Document.new(@gateway.send(:build_reference_transaction_request, 'Sale', nil, {}))
+ assert_equal '1.00', REXML::XPath.first(xml, '//n2:OrderTotal').text
+ end
+
def test_not_adds_brand_name_if_not_specified
xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 10, {}))
Please sign in to comment.
Something went wrong with that request. Please try again.