法国农业信贷Paybox支付接口商家识别失败访问拒绝求助
Hey there, let's troubleshoot that "Problème d'identification du commerce. Accès refusé !" error you're facing with Crédit Agricole's Paybox E-transactions system. I've gone through your Ruby code, form setup, and the official PHP example, and here are the most likely culprits to fix:
1. HMAC Key Packing Mismatch (Critical!)
Your Ruby code uses [key].pack("B*") to convert the HMAC key to binary, but the official PHP example uses pack("H*", $keyTest). These do completely different things:
H*converts a hexadecimal string (the standard format for Paybox HMAC keys) to binaryB*converts a string of 0s and 1s (binary literal) to bytes
This is almost certainly breaking your signature. Fix it by changing the packing line to:
binKey = [key].pack("H*")
2. Inconsistent PBX_PORTEUR Value
Your form pulls PBX_PORTEUR from an environment variable (ENV['PBX_PORTEUR']), but your signature generation code uses current_user.email. Paybox validates that every parameter in the signature matches exactly what's submitted in the form—any mismatch here will invalidate your request.
Pick one value and use it consistently everywhere:
- Either update the signature code to use
ENV['PBX_PORTEUR'] - Or update the form to use
<%= current_user.email %>forPBX_PORTEUR
3. Incorrect Message Joining Character
You're joining your signature message with & (HTML-escaped ampersand), but Paybox expects the raw & character. The PHP example's & is likely just HTML formatting in the documentation—actual signature strings need unescaped & separators.
Fix the join line in your Ruby code:
@signature = OpenSSL::HMAC.hexdigest(digest, binKey, msg.join('&')).upcase
4. Verify Environment Variable Accuracy
Double-check that all your environment variables (PBX_SITE, PBX_RANG, PBX_IDENTIFIANT, CLE_HMAC) exactly match the values provided by Crédit Agricole. Even a single extra space or typo in the HMAC key or site ID will trigger this access error.
Modified Ruby Signature Code (Fixes Included)
Here's your updated paiement method with the key fixes applied:
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') # Use consistent PBX_PORTEUR value (match what's in your form) pbx_porteur = ENV['PBX_PORTEUR'] 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=#{pbx_porteur}", "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*") # Fixed packing format digest = OpenSSL::Digest.new('sha512') @signature = OpenSSL::HMAC.hexdigest(digest, binKey, msg.join('&')).upcase # Fixed separator end
Final Note
Paybox's signature validation is extremely strict—even tiny discrepancies in parameter values, formatting, or signature generation will result in this "access refused" error. Start with the first three fixes above, as those are the most common causes of this specific issue.
内容的提问来源于stack exchange,提问作者user5914341

