|
3 | 3 | Webhooks |
4 | 4 | ********* |
5 | 5 |
|
6 | | -Webhooks are a crucial component in connecting your Django Payments application |
7 | | -with external payment gateways like Stripe, PayPal, or Braintree. They enable |
8 | | -real-time notifications or events from the payment gateway to be sent to your |
9 | | -application, eliminating the need for continuous polling or manual API |
10 | | -requests. With webhooks, your application can stay in sync with payment gateway |
11 | | -updates, such as successful payments, subscription changes, or refunds. |
12 | | - |
13 | | -In the context of Django Payments, webhooks provide a means for payment |
14 | | -gateways to send event notifications directly to your Django application. By |
15 | | -configuring the payment gateway to send these notifications to a specific URL |
16 | | -endpoint within your application, you can create a webhook handler that |
17 | | -receives and processes these events. This allows you to update your |
18 | | -application's internal state, trigger actions, or send user notifications based |
19 | | -on payment-related events. |
20 | | - |
| 6 | +Webhooks are an essential mechanism for integrating your Django Payments |
| 7 | +application with external payment gateways like Stripe, PayPal, or Braintree. |
| 8 | +They allow real-time event notifications to be sent to your application without |
| 9 | +requiring continuous polling or manual API requests. With webhooks, your |
| 10 | +application stays synchronized with payment gateway updates, such as successful |
| 11 | +payments, subscription status changes, or refunds. |
| 12 | + |
| 13 | +In the context of Django Payments, webhooks enable payment gateways to send |
| 14 | +event notifications directly to your Django application. By configuring the |
| 15 | +payment gateway to send these notifications to a specific URL endpoint in your |
| 16 | +application, you can create a webhook handler to process these events. This |
| 17 | +lets you update your internal state, trigger relevant actions, or send user |
| 18 | +notifications based on payment-related events. |
21 | 19 |
|
22 | 20 | URL Structure |
23 | 21 | ============= |
24 | | -The webhook URL structure in django-payments follows this pattern: |
25 | 22 |
|
26 | | -``{protocol}://{host}/payments/process/{variant}/`` |
| 23 | +The webhook URL structure in django-payments follows this pattern:: |
27 | 24 |
|
28 | | -Where: |
| 25 | + {protocol}://{host}/payments/process/{variant}/ |
29 | 26 |
|
30 | | -- ``{protocol}``: Configured in ``PAYMENT_PROTOCOL`` (typically "http" or "https") |
31 | | -- ``{host}``: Configured in ``PAYMENT_HOST`` |
32 | | -- ``{variant}``: The name you've configured in PAYMENT_VARIANTS |
| 27 | +Where: |
33 | 28 |
|
| 29 | +- ``{protocol}``: Defined in ``PAYMENT_PROTOCOL`` (typically "http" or "https"). |
| 30 | +- ``{host}``: Defined in ``PAYMENT_HOST``. |
| 31 | +- ``{variant}``: The payment provider name as configured in ``PAYMENT_VARIANTS``. |
34 | 32 |
|
35 | 33 | For example, with this configuration: |
36 | 34 |
|
37 | 35 | .. code-block:: python |
38 | 36 |
|
39 | | - PAYMENT_VARIANTS = { |
40 | | - 'stripe': ( # <-- This is your variant name |
41 | | - 'payments.stripe.StripeProviderV3', |
42 | | - { |
43 | | - 'api_key': 'sk_test_123456', |
44 | | - 'use_token': true, |
45 | | - 'endpoint_secret': 'whsec_123456', |
46 | | - 'secure_endpoint': true |
47 | | - } |
48 | | - ) |
49 | | - } |
| 37 | + PAYMENT_VARIANTS = { |
| 38 | + 'stripe': ( # <-- This is your variant name |
| 39 | + 'payments.stripe.StripeProviderV3', |
| 40 | + { |
| 41 | + 'api_key': 'sk_test_123456', |
| 42 | + 'use_token': True, |
| 43 | + 'endpoint_secret': 'whsec_123456', |
| 44 | + 'secure_endpoint': True |
| 45 | + } |
| 46 | + ) |
| 47 | + } |
50 | 48 |
|
51 | | - PAYMENT_HOST = 'your-app.com' |
52 | | - PAYMENT_PROTOCOL = 'https' |
| 49 | + PAYMENT_HOST = 'your-app.com' |
| 50 | + PAYMENT_PROTOCOL = 'https' |
53 | 51 |
|
54 | | -Your webhook URL would be: |
55 | | -``https://your-app.com/payments/process/stripe/`` |
| 52 | +Your webhook URL would be:: |
56 | 53 |
|
57 | | -.. note:: |
| 54 | + https://your-app.com/payments/process/stripe/ |
58 | 55 |
|
59 | | - Make sure the URL matches exactly, including the trailing slash. A common source |
60 | | - of 404 errors is using the wrong URL pattern or forgetting the trailing slash. |
| 56 | +.. note:: |
61 | 57 |
|
| 58 | + Ensure the URL matches exactly, including the trailing slash. A common cause |
| 59 | + of 404 errors is an incorrect URL pattern or a missing trailing slash. |
62 | 60 |
|
63 | | -Stripe |
64 | | -====== |
| 61 | +Stripe Webhooks |
| 62 | +=============== |
65 | 63 |
|
66 | 64 | Setting up Webhooks in Stripe |
67 | | -To receive payment notifications and updates from Stripe, you need to set up |
68 | | -webhooks. Follow these steps to configure webhooks in your Stripe Dashboard: |
| 65 | +----------------------------- |
| 66 | + |
| 67 | +To receive real-time payment notifications from Stripe, follow these steps: |
| 68 | + |
| 69 | +#. Log in to your `Stripe Dashboard <https://dashboard.stripe.com/>`_. |
| 70 | +#. In the left sidebar, navigate to **Developers** → **Webhooks**. |
| 71 | +#. Click **+ Add endpoint** to create a new webhook listener. |
| 72 | +#. Enter the webhook URL in the "Endpoint URL" field. The URL should follow the |
| 73 | + format:: |
| 74 | + |
| 75 | + https://your-app.com/payments/process/{variant}/ |
| 76 | + |
| 77 | + where ``{variant}`` is the name configured in ``PAYMENT_VARIANTS``. |
| 78 | + Example: ``https://your-app.com/payments/process/stripe/`` |
| 79 | + |
| 80 | +#. Select the events you want to receive notifications for. At a minimum, |
| 81 | + include these: |
| 82 | + |
| 83 | + - ``checkout.session.async_payment_failed`` |
| 84 | + - ``checkout.session.async_payment_succeeded`` |
| 85 | + - ``checkout.session.completed`` |
| 86 | + - ``checkout.session.expired`` |
| 87 | + |
| 88 | +#. Click **Add endpoint** to save the webhook configuration. |
| 89 | +#. Copy the **Signing secret** provided by Stripe. You will need this to verify |
| 90 | + webhook authenticity in your Django application. |
| 91 | +#. Test the webhook by sending a test event using Stripe's **Send test |
| 92 | + webhook** feature. |
| 93 | + |
| 94 | +Testing Webhooks Locally |
| 95 | +------------------------ |
| 96 | + |
| 97 | +During development, you can use the `Stripe CLI |
| 98 | +<https://stripe.com/docs/stripe-cli#install>`_ to test webhooks by forwarding |
| 99 | +Stripe events to your local server. |
| 100 | + |
| 101 | +#. Install the Stripe CLI and log in: |
| 102 | + |
| 103 | + .. code-block:: bash |
| 104 | +
|
| 105 | + stripe login |
| 106 | +
|
| 107 | +#. Start listening for events and forward them to your local server: |
69 | 108 |
|
70 | | -1. Log in to your `Stripe Dashboard <https://dashboard.stripe.com/>`_. |
71 | | -#. In the left sidebar, click on **Developers** and then select **Webhooks**. |
72 | | -#. Click on the "+ Add endpoint" button to create a new webhook listener. |
73 | | -#. In the "Endpoint URL" field, enter the URL for the Stripe variant in your |
74 | | - Django Payments application. This URL should follow the pattern: |
75 | | - ``https://your-app.com/payments/process/{variant}/``, where ``{variant}`` is |
76 | | - the name you've configured in your PAYMENT_VARIANTS setting. |
77 | | - For example: ``https://your-app.com/payments/process/stripe/`` |
78 | | -#. From the "Events to send" dropdown, choose the specific events you want to |
79 | | - receive notifications for. You need (at least) these events: |
| 109 | + .. code-block:: bash |
80 | 110 |
|
81 | | - - checkout.session.async_payment_failed |
82 | | - - checkout.session.async_payment_succeeded |
83 | | - - checkout.session.completed |
84 | | - - checkout.session.expired |
| 111 | + stripe listen --forward-to localhost:8000/payments/process/stripe/ \ |
| 112 | + -e checkout.session.async_payment_failed,checkout.session.async_payment_succeeded,checkout.session.completed,checkout.session.expired |
85 | 113 |
|
86 | | -#. Click on the "Add endpoint" button to save your webhook listener. |
87 | | -#. Once the webhook is created, you will see its details in the "Webhooks" |
88 | | - section. Take note of the "Signing secret" provided by Stripe as you will |
89 | | - need it later when configuring the webhook handler in your Django application. |
90 | | -#. Test the webhook by sending a test event to your endpoint. Stripe provides a |
91 | | - "Send test webhook" button on the webhook details page. Use this feature to |
92 | | - ensure your endpoint is correctly configured and can receive and process |
93 | | - events from Stripe. |
| 114 | +#. In another terminal, trigger test events: |
94 | 115 |
|
| 116 | + .. code-block:: bash |
95 | 117 |
|
96 | | -Testing with Stripe CLI |
97 | | ----------------------- |
| 118 | + stripe trigger checkout.session.completed |
98 | 119 |
|
99 | | -The `Stripe CLI <https://stripe.com/docs/stripe-cli#install>`_ provides a simple |
100 | | -way to test webhooks during local development by forwarding Stripe events to |
101 | | -your local server. After installing and running ``stripe login``, you can start |
102 | | -forwarding events to your local Django server with: |
| 120 | +Alternative Webhook Testing Tools |
| 121 | +--------------------------------- |
103 | 122 |
|
104 | | -.. code-block:: bash |
| 123 | +Apart from Stripe's built-in tools, you can test your webhooks using external |
| 124 | +services: |
105 | 125 |
|
106 | | - # Start webhook forwarding |
107 | | - stripe listen --forward-to localhost:8000/payments/process/stripe/ \ |
108 | | - -e checkout.session.async_payment_failed,checkout.session.async_payment_succeeded,checkout.session.completed,checkout.session.expired |
| 126 | +- `Beeceptor <https://beeceptor.com/>`_: A free webhook testing tool that |
| 127 | + allows you to inspect and debug webhook requests before integrating them into |
| 128 | + your application. |
| 129 | +- `RequestBin by Pipedream <https://pipedream.com/requestbin>`_: Provides a |
| 130 | + public or private endpoint where you can inspect incoming webhook requests in |
| 131 | + real-time. |
109 | 132 |
|
110 | | - # In another terminal, trigger test events |
111 | | - stripe trigger checkout.session.completed |
| 133 | +These tools can be useful for verifying request payloads and debugging webhook |
| 134 | +events outside of your local development environment. |
112 | 135 |
|
| 136 | +Security Best Practices |
| 137 | +----------------------- |
113 | 138 |
|
114 | 139 | .. note:: |
115 | 140 |
|
116 | | - It's essential to secure your webhook endpoint and verify the authenticity of |
117 | | - the events sent by Stripe. It's not recommended to use `secure_endpoint` |
118 | | - set to false in production. |
| 141 | + Always validate incoming webhook requests to ensure they originate from |
| 142 | + Stripe. Use the signing secret to verify authenticity before processing any |
| 143 | + event. |
119 | 144 |
|
120 | 145 | .. warning:: |
121 | 146 |
|
122 | | - Remember to setup ``PAYMENT_HOST`` and ``PAYMENT_PROTOCOL`` in your settings file, |
123 | | - otherwise the webhooks won't work, as defined in :ref:`settings`. |
| 147 | + Ensure ``PAYMENT_HOST`` and ``PAYMENT_PROTOCOL`` are correctly set in your |
| 148 | + Django settings. If they are misconfigured, webhooks will not work as |
| 149 | + expected. |
0 commit comments