Customizing Paypal Express's Review Page using

2019-03-20 17:10发布

I am using ActiveMerchant to give my rails app access to Paypal's Express Checkout. I would like to include the Order Details on the Review Page as described here: https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_ECCustomizing

Can this be done?

Currently, my controller code looks like this:

def paypal
  #currently, options is unused, I'm not sure where to send this info
  options = { 
              :L_NAME0=>"Tickets", 
              :L_QTY0=>@payment.quantity, 
              :L_DESC0=>"Tickets for #{@payment.event_name}",
              :L_AMT0=>@payment.unit_price
            }

  #the actual code that gets used
  setup_response = gateway.setup_purchase(@payment.amount,
    :ip=> request.remote_ip,
    :return_url=> url_for(:action=>:confirm, :id=>@payment.id, :only_path=>false),
    :cancel_return_url => url_for(:action=>:show, :id=>@payment.id, :only_path=>false)
  )
  redirect_to gateway.redirect_url_for(setup_response.token)
end

If what I'm trying to do is possible, what do I need to change?

4条回答
混吃等死
2楼-- · 2019-03-20 17:55

@Soleone I try your solution,but don't work for me.

xml.tag! 'n2:OrderDescription', options[:description]
xml.tag! 'n2:Name', options[:name]
xml.tag! 'n2:Description', options[:desc]
xml.tag! 'n2:Amount', options[:amount]
xml.tag! 'n2:Quantity', options[:quantity]

I think the xml structure is not right,the order items is multiple,so should like this

xml.tag! 'n2:OrderItems' do
    xml.tag! 'n2:OrderItem' do
        xml.tag! 'n2:Name', options[:name]
        xml.tag! 'n2:Description', options[:desc]
        xml.tag! 'n2:Amount', options[:amount]
        xml.tag! 'n2:Quantity', options[:quantity]
    end
end

But really I don't know the correct structure,looking for now.

====Update

I found the SOAP api doc, https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_soap_r_SetExpressCheckout#id09BHC0QF07Q

xml.tag! 'n2:PaymentDetails' do
    xml.tag! 'n2:PaymentDetailsItem' do
        xml.tag! 'n2:Name', options[:name]
        xml.tag! 'n2:Description', options[:desc]
        xml.tag! 'n2:Amount', options[:amount]
        xml.tag! 'n2:Quantity', options[:quantity]
    end
end

But also doesn't work,who can help?

=====UPDATE====

I tried the method of adding PaymentDetails parameter,but seems still not work,I found the schema of SetExpressCheckoutReq xml, http://www.visualschema.com/vs/paypal/SetExpressCheckoutReq/ , there is no definition of PaymentDetails,who did this stuff before,hope for your help.

======FINAL========

I have fixed this issue,new version of ActiveMerchant support the order details review,and mwagg pushed the patch about this,you guys can use this version https://github.com/mwagg/active_merchant

查看更多
forever°为你锁心
3楼-- · 2019-03-20 18:00

You can see the available parameters in this table (only the middle column applies as activemerchant is using the SOAP API):

https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_ECCustomizing#id086NA300I5Z__id086NAC0J0PN

To best understand how activemerchant does it is probably to look directly into the implementation. You can see the relevant parameters getting inserted in the SOAP XML request (currently) starting at line 98 where the OrderTotal gets inserted:

https://github.com/Shopify/active_merchant/blob/master/lib/active_merchant/billing/gateways/paypal_express.rb#L98

Notice how the parameters are fetched from the options hash so you can see the correct symbol to pass for each one here.

In your case as you listed the following parameters, you would do it like this:

def paypal
  options = { 
    :name => "Tickets", 
    :quantity => @payment.quantity, 
    :description => "Tickets for #{@payment.event_name}",
    :amount => @payment.unit_price
    :ip => request.remote_ip,
    :return_url => url_for(:action=>:confirm, :id=>@payment.id, :only_path=>false),
    :cancel_return_url => url_for(:action=>:show, :id=>@payment.id, :only_path=>false)
  }

  # the actual code that gets used
  setup_response = gateway.setup_purchase(@payment.amount, options)
  redirect_to gateway.redirect_url_for(setup_response.token)
end

Note though: The name, quantity and amount fields are currently not support in activemerchant. You would have to fork the repository and insert these yourself and use your copy of the project. It's really very straightforward when you look at the code and see how it is done with the other ones.

For example to add the order name, item quantity and item unit price you would put these lines after the OrderDescription gets inserted:

  xml.tag! 'n2:Name', options[:name]
  xml.tag! 'n2:Amount', options[:amount]
  xml.tag! 'n2:Quantity', options[:quantity]

Hope that helps!

UPDATE:

Okay I think according to the XML Schema for the SOAP API it looks like you have to specify it like this in activemerchant:

xml.tag! 'n2:PaymentDetails' do
  items = options[:items] || []
  items.each do |item|
    xml.tag! 'n2:PaymentDetailsItem' do
      xml.tag! 'n2:Name', item[:name]
      xml.tag! 'n2:Description', item[:desc]
      xml.tag! 'n2:Amount', item[:amount]
      xml.tag! 'n2:Quantity', item[:quantity]
    end
  end
end

And you would pass all your items in your Rails app like this:

options = {
  :items => [
    { 
      :name => "Tickets", 
      :quantity => @payment.quantity, 
      :description => "Tickets for #{@payment.event_name}",
      :amount => @payment.unit_price
    },
    { 
      :name => "Other product", 
      :quantity => @other_payment.quantity, 
      :description => "Something else for #{@other_payment.event_name}",
      :amount => @other_payment.unit_price
    }
  ]
  :ip => request.remote_ip,
  :return_url => url_for(:action=>:confirm, :id=>@payment.id, :only_path=>false),
  :cancel_return_url => url_for(:action=>:show, :id=>@payment.id, :only_path=>false) 
}

Hope that works better, good luck!

查看更多
戒情不戒烟
4楼-- · 2019-03-20 18:02

I also had problems to get this to work. The solution is that the sum of the amount of all items must be the subtotal of the order, where the subtotal, shipping, handling and tax must sum up to the total value of the order. My paypal controller looks like this:

def begin_paypal
  # ...
  options = express_options(@order)
  # ... 
  response = EXPRESS_GATEWAY.setup_purchase(@order.gross_price_in_cent, options)
  redirect_to EXPRESS_GATEWAY.redirect_url_for(response.token)
end

private
def express_options order
  options = {}
  options[:ip] = request.remote_ip
  options[:order_id] = order.bearbeitungsnummer

  # subtotal, shipping, handling and tax must sum up to the orders total value
  # subtotal must be the sum of all amounts of all items
  options[:subtotal] = order.gross_price_in_cent
  options[:shipping] = 0
  options[:handling] = 0
  options[:tax] = 0

  options[:items] = order.line_items.map do |line_item|
    {
      :name => line_item.product.name,
      :number => line_item.product.kcode,
      :quantity => line_item.quantity,
      :description => line_item.product.beschreibung,
      :amount => line_item.gross_price_in_cent,
      :url => nil
    }
  end
  # ...
end

Works fine

查看更多
三岁会撩人
5楼-- · 2019-03-20 18:06

Make sure you have activemerchant version not less than 1.12.0.

EXPRESS_GATEWAY.setup_purchase(220,
  :items => [{:name => "Tickets", :quantity => 22,:description => "Tickets for 232323",                          :amount => 10}],
  :return_url => 'example.com',
  :cancel_return_url => 'example.com'
)

Hope this helps :)

查看更多
登录 后发表回答