from datetime import datetime

import stripe
from django.conf import settings


def retrieve_stripe_subscription(customer):
    for subscription in customer.subscriptions.list().auto_paging_iter():
        # We have to use array indexing syntax, as stripe uses dicts to
        # represent its objects (dicts come with an .items method)
        for item in subscription["items"].auto_paging_iter():
            if item.plan.id == settings.STRIPE_PLAN_ID:
                return subscription

    return None


def create_stripe_customer_and_subscription_for_user(user, email, stripe_token):
    customer = (
        stripe.Customer.retrieve(user.stripe_customer_id)
        if user.stripe_customer_id
        else None
    )
    if not customer or customer.email != email:
        customer = stripe.Customer.create(email=email, source=stripe_token,)
        user.stripe_customer_id = customer.id
        user.save()

    if retrieve_stripe_subscription(customer) is None:
        stripe.Subscription.create(
            customer=customer.id, items=[{"plan": settings.STRIPE_PLAN_ID}],
        )


def retrieve_stripe_subscription_info(user):
    stripe_customer = (
        stripe.Customer.retrieve(user.stripe_customer_id, expand=["default_source"],)
        if settings.STRIPE_PLAN_ID and user.stripe_customer_id
        else None
    )

    stripe_subscription = (
        retrieve_stripe_subscription(stripe_customer)
        if stripe_customer and stripe_customer.email == user.email
        else None
    )
    if stripe_subscription:
        source = stripe_customer.default_source
        if source.object == "card":
            card = source
        elif source.object == "source":
            card = source.card
        else:
            raise ValueError(
                f"unexpected stripe customer default_source of type {source.object!r}"
            )

        return {
            "next_payment_at": datetime.fromtimestamp(
                stripe_subscription.current_period_end
            ),
            "brand": card.brand,
            "expires_at": f"{card.exp_month}/{card.exp_year}",
            "last4": card.last4,
            "zip": card.address_zip,
        }

    return None

kuma/users/utils.py
from datetime import datetime

import stripe
from django.conf import settings


def retrieve_stripe_subscription(customer):
    for subscription in customer.subscriptions.list().auto_paging_iter():
        # We have to use array indexing syntax, as stripe uses dicts to
        # represent its objects (dicts come with an .items method)
        for item in subscription["items"].auto_paging_iter():
            if item.plan.id == settings.STRIPE_PLAN_ID:
                return subscription

    return None


def create_stripe_customer_and_subscription_for_user(user, email, stripe_token):
    customer = (
        stripe.Customer.retrieve(user.stripe_customer_id)
        if user.stripe_customer_id
        else None
    )
    if not customer or customer.email != email:
        customer = stripe.Customer.create(email=email, source=stripe_token,)
        user.stripe_customer_id = customer.id
        user.save()

    if retrieve_stripe_subscription(customer) is None:
        stripe.Subscription.create(
            customer=customer.id, items=[{"plan": settings.STRIPE_PLAN_ID}],
        )


def retrieve_stripe_subscription_info(user):
    stripe_customer = (
        stripe.Customer.retrieve(user.stripe_customer_id, expand=["default_source"],)
        if settings.STRIPE_PLAN_ID and user.stripe_customer_id
        else None
    )

    stripe_subscription = (
        retrieve_stripe_subscription(stripe_customer)
        if stripe_customer and stripe_customer.email == user.email
        else None
    )
    if stripe_subscription:
        source = stripe_customer.default_source
        if source.object == "card":
            card = source
        elif source.object == "source":
            card = source.card
        else:
            raise ValueError(
                f"unexpected stripe customer default_source of type {source.object!r}"
            )

        return {
            "next_payment_at": datetime.fromtimestamp(
                stripe_subscription.current_period_end
            ),
            "brand": card.brand,
            "expires_at": f"{card.exp_month}/{card.exp_year}",
            "last4": card.last4,
            # Cards that are part of a "source" don't have a zip
            "zip": card.get("address_zip", None),
        }

    return None

kuma/users/utils.py
diff --git a/kuma/users/utils.py b/kuma/users/utils.py
index 2e0d2d0765a..d57fc2c2148 100644
--- a/kuma/users/utils.py
+++ b/kuma/users/utils.py
@@ -62,7 +62,8 @@ def retrieve_stripe_subscription_info(user):
             "brand": card.brand,
             "expires_at": f"{card.exp_month}/{card.exp_year}",
             "last4": card.last4,
