From 2124152a5402ca127c519232904b474a23cb3239 Mon Sep 17 00:00:00 2001 From: Pelle Koster <pelle.koster@geant.org> Date: Thu, 13 Feb 2025 16:48:17 +0100 Subject: [PATCH] cleanup readme and link to sphinx documentation --- README.md | 212 +----------------------------------------------------- 1 file changed, 1 insertion(+), 211 deletions(-) diff --git a/README.md b/README.md index 859df5c..12bbc96 100644 --- a/README.md +++ b/README.md @@ -15,214 +15,4 @@ service acts as an in-between layer and does support these features When visitors are registering to TNC2025 in Visit cloud, they are redirected to this service in the final step -See the full documentation on - - -# Design -The design of the stripe-checkout service is roughly as following: - -* Whenever a visitor registers for TNC, they fill out a form in Visit. This form sets their - `registrationType`. While filling out the form, the visitor may also want to purchase some extras, - such as access to side meetings or social events. The information for extras is stored in the - visitors profile as answers to certain questions. For example, there is a question for "Side - meetings" with answers "Friday" and "Sunday" -* As the final page in the registration form, the visitor is redirected to the stripe checkout - service. Here they see what they've checked out and how much they need to pay. - - * The checkout service reads the visitor's profile through the Visit API (the visitor is - identified by their visitor id in the url). - * From the visitor's profile, the Stripe products that the visitor needs to pay for are - determined. A visitor can have a single Registration Type item and multiple extras. Every - category of extras has two questions: One that the visitor answers with the extras they want, - and one that is goverened by the stripe checkout service when the visitor's payment has been - processed. Every answer in the paid-questions represents an extra that the visitor has paid for - - These are defined as `PricedItem` objects in the database. See also: - [Adding new products or price information to the database](#adding-new-products-or-price-information-to-the-database) - below. - * All items that the visitor has not previously purchased (see `Order` below) are added to a - `ShoppingCart` and this collection is shown to the user in their checkout page - -* In their checkout page, the visitor can add some additional information that will be shown on - the invoice. These are a Purchase Order (PO) number and/or a VAT id. These fields are optional. - Then the visitor clicks Confirm to finalize the purchase -* The stripe checkout service now creates an invoice in Stripe for the items that they need to pay - for: - - * All `PricedItem` objects that the visitor needs to pay for are collected in an `Order` and - stored in the database. Any items for which the visitor already has an `Order` are excluded from - the new `Order`, so that the visitor is charged only once for an item. - * The visitor's billing address is read from their Visit profile. `contact.addresses` should - contain an address object of `"type": "billing"`. **In order for any billing information to be - shown in the Invoice, it is required that the `country` field is set to a valid country code in - the billing address.** - * The visitor is identified in stripe by their email address. If the visitor's email address - is already bound to a customer in Stripe, we use that customer, but update the billing details - using their Visit profile - * Additional fields are added to the the invoice as `custom_fields`. These are: - * Purchase Order (if any) - * VAT number (if any) - * GBP VAT (The VAT amount in GBP. The exchange rate read from the database and is periodically - updated by management command `getexchangerate`) - * We tell Stripe to finalize and send the invoice by email to the visitor. Stripe also generates - a url where the visitor can directly pay their invoice. We redirect the user to this url. The - visitor facing part of the stripe checkout service is now finished. - * When creating and finalizing the Invoice, Stripe also creates a payment intent. Before - redirecting the visitor to their Stripe payment page, we store the payment intent's id - (starting with `pi_`) along with the `Order` so that we can reference it later. - -* We now wait for the visitor to pay. The visitor may pay by credit card or by bank transfer. While - credit card payments are processed almost instantly, bank transfers may take time to be - processed. First, the visitor needs to actually pay, and then Stripe needs to process the - payment. The total time between placing the order and strip processing the payment may take weeks - or longer. -* When the visitor's payment has been succesfully processed by Stripe, Stripe calls our webhook at - the `stripe-event-webhook/` endpoint. This endpoint does not process the event, but merely stores - it in the database as an Event. Stripe requires that this endpoint returns quickly so processing - the events happens asynchronously by periodically running the django managemement command - `processevents` -* The `processevents` command looks in the database for Events that are has not processed yet. It - looks at two types of events: `payment_intent.succeeded` and `payment_intent.canceled`. - * `payment_intent.succeeded` events indicate that the visitor has paid. We look in the `Order` - table for a matching Order, and update the visitor's Profile in Visit. We add the `PAID` tag - to the visitor to indicate that they've paid for their main registration, and add the relevant - answers to the "paid"-question for extra's. - - - - -# Development - -## Config -This service needs configuation data in the form of a config json file. By default, django look -a file called `config.json` in the current directory. It is possble to override this by setting -the environment variable `CONFIG_FILENAME` to point to a different location. A sample config is -given in `config-example.json`. Make a copy named `config.json` and fill in the required data -such as the `STRIPE_API_KEY` and the `VISIT.api-key` variables. - -## Database -Connecting to a database can be done by setting the DATABASE_URL environment variable to a valid -value: -``` -export DATABASE_URL=postgresql://<username>:<password>@<host_address>/<database> -``` - -Altenatively, you can set up a local (sqlite) database. This can be done easily from the -root of this repository - -``` -python manage-dev.py migrate -``` - -This will create a database file 'db.sqlite' in the current directory. You can then create a -superuser account - -``` -python manage-dev.py createsuperuser -``` - -And finally you need to populate the database with price information. Sample price information -is given in the `prices.json` file, but this file may not be completely up to date - -``` -python manage-dev.py createprices --file prices.json -``` - -## Development server -You can then run the development server by running - -``` -python manage-dev.py runserver -``` - -## Admin interface -The django admin interface is enabled, so when running the development server you can browse to -`http://127.0.0.1:5000/admin` to login to the admin interface using the credentials you created - using the createsuperuser (or other valid credentials if connected to an existing database). Here - you can manage administrative users, priced items and other things. - -## Migrate price information to deployments - -with the correct enviroment settings setup, it is possble to dump the latest price information by -running from the source database: - -``` -django-admin dumpdata stripe_checkout.PricedItem | json_pp > prices.json -``` - -To load price information into the target database, run: -``` -django-admin loaddata prices.json -``` - -## 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. - -# Administration - -Administrative credentials are available in Lastpass - -## Adding new products or price information to the database - -Log in to the django admin console and add or update a `PricedItem`. There are two different kinds -of `PricedItem`: `Registration Type` and `Extra` - -`Registration Type` items are used to link a visitor's `registrationType.id` to a Stripe product -id. Required fields are -* `Stripe Product id`: The stripe product for this item. Stripe product ids start with `prod_` -* `Visit registration id`: The visit `registrationType.id` for this registration type. See also - "New registration types" below - -`Extra` items are - - -Aside from the fields described above, the following fields are required for all `PricedItem` -objects: - -* `Name`: a snake case name that helps with idenfication. This name is not shown to visitors -* `Display Name`: a user friendly name. This name is shown to visitors in their checkout page and -should match the user facing name in Visit and Stripe -* `Kind`: See above - - -## GBP Vat - - - -# Visit - -## Forms -Visitors are redirected to the stripe checkout server by custom javascript - -## Stripe checkout host -The redirect stripe checkout host is defined in Visit as a Custom field. Navigate to the -Event -> Setup -> Custom fields, where you will find the `bridgeserviceurl` variable. Edit this -variable to point the forms to a different url in their final redirect - -## New registration types -When creating a new registration type, its id can't be immediately retrieved. You first need to -create a visitor with that registration type, - -## Adding a new checkout question - - - - -# Stripe -We use a number of Stripe resources that may need to be managed -* Customers -* Custom tax rate -* Invoice template -* Webhooks (+ signing secret) - -## Webhooks \ No newline at end of file +See the full documentation on [SWD Documentation](https://swd-documentation.geant.org/stripe-checkout/develop/) -- GitLab