Skip to content

Commit

Permalink
Lot of things, main base for transaction, trasactions working, sample
Browse files Browse the repository at this point in the history
client.
  • Loading branch information
the-glu committed Jan 9, 2014
1 parent b2f2d72 commit e3c67cf
Show file tree
Hide file tree
Showing 31 changed files with 1,045 additions and 19 deletions.
1 change: 1 addition & 0 deletions client/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
config.py
Empty file added client/config.py.dist
Empty file.
35 changes: 35 additions & 0 deletions client/httpd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from flask import Flask
from flask import render_template
from flask import request

import config
from libs.polybanking import PolyBanking

import uuid

api = PolyBanking(config.POLYBANKING_SERVER, config.CONFIG_ID, config.KEY_REQUESTS, config.KEY_IPN, config.KEY_API)

app = Flask(__name__)


@app.route("/")
def home():
"""Display the home page"""
return render_template('home.html')


@app.route('/start')
def start():
"""Start a new paiement"""

(result, url) = api.new_transation(request.args.get('amount', ''), str(uuid.uuid4()))

return render_template('start.html', result=result, url=url)

@app.route('/back')
def back():

return render_template('back.html', result='ok' in request.args)

if __name__ == "__main__":
app.run(debug=True)
Empty file added client/libs/__init__.py
Empty file.
47 changes: 47 additions & 0 deletions client/libs/polybanking.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import requests
import hashlib


class PolyBanking():
"""Api for polybanking accesses"""

def __init__(self, server, config_id, keyRequests, keyIPN, keyAPI):
self.server = server
self.config_id = config_id
self.keyRequests = keyRequests
self.keyIPN = keyIPN
self.keyAPI = keyAPI

def compute_sign(self, secret, data):
"""Compute the signature for a dict"""

def escape_chars(s):
"""Remove = and ; from a string"""
return s.replace(';', '!!').replace('=', '??')

h = hashlib.sha512()

for key, value in sorted(data.iteritems(), key=lambda (k, v): k):
h.update(escape_chars(key))
h.update('=')
h.update(escape_chars(value))
h.update(';')
h.update(secret)
h.update(';')

return h.hexdigest()

def new_transation(self, amount, reference, extra_data=''):
"""Start a new transation, with the specified amount and reference. The reference must be unique.
Return (Status, the URL where the user should be redirected or None)
Status can be 'OK', 'KEY_ERROR', 'CONFIG_ERROR', 'AMOUNT_ERROR', 'REFERENCE_ERROR', 'ERROR'"""

data = {'amount': amount, 'reference': reference, 'extra_data': extra_data, 'config_id': self.config_id}

data['sign'] = self.compute_sign(self.keyRequests, data)

try:
result = requests.post(self.server + '/paiements/start/', data=data).json()
return (result['status'], result['url'])
except:
return ('ERROR', '')
3 changes: 3 additions & 0 deletions client/templates/back.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<h3>PolyBanking Test/Demo client</h3>

We're back. {% if result %}Status seem ok{% else %}Status seem err{%endif %}
4 changes: 4 additions & 0 deletions client/templates/home.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<h3>PolyBanking Test/Demo client</h3>

<a href="/start?amount=10000">New payement, 100.-</a><br />
<a href="/start?amount=1000000">New payement, 10'000.-</a><br />
7 changes: 7 additions & 0 deletions client/templates/start.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<h3>PolyBanking Test/Demo client</h3>

Result is {{result}}.

User should go to <a href="{{url}}">{{url}}</a><br /><br />

<a href="/">Home</a>
1 change: 1 addition & 0 deletions server/app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
'main',
'users',
'configs',
'paiements',
)

SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'
Expand Down
16 changes: 16 additions & 0 deletions server/app/settingsLocal.py.dist
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,19 @@ DATABASES = {

# Make this unique, and don't share it with anybody.
SECRET_KEY = ''

SHA_IN_TEST = ''
SHA_OUT_TEST = ''

SHA_IN_PROD = ''
SHA_OUT_PROD = ''

EXTERNAL_BASE_URL = ''

POSTFINANCE_TEST_URL = 'https://e-payment.postfinance.ch/ncol/test/orderstandard.asp'
POSTFINANCE_PROD_URL = 'https://e-payment.postfinance.ch/ncol/prod/orderstandard.asp'

PSPID_TEST = ''
PSPID_PROD = ''

CURRENCY = 'CHF'
1 change: 1 addition & 0 deletions server/app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
url(r'', include('main.urls')),
url(r'^users/', include('users.urls')),
url(r'^configs/', include('configs.urls')),
url(r'^paiements/', include('paiements.urls')),

(r'^' + settings.MEDIA_URL[1:] + '(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}), # In prod, use apache !
(r'^' + settings.STATIC_URL[1:] + '(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}), # In prod, use apache !
Expand Down
3 changes: 2 additions & 1 deletion server/configs/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.db import models
from django.contrib.auth.models import User
from django.utils.html import escape

import uuid
import datetime
Expand Down Expand Up @@ -39,7 +40,7 @@ def __unicode__(self):
if bonus:
bonus = ' (' + bonus + ')'

return self.name + bonus
return escape(self.name) + bonus

def build_user_list(self):
"""Return a list of user in text format"""
Expand Down
5 changes: 5 additions & 0 deletions server/configs/templates/configs/configs/show.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ <h3 class="panel-title">{% trans "Details of a config" %}</h3>
<p class="form-control-static"><span class="label label-{{object.admin_enable|yesno:"success,danger"}}">{{object.admin_enable|yesno}}</span></p>
</div>

<div class="form-group">
<label>{% trans "Config ID" %}</label>
<p class="form-control-static">{{object.pk}}</p>
</div>

<div class="form-group">
<label>{% trans "Key for requests" %}</label>
<p class="form-control-static">
Expand Down
14 changes: 7 additions & 7 deletions server/configs/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
'configs.views',

url(r'^$', 'list'),
url(r'^(?P<pk>[0-9]?)/show/$', 'show'),
url(r'^(?P<pk>[0-9]?)/edit/$', 'edit'),
url(r'^(?P<pk>[0-9]?)/logs/$', 'show_logs'),
url(r'^(?P<pk>[0-9]+)/show/$', 'show'),
url(r'^(?P<pk>[0-9]+)/edit/$', 'edit'),
url(r'^(?P<pk>[0-9]+)/logs/$', 'show_logs'),

#url(r'^(?P<pk>[0-9]?)/delete/$', 'delete'),
#url(r'^(?P<pk>[0-9]+)/delete/$', 'delete'),

url(r'^(?P<pk>[0-9]?)/keys/ipn/new/$', 'new_ipn_key'),
url(r'^(?P<pk>[0-9]?)/keys/requests/new/$', 'new_requests_key'),
url(r'^(?P<pk>[0-9]?)/keys/api/new/$', 'new_api_key'),
url(r'^(?P<pk>[0-9]+)/keys/ipn/new/$', 'new_ipn_key'),
url(r'^(?P<pk>[0-9]+)/keys/requests/new/$', 'new_requests_key'),
url(r'^(?P<pk>[0-9]+)/keys/api/new/$', 'new_api_key'),

)
8 changes: 4 additions & 4 deletions server/configs/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def edit(request, pk):

messages.success(request, 'The config has been saved.')

return redirect(reverse('configs.views.list'))
return redirect('configs.views.list')
else:
form = ConfigForm(request.user, instance=object)

Expand Down Expand Up @@ -122,7 +122,7 @@ def new_ipn_key(request, pk):

messages.success(request, 'A new IPN key has been generated !')

return redirect(reverse('configs.views.show', args=(pk,)))
return redirect('configs.views.show', pk=pk)


@login_required
Expand All @@ -141,7 +141,7 @@ def new_requests_key(request, pk):

messages.success(request, 'A new requests key has been generated !')

return redirect(reverse('configs.views.show', args=(pk,)))
return redirect('configs.views.show', pk=pk)


@login_required
Expand All @@ -160,7 +160,7 @@ def new_api_key(request, pk):

messages.success(request, 'A new api key has been generated !')

return redirect(reverse('configs.views.show', args=(pk,)))
return redirect('configs.views.show', pk=pk)


@login_required
Expand Down
Empty file added server/libs/__init__.py
Empty file.
47 changes: 47 additions & 0 deletions server/libs/postfinance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import requests
import hashlib
from django.conf import settings


class PostFinance():
"""Api for postfinance"""

def __init__(self, SHA_IN, SHA_OUT, PSPID, testMode=False):
self.SHA_IN = SHA_IN
self.SHA_OUT = SHA_OUT
self.PSPID = PSPID
self.testMode = testMode

def computeSign(self, secret, data):
"""Compute a SHA signature following PostFinance's protocol"""

h = hashlib.sha512()

for key, value in sorted(data.iteritems(), key=lambda (k, v): k):
h.update(key)
h.update('=')
h.update(value)
h.update(secret)

return h.hexdigest()

def computeOutSign(self, data):
"""Compute a SHA signature following PostFinance's protocol using OUT key"""
return self.computeSign(self.SHA_OUT, data)

def computeInSign(self, data):
"""Compute a SHA signature following PostFinance's protocol using IN key"""
return self.computeSign(self.SHA_IN, data)

def getPspIp(self):
"""Return the pspId"""
return self.PSPID


def buildPostFinance(testMode=False):
"""Return a postfinance object with correct parameters"""

if testMode:
return PostFinance(settings.SHA_IN_TEST, settings.SHA_OUT_TEST, settings.PSPID_TEST, True)
else:
return PostFinance(settings.SHA_IN_PROD, settings.SHA_OUT_PROD, settings.PSPID_PROD, False)
21 changes: 21 additions & 0 deletions server/libs/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import hashlib


def compute_sign(secret, data):
"""Compute the signature for a dict"""

def escape_chars(s):
"""Remove = and ; from a string"""
return s.replace(';', '!!').replace('=', '??')

h = hashlib.sha512()

for key, value in sorted(data.iteritems(), key=lambda (k, v): k):
h.update(escape_chars(key))
h.update('=')
h.update(escape_chars(value))
h.update(';')
h.update(secret)
h.update(';')

return h.hexdigest()
3 changes: 0 additions & 3 deletions server/main/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
from django.db import models

# Create your models here.
20 changes: 20 additions & 0 deletions server/paiements/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models


class Migration(SchemaMigration):

def forwards(self, orm):
pass

def backwards(self, orm):
pass

models = {

}

complete_apps = ['paiements']
Loading

0 comments on commit e3c67cf

Please sign in to comment.