{ "info": { "author": "Ben Lopatin", "author_email": "ben@benlopatin.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Topic :: Internet :: WWW/HTTP", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "===========================================\nQuagga: the extinct Zebra (just as Stripey)\n===========================================\n\nZebra is a library that makes using Stripe with Django even easier.\n\nQuagga is a fork of the original Django Zebra library. See the note on\ncompatibility below.\n\n.. image:: https://github.com/bennylope/django-quagga/raw/master/quagga.jpg\n\nIt's made of:\n\n* `zebra`, the core library, with forms, webhook handlers, abstract models,\n mixins, signals, and templatetags that cover most stripe implementations.\n* `marty`, an example app for how to integrate zebra, that also serves as its test suite.\n\nPull requests are quite welcome!\n\n**Note (2016)**: this fork is maintained solely to maintain compatability between existing\nfunctionality and current versions of Django.\n\nUsage\n=====\n\nInstallation\n------------\n\n1. `pip install django-quagga`\n\n2. Edit your `settings.py`::\n\n INSTALLED_APPS += (\"zebra\",)\n STRIPE_SECRET = \"YOUR-SECRET-API-KEY\"\n STRIPE_PUBLISHABLE = \"YOUR-PUBLISHABLE-API-KEY\"\n # Set any optional settings (below)\n\n3. (optional) `./manage.py migrate` if you have `ZEBRA_ENABLE_APP = True`\n\n4. (optional) Add in the webhook urls::\n\n urlpatterns += [\n url(r'zebra/', include('zebra.urls', namespace=\"zebra\", app_name='zebra')),\n ]\n\n5. Enjoy easy billing.\n\n\nOptional Settings\n-----------------\n\n* `ZEBRA_ENABLE_APP`\n Defaults to `False`. Enables Customer, Plan, and Subscription django\n models, as a part of zebra.\n* `ZEBRA_CUSTOMER_MODEL`\n The app+model string for the model that implements the StripeCustomerMixin.\n ie `\"myapp.MyCustomer\"`. If `ZEBRA_ENABLE_APP` is true, defaults to\n `\"zebra.Customer\"`.\n* `ZEBRA_AUTO_CREATE_STRIPE_CUSTOMERS`\n Defaults to `True`. Automatically creates a stripe customer object on\n stripe_customer access, if one doesn't exist.\n\nWebhooks\n========\n\nZebra handles all the webhooks that stripe sends back and calls a set of\nsignals that you can plug your app into. To use the webhooks:\n\n* Include the zebra urls\n* Update your stripe account to point to your webhook URL (aka\n https://www.mysite.com/zebra/webhooks)\n* Plug into any webhook signals you care about.\n\n**Note: The initial Stripe webhook system is being deprecated. See below for a\ndescription of Zebra's support for the new system.**\n\nZebra provides:\n\n* `zebra_webhook_recurring_payment_failed`\n* `zebra_webhook_invoice_ready`\n* `zebra_webhook_recurring_payment_succeeded`\n* `zebra_webhook_subscription_trial_ending`\n* `zebra_webhook_subscription_final_payment_attempt_failed`\n\nAll of the webhooks provide the same arguments:\n\n* `customer` - if `ZEBRA_CUSTOMER_MODEL` is set, returns an instance that\n matches the `stripe_customer_id`, or `None`. If `ZEBRA_CUSTOMER_MODEL` is\n not set, returns `None`.\n* `full_json` - the full json response, parsed with simplejson.\n\nSo, for example, to update the customer's new billing date after a successful\npayment, you could:\n\n(assuming you've set `ZEBRA_CUSTOMER_MODEL` or are using `ZEBRA_ENABLE_APP`)::\n\n from zebra.signals import zebra_webhook_recurring_payment_succeeded\n\n def update_last_invoice_date(sender, **kwargs):\n customer = kwargs.pop(\"customer\", None)\n full_json = kwargs.pop(\"full_json\", None)\n customer.billing_date = full_json.date\n customer.save()\n\n zebra_webhook_recurring_payment_succeeded.connect(update_last_invoice_date)\n\nWebhooks Update\n---------------\n\nStripe recently updated their webhook implementation (see\nhttps://stripe.com/blog/webhooks). Zebra includes an implementation of the new\nsystem.\n\n* Include the zebra urls\n* Update your stripe account to point to your webhook URL (aka\n https://www.mysite.com/zebra/webhooks/v2/)\n* Plug into any webhook signals you care about.\n\nZebra provides:\n\n* `zebra_webhook_charge_succeeded`\n* `zebra_webhook_charge_failed`\n* `zebra_webhook_charge_refunded`\n* `zebra_webhook_charge_disputed`\n* `zebra_webhook_customer_created`\n* `zebra_webhook_customer_updated`\n* `zebra_webhook_customer_deleted`\n* `zebra_webhook_customer_subscription_created`\n* `zebra_webhook_customer_subscription_updated`\n* `zebra_webhook_customer_subscription_deleted`\n* `zebra_webhook_customer_subscription_trial_will_end`\n* `zebra_webhook_customer_discount_created`\n* `zebra_webhook_customer_discount_updated`\n* `zebra_webhook_customer_discount_deleted`\n* `zebra_webhook_invoice_created`\n* `zebra_webhook_invoice_updated`\n* `zebra_webhook_invoice_payment_succeeded`\n* `zebra_webhook_invoice_payment_failed`\n* `zebra_webhook_invoiceitem_created`\n* `zebra_webhook_invoiceitem_updated`\n* `zebra_webhook_invoiceitem_deleted`\n* `zebra_webhook_plan_created`\n* `zebra_webhook_plan_updated`\n* `zebra_webhook_plan_deleted`\n* `zebra_webhook_coupon_created`\n* `zebra_webhook_coupon_updated`\n* `zebra_webhook_coupon_deleted`\n* `zebra_webhook_transfer_created`\n* `zebra_webhook_transfer_failed`\n* `zebra_webhook_ping`\n\nZebra also provides an easy map of all the signals as\n`zebra.signals.WEBHOOK_MAP`, which maps events (`charge_succeeded`) to the\nZebra signal (`zebra_webhook_charge_succeeded`). To assign a handler to all the\nsignals that zebra sends, for example, loop over the items in the map::\n\n for event_key, webhook_signal in WEBHOOK_MAP.items():\n webhook_signal.connect(webhook_logger)\n\nForms\n=====\n\nThe StripePaymentForm sets up a form with fields like [the official stripe\nexample](https://gist.github.com/1204718#file_stripe_tutorial_page.html).\n\nIn particular, the form is stripped of the name attribute for any of the credit\ncard fields, to prevent accidental submission. Media is also provided to set up\nstripe.js (it assumes you have jQuery).\n\nUse it in a view like so::\n\n if request.method == 'POST':\n zebra_form = StripePaymentForm(request.POST)\n if zebra_form.is_valid():\n my_profile = request.user.get_profile()\n stripe_customer = stripe.Customer.retrieve(my_profile.stripe_customer_id)\n stripe_customer.card = zebra_form.cleaned_data['stripe_token']\n stripe_customer.save()\n\n my_profile.last_4_digits = zebra_form.cleaned_data['last_4_digits']\n my_profile.stripe_customer_id = stripe_customer.id\n my_profile.save()\n\n # Do something kind for the user\n\n else:\n zebra_form = StripePaymentForm()\n\nTemplate Tags\n=============\n\nThere are a couple of template tags that take care of setting up the stripe\nenv, and rendering a basic cc update form. Note that it's expected your\n`StripePaymentForm` is called either `zebra_form` or `form`.\n\nTo use in a template::\n\n {% extends \"base.html\" %}{% load zebra_tags %}\n\n {% block head %}{{block.super}}\n {% zebra_head_and_stripe_key %}\n {% endblock %}\n\n {% block content %}\n {% zebra_card_form %}\n {% endblock %}\n\nThat's it - all the stripe tokeny goodness happens, and errors are displayed to\nyour users.\n\nModels and Mixins\n=================\n\nModel and Mixin docs coming. For now, the code is pretty self-explanatory, and\ndecently documented inline.\n\nOther Useful Bits\n=================\n\nZebra comes with a manage.py command to clear out all the test customers from\nyour account.\n\nTo use it, run::\n\n ./manage.py clear_stripe_test_customers\n\nIt responds to `--verbosity=[0-3]`.\n\nCredits\n=======\n\nI did not write any of stripe. It just makes me happy to use, and inspired to\nmake better APIs for my users. For Stripe info, ask them:\n[stripe.com](http://stripe.com)\n\nCode credits are in the AUTHORS file. Pull requests welcome!\n\n\n\n\nHistory\n=======\n\n0.6.1\n-----\n\nFix some Python3 compatability issue.\n\n0.6.0\n-----\n\nAdd working logging into webhooks.\n\n0.5.0\n-----\n\nIntroduction of django-quagga, a semi-updated version of the original\ndjango-zebra designed to [mostly] work with up-to-date Django.\n\n0.4.5\n-----\n\nThe last public release of django-zebra.\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/bennylope/django-quagga", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "django-quagga", "package_url": "https://pypi.org/project/django-quagga/", "platform": "", "project_url": "https://pypi.org/project/django-quagga/", "project_urls": { "Homepage": "https://github.com/bennylope/django-quagga" }, "release_url": "https://pypi.org/project/django-quagga/0.6.1/", "requires_dist": [ "stripe (>=1.0.0)" ], "requires_python": "", "summary": "Library for Django and Stripe", "version": "0.6.1" }, "last_serial": 4288811, "releases": { "0.5.0": [ { "comment_text": "", "digests": { "md5": "d44745ffc6ea3546b0584df3b42979b4", "sha256": "4612218b48467cb9dcffcec1b0f91b3698b3e10c43bd7b3d0fe5fa7356a5cb59" }, "downloads": -1, "filename": "django_quagga-0.5.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "d44745ffc6ea3546b0584df3b42979b4", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 25683, "upload_time": "2016-06-01T18:13:11", "url": "https://files.pythonhosted.org/packages/22/82/64bbd65a3122345fe0d6151293e497f20a8ad4c3277caf6644b2e08fb082/django_quagga-0.5.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "599b0740093fd26904d7631ef1ee4ddd", "sha256": "67552792a22cff35cade560e7cb20dad7c49c4dcd7585ef4e3da71fa04951085" }, "downloads": -1, "filename": "django-quagga-0.5.0.tar.gz", "has_sig": false, "md5_digest": "599b0740093fd26904d7631ef1ee4ddd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16493, "upload_time": "2016-06-01T18:13:17", "url": "https://files.pythonhosted.org/packages/23/85/1383a3327de9f5980f801ed586d964bf677eb3e9d78961db9f56aaff0373/django-quagga-0.5.0.tar.gz" } ], "0.6.0": [ { "comment_text": "", "digests": { "md5": "15c8a0ae3f2651d6adb9ea3c72b9ca15", "sha256": "24be0686e9075af6b20281816349c5d7fa59cae843ad014dd0f85f7b76dabaab" }, "downloads": -1, "filename": "django_quagga-0.6.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "15c8a0ae3f2651d6adb9ea3c72b9ca15", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 25910, "upload_time": "2018-06-10T17:19:48", "url": "https://files.pythonhosted.org/packages/26/b7/d9afb0b08965ffe09d1fb4fa89a6561559552f0ecfe0678157db8f095206/django_quagga-0.6.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c17d07aab08d94543d2f5d0958d2e8c4", "sha256": "fab361426f9f735c33c14d90018de963fa7ec49b85f4913573e7b8664cf5d26a" }, "downloads": -1, "filename": "django-quagga-0.6.0.tar.gz", "has_sig": false, "md5_digest": "c17d07aab08d94543d2f5d0958d2e8c4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18583, "upload_time": "2018-06-10T17:19:50", "url": "https://files.pythonhosted.org/packages/68/80/5d59b904b00f9632d6f38ae6d56e1e2169e2addfd5492a3db35aa97b9349/django-quagga-0.6.0.tar.gz" } ], "0.6.1": [ { "comment_text": "", "digests": { "md5": "9cc9ab9aeddd848bc23be97fde027ed2", "sha256": "b4c5ea3905254f6a60e9a9f876e6720b78e760ae40a8bcddba56300e6a779eb8" }, "downloads": -1, "filename": "django_quagga-0.6.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "9cc9ab9aeddd848bc23be97fde027ed2", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 25998, "upload_time": "2018-09-19T14:48:55", "url": "https://files.pythonhosted.org/packages/f7/1f/8cd67a27af2cbd8bd73ad002dd2e3af0d773a70981008476824d2493c6c8/django_quagga-0.6.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5d3a5d4d419f99c6e4581d28f5ee46f7", "sha256": "18f0fce3c3a3dc8178cff7c201e4adab2a1251ee799e6b88ac1e9064b5926740" }, "downloads": -1, "filename": "django-quagga-0.6.1.tar.gz", "has_sig": false, "md5_digest": "5d3a5d4d419f99c6e4581d28f5ee46f7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18639, "upload_time": "2018-09-19T14:48:57", "url": "https://files.pythonhosted.org/packages/99/98/9e09c6939288b0b381089401775c59d2a519100675e9c2c07955971e2476/django-quagga-0.6.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "9cc9ab9aeddd848bc23be97fde027ed2", "sha256": "b4c5ea3905254f6a60e9a9f876e6720b78e760ae40a8bcddba56300e6a779eb8" }, "downloads": -1, "filename": "django_quagga-0.6.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "9cc9ab9aeddd848bc23be97fde027ed2", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 25998, "upload_time": "2018-09-19T14:48:55", "url": "https://files.pythonhosted.org/packages/f7/1f/8cd67a27af2cbd8bd73ad002dd2e3af0d773a70981008476824d2493c6c8/django_quagga-0.6.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5d3a5d4d419f99c6e4581d28f5ee46f7", "sha256": "18f0fce3c3a3dc8178cff7c201e4adab2a1251ee799e6b88ac1e9064b5926740" }, "downloads": -1, "filename": "django-quagga-0.6.1.tar.gz", "has_sig": false, "md5_digest": "5d3a5d4d419f99c6e4581d28f5ee46f7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18639, "upload_time": "2018-09-19T14:48:57", "url": "https://files.pythonhosted.org/packages/99/98/9e09c6939288b0b381089401775c59d2a519100675e9c2c07955971e2476/django-quagga-0.6.1.tar.gz" } ] }