paiementcic/lib/paiement_cic.rb

115 lines
3.7 KiB
Ruby
Raw Normal View History

2009-08-17 10:37:35 +02:00
require 'digest/sha1'
require 'openssl'
class String
def ^(other)
raise ArgumentError, "Can't bitwise-XOR a String with a non-String" \
unless other.kind_of? String
raise ArgumentError, "Can't bitwise-XOR strings of different length" \
unless self.length == other.length
result = (0..self.length-1).collect { |i| self[i].ord ^ other[i].ord }
2009-08-17 10:37:35 +02:00
result.pack("C*")
end
end
class PaiementCic
autoload :FormHelper, "paiement_cic/form_helper"
2009-12-21 11:24:45 +01:00
@@version = "3.0" # clé extraite grâce à extract2HmacSha1.html fourni par le Crédit Mutuel
cattr_accessor :version
2009-08-17 10:37:35 +02:00
@@hmac_key = "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" # clé extraite grâce à extract2HmacSha1.html fourni par le Crédit Mutuel
cattr_accessor :hmac_key
2013-06-05 10:28:56 +02:00
2009-12-21 11:24:45 +01:00
@@target_url = "https://paiement.creditmutuel.fr/test/paiement.cgi" # "https://ssl.paiement.cic-banques.fr/paiement.cgi"
2009-08-17 10:37:35 +02:00
cattr_accessor :target_url
2013-06-05 10:28:56 +02:00
2009-08-17 10:37:35 +02:00
@@tpe = "123456"
cattr_accessor :tpe
2013-06-05 10:28:56 +02:00
2009-08-17 10:37:35 +02:00
@@societe = "masociete"
cattr_accessor :societe
2013-06-05 10:28:56 +02:00
2009-12-21 11:24:45 +01:00
@@url_ok = ""
cattr_accessor :url_ok
2009-08-17 10:37:35 +02:00
def self.date_format
"%d/%m/%Y:%H:%M:%S"
end
def self.config(amount_in_cents, reference)
oa = ActiveSupport::OrderedHash.new
2009-12-21 11:24:45 +01:00
oa["version"] = "3.0"
2009-08-17 10:37:35 +02:00
oa["TPE"] = tpe
oa["date"] = Time.now.strftime(date_format)
2009-12-21 11:24:45 +01:00
oa["montant"] = ("%.2f" % amount_in_cents) + "EUR"
2009-08-17 10:37:35 +02:00
oa["reference"] = reference
oa["texte-libre"] = ""
oa["lgue"] = "FR"
oa["societe"] = societe
2009-12-21 11:24:45 +01:00
oa["mail"] = ""
2009-08-17 10:37:35 +02:00
oa
end
2009-12-21 11:24:45 +01:00
def self.mac_string params
hmac_key = PaiementCic.new
mac_string = [hmac_key.tpe, params["date"], params['montant'], params['reference'], params['texte-libre'], hmac_key.version, params['code-retour'], params['cvx'], params['vld'], params['brand'], params['status3ds'], params['numauto'], params['motifrefus'], params['originecb'], params['bincb'], params['hpancb'], params['ipclient'], params['originetr'], params['veres'], params['pares']].join('*') + "*"
2009-08-17 10:37:35 +02:00
end
2009-12-21 11:24:45 +01:00
2009-08-17 10:37:35 +02:00
def self.verify_hmac params
2009-12-21 11:24:45 +01:00
hmac_key = PaiementCic.new
mac_string = [hmac_key.tpe, params["date"], params['montant'], params['reference'], params['texte-libre'], hmac_key.version, params['code-retour'], params['cvx'], params['vld'], params['brand'], params['status3ds'], params['numauto'], params['motifrefus'], params['originecb'], params['bincb'], params['hpancb'], params['ipclient'], params['originetr'], params['veres'], params['pares']].join('*') + "*"
hmac_key.valid_hmac?(mac_string, params['MAC'])
2009-08-17 10:37:35 +02:00
end
2013-06-05 10:28:56 +02:00
2009-12-21 11:24:45 +01:00
# Check if the HMAC matches the HMAC of the data string
2013-06-05 10:28:56 +02:00
def valid_hmac?(mac_string, sent_mac)
computeHMACSHA1(mac_string) == sent_mac.downcase
end
2009-12-21 11:24:45 +01:00
# Return the HMAC for a data string
2013-06-05 10:28:56 +02:00
def computeHMACSHA1(data)
hmac_sha1(usable_key(self), data).downcase
end
2009-12-21 11:24:45 +01:00
def hmac_sha1(key, data)
2013-06-05 10:28:56 +02:00
length = 64
2009-08-17 10:37:35 +02:00
2013-06-05 10:28:56 +02:00
if (key.length > length)
key = [Digest::SHA1.hexdigest(key)].pack("H*")
end
2009-12-21 11:24:45 +01:00
2013-06-05 10:28:56 +02:00
key = key.ljust(length, 0.chr)
ipad = ''.ljust(length, 54.chr)
opad = ''.ljust(length, 92.chr)
2009-12-21 11:24:45 +01:00
2013-06-05 10:28:56 +02:00
k_ipad = key ^ ipad
k_opad = key ^ opad
2009-12-21 11:24:45 +01:00
2013-06-05 10:28:56 +02:00
#Digest::SHA1.hexdigest(k_opad + [Digest::SHA1.hexdigest(k_ipad + sData)].pack("H*"))
OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new("sha1"), key, data)
end
2009-12-21 11:24:45 +01:00
private
2013-06-05 10:28:56 +02:00
# Return the key to be used in the hmac function
def usable_key(payement)
2009-12-21 11:24:45 +01:00
2013-06-05 10:28:56 +02:00
hex_string_key = payement.hmac_key[0..37]
hex_final = payement.hmac_key[38..40] + "00";
2009-12-21 11:24:45 +01:00
2013-06-05 10:28:56 +02:00
cca0 = hex_final[0].ord
2009-12-21 11:24:45 +01:00
2013-06-05 10:28:56 +02:00
if cca0 > 70 && cca0 < 97
hex_string_key += (cca0 - 23).chr + hex_final[1..2]
elsif hex_final[1..2] == "M"
hex_string_key += hex_final[0..1] + "0"
else
hex_string_key += hex_final[0..2]
end
2009-12-21 11:24:45 +01:00
2013-06-05 10:28:56 +02:00
[hex_string_key].pack("H*")
end
2009-12-21 11:24:45 +01:00
end