Development
Installation
Install the package and dependencies:
pip install -r requirements.txt
pipe install -e .
Create a config.json
file:
cp config-example.json config.json
Fill out the STRIPE_API_KEY
and VISIT_API_KEY
settings.
Setup a local (sqlite) database:
python manage-dev.py migrate
python manage-dev.py createsuperuser
python manage-dev.py loaddata prices-test.json
This will create a file db.sqlite
and initialize it with the necessary tables and data. You
can now run a development server by running:
python manage-dev.py runserver
Invoking management commands
The manage-dev.py
file is an entrypoint to running django management commands. The generic CLI
tool for running
django-admin<https://docs.djangoproject.com/en/4.2/ref/django-admin/>
This command requires at least one enviroment variable to be set DJANGO_SETTINGS_MODULE
to
point to a python module for the project’s settings as a dotted path. For local development, the
path should be stripe_checkout.settings.dev
. Inside the root of the stripe_checkout
repository,
The manage-dev.py
file is preconfigured with this enviroment variable, and a CONFIG_FILENAME
environment variable pointing to the config.json
file created during Installation.
When invoking management commands in the deployed VMs you should use the /home/tnc/cmd.sh
script instead of django-admin
. This script is configured with the correct environment variables
for running django commands against the deployed instance.
Settings
There are three ways of supplying settings. These are described below
Settings file
For development, use the stripe_checkout.settings.dev
settings module. Deployed environments
(test, uat, prod) use the stripe_checkout.settings.prod
settings module. These files contain
settings that are static between the environments, and contain some logic for reading and parsing
environment variables that are set for specific environments.
Config file
The config file is a way to supply settings that are non-static, and therefore cannot be placed
in a settings file. The config file must be a json file containing a top level dictionary, where
the keys are settings (are therefore must be UPPER_CASE
) and are directly interpreted as django
settings. This allows the values to have an arbitrary structure other than a single string, such
as an array. The config file is validated to a json schema, located in stripe_checkout.config
.
In order to use a specific config file, set the CONFIG_FILENAME
environment variable to a file
path path/to/config.json
that points to a valid config file. This can be an absolute path or
a relative path. For discoverability, it is better to use an absolute path.
Environment Variables
We use the DJANGO_SETTINGS_MODULE
and CONFIG_FILENAME
to point to the settings file
dotted.path
and config file path/to/config.json
. There are also other environment variables
for settings that cannot be static in a settings file, because they either vary between environments,
or contain sensitive information. The settings files are set up in a way to read certain enviroment
variables and use them for specific settings.
Note
Both the config.json
and environment variables can be used for variable settings. When to use one
over the other is somewhat arbitrary, but there are guidelines. Settings that are relevant to the
application specifics should be placed in the config.json
, such as api keys and specific
stripe or visit ids. Also settings that have a more complex structure than a single string (such
as an array) are more easily set using a config.json
Settings that have a more
infrastructure-like nature, or have to do with django internals, such as DJANGO_FRONTEND_URL
or DJANGO_SECRET_KEY
are supplied using environment variables. Another reason to use an
environment variable is when a value needs to be processed before being assigned to the actual
setting, as is the case with the DATABASE_URL
environment variable.
Database
Stripe checkout needs a database to function properly. In development this is a sqlite database.
You can also connect to the test database by setting the DATABASE_URL
environment variable
(substitute the username and password with the data in Lastpass):
export DATABASE_URL=postgres://<username>:<password>@test-postgres.geant.org/stripe_checkout
If you now run django-admin
or manage-dev.py
this will connect to the database for the
test deployment.
Email
stripe-checkout
sends an email when it sees a succeeded payment intent that doesn’t match an
Order
in the database, and therefore can’t link it to a visitor’s purchase. It uses Django’s
send_mail functionality. Django uses the following settings:
EMAIL_HOST (default: localhost)
EMAIL_PORT (default: 25)
It so happens postfix is configured on the stripe-checkout
vm’s to forward to the geant smtp
servers. So we don’t need much additional configuration. We only configure the DEFAULT_FROM_EMAIL
setting. The recipients for these emails can be set using the SEND_ERROR_EMAILS_TO
setting in the Config file
Stripe webhook endpoint
Stripe can be configured to call a webhook endpoint for certain
Stripe events. These webhooks can be configured in the Stripe Workbench.
Stripe is configured to call the /stripe-event-webhook/
endpoint for payment_intent.succeeded
and payment_intent.canceled
webhooks (see also: Design). There may be other events
configured as well, but these are ignored when processing events.
During development it is possible to register your locally running development server as an event webhook using the stripe cli and register a local listener. After setting up stripe cli and logging in, you can hook up the local developer server with the following command:
stripe listen --events payment_intent.succeeded,payment_intent.canceled \
--forward-to 127.0.0.1:8000/stripe-event-webhook/
Upon running this command, the stripe cli will output a stripe signing secret. This is a secret key
that stripe will use to sign the event payload so that we can be certain the events are actually
coming from Stripe. Add this secret to you config.json
as the STRIPE_SIGNING_SECRET
setting
and restart the development server.
Events
s will now be registered in the local database. Run the following command to process these
events:
python manage-dev.py processevents
Note
One way the /stripe-event-webhook
is secured is through the signing secret. The second way
this endpoint is secured, is that only IP addresses from stripe can actually call this endpoint.
The full list of stripe webhook IP addresses can be found
here. These IP addresses are placed in the
STRIPE_WEBHOOK_ALLOWED_IPS
setting in the stripe_checkout.settings.prod
settings module.
Visit redirect
The redirect to the stripe checkout server in Visit is done using a custom javascript snippet:
Click the final page “Complete”
Click “current page settings”
Clikc “Edit Javascript”

Warning
There is another method of adding javascript, namely in the form settings rather than the custom page settings. These are the first settings you see when editing the form. Any javascript placed here is activated for the whole form rather than a single page. Also, Javascript placed in the form settings, overrides any javascript placed in page settings, so this will deactivate the automatic redirect.
Redirect URL
The redirect url is stored in the Visit custom field bridgeserviceurl
. To edit this, login to
Visit, open the TNC 2025 event and follow these steps:
Click on Event
Click on Setup
Click on Custom fields

For more information on custom fields, see the Visit documentation