Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

21 document webhooks #22

Merged
merged 5 commits into from
Aug 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 109 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,45 @@
# Recieve connect webhooks from Stripe & forward them to the correct shop

### What does this code do?

### Install
tldr: It receives Stripe events, and forwards them to the correct shop.

When events happen at Stripe (e.g. a user completes a payment),
Then, if you have configured webhook endpoint in Stripe) will send
*the events you ask for*, to you webhook endpoint.

> Note: During webhook creation, you tell Stripe *which* events you're
interested it. It is an *error* to ask for all events, unless the webhook
endpoint implements a listener for every event type.

##### Which events does Subscribie listen to?
At the time of writing:

- checkout.session.completed
- payment_intent.succeeded

##### What's a Stripe 'connect account`?
tldr: Every Subscribie shop, if connected to Stripe has a 'Stripe connect express account'.

Subscribie shops use Stripe express accounts, see https://stripe.com/docs/connect/express-accounts.
The *events* send to this code are recieved for *all* Subscribie shops, and this code routes the events to
the correct Subscribie shop.

### How does this code know which shop to send events to?

The Stripe `connect_account` id, and the Subscribie `shop url` are stored in Redis.
When a Stripe event is recieved, the following happens:

1. The event is [validated to check it came from Stripe](https://stripe.com/docs/webhooks/signatures)
Blocked if not valid.
2. The Subscribie shop url is checked by comparing with the `connect_account` recieved from Stripe
3. The Strip event is forwarded to the correct Shop

> Note: We used to have one webhook for each Shop- this cannot work because Stripe limits the number of
webhooks you can create to 15.


### Local Install

```
virtualenv venv
Expand All @@ -26,6 +64,76 @@ flask run

See apache example config & wsgi config example in repo. (assumes mod wsgi is installed & enabled on apache)

### Create webhook endpoints in Stripe

1. Check the webhook is *not* already created https://dashboard.stripe.com/webhooks (do you already see the endpoint?)
There should be two, one endpoint for connect accounts in testmode, and one for connect accounts in live mode.

e.g. my-api-live.example.com/stripe_webhooks and my-api-test.example.com/stripe_webhooks

> Note: Stripe livemode is *always* true for Stripe connect. Why?
Because Stripe connect accounts can either be in live or test mode so
the live/test mode config is moved to each Stipe connect account (and
they can change their account to be in live or test mode).


2. If not, create it:

Use `create_stripe_connect_webhook.py` in this repo:

```
. venv/bin/activate
python create_stripe_connect_webhook.py
Stripe secret api key:sk_live_abc123
Webhook url:https://testing-example.com
{
"api_version": null,
"application": "ca_",
"created": ,
"description": null,
"enabled_events": [
"checkout.session.completed",
"payment_intent.succeeded"
],
"id": "we_",
"livemode": true,
"metadata": {},
"object": "webhook_endpoint",
"secret": "whsec_ndisofndio23iono",
"status": "enabled",
"url": "https://testing-example.com"
}

```
3. Copy the `secret` from the output, this app needs the secret to verify the events come from Stripe.
4. Set the dokku app secret:
```
dokku config:set testing-stripe-connect-webhook-endpoint-router STRIPE_WEBHOOK_SECRET=<secret>
```
<img src="./stripe-webhook-created-testing.png" />

###

It it not possible or desireable to create Stripe webhooks endpoints in 'test mode' using the UI, they are all live by default. We must use the api for that.

https://testing-stripe-connect-webhook-endpoint-router.pcpink.co.uk


- test mode, is where all shops in test mode Stripe sends events to *including* our GithubAction playwright tests , they are in test mode too



Event types
checkout.session.completed
payment_intent.succeeded

Mode


Signing secret



## Smoke test

```
Expand Down
8 changes: 7 additions & 1 deletion create_stripe_connect_webhook.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@
the events required.

Returns the endpoint secret, needed for Stripe webhook validation

Note: Stripe livemode is *always* true for Stripe connect. Why?

Because Stripe connect accounts can either be in live or test mode so
the live/test mode config is moved to each Stipe connect account (and
they can change their account to be in live or test mode).
"""

import stripe

stripe_api_key = input("Stripe api key:")
stripe_api_key = input("Stripe secret api key:")
endpoint_url = input("Webhook url:")

stripe.api_key = stripe_api_key
Expand Down
Binary file added stripe-webhook-created-testing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.