Отправить данные PayPal зашифрованные из кода - PullRequest
1 голос
/ 17 августа 2011

Я работаю с Ruby On Rails 3, и я хотел бы сделать следующее, но из кода:

<% form_tag "https://www.sandbox.paypal.com/cgi-bin/webscr" do %>  
  <%= hidden_field_tag :cmd, "_s-xclick" %>  
  <%= hidden_field_tag :encrypted, @cart.paypal_encrypted(products_url, payment_notifications_url) %>  
    <p><%= submit_tag "Checkout" %></p>  
<% end %>

Я пробовал это в моей Cart модели, ноон никуда не перенаправляется, и я не знаю, что делать:

  PAYPAL_CERT_PEM = File.read("#{Rails.root}/certs/paypal_cert.pem")
  APP_CERT_PEM = File.read("#{Rails.root}/certs/app_cert.pem")
  APP_KEY_PEM = File.read("#{Rails.root}/certs/app_key.pem")

  PANEL = 'sandbox.paypal.com'
  PATH = '/cgi-bin/webscr'
  USERAGENT = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1'

  def paypal_url(order_id, return_url, notify_url)
    http = Net::HTTP.new(PANEL, 443)
    http.use_ssl = true

    http.verify_mode = OpenSSL::SSL::VERIFY_NONE

    # GET request -> so the host can set cookies
    resp, data = http.get2(PATH, {'User-Agent' => USERAGENT})
    cookie = resp.response['set-cookie'].split('; ')[0]

    values = {
        :cmd => '_s-xclick',
        :encrypted => paypal_encrypted(order_id, return_url, notify_url)
    }

    @headers = {
      'Cookie' => cookie,
      'Referer' => 'https://'+PANEL+PATH,
      'Content-Type' => 'application/x-www-form-urlencoded',
      'User-Agent' => USERAGENT
    }

    resp, data = http.post2(PATH, values.to_query, @headers)
  end

  def paypal_encrypted(order_id, return_url, notify_url)
    values      = {
        :business => 'seller_1234111143_biz@asciicasts.com',
        :cmd => '_cart',
        :upload => 1,
        :return => return_url,
        :invoice => order_id.to_s,
        :notify_url => notify_url,
        :currency_code => "USD"
    }

    items.each_with_index do |item, index|
      values.merge!({
                        "amount_#{index + 1}"      => item.unit_price,
                        "item_name_#{index + 1}"   => item.product.title,
                        "item_number_#{index + 1}" => item.product.id + Time.now.to_i,
                        "quantity_#{index + 1}"    => item.quantity.to_i
                    })
    end

    encrypt_for_paypal(values)
  end

  def encrypt_for_paypal(values)
      signed = OpenSSL::PKCS7::sign(OpenSSL::X509::Certificate.new(APP_CERT_PEM), OpenSSL::PKey::RSA.new(APP_KEY_PEM, ''), values.map { |k, v| "#{k}=#{v}" }.join("\n"), [], OpenSSL::PKCS7::BINARY)
      OpenSSL::PKCS7::encrypt([OpenSSL::X509::Certificate.new(PAYPAL_CERT_PEM)], signed.to_der, OpenSSL::Cipher::Cipher::new("DES3"), OpenSSL::PKCS7::BINARY).to_s.gsub("\n", "")
  end

Если вам интересно, почему я не могу просто использовать HTML-форму, это потому, что я позволяю пользователям выбирать между более чем однимОпция оплаты, используя радиополя, и после того, как они выберут одно, они нажимают кнопку «Отправить заказ», генерируя соответствующие движения в моей базе данных, прежде чем перенаправить на способ оплаты.

...