Хеш-сообщение Rails
У меня проблемы с подключением моего Rails-приложения к Paybox (через французский банк).
Техническая поддержка сообщает, что проблема может быть связана с хеш-сообщением, которое я им отправляю (через форму). Но они не знают о Ruby, поэтому не могут ничего гарантировать.
Может быть, некоторые из вас найдут что-то не так?
Вот метод:
def paiement
@commande = Commande.find_by(code: params[:id])
@confirmation_url = ENV['PBX_EFFECTUE'].gsub('CODE_COMMANDE', @commande.code)
@annulation_url = ENV['PBX_ANNULE'].gsub('CODE_COMMANDE', @commande.code)
@refus_url = ENV['PBX_REFUSE'].gsub('CODE_COMMANDE', @commande.code)
@current_time = Time.now.strftime('%FT%T%:z')
msg = {
PBX_SITE: "#{ENV['PBX_SITE']}",
PBX_RANG: "#{ENV['PBX_RANG']}",
PBX_IDENTIFIANT: "#{ENV['PBX_IDENTIFIANT']}",
PBX_TOTAL: "#{@commande.total_price_centimes}",
PBX_DEVISE: "978",
PBX_CMD: "#{@commande.code}",
PBX_PORTEUR: "#{current_user.email}",
PBX_REPONDRE_A: "#{ENV['PBX_REPONDRE_A']}",
PBX_RETOUR: "#{ENV['PBX_RETOUR']}",
PBX_EFFECTUE: "#{@confirmation_url}",
PBX_ANNULE: "#{@annulation_url}",
PBX_REFUSE: "#{@refus_url}",
PBX_HASH: "SHA512",
PBX_TIME: "#{@current_time}"
}
key = ENV['CLE_HMAC']
binKey = [key].pack('H*')
digest = OpenSSL::Digest.new('sha512')
@signature = OpenSSL::HMAC.hexdigest(digest, binKey, msg.keys.map{|k,v| "#{k}=#{v}"}.join('&')).upcase
#binding.pry
end
Форма:
<form method="POST" action="<%= ENV['CREDIT_AGRICOLE_URL'] %>" id="paiement-form">
<input type="hidden" name="PBX_SITE" value="<%= ENV['PBX_SITE'] %>">
<input type="hidden" name="PBX_RANG" value="<%= ENV['PBX_RANG'] %>">
<input type="hidden" name="PBX_IDENTIFIANT" value="<%= ENV['PBX_IDENTIFIANT'] %>">
<input type="hidden" name="PBX_TOTAL" value="<%= @commande.total_price_centimes %>">
<input type="hidden" name="PBX_DEVISE" value="978">
<input type="hidden" name="PBX_CMD" value="<%= @commande.code %>">
<input type="hidden" name="PBX_PORTEUR" value="<%= ENV['PBX_PORTEUR'] %>">
<input type="hidden" name="PBX_REPONDRE_A" value="<%= ENV['PBX_REPONDRE_A'] %>">
<input type="hidden" name="PBX_RETOUR" value="<%= ENV['PBX_RETOUR'] %>">
<input type="hidden" name="PBX_EFFECTUE" value="<%= @confirmation_url %>">
<input type="hidden" name="PBX_ANNULE" value="<%= @annulation_url %>">
<input type="hidden" name="PBX_REFUSE" value="<%= @refus_url %>">
<input type="hidden" name="PBX_HASH" value="SHA512">
<input type="hidden" name="PBX_TIME" value="<%= @current_time %>">
<input type="hidden" name="PBX_HMAC" value="<%= @signature %>">
<input type="submit" value="Envoyer">
</form>
Где paiement
действие срабатывает:
<div class="cmd-actions">
<%= form_for @commande, {url: commande_path(@commande.code)} do |f| %>
<div class="recap-commande-container">
<div class="etape">
<div>3</div>
<h1>Récapitulatif et paiement de votre commande</h1>
</div>
<%= render partial: 'line_items_table', locals: {recap_commande: @commande} %>
</div>
<div id="secured-paiement">
<div>
<h3>Choisissez votre mode de paiement :</h3>
</div>
<div class="secured-paiement-logo">
<div class="paiement-row">
<div class="input-radio">
<%= radio_button_tag("commande[methode_paiement]", 'carte_bancaire', {onchange: 'methode(1)', data: {a: "carte_bancaire"}, id: 'carte_bancaire'}) %>
</div>
<div class="input-img">
<%= image_tag('logo/ca-e-transactions', style: 'width: 170px;height: 40px') %>
<%= image_tag('logo/mastercard', style: 'width: 50px;height: 40px') %>
<%= image_tag('logo/visa', style: 'width: 50px;height: 40px') %>
<%= image_tag('logo/cb', style: 'width: 50px;height: 40px') %>
</div>
</div>
<div class="paiement-row" style="margin-top: 20px;">
<div class="input-radio">
<%= radio_button_tag("commande[methode_paiement]", 'le_pot_commun', {onchange: 'methode(2)', data: {a: "le_pot_commun"}, id: 'le_pot_commun'}) %>
</div>
<div class="input-img">
<%= image_tag('logo/pot-commun') %>
</div>
</div>
</div>
</div>
<div id="proceed-actions">
<div id="cgv">
<%= check_box_tag "cgv" %>
<label>J'accepte les <%= link_to "conditions générales de vente", conditions_generales_de_vente_path, style: 'color:black', target: 'blank' %></label>
</div>
</div>
<div class="commander-link" id="paiement-cmd-btn">
<%= f.submit "Payer ma commande" %>
</div>
<% end %>
</div>
Форма должна перенаправлять на https://preprod-tpeweb.paybox.com/cgi/MYchoix_pagepaiement.cgi, и это то, что она делает. Но на той же странице у меня появляется следующее сообщение об ошибке: "Проблема коммерции. Отказ от ответственности!" ("Проблема аутентификации. Доступ запрещен!").
Эта проблема связана с этой: проблема подписи Ruby HMAC
Есть идеи?
3 ответа
На дату я использую
@date_time = Time.now.iso8601
Чтобы создать Hmac:
bin_key = Array(keyTest).pack 'H*'
@hmac = OpenSSL::HMAC.hexdigest("SHA512", bin_key, data).upcase
Также ваш ключ должен быть активирован после генерации.
Кажется, вы сделали опечатку при сборе данных из вашего хэша. Вы в настоящее время используете:
msg.keys.map { |k,v| "#{k}=#{v}" }.join('&')
но, вызвав #keys для хэша, вы получите массив только с ключами.
Я думаю, вы хотели напечатать
msg.map { |k,v| "#{k}=#{v}" }.join('&')
в противном случае вы потеряете значения и V всегда nil
,
Обычно с подписями HMAC ключи сортируются в алфавитном порядке, прежде чем подписываться. Если вы выполняете итерацию по парам ключ / значение Hash, то порядок итераций в значительной степени недетерминирован (или, по крайней мере, должен рассматриваться как таковой).
Попробуйте сначала отсортировать ключи, например:
msg.keys.sort.map{|k| "#{k}=#{msg[k]}"}