viernes, 18 de marzo de 2011

Integración con Moneybookers con formulario HTML

¿Quieres integrar una pasarela de pagos en tu aplicación rails? ¿Prefieres integrar con moneybookers en lugar de la típica pasarela de paypal? Pues hay dos formas: con un formulario html que describe moneybookers o con una gema para realizar el submit del formulario desde nuestro servidor rails. Ambas soluciones utilizan activemerchant.

Antes de empezar a tirar código, date de alta en moneybookers como "merchant", es decir, como vendedor. Créate también una cuenta como comprador. Luego les mandas un mail y les dices que hagan que esas cuentas sean de prueba, para que puedas empezar a integrar. Si necesitas pagos recurrentes, también tendrás que mandarles un mail. Si sólo vas a utilizar unos determinados tipos de pago, tendrás que enviarles un mail para que te habiliten el fixed split gateway... En resumen, todo por mail... y un poco lento.

Parece ser que no permiten pagos recurrentes para usuarios que no tengan cuenta de comprador en moneybookers: FAIL.

Moneybookers describe en su manual y en su página de pruebas, el contenido del formulario que se debe enviar a su servidor. Así mismo, activemerchant tiene un módulo de "integraciones" que permite generar formularios de este tipo para varias pasarelas.

En cuanto a los parámetros, hay que destacar los siguientes:
  • return_url_target y cancel_url_target permiten pasar el nombre de un iframe para incrustar el formulario de moneybookers en tu aplicación.
  • Una vez realizado el pago, moneybookers llama a la dirección especificada en notify_url para que le indiquemos si el pago ha sido validado por nosotros.
  • hide_login permite ocultar el formulario de login en moneybookers

Formulario HTML:

# app/helpers/payment_helper.rb
module PaymentsHelper
  include ActiveMerchant::Billing::Integrations::ActionViewHelper

end

# app/views/payments/new.html.erb

<iframe id="mb-iframe"
        name="mb-iframe"
        frameborder="no"
        style="height: 600px; width:500px;"
        scrolling = "auto">
</iframe>

<% payment_service_for @payment.transaction_id, "paytoemail@merchant.com",
                                                :amount => @payment.amount,
                                                :currency => 'EUR',
                                                :service => :moneybookers,
                                                :html => { :id => 'mb-form',
                                                           :target => 'mb-iframe' } do |service| %>

  <% service.customer :first_name => @payment.owner.first_name,
                      :last_name  => @payment.owner.last_name,
                      :email      => @payment.owner.email %>

  <% service.billing_address :city     => @payment.owner.city,
                             :address1 => @payment.owner.street1,
                             :address2 => @payment.owner.street2,
                             :zip      => @account.owner.postal_code,
                             :country  => @account.owner.country.code %>

  <% service.notify_url "http://localhost:3000/payments/notify" %>
  <% service.return_url url_for(:only_path => false, :action => 'done', :merchant_id => "2200220022") %>
  <% service.cancel_return_url "http://localhost:3000/payments" %>

  <%= hidden_field_tag :return_url_target,     "mb-iframe" %>
  <%= hidden_field_tag :cancel_url_target,     "mb-iframe" %>
  <%= hidden_field_tag :language,              "ES" %>
  <%= hidden_field_tag :hide_login,            "1" %>
  <%= hidden_field_tag :detail1_description,   "Bach Complete Collection" %>
  <%= hidden_field_tag :detail1_text,          "#{@payment.amount} €" %>


  <%= submit_tag "Pagar" %>

<% end %>


# app/controllers/payment_controller.rb 
def notify
  http_status = 500
  notify = ActiveMerchant::Billing::Integrations::Moneybookers::Notification.new(request.raw_post)


  if notify.acknowledge(CONFIG['moneybookers']['secret'])
    begin
      if notify.complete?
        payment = Payment.find_by_transaction_id(notify.transaction_id)

        if notify.posted_amount.to_f == payment.amount.to_f

          payment.status = notify.status
          payment.save

          http_status = 200
        else
          logger.error("Failed to verify MoneyBookers's notification parameters, please investigate")
        end
      else

        logger.error("Failed to verify MoneyBookers's notification, please investigate")
      end
    rescue Exception => ex
      logger.error(ex.message)
    end
  else
    logger.error("Failed to verify MoneyBookers's notification, please investigate")
  end

  render :nothing => true, :status => http_status
end



Lo malo de esta opción es que el formulario está visible en el navegador del cliente, y se podría modificar el contenido. La mejor opción es utilizar el parámetro "prepare_only", que permite enviar toda esta información desde el servidor rails, y moneybookers nos contesta con un identificador de sesión en su site, así que ya puedes entrar en https://www.moneybookers.com/app/payment.pl?sid=<id de sesion> y ahí ya está toda la información necesaria. Así el navegador no tiene ningún tipo de información "sensible". Este método lo describiré en el siguiente post.

No hay comentarios:

Publicar un comentario