Integració del TVP CECA
Escrit per Aaloy a 26 de July , 2010 a les 8:20 p.m.
Després de barallar-m'hi un bon grapat de dies he aconseguit integrar el TPV de CECA en una de les aplicacions que estic desenvolupant per APSL. Com en el cas de la integració amb el BBVA he de dir que la qualitat de la documentació és inversament proporcional al suport que tens dels tècnics, per a que quedi clar: la documentació és pèssima, plena de inconsistències i exemples que no funcionen. El suport dels tècnics de CECA molt bo. Poc temps per a contestat (llevat de si demanes en divendres, clar) i respostes clares i concises. Un deu! Amb la gent del BBVA el mateix, se coneix que els ha tocat bregar amb la documentació.
No acab d'entendre què costa mantenir la documentació actualitzada. Si ja no es fa servir un programa per a generar la firma, llavors es refà la documentació i se'n lleva la referència. Si s'incorpora un tag obligatori nou que s'ha d'enviar, llavors s'actualitzen els exemples.
Per si a algú més li serveix faig cinc cèntims del que m'he trobat i del que funciona a l'hora d'escriure aquest apunt.
Generació de la firma
La firma és diferent per l'enviament i per la resposta. En ambdós casos es fa servir el xifrat sha1
Per l'enviament hem de fer una concatenació formada per:
clau_encriptació
merchantid
adquirerbin
terminalid
num_operacion
importe
tipomoneda
exponente
referencia
SHA1
url_ok
url_nokEl que és cada cosa està a la documentació, aquí el que s'ha de saber és: SHA1 és una cadena de caràcters i és necessari posar-la. La referència apareix a la documetació, però NO s'ha de posar, millor dit, és una cadena buida. El número d'operació és el que identificarà la nostra operació i vendrà també a la confirmació així que convé (i és necessari) que sigui un codi numèric únic. L'import és un nombre on les dues posicions representen els decimals, així 12.23 passa a ser 1223. Damunt la concatenació s'ha de fer l'sha1 i passar-ho tot a una cadena hexadecimal i a minúscules. Per exemple:
m = hashlib.sha1() m.update(s) valor = m.hexdigest().lower()
El calcul de la firma per la signatura de la resposta és diferent: clave_encriptacion merchantid adquirerbin terminalid num_operacion importe tipomoneda exponente referencia
Fixau-vos que no hi ha SHA1 aquí i com a cosa important l'import s'ha de posar tal com ve de la resposta, veureu que ve completat a zeros per l'esquerra. En aquest cas la referència sí que ve i està generada per la pasarel·la de pagament.
Enviament de les dades
<form id="pago_form" action="{{url_ceca}}" method="post" accept-charset="utf-8" enctype="application/x-www-form-urlencoded">
<input id="MerchantID" name="MerchantID" type="hidden" value="{{merchant_id}}"/>
<input id="AcquirerBIN" name="AcquirerBIN" type="hidden" value="{{acquirer_bin}}"/>
<input id="TerminalID" name="TerminalID" type="hidden" value="{{terminal_id}}"/>
<input id="firma" name="Firma" type="hidden" value="{{firma}}"/>
<input id="importe" name="Importe" type="hidden" value="{{importe}}"/>
<input name="TipoMoneda" type="hidden" value="978"/>
<input name="Exponente" type="hidden" value="2"/>
<input id="referencia" name="Referencia" type="hidden" value=""/>
<input name="URL_OK" type="hidden" value="{{url_ok}}"/>
<input name="URL_NOK" type="hidden" value="{{url_nok}}"/>
<input name="Pago_soportado" type="hidden" value="SSL"/>
<input name="Cifrado" type="hidden" value="SHA1"/>
<input name="Idioma" type="hidden" value="1"/>
<input name="Descripcion" type="{{descripcion}}"/>
<input type="submit" value="Comprar" />
</form>Si mirau la documentació veureu que qualsevol parescut amb els exemples és pura coincidència. Tots els camps hi són però no hi ha cap exemple que funcioni amb els camps que hi ha. L'import ha d'estar en el mateix format que la firma, és a dir com a nombre sencer on les dues darreres xifres representen la part decimal.
És important notar que la referència viatja buida i que s'ha de posar el camp Cifrado. L'exemple està agafat d'una plantilla Django i preparat per a funcionar amb Euros com a moneda i en castellà com a idioma.
Rebre la resposta
CECA us enviarà la resposta en un POST a la url que l'indiqueu. Ja he comentat abans el tema de la firma. Convé comprovar sempre que la firma de l'operació calculada amb els paràmetres que ens ha donat CECA coincideix amb el que rebem, d'altra manera implicaria que algú altra està intentant validar l'operació de pagament i marcar-la com a correcta quan no seria així.
Si feis com nosaltres la integració fent servir Django heu de tenir en compte que la protecció CSRF evita que pugui enviar-se un post com el que necessitam, així que hem de marcar la url com a exempta d'aquesta protecció. No fa gaire gràcia, però com a protecció addicional convindrà configurar el firewall per a que sols accepti peticions cap a la url confirmació des de les IPs de CECA.
Com a consideracions importants heu de tenir en compte que CECA passarà l'import completat a zeros per l'esquerra i que heu de guardar la referència i el camp Num_aut, ja que són els dos camps que CECA us demanaria en cas de reclamació. El camp Num_operacion se correspon amb el nombre d'operació que nosaltres hem enviat i ens servirà per a localitzar i processar la venda.
Esper que la informació sigui d'utilitat.
Traducciones/Translations by apertium
4 comentaris, 0 trackbacks (URL) , Tags: Python APSL Django
Comparant Python i PHP: Xor encryption
Escrit per Aaloy a 18 de July , 2010 a les 10:26 a.m.
Quan xerram de Python una de les coses en que es fa més èmfasi és la claretat i expressivitat del llenguatge, que ens permet posar les nostres idees en forma de codi de manera ràpida i a més entenedora.
També és important remarcar que Python sovint necessite moltes menys línies de codi per fer el mateix que altres llenguatges, ja no dic un C, C++ o Java, sinó que un PHP, ja sigui per la pròpia potència de Python o bé per que ja hi ha una llibreria estàndard que té implementada aquella funcionalitat que cercam.
Aquesta setmana estava fent una integració amb la passarel·la de pagament del BBVA i m'he trobat amb un d'aquests casos. Per a la comunicació de les dades BBVA signa l'enviament i ho encripta fent servir l'algoristme d'encriptació xor. A la docuentació hi ha un exemple de vàries planes de codi de com es fa això amb PHP i Java/JSP.
Podeu trobar un exemple de com es fa amb PHP al SicilianGirl o també a l'IES Puig Castellar
La implementació de l'encriptació XOR en PHP, treta d'un snippet de php és:
function XOREncryption($InputString, $KeyPhrase){
$KeyPhraseLength = strlen($KeyPhrase);
// Loop trough input string
for ($i = 0; $i < strlen($InputString); $i++){
// Get key phrase character position
$rPos = $i % $KeyPhraseLength;
// Magic happens here:
$r = ord($InputString[$i]) ^ ord($KeyPhrase[$rPos]);
// Replace characters
$InputString[$i] = chr($r);
}
return $InputString;
}En Python això es faria així:
from itertools import izip, cycle def xor_crypt_string(data, key): return ''.join(chr(ord(x) ^ ord(y)) for (x,y) in izip(data, cycle(key)))
Python és un llenguatge molt potent, i part d'aquesta potència és la possibilitat de fer servir la programació funcional i els iteradors.
Com el seu nom indica cycle va retornant elements d'un iterable de manera cíclica, és a dir que quan arriba al darrer torna a començar.
izip té un nom potser més confús, ja que no té res a veure amb el popular format de compressió, és un iterador que donats dos iterables (dues llistes de caràcters en el nostre cas) ens retorna cada vegada una parella d'elements on el primer element pertany a la primera llista i el segon element a la segona.
Fixau-vos que el cycle ens permet eliminar el codi que manté el comptador al PHP, és a dir $rPos i tot el relacionat amb ell.
Una altra raó més per fer servir Python! :)
Traducciones/Translations by apertium
7 comentaris, 0 trackbacks (URL) , Tags: Python
Cerca i substitució a Vim
Escrit per Aaloy a 17 de July , 2010 a les 11:13 a.m.
Ahir volia substituir una paraula però sols dins un bloc de codi concret. Per les presses no vaig anar a cercar com fer-ho amb Vim (la primera opció que vaig provar no va anar bé), però me va quedar el cuquet de com fer-ho, així que un poc de cerca a Google m'ha duit fins a aquesta recepta.
A Vim podem seleccionar blocs de texts entrant en mode visual (v, V o Ctrl+V per seleccionar en columnes).
Quan tenim el text seleccionat pitjarem : per entrar en mode comandes i en sortirà l'editor amb
:'<,'>
Això ens indica que podem començar a escriure la comanda, entre d'altres la d'edició i substitució. Així doncs bastarà teclejar s/{patró de cerca}/{patró de substitució}, el que feia jo malament era posar un % davant la essa.
Tot i la selecció que hagem fet, aquest tipus de substitució sols funciona per a línies completes, en la majoria de casos ens bastarà, però si volem liminar-nos exactament a la columna que hem seleccionat, hem de limitar més la cerca. Vim ens permet utilitzar %V per restringir la cerca al que volem. Així, la nostra cerca serà:
:%s/\%V{patró de cerca}/{patró de substitució}/gCom a curiositat destacar que la barra de separació de bloc entre cerca i substitució no té perquè ser una barra, pot ser qualsevol caràcter que ens agradi.
Traducciones/Translations by apertium
0 comentaris, 0 trackbacks (URL) , Tags: Informàtica Vim IDE
El cicle de desenvolupament
Escrit per Aaloy a 11 de July , 2010 a les 10:51 a.m.
L'altra dia vaig tenir l'ocasió de parlar amb un responsable informàtic d'una empresa gran. Una conversa llarga però entretinguda, afegiria.
El cas és que en un moment de la conversa l'home va venir a dir que abans es pensava molt més a l'hora de programar, que com que el temps de CPU era molt més car, llavors els programadors s'havien de pensar molt el que feien, que els programes tenien menys errors d'entrada.
La veritat és que no tenc dades estadístiques de la quantitat d'errors que hi podria haver, però també és veritat és que pareix que la taxa d'errors per línia de codi és una constant que s'ha mantingut pràcticament constant al llarg del temps. De fet és una de les raons per elegir llenguatges d'alt nivell respecte a llenguatges de baix nivell a l'hora de programar, ja que hem d'escriure menys línies de codi, llavors la quantitat total d'errors introduït també serà menor.
Així doncs, tenir molt repensant els programes a l'hora de picar-los no feia que tinguessin menys errors, sinó que sintàcticament eren correctes. Però la gràcia dels analitzadors de codi actuals, dels compiladors, és que permeten caçar tots aquests errors de manera ràpida.
És a dir, actualment es pot teclejar el codi directament a l'editor, compilar-lo (o no si feis servir un llenguatge interpretat) i provar-lo en un cicle de realimentació ràpid. El que estam fent és aprofitar la tecnologia al nostre favor, deixar que l'ordinador caci els errors de sintaxi i ens avisi dels errors més obvis. En definitiva el que estam fent és aprofitar-nos de que l'hora de CPU té un preu al voltant de zero, superant en molt el cost de l'hora de programador.
Els programes s'han fet més complexos, amb més línies de codi, on cada vegada hi ha més capes i més distribució, i això fa que les tècniques de programació i testeig també hagin evolucionat. Encara tenim que picar el codi, però podem fer-ho directament a l'ordinador, no hem d'esperar per saber si el codi té errors de sintaxi o no, i això ens fa més productius i evita temps d'espera. Això no vol dir que els programador siguin ara més descuidats en el seu codi ara que abans, sinó que senzillament poden dedicar-se més ara a la funcionalitat i no tant a tenir que validar manualment que tota la sintaxi del programa sigui correcta.
Personalment no he tingut que tractar amb mainframes i amb el tipus de programació i feina de la que parlava el meu interlocutor, però tenc clar que en informàtica com en altres coses el temps passat no era millor. Potser ara el veim amb nostàlgia, però la realitat és que ara comptam amb una gran quantitat d'eines i ajudes a la programació que fan que el programador pugui destacar per la seva creativitat i coneixements i no per la seva habilitat mecanogràfica.
Traducciones/Translations by apertium
1 comentari, 0 trackbacks (URL) , Tags: Informàtica Gestió de projectes
Django caché invalidation
Escrit per Aaloy a 04 de July , 2010 a les 4:32 p.m.
Un dels problemes més importants del desenvolupament d'aplicacions web que necessiten suportar una gran quantitat de visités és el de decidir com es farà l'arquitectura de caché i quan i com s'invalida el contingut de la mateixa.
Al respecte he trobat dues presentacions realment excel·lents de la Djangocon:
Les dues són molt bones, però especialment us recoman la segona si voleu passar una estona divertida a més d'aprendre com funciona el tema de les cachés. Jared Kuolt broda una presentació plena d'ocurrències, dobles sentits i acudits freaks al mateix temps que aconsegueix introduir-nos en la problemàtica de les cachés.
La primera presentació té moltíssima informació, Michel Malone de Pownce explica els problemes que s'han trobat a Pownce i com els han anat solucionant a Django.
El problema fonamental de les cachés a Django és el tema de la invalidació. Django oculta bastant el nom de les claus que genera i sense aquestes claus un no pot anar a Memecached per invalidar-les.
La sol·lució passa invariablement per generar les nostres pròpies claus de manera repetible i fer un us dels signals de Django per a realitzar la invalidació de les cachés.
Això vol dir ser conscients de com està construïda la nostra aplicació, saber com es genera cada plana i poder enviar el senyal adeqüat per a que s'invalidi la caché quan es modifica cert contingut.
Per llocs amb una càrrega mitjana, les eines per defecte que ens dóna Django són més que suficients. El problema ens ho trobam quan tenim llocs amb mil·lions de visites o bé, quan tenim un lloc web amb relativament poques visites però on l'usuari no és conscient de la importància que té servir les planes ràpidament i per tant de la importància de les cachés.
És el tipus d'aplicació que necessita que qualsevol tipus de canvi es vegi reflexat de manera immediata a la web. Si el lloc és petit, senzillament es pot invalidar tota la caché, si el lloc comença a tenir moltes visites aquest tipus d'invalidació no és convenient i ens trobam gairebé amb la mateixa necessitat d'invalidació de cachés que poden tenir llocs amb moltes més visites.
Jared diu a la seva presentació que el tema del rendiment d'una aplicació web és soluciona amb ^ca(sh|che)$. Personalment crec que les dues opcions van lligades, ja que encara que no es faci la despesa en hardware, un lloc web que requereixi um molt bon rendiment i a la vegada tengui poca inversió amb ferro, necessitarà d'una gestió molt fina de les cachés i de la seva invalidació.
Traducciones/Translations by apertium
0 comentaris, 0 trackbacks (URL) , Tags: Python Django
