bornhack-website/src/shop/coinify.py

151 lines
4.4 KiB
Python
Raw Normal View History

from vendor.coinify.coinify_api import CoinifyAPI
from vendor.coinify.coinify_callback import CoinifyCallback
from .models import CoinifyAPIRequest, CoinifyAPIInvoice
2017-05-22 18:12:37 +00:00
from django.conf import settings
import json, logging
logger = logging.getLogger("bornhack.%s" % __name__)
def process_coinify_invoice_json(invoicejson, order):
# create or update the invoice object in our database
coinifyinvoice, created = CoinifyAPIInvoice.objects.update_or_create(
coinify_id=invoicejson['id'],
order=order,
defaults={
invoicejson: invoicejson
},
)
# if the order is paid in full call the mark as paid method now
if invoicejson['state'] == 'complete':
coinifyinvoice.order.mark_as_paid()
return coinifyinvoice
def save_coinify_callback(request):
# first make a dict with all HTTP_ headers
headerdict = {}
for key, value in list(request.META.items()):
if key[:5] == 'HTTP_':
headerdict[key[5:]] = value
# now attempt to parse json
try:
parsed = json.loads(request.body.decode('utf-8'))
except Exception as E:
parsed = ''
# save this callback to db
callbackobject = CoinifyAPICallback.objects.create(
headers=headerdict,
body=request.body,
payload=parsed,
order=self.get_object(),
)
return callbackobject
def coinify_api_request(api_method, order, **kwargs):
# Initiate coinify API
coinifyapi = CoinifyAPI(
settings.COINIFY_API_KEY,
settings.COINIFY_API_SECRET
)
# is this a supported method?
if not hasattr(coinifyapi, api_method):
logger.error("coinify api method not supported" % api_method)
return False
# get and run the API call using the SDK
method = getattr(coinifyapi, api_method)
# catch requests exceptions as described in https://github.com/CoinifySoftware/python-sdk#catching-errors and
# http://docs.python-requests.org/en/latest/user/quickstart/#errors-and-exceptions
try:
response = method(**kwargs)
except requests.exceptions.RequestException as E:
logger.error("requests exception during coinify api request: %s" % E)
return False
# save this API request to the database
req = CoinifyAPIRequest.objects.create(
order=order,
method=api_method,
payload=json.dumps(invoicedict),
response=json.dumps(response),
)
logger.debug("saved coinify api request %s in db" % req.id)
return req
def handle_coinify_api_response(req, order):
if req.method == 'invoice_create' or req.method == 'invoice_get':
# Parse api response
if req.response['success']:
# save this new coinify invoice to the DB
coinifyinvoice = process_coinify_invoice_json(
invoicejson = req.response['data'],
order = order,
)
return coinifyinvoice
else:
api_error = req.response['error']
logger.error("coinify API error: %s (%s)" % (
api_error['message'],
api_error['code']
))
return False
else:
logger.error("coinify api method not supported" % req.method)
return False
################### API CALLS ################################################
def get_coinify_invoice(coinify_invoiceid, order):
# put args for API request together
invoicedict = {
'invoice_id': coinify_invoiceid
}
# perform the api request
req = coinify_api_request(
api_method='invoice_get',
2017-05-22 18:03:41 +00:00
order=order,
**invoicedict
)
coinifyinvoice = handle_coinify_api_response(req, order)
return coinifyinvoice
def create_coinify_invoice(order):
# put args for API request together
invoicedict = {
'amount': float(order.total),
'currency': 'DKK',
'plugin_name': 'BornHack webshop',
'plugin_version': '1.0',
'description': 'BornHack order id #%s' % order.id,
'callback_url': order.get_coinify_callback_url(request),
'return_url': order.get_coinify_thanks_url(request),
'cancel_url': order.get_cancel_url(request),
}
# perform the API request
req = coinify_api_request(
api_method='invoice_create',
order=order,
**invoicedict
)
coinifyinvoice = handle_coinify_api_response(req, order)
return coinifyinvoice