Implement parts of the ET API

This commit is contained in:
Skia 2016-07-24 18:26:03 +02:00
parent 0ecb78a101
commit d837b624e2
4 changed files with 71 additions and 10 deletions

View File

@ -31,7 +31,6 @@
<p><strong>{% trans %}Total: {% endtrans %}{{ "%0.2f"|format(basket_total) }} €</strong></p>
<form method="post" action="{{ url('eboutic:command') }}">
{% csrf_token %}
<input type="hidden" name="action" value="ask_payment">
<input type="submit" value="{% trans %}Proceed to command{% endtrans %}" />
</form>
</div>

View File

@ -23,9 +23,10 @@
{% endfor %}
<tbody>
</table>
<form method="post" action="{{ url('eboutic:command') }}">
{% csrf_token %}
<input type="hidden" name="action" value="pay_with_credit_card">
<form method="post" action="{{ settings.SITH_EBOUTIC_ET_URL }}">
{% for (field_name,field_value) in et_request.items() -%}
<input type="hidden" name="{{ field_name }}" value="{{ field_value }}">
{% endfor %}
<input type="submit" value="{% trans %}Pay with credit card{% endtrans %}" />
</form>
<form method="post" action="{{ url('eboutic:pay_with_sith') }}">

View File

@ -1,11 +1,17 @@
from django.shortcuts import render
from collections import OrderedDict
from datetime import datetime
import hmac
import base64
from OpenSSL import crypto
from django.shortcuts import render
from django.core.urlresolvers import reverse_lazy
from django.views.generic import TemplateView, View
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from django.db import transaction, DataError
from django.utils.translation import ugettext as _
from django.conf import settings
from counter.models import Product, Customer, Counter
from eboutic.models import Basket, Invoice, BasketItem, InvoiceItem
@ -74,15 +80,17 @@ class EbouticMain(TemplateView):
class EbouticCommand(TemplateView):
template_name = 'eboutic/eboutic_makecommand.jinja'
def get(self, request, *args, **kwargs):
return HttpResponseRedirect(reverse_lazy('eboutic:main', args=self.args, kwargs=kwargs))
def post(self, request, *args, **kwargs):
if 'basket' not in request.session.keys():
return HttpResponseRedirect(reverse_lazy('eboutic:main', args=self.args, kwargs=kwargs))
if 'ask_payment' in request.POST['action']:
if self.ask_payment(request):
if self.make_basket(request):
kwargs['basket'] = self.basket
return self.render_to_response(self.get_context_data(**kwargs))
def ask_payment(self, request):
def make_basket(self, request):
b = None
if 'basket_id' in request.session.keys():
b = Basket.objects.filter(id=request.session['basket_id']).first()
@ -99,6 +107,24 @@ class EbouticCommand(TemplateView):
self.basket = b
return True
def get_context_data(self, **kwargs):
kwargs = super(EbouticCommand, self).get_context_data(**kwargs)
kwargs['et_request'] = OrderedDict()
kwargs['et_request']['PBX_SITE'] = settings.SITH_EBOUTIC_PBX_SITE
kwargs['et_request']['PBX_RANG'] = settings.SITH_EBOUTIC_PBX_RANG
kwargs['et_request']['PBX_IDENTIFIANT'] = settings.SITH_EBOUTIC_PBX_IDENTIFIANT
kwargs['et_request']['PBX_TOTAL'] = int(self.basket.get_total()*100)
kwargs['et_request']['PBX_DEVISE'] = 978 # This is Euro. ET support only this value anyway
kwargs['et_request']['PBX_CMD'] = "CMD_"+str(self.basket.id)
kwargs['et_request']['PBX_PORTEUR'] = self.basket.user.email
kwargs['et_request']['PBX_RETOUR'] = "Amount:M;BasketID:R;Auto:A;Error:E;Sig:K"
kwargs['et_request']['PBX_HASH'] = "SHA512"
kwargs['et_request']['PBX_TIME'] = str(datetime.now().replace(microsecond=0).isoformat('T'))
kwargs['et_request']['PBX_HMAC'] = hmac.new(settings.SITH_EBOUTIC_HMAC_KEY,
bytes("&".join(["%s=%s"%(k,v) for k,v in kwargs['et_request'].items()]), 'utf-8'),
"sha512").hexdigest().upper()
return kwargs
class EbouticPayWithSith(TemplateView):
template_name = 'eboutic/eboutic_payment_result.jinja'
@ -131,5 +157,29 @@ class EbouticPayWithSith(TemplateView):
return self.render_to_response(self.get_context_data(**kwargs))
class EtransactionAutoAnswer(View):
def get(self, request, *args, **kwargs): # TODO implement CA's API
def get(self, request, *args, **kwargs):
# test URL:
# http://127.0.0.1:8000/eboutic/et_autoanswer?Amount=guy&BasketID=4000&Auto=42&Error=00000&Sig=OeKzrHyh9XgjWY8zN2N/Itsg70y3/RRxOTYlW8zx8fDeMwv10LVo6BHB0NTY0WEv/gNY1uNjYEW8IGLz4HzvPcR4w7vsM7dTkSWDvGhVpA57LydRqyQVu6CjY1SL71s4htZRN6XZrexCJag8IBNUOj8rvEu4EdFKqUOQlxU4W3c=
if (not 'Amount' in request.GET.keys() or
not 'BasketID' in request.GET.keys() or
not 'Auto' in request.GET.keys() or
not 'Error' in request.GET.keys() or
not 'Sig' in request.GET.keys()):
return HttpResponse(status=400)
key = crypto.load_publickey(crypto.FILETYPE_PEM, settings.SITH_EBOUTIC_PUB_KEY)
cert = crypto.X509()
cert.set_pubkey(key)
sig = base64.b64decode(request.GET['Sig'])
print(sig)
print('&'.join(request.META['QUERY_STRING'].split('&')[:-1]))
try:
crypto.verify(cert, sig, '&'.join(request.META['QUERY_STRING'].split('&')[:-1]), "sha1")
except:
print("Bad signature")
return HttpResponse(status=400)
if request.GET['Error'] == "00000":
print("OK")
else:
print("FAIL")
return HttpResponse()

View File

@ -298,3 +298,14 @@ SITH_MAXIMUM_FREE_ROLE=1
# Minutes to timeout the logged barmen
SITH_BARMAN_TIMEOUT=20
# ET variables
SITH_EBOUTIC_ET_URL = "https://preprod-tpeweb.e-transactions.fr/cgi/MYchoix_pagepaiement.cgi"
SITH_EBOUTIC_PBX_SITE = "1520411"
SITH_EBOUTIC_PBX_RANG = "01"
SITH_EBOUTIC_PBX_IDENTIFIANT = "650995411"
SITH_EBOUTIC_HMAC_KEY = bytes("0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF", 'utf-8')
SITH_EBOUTIC_PUB_KEY = ""
with open('./sith/et_keys/pubkey.pem') as f:
SITH_EBOUTIC_PUB_KEY = f.read()