Package: django-quagga
Zebra is a library that makes using Stripe with Django even easier.Quagga is a fork of the original Django Zebra library. See the note on
compatibility below.It’s made of:zebra, the core library, with forms, webhook handlers, abstract models,
mixins, signals, and templatetags that cover most stripe implementations.marty, an example app for how to integrate zebra, that also serves as its test suite.Pull requests are quite welcome!Note (2016): this fork is maintained solely to maintain compatability between existing
functionality and current versions of Django.UsageInstallationpip install django-quaggaEdit yoursettings.py:INSTALLED_APPS += ("zebra",)
STRIPE_SECRET = "YOUR-SECRET-API-KEY"
STRIPE_PUBLISHABLE = "YOUR-PUBLISHABLE-API-KEY"
# Set any optional settings (below)(optional)./manage.py migrateif you haveZEBRA_ENABLE_APP = True(optional) Add in the webhook urls:urlpatterns += [
    url(r'zebra/', include('zebra.urls',  namespace="zebra",  app_name='zebra')),
]Enjoy easy billing.Optional SettingsZEBRA_ENABLE_APPDefaults toFalse.  Enables Customer, Plan, and Subscription django
models, as a part of zebra.ZEBRA_CUSTOMER_MODELThe app+model string for the model that implements the StripeCustomerMixin.
ie“myapp.MyCustomer”.  IfZEBRA_ENABLE_APPis true, defaults to“zebra.Customer”.ZEBRA_AUTO_CREATE_STRIPE_CUSTOMERSDefaults toTrue.  Automatically creates a stripe customer object on
stripe_customer access, if one doesn’t exist.WebhooksZebra handles all the webhooks that stripe sends back and calls a set of
signals that you can plug your app into.  To use the webhooks:Include the zebra urlsUpdate your stripe account to point to your webhook URL (akahttps://www.mysite.com/zebra/webhooks)Plug into any webhook signals you care about.Note: The initial Stripe webhook system is being deprecated. See below for a
description of Zebra’s support for the new system.Zebra provides:zebra_webhook_recurring_payment_failedzebra_webhook_invoice_readyzebra_webhook_recurring_payment_succeededzebra_webhook_subscription_trial_endingzebra_webhook_subscription_final_payment_attempt_failedAll of the webhooks provide the same arguments:customer- ifZEBRA_CUSTOMER_MODELis set, returns an instance that
matches thestripe_customer_id, orNone.  IfZEBRA_CUSTOMER_MODELis
not set, returnsNone.full_json- the full json response, parsed with simplejson.So, for example, to update the customer’s new billing date after a successful
payment, you could:(assuming you’ve setZEBRA_CUSTOMER_MODELor are usingZEBRA_ENABLE_APP):from zebra.signals import zebra_webhook_recurring_payment_succeeded

def update_last_invoice_date(sender, **kwargs):
    customer = kwargs.pop("customer", None)
    full_json = kwargs.pop("full_json", None)
    customer.billing_date = full_json.date
    customer.save()

zebra_webhook_recurring_payment_succeeded.connect(update_last_invoice_date)Webhooks UpdateStripe recently updated their webhook implementation (seehttps://stripe.com/blog/webhooks). Zebra includes an implementation of the new
system.Include the zebra urlsUpdate your stripe account to point to your webhook URL (akahttps://www.mysite.com/zebra/webhooks/v2/)Plug into any webhook signals you care about.Zebra provides:zebra_webhook_charge_succeededzebra_webhook_charge_failedzebra_webhook_charge_refundedzebra_webhook_charge_disputedzebra_webhook_customer_createdzebra_webhook_customer_updatedzebra_webhook_customer_deletedzebra_webhook_customer_subscription_createdzebra_webhook_customer_subscription_updatedzebra_webhook_customer_subscription_deletedzebra_webhook_customer_subscription_trial_will_endzebra_webhook_customer_discount_createdzebra_webhook_customer_discount_updatedzebra_webhook_customer_discount_deletedzebra_webhook_invoice_createdzebra_webhook_invoice_updatedzebra_webhook_invoice_payment_succeededzebra_webhook_invoice_payment_failedzebra_webhook_invoiceitem_createdzebra_webhook_invoiceitem_updatedzebra_webhook_invoiceitem_deletedzebra_webhook_plan_createdzebra_webhook_plan_updatedzebra_webhook_plan_deletedzebra_webhook_coupon_createdzebra_webhook_coupon_updatedzebra_webhook_coupon_deletedzebra_webhook_transfer_createdzebra_webhook_transfer_failedzebra_webhook_pingZebra also provides an easy map of all the signals aszebra.signals.WEBHOOK_MAP, which maps events (charge_succeeded) to the
Zebra signal (zebra_webhook_charge_succeeded). To assign a handler to all the
signals that zebra sends, for example, loop over the items in the map:for event_key, webhook_signal in WEBHOOK_MAP.items():
    webhook_signal.connect(webhook_logger)FormsThe StripePaymentForm sets up a form with fields like [the official stripe
example](https://gist.github.com/1204718#file_stripe_tutorial_page.html).In particular, the form is stripped of the name attribute for any of the credit
card fields, to prevent accidental submission. Media is also provided to set up
stripe.js (it assumes you have jQuery).Use it in a view like so:if request.method == 'POST':
    zebra_form = StripePaymentForm(request.POST)
    if zebra_form.is_valid():
        my_profile = request.user.get_profile()
        stripe_customer = stripe.Customer.retrieve(my_profile.stripe_customer_id)
        stripe_customer.card = zebra_form.cleaned_data['stripe_token']
        stripe_customer.save()

        my_profile.last_4_digits = zebra_form.cleaned_data['last_4_digits']
        my_profile.stripe_customer_id = stripe_customer.id
        my_profile.save()

        # Do something kind for the user

else:
    zebra_form = StripePaymentForm()Template TagsThere are a couple of template tags that take care of setting up the stripe
env, and rendering a basic cc update form.  Note that it’s expected yourStripePaymentFormis called eitherzebra_formorform.To use in a template:{% extends "base.html" %}{% load zebra_tags %}

{% block head %}{{block.super}}
    {% zebra_head_and_stripe_key %}
{% endblock %}

{% block content %}
    {% zebra_card_form %}
{% endblock %}That’s it - all the stripe tokeny goodness happens, and errors are displayed to
your users.Models and MixinsModel and Mixin docs coming.  For now, the code is pretty self-explanatory, and
decently documented inline.Other Useful BitsZebra comes with a manage.py command to clear out all the test customers from
your account.To use it, run:./manage.py clear_stripe_test_customersIt responds to–verbosity=[0-3].CreditsI did not write any of stripe. It just makes me happy to use, and inspired to
make better APIs for my users. For Stripe info, ask them:
[stripe.com](http://stripe.com)Code credits are in the AUTHORS file. Pull requests welcome!History0.6.1Fix some Python3 compatability issue.0.6.0Add working logging into webhooks.0.5.0Introduction of django-quagga, a semi-updated version of the original
django-zebra designed to [mostly] work with up-to-date Django.0.4.5The last public release of django-zebra.