Repository: dj-stripe/dj-stripe

Issue:
Webhook is not syncing TaxRate model
**Describe the bug**
Whenever I create or modify an existing TaxRate, the webhooks (signals tax_rate.created and tax_rate.updated) are triggered but the changes are not reflected in the database.

**To Reproduce**
Steps to reproduce the behavior:

1. Create a new TaxRate object using the Django shell:

```
import stripe
stripe.TaxRate.create(display_name='name', description='desc', jurisdiction='ES', percentage=21.0, inclusive=False)
```

2. Modify the created TaxRate object using the Stripe Dashboard

**Expected behavior**
Changes should be reflected in the database.

A possible workaround is running: `./manage.py djstripe_sync_models TaxRate`

**Environment**
- dj-stripe version: 2.2.1
- Your Stripe account's default API version: 2019-11-05
- Database: Postgres 10.10
- Python version: 3.6
- Django version: 2.2.7

**Can you reproduce the issue with the latest version of master?**

Yes



Discussion:
Thanks for the report.
It's probably because TaxRate isn't handled here: 

https://github.com/dj-stripe/dj-stripe/blob/5b7ba439e54ba7161ca5e02d8699610f87c974b0/djstripe/event_handlers.py#L155

Resolving patch:
diff --git a/djstripe/event_handlers.py b/djstripe/event_handlers.py
--- a/djstripe/event_handlers.py
+++ b/djstripe/event_handlers.py
@@ -153,7 +153,6 @@ def payment_method_handler(event):
 
 
 @webhooks.handler(
-    "transfer",
     "charge",
     "coupon",
     "invoice",
@@ -163,21 +162,26 @@ def payment_method_handler(event):
     "product",
     "setup_intent",
     "source",
+    "tax_rate",
+    "transfer",
 )
 def other_object_webhook_handler(event):
     """
-    Handle updates to transfer, charge, coupon, invoice, invoiceitem, payment_intent,
-    plan, product, setup_intent and source objects.
+    Handle updates to charge, coupon, invoice, invoiceitem, payment_intent,
+    plan, product, setup_intent, source, tax_rate and transfer objects.
 
     Docs for:
-    - charge: https://stripe.com/docs/api#charges
-    - coupon: https://stripe.com/docs/api#coupons
-    - invoice: https://stripe.com/docs/api#invoices
-    - invoiceitem: https://stripe.com/docs/api#invoiceitems
-    - plan: https://stripe.com/docs/api#plans
-    - product: https://stripe.com/docs/api#products
-    - source: https://stripe.com/docs/api#sources
+    - charge: https://stripe.com/docs/api/charges
+    - coupon: https://stripe.com/docs/api/coupons
+    - invoice: https://stripe.com/docs/api/invoices
+    - invoiceitem: https://stripe.com/docs/api/invoiceitems
     - payment_intent: https://stripe.com/docs/api/payment_intents
+    - plan: https://stripe.com/docs/api/plans
+    - product: https://stripe.com/docs/api/products
+    - setup_intent: https://stripe.com/docs/api/setup_intents
+    - source: https://stripe.com/docs/api/sources
+    - tax_rate: https://stripe.com/docs/api/tax_rates/
+    - transfer: https://stripe.com/docs/api/transfers
     """
 
     if event.parts[:2] == ["charge", "dispute"]:
@@ -196,6 +200,7 @@ def other_object_webhook_handler(event):
             "transfer": models.Transfer,
             "setup_intent": models.SetupIntent,
             "source": models.Source,
+            "tax_rate": models.TaxRate,
         }.get(event.category)
 
     _handle_crud_like_event(target_cls=target_cls, event=event)


Test patch: