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

View File

@ -23,9 +23,10 @@
{% endfor %} {% endfor %}
<tbody> <tbody>
</table> </table>
<form method="post" action="{{ url('eboutic:command') }}"> <form method="post" action="{{ settings.SITH_EBOUTIC_ET_URL }}">
{% csrf_token %} {% for (field_name,field_value) in et_request.items() -%}
<input type="hidden" name="action" value="pay_with_credit_card"> <input type="hidden" name="{{ field_name }}" value="{{ field_value }}">
{% endfor %}
<input type="submit" value="{% trans %}Pay with credit card{% endtrans %}" /> <input type="submit" value="{% trans %}Pay with credit card{% endtrans %}" />
</form> </form>
<form method="post" action="{{ url('eboutic:pay_with_sith') }}"> <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.core.urlresolvers import reverse_lazy
from django.views.generic import TemplateView, View from django.views.generic import TemplateView, View
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render from django.shortcuts import render
from django.db import transaction, DataError from django.db import transaction, DataError
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.conf import settings
from counter.models import Product, Customer, Counter from counter.models import Product, Customer, Counter
from eboutic.models import Basket, Invoice, BasketItem, InvoiceItem from eboutic.models import Basket, Invoice, BasketItem, InvoiceItem
@ -74,15 +80,17 @@ class EbouticMain(TemplateView):
class EbouticCommand(TemplateView): class EbouticCommand(TemplateView):
template_name = 'eboutic/eboutic_makecommand.jinja' 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): def post(self, request, *args, **kwargs):
if 'basket' not in request.session.keys(): if 'basket' not in request.session.keys():
return HttpResponseRedirect(reverse_lazy('eboutic:main', args=self.args, kwargs=kwargs)) return HttpResponseRedirect(reverse_lazy('eboutic:main', args=self.args, kwargs=kwargs))
if 'ask_payment' in request.POST['action']: if self.make_basket(request):
if self.ask_payment(request): kwargs['basket'] = self.basket
kwargs['basket'] = self.basket
return self.render_to_response(self.get_context_data(**kwargs)) return self.render_to_response(self.get_context_data(**kwargs))
def ask_payment(self, request): def make_basket(self, request):
b = None b = None
if 'basket_id' in request.session.keys(): if 'basket_id' in request.session.keys():
b = Basket.objects.filter(id=request.session['basket_id']).first() b = Basket.objects.filter(id=request.session['basket_id']).first()
@ -99,6 +107,24 @@ class EbouticCommand(TemplateView):
self.basket = b self.basket = b
return True 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): class EbouticPayWithSith(TemplateView):
template_name = 'eboutic/eboutic_payment_result.jinja' template_name = 'eboutic/eboutic_payment_result.jinja'
@ -131,5 +157,29 @@ class EbouticPayWithSith(TemplateView):
return self.render_to_response(self.get_context_data(**kwargs)) return self.render_to_response(self.get_context_data(**kwargs))
class EtransactionAutoAnswer(View): 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() return HttpResponse()

View File

@ -298,3 +298,14 @@ SITH_MAXIMUM_FREE_ROLE=1
# Minutes to timeout the logged barmen # Minutes to timeout the logged barmen
SITH_BARMAN_TIMEOUT=20 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()