Здравствуй, Хабрасообщество!
Сегодня я расскажу вам, как и обещал в прошлой статье, про реализацию 3-D Secure authentication в SaaS-приложениях. 3-D Secure добавляет ещё один шаг аутентификации для онлайн-платежей. Обычно происходит редирект на сайт банка-эмитента, где пользователю предлагается ввести проверочный смс-пин для подверждения платежа. Этот процесс жутко неудобен, ваши клиенты обязаны уходить с вашего сервиса, чтобы пройти эту аутентификацию.
В LPCloud мы решили сделать 3-D Secure аутентификацию во фрейме, чтобы пользователь не покидал наш сервис.

Если для карты вашего клиента необходима 3-DS, то cloudpayments возвращает необходимые параметры для прохождения аутентификации, в том числе url страницы на сайте банка-эмитента, где, как раз, вводится смс-пин, его-то мы и открываем во фрейме. Далее после прохождения аутентификации сайт банка-эмитента прям во фрейме перенаправит клиента на ваш сайт, где вы можете вывести сообщение об оплате. А что если после прохождения аутентификации вы хотите автоматически закрыть попап с фреймом и вывести alert?
Просто передаем результаты ответа от сервера cloudpayments в js переменную и вызываем функцию в parent'е.
На этом все. Если есть предложения как улучшить этот метод буду рад выслушать вас в комментариях.
Сегодня я расскажу вам, как и обещал в прошлой статье, про реализацию 3-D Secure authentication в SaaS-приложениях. 3-D Secure добавляет ещё один шаг аутентификации для онлайн-платежей. Обычно происходит редирект на сайт банка-эмитента, где пользователю предлагается ввести проверочный смс-пин для подверждения платежа. Этот процесс жутко неудобен, ваши клиенты обязаны уходить с вашего сервиса, чтобы пройти эту аутентификацию.
В LPCloud мы решили сделать 3-D Secure аутентификацию во фрейме, чтобы пользователь не покидал наш сервис.

Контроллер
def purchase
updating_card = current_user.account.present?
options = {
:IpAddress => request.ip,
:AccountId => current_user.email,
:Name => params[:name],
:JsonData => { plan: params[:plan], updating_card: updating_card }.to_json,
:Currency => current_subscription.currency,
:Description => "Storing card details"
}
current_subscription.plan = Plan.find(params[:plan]) if params[:plan].present?
amount = updating_card ? 1 : current_subscription.amount
response = gateway.purchase(params[:cryptogram], amount, options, true)
# making response as action controller params
@params = parametrize(response.params)
if response.success?
resp = { json: success_transaction(@params) }
else
# if 3d-secure needed
if @params and @params['PaReq'].present?
resp = { json: { response: @params, type: '3ds' }, status: 422 }
else
resp = { json: { response: response, type: 'error' }, status: 422 }
end
end
render resp
end
private
def gateway
ActiveMerchant::Billing::CloudpaymentsGateway.new(public_id: configatron.cloudpayments.public_id, api_secret: configatron.cloudpayments.api_secret)
end
Если для карты вашего клиента необходима 3-DS, то cloudpayments возвращает необходимые параметры для прохождения аутентификации, в том числе url страницы на сайте банка-эмитента, где, как раз, вводится смс-пин, его-то мы и открываем во фрейме. Далее после прохождения аутентификации сайт банка-эмитента прям во фрейме перенаправит клиента на ваш сайт, где вы можете вывести сообщение об оплате. А что если после прохождения аутентификации вы хотите автоматически закрыть попап с фреймом и вывести alert?
Контроллер
def post3ds
response = gateway.check_3ds(params[:MD], params[:PaRes])
@params = parametrize(response.params)
if response.success?
resp = success_transaction(@params)
else
resp = { message: response.message }
end
@response = { response: resp, success: response.success? }
end
Вьюха
Просто передаем результаты ответа от сервера cloudpayments в js переменную и вызываем функцию в parent'е.
javascript:
var resp = JSON.parse('#{@response.to_json.html_safe}');
parent.window.showMessage(resp);
Функция на клиенте
window.showMessage = function(r) {
alert(r.response.message);
}
На этом все. Если есть предложения как улучшить этот метод буду рад выслушать вас в комментариях.