# -*- coding: utf8 -*- from pyramid.response import Response from pyramid.renderers import render, get_renderer from pyramid.view import ( view_config, ) from pyramid.httpexceptions import ( HTTPFound, ) from datetime import * from dateutil.relativedelta import relativedelta from time import strftime import math import hashlib import binascii import hmac from ..models.default import * from ..models.reglement import * from ..views.default import ( to_decimal, ) def hash_hmac(request, msg): # lire la clé HMAC donné par PAYBOX et stocké dans agence 6 agence6 = get_agences(request, 6) hmac_key = agence6.hmac_key # Transformer la key en binaire binary_key = binascii.unhexlify(hmac_key.encode('utf-8')) # hasher le msg avec la key binaire res = hmac.new(binary_key, msg.encode('utf-8'), hashlib.sha512).hexdigest() return res.upper() # - - - - - - - - - - - - - - - - - - - - - - - - - - @view_config(route_name='crediter', renderer='../templates/reglement/crediter.pt') def crediter(request): url = request.route_url('crediter') logged_in = request.authenticated_userid eleve_info = get_eleve_info(request, logged_in) message = "" # lire les articles possibles selon le permise demandé ? items = get_tarifs(request, eleve_info['permis']) qtes = [] for item in items : qtes.append('0') mttotal = 0 if 'form.submitted' in request.params or 'regler.submitted' in request.params: # calculer le montant total qtes = [] for item in items : # récupère la qté saisie pour la REF qte = int(request.params[item.REF]) qtes.append(str(qte)) mttotal += item.PUTTC * qte if 'regler.submitted' in request.params: # case CGV cocher ? if 'cb_cgv' not in request.params: request.session.flash(u"Veuillez accepter les Conditions Générales de Vente pour continuer.", 'danger') else: return HTTPFound(location=request.route_url('reglement', ref='CRE', mttotal=mttotal, nfois='1')) return { 'page_title': "Créditer mon compte", 'url': url, 'message': message, 'items': items, 'qtes': qtes, 'mttotal': mttotal, } @view_config(route_name='reglement', renderer='../templates/reglement/reglement.pt', permission='view') def reglement(request): def get_cb_maxdate(nfois): today = date.today() cb_maxdate = today + relativedelta(months=+int(nfois)-1) return cb_maxdate.strftime('%y%m') # format AAMM def get_schedule_dates(): today = date.today() second_reglement = today + relativedelta(months=+1) third_reglement = today + relativedelta(months=+2) return [today.strftime('%d/%m/%Y'), second_reglement.strftime('15/%m/%Y'), third_reglement.strftime('15/%m/%Y')] def calc_montant_nfois(total, display): """Divise total par 3, et retourne le binôme suivant : [ ([int] résultat entier + reste), ([str10] résultat entier avec zéros devant) ] display est utilisé pour produire soit des paramètres (display = 0), soit des chaînes d'affichage (display = 1). """ total = int(total) a = int(total / 3 + total % 3) b = int(total / 3) if display == 0: b = str(b) b = b.zfill(10) return [a, b] ref = request.matchdict['ref'] sum_to_pay = float(request.matchdict['mttotal']) nfois = request.matchdict['nfois'] logged_in = request.authenticated_userid url = request.route_url('reglement', ref=ref, mttotal=request.matchdict['mttotal'], nfois=nfois) # --- sites de prod url_paybox = "https://tpeweb.e-transactions.fr/cgi/MYchoix_pagepaiement.cgi" url_retour = request.route_url('reglement_ret') # --- sites de test # carte de test : 1111222233334444 12/18 123 # url_paybox = "https://preprod-tpeweb.e-transactions.fr/cgi/MYchoix_pagepaiement.cgi" # url_retour = "http://62.35.112.130/reglement_ret" pbx_site = '1119903' pbx_rang = '01' pbx_identifiant = '210073358' pbx_total = 0 pbx_devise = '978' pbx_cmd = '%s%s/' % (ref, logged_in) pbx_porteur = get_eleve_info(request, logged_in)['email'] pbx_retour = 'reference:R;montant:M;autorisation:A;erreur:E' pbx_datevalmax = '' pbx_repondre_a = url_retour pbx_hash = 'SHA512' pbx_time = datetime.now().isoformat() pbx_hmac = '' # préparer les macros snippets = get_renderer('../templates/inscriptions/macros.pt').implementation() pay_ok = False schedule_dates = None schedule_sums = None mt_total = 0 if 'form.submitted' in request.params: pay_ok = True nfois = request.params['nfois'] pbx_datevalmax = get_cb_maxdate(nfois) pbx_total = int(math.ceil(to_decimal(100.)*to_decimal(sum_to_pay))) # was montantcmd mt_total = sum_to_pay if nfois == '3': # Splitted reglement if pbx_total < 30000: pay_ok = False else: sums = calc_montant_nfois(pbx_total, 0) save_total = pbx_total pbx_total = sums[0] # 1ere echeance mt_total = float(pbx_total) today = strftime('%d-%m-%Y') # compléter la référence commande pbx_cmd += today + 'PBX_2MONT' + sums[1] + 'PBX_NBPAIE02PBX_FREQ01PBX_QUAND00' schedule_dates = get_schedule_dates() schedule_sums = calc_montant_nfois(save_total, 1) # hash the parameters by hmac param = 'PBX_SITE=%s&PBX_RANG=%s&PBX_IDENTIFIANT=%s' % (pbx_site, pbx_rang, pbx_identifiant) param += '&PBX_TOTAL=%s&PBX_DEVISE=%s&PBX_CMD=%s&PBX_PORTEUR=%s&PBX_RETOUR=%s' % ( pbx_total, pbx_devise, pbx_cmd, pbx_porteur, pbx_retour) param += '&PBX_DATEVALMAX=%s&PBX_REPONDRE_A=%s&PBX_HASH=%s&PBX_TIME=%s' % ( pbx_datevalmax, pbx_repondre_a, pbx_hash, pbx_time) pbx_hmac = hash_hmac(request, param) return { 'page_title': 'Paiement', 'url': url, 'url_paybox': url_paybox, 'pbx_site': pbx_site, 'pbx_rang': pbx_rang, 'pbx_identifiant': pbx_identifiant, 'pbx_total': pbx_total, 'pbx_devise': pbx_devise, 'pbx_cmd': pbx_cmd, 'pbx_porteur': pbx_porteur, 'pbx_retour': pbx_retour, 'pbx_datevalmax': pbx_datevalmax, 'pbx_repondre_a': pbx_repondre_a, 'pbx_hash': pbx_hash, 'pbx_time': pbx_time, 'pbx_hmac': pbx_hmac, 'ref': ref, 'sum_to_pay': sum_to_pay, 'mt_total': mt_total, 'nfois': nfois, 'pay_ok': pay_ok, 'schedule_dates': schedule_dates, 'schedule_sums': schedule_sums, 'snippets': snippets, } @view_config(route_name='reglement_acc', renderer='../templates/reglement/reglement_acc.pt') def reglement_acc(request): page_title = "Paiement accepté" return { 'page_title': "Paiement accepté", } @view_config(route_name='reglement_ann', renderer='../templates/reglement/reglement_ann.pt') def reglement_ann(request): return { 'page_title': "Paiement annulé", } @view_config(route_name='reglement_ref', renderer='../templates/reglement/reglement_ref.pt') def reglement_ref(request): return { 'page_title': "Paiement refusé", } @view_config(route_name='reglement_ret') def reglement_ret(request): reference = request.params['reference'] montant = request.params['montant'] erreur = request.params['erreur'] if 'autorisation' in request.params: autorisation = request.params['autorisation'] else: #en cas de refus de paybox autorisation = 'ERREUR' if reference.find("/") > 6: cd_cli = reference[3:9] else: # ancien format cd_cli = reference[:6] montant = float(montant)/100 # paiement en 1 fois ? if reference.find("PBX") == -1: # réglement comptant prochain_montant = 0.0 # réglement PASS ROUSSEAU ? oui, confirmer if reference[:3] == "PRS" and erreur == '00000': confirmerPass(request, cd_cli) else: # réglement 3 fois sans frais # reference = CPT100481/22-09-2020PBX_2MONT0000076300PBX_NBPAIE02PBX_FREQ01PBX_QUAND00 # reference = CRE661759/18-06-2018PBX_2MONT0000018800PBX_NBPAIE02PBX_FREQ01PBX_QUAND00 prochain_montant = reference.split("PBX")[1] prochain_montant = prochain_montant.split("MONT")[1] prochain_montant = float(int (prochain_montant))/100 reference = reference.split("PBX")[0] if 'ETAT_PBX' in request.params: reconduction = request.params['ETAT_PBX'] else: reconduction = '' ins_tickets(request, cd_cli, datetime.now(), reference[:20], montant, autorisation, erreur, prochain_montant, reconduction) return Response( content_type='text/plain', body='1' )