-            "zip": card.address_zip,
+            # Cards that are part of a "source" don't have a zip
+            "zip": card.get("address_zip", None),
         }
 
     return None

AttributeError: address_zip on strip object 
https://sentry.prod.mozaws.net/operations/mdn-prod/issues/7356686/

```
Resolver404: {'tried': [[<RegexURLPattern None ^media/(?:redesign/)?css/(?P<doc>.*)-min.css$>], [<RegexURLPattern None ^media/(?:redesign/)?js/(?P<doc>.*)-min.js$>], [<RegexURLPattern None ^media/(?:redesign/)?img(?P<suffix>.*)$>], [<RegexURLPattern None ^media/(?:redesign/)?css(?P<suffix>.*)$>], [<RegexURLPattern None ^media/(?:redesign/)?js(?P<suffix>.*)$>], [<RegexURLPattern None ^media/(?:redesign/)?fonts(?P<suffix>.*)$>], [<RegexURLPattern None ^media/uploads/demos/(?:.*)$>], [<RegexURLPattern None (?i)^(?P<one>.*)//(?P<two>.*)//(?P<three>.*)$>], [<RegexURLPattern None (?i)^(?P<one>.*)//(?P<two>.*)$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/2_1_canvas_rect.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/2_2_canvas_moveto.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/2_3_canvas_lineto.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/2_4_canvas_arc.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/2_5_canvas_quadraticcurveto.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/2_6_canvas_beziercurveto.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/3_1_canvas_drawimage.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/3_2_canvas_drawimage.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/3_3_canvas_drawimage.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/3_4_canvas_gallery.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/4_1_canvas_fillstyle.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/4_2_canvas_strokestyle.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/4_3_canvas_globalalpha.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/4_4_canvas_rgba.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/4_5_canvas_linewidth.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/4_6_canvas_linecap.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/4_7_canvas_linejoin.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/4_8_canvas_miterlimit.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/4_9_canvas_lineargradient.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/4_10_canvas_radialgradient.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/4_11_canvas_createpattern.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/5_1_canvas_savestate.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/5_2_canvas_translate.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/5_3_canvas_rotate.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/5_4_canvas_scale.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/6_1_canvas_composite.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/6_2_canvas_clipping.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/globalCompositeOperation.html$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/images/backdrop.png$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/images/bg_gallery.png$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/images/gallery_1.jpg$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/images/gallery_2.jpg$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/images/gallery_3.jpg$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/images/gallery_4.jpg$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/images/gallery_5.jpg$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/images/gallery_6.jpg$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/images/gallery_7.jpg$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/images/gallery_8.jpg$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/images/picture_frame.png$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/images/rhino.jpg$>], [<RegexURLPattern None (?i)^samples/canvas-tutorial/images/wallpaper.png$>], [<RegexURLPattern None (?i)^samples/domref/mozGetAsFile.html$>], [<RegexURLPattern None (?i)^samples/raycaster/input.js$>], [<RegexURLPattern None (?i)^samples/raycaster/Level.js$>], [<RegexURL...
  File "redirect_urls/middleware.py", line 14, in __call__
    resolver_match = self.resolver.resolve(request.path_info)
  File "newrelic/hooks/framework_django.py", line 600, in wrapper
    return _wrapped(*args, **kwargs)
  File "newrelic/hooks/framework_django.py", line 588, in _wrapped
    result = wrapped(path)
  File "newrelic/hooks/framework_django.py", line 575, in wrapper
    return wrapped(*args, **kwargs)
  File "django/urls/resolvers.py", line 394, in resolve
    raise Resolver404({'tried': tried, 'path': new_path})

KeyError: 'address_zip'
  File "stripe/stripe_object.py", line 90, in __getattr__
    return self[k]
  File "stripe/stripe_object.py", line 131, in __getitem__
    raise err
  File "stripe/stripe_object.py", line 119, in __getitem__
    return super(StripeObject, self).__getitem__(k)

AttributeError: address_zip
(4 additional frame(s) were not displayed)
...
  File "django/views/decorators/cache.py", line 57, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "kuma/core/decorators.py", line 210, in wrapped
    return func(request, *args, **kwargs)
  File "kuma/users/views.py", line 476, in user_edit
    "subscription_info": retrieve_stripe_subscription_info(edit_user,),
  File "kuma/users/utils.py", line 65, in retrieve_stripe_subscription_info
    "zip": card.address_zip,
  File "stripe/stripe_object.py", line 92, in __getattr__
    raise AttributeError(*err.args)

AttributeError: address_zip
```
