diff options
author | Magnus Hagander | 2023-06-18 15:48:16 +0000 |
---|---|---|
committer | Magnus Hagander | 2023-06-18 16:14:07 +0000 |
commit | 989a343a64ab9b372c606ce0cb716dc43f7574c0 (patch) | |
tree | 67e4f74040e203261679a736a3d28d3ccf3be3a7 /postgresqleu/plaid/backendviews.py | |
parent | 7f204cf595c5fb5a0daae20fe1f9eb809b173acb (diff) |
Implement support for Plaid banktransactions
This module will use the plaid.com service to download bank transaction
lists from any supported bank. If available, it will also respond to
webhooks sent by plaid whenever transactions show up, but failing that
will just poll twice per day.
Diffstat (limited to 'postgresqleu/plaid/backendviews.py')
-rw-r--r-- | postgresqleu/plaid/backendviews.py | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/postgresqleu/plaid/backendviews.py b/postgresqleu/plaid/backendviews.py new file mode 100644 index 00000000..7249a9fe --- /dev/null +++ b/postgresqleu/plaid/backendviews.py @@ -0,0 +1,57 @@ +from django.http import HttpResponseRedirect +from django.shortcuts import get_object_or_404, render +from django.contrib import messages +from django.conf import settings + +from postgresqleu.util.auth import authenticate_backend_group +from postgresqleu.invoices.models import InvoicePaymentMethod + + +def _do_balance_check(request, paymentmethod, impl): + balances = impl.get_account_balances() + if len(balances) == 0: + # 0 accounts can mean we just haven't updated yet, so set up a loop + return render(request, 'plaid/check_account.html', { + }) + if len(balances) != 1: + messages.error(request, 'Returned {} accounts, should be 1, cannot use this connection.'.format(len(balances))) + impl.disconnect() + return HttpResponseRedirect("../") + elif balances[0]['currency'] != settings.CURRENCY_ISO: + messages.error(request, 'Currency on account {} is {}, expected {}, cannot use this connection.'.format(balances[0]['accountid'], balances[0]['currency'], settings.CURRENCY_ISO)) + impl.disconnect() + return HttpResponseRedirect("../") + else: + messages.info(request, "Account {} connected.".format(balances[0]['accountid'])) + paymentmethod.config['accountid'] = balances[0]['accountid'] + paymentmethod.save(update_fields=['config', ]) + return HttpResponseRedirect('../') + + +def connect_to_plaid(request, paymentmethodid): + authenticate_backend_group(request, 'Invoice managers') + + paymentmethod = get_object_or_404(InvoicePaymentMethod, pk=paymentmethodid, classname='postgresqleu.util.payment.plaid.Plaid') + + impl = paymentmethod.get_implementation() + + if request.method == 'GET' and request.GET.get('check_account', '0') == '1': + # We're in the check account loop + return _do_balance_check(request, paymentmethod, impl) + + if request.method == 'POST': + paymentmethod.config['access_token'] = impl.exchange_token(request.POST['public_token']) + if not paymentmethod.config['access_token']: + messages.error(request, 'Could not exchange public token for permanent token.') + return HttpResponseRedirect('../') + + return _do_balance_check(request, paymentmethod, impl) + + token = impl.get_link_token() + if not token: + messages.error(request, "Could not create link token") + return HttpResponseRedirect("../") + + return render(request, 'plaid/connectaccount.html', { + 'token': token, + }) |