modifications to support version 3
parent
8cb1aff141
commit
d9c53853ed
63
MIT-LICENSE
63
MIT-LICENSE
|
@ -18,3 +18,66 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#==============================================================================
|
||||
#
|
||||
# "Open source" kit for P@iement CM-CIC(TM).
|
||||
# Integration sample in a merchant site for Ruby
|
||||
#
|
||||
# Author : Euro-Information/e-Commerce (contact: centrecom@e-i.com)
|
||||
# Version : 1.0
|
||||
# Date : 01/01/2009
|
||||
#
|
||||
# Copyright: (c) 2009 Euro-Information. All rights reserved.
|
||||
#
|
||||
#==============================================================================
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
- Neither the name of Euro-Information nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Note: Euro-Information does not provide person-to-person technical
|
||||
support for tryout of CM-CIC P@iement examples. We do however
|
||||
welcome your feedback which can be sent to <centrecom@e-i.com>.
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
This software uses RSA Data Security, Inc. MD5 Message-Digest Algorithm.
|
||||
|
||||
License to copy and use this software is granted provided that it is
|
||||
identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software or
|
||||
this function.
|
||||
License is also granted to make and use derivative works provided that
|
||||
such works are identified as "derived from the RSA Data Security,
|
||||
Inc. MD5 Message-Digest Algorithm" in all material mentioning or
|
||||
referencing the derived work.
|
||||
RSA Data Security, Inc. makes no representations concerning either the
|
||||
merchantability of this software or the suitability of this software
|
||||
for any particular purpose. It is provided "as is" without express or
|
||||
implied warranty of any kind.
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
|
||||
#==============================================================================
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Paiement CIC
|
||||
|
||||
Paiement CIC is a plugin to ease credit card payment with the CIC / Crédit Mutuel banks system.
|
||||
Paiement CIC is a plugin to ease credit card payment with the CIC / Crédit Mutuel banks system version 3.0.
|
||||
It's a Ruby on Rails port of the connexion kits published by the bank.
|
||||
|
||||
* The Plugin [site](http://github.com/novelys/cicpayment)
|
||||
|
@ -24,11 +24,11 @@ script/plugin install git://github.com/novelys/paiementcic.git
|
|||
|
||||
### in development.rb :
|
||||
|
||||
PaiementCic.target_url = "https://ssl.paiement.cic-banques.fr/test/paiement.cgi"
|
||||
PaiementCic.target_url = "https://ssl.paiement.cic-banques.fr/test/paiement.cgi" # or https://paiement.creditmutuel.fr/test/paiement.cgi
|
||||
|
||||
### in production.rb :
|
||||
|
||||
PaiementCic.target_url = "https://ssl.paiement.cic-banques.fr/paiement.cgi"
|
||||
PaiementCic.target_url = "https://ssl.paiement.cic-banques.fr/paiement.cgi" # or https://paiement.creditmutuel.fr/paiement.cgi
|
||||
|
||||
### in order controller :
|
||||
|
||||
|
@ -71,15 +71,15 @@ script/plugin install git://github.com/novelys/paiementcic.git
|
|||
|
||||
order_transaction.update_attribute :success, true
|
||||
|
||||
receipt = "OK"
|
||||
receipt = "0"
|
||||
else
|
||||
order.transaction_declined!
|
||||
order.update_attribute :description, "Document Falsifie."
|
||||
order_transaction.update_attribute :success, false
|
||||
|
||||
receipt = "Document Falsifie"
|
||||
receipt = "1\n#{PaiementCic.mac_string}"
|
||||
end
|
||||
render :text => "Version: 1\n#{receipt}\n"
|
||||
render :text => "Pragma: no-cache\nContent-type: text/plain\n\nversion=2\ncdr=#{receipt}"
|
||||
end
|
||||
|
||||
def bank_ok
|
||||
|
|
|
@ -14,10 +14,13 @@ class String
|
|||
end
|
||||
|
||||
class PaiementCic
|
||||
@@version = "3.0" # clé extraite grâce à extract2HmacSha1.html fourni par le Crédit Mutuel
|
||||
cattr_accessor :version
|
||||
|
||||
@@hmac_key = "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" # clé extraite grâce à extract2HmacSha1.html fourni par le Crédit Mutuel
|
||||
cattr_accessor :hmac_key
|
||||
|
||||
@@target_url = "https://ssl.paiement.cic-banques.fr/test/paiement.cgi" # "https://ssl.paiement.cic-banques.fr/paiement.cgi"
|
||||
@@target_url = "https://paiement.creditmutuel.fr/test/paiement.cgi" # "https://ssl.paiement.cic-banques.fr/paiement.cgi"
|
||||
cattr_accessor :target_url
|
||||
|
||||
@@tpe = "123456"
|
||||
|
@ -26,61 +29,84 @@ class PaiementCic
|
|||
@@societe = "masociete"
|
||||
cattr_accessor :societe
|
||||
|
||||
@@url_ok = ""
|
||||
cattr_accessor :url_ok
|
||||
|
||||
def self.date_format
|
||||
"%d/%m/%Y:%H:%M:%S"
|
||||
end
|
||||
|
||||
def self.config(amount_in_cents, reference)
|
||||
oa = ActiveSupport::OrderedHash.new
|
||||
oa["version"] = "3.0"
|
||||
oa["TPE"] = tpe
|
||||
oa["date"] = Time.now.strftime(date_format)
|
||||
oa["montant"] = ("%.2f" % (amount_in_cents/100.0)) + "EUR"
|
||||
oa["montant"] = ("%.2f" % amount_in_cents) + "EUR"
|
||||
oa["reference"] = reference
|
||||
oa["texte-libre"] = ""
|
||||
oa["version"] = "1.2open"
|
||||
oa["lgue"] = "FR"
|
||||
oa["societe"] = societe
|
||||
oa["mail"] = ""
|
||||
oa
|
||||
end
|
||||
|
||||
def self.calculate_hmac(ordered_hash)
|
||||
data = ordered_hash.values.join("*") + "*"
|
||||
hmac(data)
|
||||
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('*') + "*"
|
||||
end
|
||||
|
||||
def self.verify_hmac params
|
||||
tpe = params[:TPE]
|
||||
date = params[:date]
|
||||
montant = params[:montant]
|
||||
reference = params[:reference]
|
||||
mac = params[:MAC].downcase
|
||||
texte_libre = params['texte-libre']
|
||||
code_retour = params['code-retour']
|
||||
retour_plus = params['retourPLUS']
|
||||
version = "1.2open"
|
||||
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('*') + "*"
|
||||
|
||||
data = retour_plus + [tpe, date, montant, reference, texte_libre, version, code_retour].join("+") + "+"
|
||||
|
||||
mac == hmac(data)
|
||||
hmac_key.valid_hmac?(mac_string, params['MAC'])
|
||||
end
|
||||
|
||||
def self.hmac(data)
|
||||
pass = "";
|
||||
k1 = [Digest::SHA1.hexdigest(pass)].pack("H*");
|
||||
l1 = k1.length
|
||||
# Check if the HMAC matches the HMAC of the data string
|
||||
def valid_hmac?(mac_string, sent_mac)
|
||||
computeHMACSHA1(mac_string) == sent_mac.downcase
|
||||
end
|
||||
|
||||
k2 = [hmac_key].pack("H*")
|
||||
l2 = k2.length
|
||||
if (l1 > l2)
|
||||
k2 = k2.ljust(l1, 0.chr)
|
||||
elsif (l2 > l1)
|
||||
k1 = k1.ljust(l2, 0.chr)
|
||||
end
|
||||
xor_res = k1 ^ k2
|
||||
hmac_sha1(xor_res, data).downcase
|
||||
end
|
||||
# Return the HMAC for a data string
|
||||
def computeHMACSHA1(data)
|
||||
hmac_sha1(usable_key(self), data).downcase
|
||||
end
|
||||
|
||||
def self.hmac_sha1(key, data)
|
||||
OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new("sha1"), key, data)
|
||||
end
|
||||
def hmac_sha1(key, data)
|
||||
length = 64
|
||||
|
||||
if (key.length > length)
|
||||
key = [Digest::SHA1.hexdigest(key)].pack("H*")
|
||||
end
|
||||
|
||||
key = key.ljust(length, 0.chr)
|
||||
ipad = ''.ljust(length, 54.chr)
|
||||
opad = ''.ljust(length, 92.chr)
|
||||
|
||||
k_ipad = key ^ ipad
|
||||
k_opad = key ^ opad
|
||||
|
||||
#Digest::SHA1.hexdigest(k_opad + [Digest::SHA1.hexdigest(k_ipad + sData)].pack("H*"))
|
||||
OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new("sha1"), key, data)
|
||||
end
|
||||
|
||||
private
|
||||
# Return the key to be used in the hmac function
|
||||
def usable_key(payement)
|
||||
|
||||
hex_string_key = payement.hmac_key[0..37]
|
||||
hex_final = payement.hmac_key[38..40] + "00";
|
||||
|
||||
cca0 = hex_final[0]
|
||||
|
||||
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
|
||||
|
||||
[hex_string_key].pack("H*")
|
||||
end
|
||||
end
|
|
@ -1,17 +1,27 @@
|
|||
## refactor this
|
||||
module PaiementCicHelper
|
||||
def paiement_cic_hidden_fields(order, order_transaction, options = {})
|
||||
oa = PaiementCic.config(order.amount, order_transaction.reference)
|
||||
def paiement_cic_hidden_fields(order, price, order_transaction, options = {})
|
||||
oa = PaiementCic.config(price, order_transaction.reference)
|
||||
|
||||
hsh = oa.dup
|
||||
hsh["url_retour"] = options[:url_retour] || edit_order_url(order)
|
||||
hsh["url_retour_ok"] = options[:url_retour_ok] || bank_ok_order_transaction_url(order_transaction)
|
||||
hsh["url_retour_err"] = options[:url_retour_err] || bank_err_order_transaction_url(order_transaction)
|
||||
hsh["MAC"] = PaiementCic.calculate_hmac(oa)
|
||||
oMac = PaiementCic.new
|
||||
sDate = Time.now.strftime("%d/%m/%Y:%H:%M:%S")
|
||||
chaine = [oMac.tpe, sDate, oa["montant"], oa["reference"].to_s, oa["texte-libre"], oMac.version, "FR", oMac.societe, "", "", "", "", "", "", "", "", "", "", ""].join("*")
|
||||
chaineMAC = oMac.computeHMACSHA1(chaine)
|
||||
|
||||
res = "\n"
|
||||
hsh.each{|key, value|
|
||||
res << hidden_field_tag(key, value) << "\n"
|
||||
}
|
||||
res
|
||||
html = '
|
||||
<input type="hidden" name="version" id="version" value="' + oa["version"] + '" />
|
||||
<input type="hidden" name="TPE" id="TPE" value="' + oa["TPE"] + '" />
|
||||
<input type="hidden" name="date" id="date" value="' + oa["date"] + '" />
|
||||
<input type="hidden" name="montant" id="montant" value="' + oa["montant"] + '" />
|
||||
<input type="hidden" name="reference" id="reference" value="' + oa["reference"].to_s + '" />
|
||||
<input type="hidden" name="MAC" id="MAC" value="' + chaineMAC + '" />
|
||||
<input type="hidden" name="url_retour" id="url_retour" value="' + bank_callback_order_transactions_url + '" />
|
||||
<input type="hidden" name="url_retour_ok" id="url_retour_ok" value="' + bank_ok_order_transaction_url(order) + '" />
|
||||
<input type="hidden" name="url_retour_err" id="url_retour_err" value="' + bank_err_order_transaction_url(order) + '" />
|
||||
<input type="hidden" name="lgue" id="lgue" value="' + oa["lgue"] + '" />
|
||||
<input type="hidden" name="societe" id="societe" value="' + oa["societe"] + '" />
|
||||
<input type="hidden" name="texte-libre" id="texte-libre" value="' + oa["texte-libre"] + '" />
|
||||
<input type="hidden" name="mail" id="mail" value="''" />'
|
||||
html
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue