
Robokassa Integration in ActiveMerchant
- Transfer
Note translator - there was already a post about integrating Robokassa and Rails , but I believe that the method provided there will not suit many.
When you have an application written in Ruby on Rails and you plan to add some kind of payment system (for example, PayPal, Moneybookers or Robokassa, as in our case), then the first gem you should think about is Shopify's active_merchant .
ActiveMerchant is a simple abstract payment library used and sponsored by Shopify.
Therefore, when I needed to add payments via Robokassa to our project, I opened the list of supported payment systems and was a little disappointed because Robokassa was not included there. A little later, I found a fork that added its support, but it is already deprecated, so some tests crashed ec801d3d4f8 . So I decided to look at this code and fix it, and not write everything from scratch.
In fact, to fix the tests, I just had to fix a small typo 07fb5494134 ( zbs - approx.) Yes, that was easy. Then I decided to add different urls to the test environment and production to the previous solution (Robokassa recommends that you first test your code in the sandbox, and then, when everything works, use it in live mode). You can look at this code here - c2ec85d53cb .
Now it's time to add active_merchant to the project. Add it to the gemfile:
To use ActionView helpers (such as payment_service_for), you need to put the activemerchant.rb file in the initializers folder:
To use production mode in the initializer, you need to add another line:
The next step is the routes. Robokassa makes a push request to the application when the transaction is completed, so you need to add the following lines to routes.rb:
Now create a controller to make it work:
Finally, add the form to the page:
That's all! Now, if an object exists
When you have an application written in Ruby on Rails and you plan to add some kind of payment system (for example, PayPal, Moneybookers or Robokassa, as in our case), then the first gem you should think about is Shopify's active_merchant .
ActiveMerchant is a simple abstract payment library used and sponsored by Shopify.
Therefore, when I needed to add payments via Robokassa to our project, I opened the list of supported payment systems and was a little disappointed because Robokassa was not included there. A little later, I found a fork that added its support, but it is already deprecated, so some tests crashed ec801d3d4f8 . So I decided to look at this code and fix it, and not write everything from scratch.
In fact, to fix the tests, I just had to fix a small typo 07fb5494134 ( zbs - approx.) Yes, that was easy. Then I decided to add different urls to the test environment and production to the previous solution (Robokassa recommends that you first test your code in the sandbox, and then, when everything works, use it in live mode). You can look at this code here - c2ec85d53cb .
Now it's time to add active_merchant to the project. Add it to the gemfile:
gem 'activemerchant', :require => 'active_merchant'
To use ActionView helpers (such as payment_service_for), you need to put the activemerchant.rb file in the initializers folder:
require 'active_merchant'
require 'active_merchant/billing/integrations/action_view_helper'
ActionView::Base.send(:include, ActiveMerchant::Billing::Integrations::ActionViewHelper)
To use production mode in the initializer, you need to add another line:
ActiveMerchant::Billing::Base.integration_mode = :production # :test for sandbox
The next step is the routes. Robokassa makes a push request to the application when the transaction is completed, so you need to add the following lines to routes.rb:
scope 'robokassa' do
match 'paid' => 'robokassa#paid', :as => :robokassa_paid # to handle Robokassa push request
match 'success' => 'robokassa#success', :as => :robokassa_success # to handle Robokassa success redirect
match 'fail' => 'robokassa#fail', :as => :robokassa_fail # to handle Robokassa fail redirect
end
Now create a controller to make it work:
class RobokassaController < ApplicationController
include ActiveMerchant::Billing::Integrations
skip_before_filter :verify_authenticity_token # skip before filter if you chosen POST request for callbacks
before_filter :create_notification
before_filter :find_payment
# Robokassa call this action after transaction
def paid
if @notification.acknowledge # check if it’s genuine Robokassa request
@payment.approve! # project-specific code
render :text => @notification.success_response
else
head :bad_request
end
end
# Robokassa redirect user to this action if it’s all ok
def success
if !@payment.approved? && @notification.acknowledge
@payment.approve!
end
redirect_to @payment, :notice => I18n.t("notice.robokassa.success")
end
# Robokassa redirect user to this action if it’s not
def fail
redirect_to @payment, :notice => I18n.t("notice.robokassa.fail")
end
private
def create_notification
@notification = Robokassa::Notification.new(request.raw_post, :secret => AppConfig.robokassa_secret)
end
def find_payment
@payment = Payment.find(@notification.item_id)
end
end
Finally, add the form to the page:
<%= payment_service_for @payment.id, AppConfig.robokassa_login,
:amount => @payment.amount,
:service => :robokassa,
:secret => AppConfig.robokassa_secret do |s| %>
<%= submit_tag "Submit" %>
<% end %>
That's all! Now, if an object exists
@payment
, then after submitting the form, a redirect to the Robokassa website will occur, where it will be possible to make a payment for the amount indicated in @payment.amount
.