Skip to content

Интеграция в Rails

Aleksandr Panasyuk edited this page Sep 16, 2019 · 7 revisions

В этом примере параметры платежа (сумма в копейках и номер заказа) вводятся в форме, после отправки которой пользователь перенаправляется на платежный шлюз Сбербанка. В случае успешной оплаты, пользователь перенаправляется обратно на сайт, где проверяется статус оплаты и, в случае успеха, пользователю показывается соответствующее сообщение. В случае ошибки на каком-либо этапе оплаты, пользователь видит сообщение об ошибке.

# Gemfile
gem 'sberbank-acquiring', '~> 0.2'
# config/routes.rb
Rails.application.routes.draw do
  # GET  /sberbank_payments/callback
  # GET  /sberbank_payments/new
  # GET  /sberbank_payments/notify
  # GET  /sberbank_payments/success
  # POST /sberbank_payments

  resources :sberbank_payments, only: [:new, :create] do
    collection do
      get :callback
      get :success
      get :fail
    end
  end
end
<% # app/views/sberbank_payments/new.html.erb %>
<%= form_for :sberbank_payment, url: sberbank_payments_path, method: :post do |f| %>
  <%= f.label :amount %>
  <%= f.number_field :amount, placeholder: 'in cents', required: true %>
  <%= f.label :order_number %>
  <%= f.text_field :order_number, required: true %>
  <%= f.submit %>
<% end %>
<% # app/views/sberbank_payments/fail.html.erb %>
Payment processing failed.
<%= link_to 'Back', new_sberbank_payment_path %>
<% # app/views/sberbank_payments/success.html.erb %>
Payment processing succeeded.
<%= link_to 'Back', new_sberbank_payment_path %>
# app/controllers/sberbank_payments_controller.rb
class SberbankPaymentsController < ApplicationController
  before_action :validate_checksum!, only: :callback

  def fail; end
  def new; end

  def callback
    # Код обработки успешной оплаты
    # params:
    # :mdOrder - Уникальный номер заказа в системе платёжного шлюза.
    # :orderNumber - Уникальный номер (идентификатор) заказа в системе продавца.
    # :checksum - Аутентификационный код, или контрольная сумма, полученная из набора параметров.
    # :operation - Тип операции, о которой пришло уведомление:
    #   'approved' - операция удержания (холдирования) суммы;
    #   'deposited' - операция завершения;
    #   'reversed' - операция отмены;
    #   'refunded' - операция возврата.
    # :status - Индикатор успешности операции, указанной в параметре operation:
    #   '1' - операция прошла успешно;
    #   '0' - операция завершилась ошибкой.
  end

  def create
    register_params = sberbank_payment_params.to_unsafe_h
    register_params[:return_url] = success_sberbank_payments_url
    register_params[:fail_url] = fail_sberbank_payments_url

    sberbank_response = sberbank_client.register(register_params)

    if sberbank_response.success?
      redirect_to sberbank_response.form_url
    else
      Rails.logger.error("Ошибка регистрации заказа. Сервер ответил: #{sberbank_response.http.body}")
      render :fail, status: :unprocessable_entity
    end
  end

  def success
    sberbank_response = sberbank_client.get_order_status_extended(order_id: params[:orderId])
    if sberbank_response.success? && sberbank_response.order_status == SBRF::Acquiring::ORDER_AUTHORIZED
      # Код обработки успешной оплаты
      # локальный заказ можно найти по sberbank_response.order_number
    else
      Rails.logger.error("Ошибка проверки заказа. Сервер ответил: #{sberbank_response.http.body}")
      render :fail, status: :unprocessable_entity
    end
  end

  private

  def sberbank_payment_params
    params.require(:sberbank_payment).permit(:amount, :order_number)
  end

  def sberbank_client
    @sberbank_client ||=
      SBRF::Acquiring::Client.new(username: ENV['SBRF_USERNAME'], password: ENV['SBRF_PASSWORD'])
  end

  def validate_checksum!
    params_to_validate = params.to_unsafe_h.except(:action, :controller, :sberbank_payment)
    validator = SBRF::Acquiring::SymmetricKeyChecksumValidator.new(ENV['SBRF_SHARED_KEY'])

    render :fail, status: :unprocessable_entity unless validator.valid?(params_to_validate)
  end
end
Clone this wiki locally