Forms, widgets, template tags and examples that make Stripe + Django easier.

Overview

Overview

Zebra is a library that makes using Stripe with Django even easier.

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!

Usage

Installation

  1. pip install django-zebra

  2. Edit your settings.py:

    INSTALLED_APPS += ("zebra",)
    STRIPE_SECRET = "YOUR-SECRET-API-KEY"
    STRIPE_PUBLISHABLE = "YOUR-PUBLISHABLE-API-KEY"
    # Set any optional settings (below)
    
  3. (optional) ./manage.py syncdb if you have ZEBRA_ENABLE_APP = True

  4. (optional) Add in the webhook urls:

    urlpatterns += patterns('',          
    	url(r'zebra/',   include('zebra.urls',  namespace="zebra",  app_name='zebra') ),
    )
    
  5. Enjoy easy billing.

Optional Settings:

  • ZEBRA_ENABLE_APP Defaults to False. Enables Customer, Plan, and Subscription django models, as a part of zebra.
  • ZEBRA_CUSTOMER_MODEL The app+model string for the model that implements the StripeCustomerMixin. ie "myapp.MyCustomer". If ZEBRA_ENABLE_APP is true, defaults to "zebra.Customer".
  • ZEBRA_AUTO_CREATE_STRIPE_CUSTOMERS Defaults to True. Automatically creates a stripe customer object on stripe_customer access, if one doesn't exist.

Webhooks

Zebra 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:

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_failed
  • zebra_webhook_invoice_ready
  • zebra_webhook_recurring_payment_succeeded
  • zebra_webhook_subscription_trial_ending
  • zebra_webhook_subscription_final_payment_attempt_failed

All of the webhooks provide the same arguments:

  • customer - if ZEBRA_CUSTOMER_MODEL is set, returns an instance that matches the stripe_customer_id, or None. If ZEBRA_CUSTOMER_MODEL is not set, returns None.
  • 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 set ZEBRA_CUSTOMER_MODEL or are using ZEBRA_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 Update

Stripe recently updated their webhook implementation (see https://stripe.com/blog/webhooks). Zebra includes an implementation of the new system.

Zebra provides:

  • zebra_webhook_charge_succeeded
  • zebra_webhook_charge_failed
  • zebra_webhook_charge_refunded
  • zebra_webhook_charge_disputed
  • zebra_webhook_customer_created
  • zebra_webhook_customer_updated
  • zebra_webhook_customer_deleted
  • zebra_webhook_customer_subscription_created
  • zebra_webhook_customer_subscription_updated
  • zebra_webhook_customer_subscription_deleted
  • zebra_webhook_customer_subscription_trial_will_end
  • zebra_webhook_customer_discount_created
  • zebra_webhook_customer_discount_updated
  • zebra_webhook_customer_discount_deleted
  • zebra_webhook_invoice_created
  • zebra_webhook_invoice_updated
  • zebra_webhook_invoice_payment_succeeded
  • zebra_webhook_invoice_payment_failed
  • zebra_webhook_invoiceitem_created
  • zebra_webhook_invoiceitem_updated
  • zebra_webhook_invoiceitem_deleted
  • zebra_webhook_plan_created
  • zebra_webhook_plan_updated
  • zebra_webhook_plan_deleted
  • zebra_webhook_coupon_created
  • zebra_webhook_coupon_updated
  • zebra_webhook_coupon_deleted
  • zebra_webhook_transfer_created
  • zebra_webhook_transfer_failed
  • zebra_webhook_ping

Zebra also provides an easy map of all the signals as zebra.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.iteritems():
    webhook_signal.connect(webhook_logger)

Forms

The StripePaymentForm sets up a form with fields like the official stripe example.

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 Tags

There 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 your StripePaymentForm is called either zebra_form or form.

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 Mixins

Model and Mixin docs coming. For now, the code is pretty self-explanatory, and decently documented inline.

Other Useful Bits

Zebra 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_customers

It responds to --verbosity=[0-3].

Credits

I 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

Code credits are in the AUTHORS file. Pull requests welcome!

Owner
GoodCloud
GoodCloud
payu payment gateway integration for django projects

Django-PayU This package provides integration between Django and PayU Payment Gateway. Quick start Install 'django-payu' using the following command:

MicroPyramid 37 Nov 09, 2022
PayPal integration for django-oscar. Can be used without Oscar too.

PayPal package for django-oscar This package provides integration between django-oscar and both PayPal REST API, PayPal Express (NVP) and PayPal Payfl

Oscar 146 Nov 25, 2022
A pluggable Django application for integrating PayPal Payments Standard or Payments Pro

Django PayPal Django PayPal is a pluggable application that integrates with PayPal Payments Standard and Payments Pro. See https://django-paypal.readt

Luke Plant 672 Dec 22, 2022
Adyen package for django-oscar

Adyen package for django-oscar This package provides integration with the Adyen payment gateway. It is designed to work with the e-commerce framework

Oscar 13 Jan 10, 2022
A Django app to accept payments from various payment processors via Pluggable backends.

Django-Merchant Django-Merchant is a django application that enables you to use multiple payment processors from a single API. Gateways Following gate

Agiliq 997 Dec 24, 2022
Django + Stripe Made Easy

dj-stripe Stripe Models for Django. Introduction dj-stripe implements all of the Stripe models, for Django. Set up your webhook endpoint and start rec

dj-stripe 1.3k Dec 28, 2022
Forms, widgets, template tags and examples that make Stripe + Django easier.

Overview Zebra is a library that makes using Stripe with Django even easier. It's made of: zebra, the core library, with forms, webhook handlers, abst

GoodCloud 189 Jan 01, 2023
Django library to simplify payment processing with pin

Maintainer Wanted I no longer have any side projects that use django-pinpayments and I don't have the time or headspace to maintain an important proje

Ross Poulton 25 May 25, 2022