Skip to main content

dj-paypal-checkout

CI codecov Documentation Django 5.2 | 6.0 Python 3.11+ PayPal REST

A modern, REST-first PayPal integration for Django: Orders v2 checkout, refunds and verified webhooks, with models, signals and admin.

Status: 0.3.0. One-off payments are covered end to end: configuration, OAuth2 auth with token caching, sync/async HTTP clients, amount handling, models with persisted idempotency keys, the Orders v2 create/authorize/capture flows, refunds and voids, verified webhooks, a reconciliation command, signals, a read-only admin and a runnable demo. Subscriptions add the products/plans catalog, create/revise and lifecycle operations, verified lifecycle/payment webhooks and recurring-payment records. Payment Method Tokens v3 adds setup/payment tokens, verified Vault webhooks and local audit records. Browser-side Card Fields still requires merchant enablement and application UI.

It has not been run against live PayPal traffic yet, and the API may still change on minor versions before 1.0. See PROGRESS.md.

Why another PayPal library?

The established django-paypal package is built on Payments Standard with IPN/PDT, i.e. PayPal's Classic stack. PayPal now recommends webhooks for all new integrations and IPN is not fired by newer payment products. Meanwhile PayPal's own paypal-server-sdk is sync-only and ships neither webhook signature verification nor the subscription plans/products catalog.

This library targets the current REST APIs and fills those gaps:

Area API / implementation
Checkout Orders v2 (create → approve → capture)
Captures/refunds Payments v2, with a local guard against over-refunding
Notifications Webhooks with RSA-SHA256 signature verification — no IPN
Client side JS SDK v6 loader; checkout UI remains application policy
Subscriptions Subscriptions v1 + plans/products catalog and lifecycle webhooks
Saved methods Payment Method Tokens v3 (setup tokens → permanent vault tokens)
Async sync and async client, same surface

Design principles

  • The server owns the amount. It is computed from your own order; the browser only ever receives a PayPal order id.
  • Webhooks are the source of truth for money having moved, and handlers are idempotent — PayPal retries, and events can arrive more than once.
  • Writes are idempotent, via PayPal-Request-Id, so a retry cannot double-charge.
  • Decimal end to end, with currency-correct scale (never float).
  • One config entry point: a single PAYPAL settings dict, read only by paypal_checkout.config.
  • The DB is a local cache of PayPal state — concrete models plus a generic FK to your own order object, so admin, audit and re-sync work out of the box.

Requirements

  • Python 3.11+
  • Django 5.2 LTS or 6.0

Try it

example/ is a runnable sandbox checkout — two endpoints, signals, and a read-only admin:

cp example/.env.example example/.env
# Edit example/.env with the client id and secret of a PayPal sandbox REST app.
./run_demo.sh                    # http://127.0.0.1:8000/

run_demo.sh loads example/.env automatically. The file is ignored by Git and must never contain live credentials. PAYPAL_WEBHOOK_ID is optional for the synchronous checkout and is only needed to test verified webhook delivery. The demo also sets Django's SECURE_CROSS_ORIGIN_OPENER_POLICY to "same-origin-allow-popups", as required for the cross-origin PayPal popup to communicate with its opener.

Development

# Run the test suite (custom runner, uses tests/test_settings.py)
python tests/runtests.py

# Coverage (what CI runs; fails below 100% via .coveragerc)
coverage run tests/runtests.py && coverage report -m

# Docs the way CI and Read the Docs build them (warnings are errors)
sphinx-build -W --keep-going -b html docs/source docs/build/html

Invoke tasks are available too: invoke test, invoke coverage, invoke docs, invoke clean.

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dj_paypal_checkout-0.3.0.tar.gz (97.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dj_paypal_checkout-0.3.0-py3-none-any.whl (67.3 kB view details)

Uploaded Python 3

File details

Details for the file dj_paypal_checkout-0.3.0.tar.gz.

File metadata

  • Download URL: dj_paypal_checkout-0.3.0.tar.gz
  • Upload date:
  • Size: 97.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for dj_paypal_checkout-0.3.0.tar.gz
Algorithm Hash digest
SHA256 e56c0e1e7eac37f6ad48c3a450c573f81a7614ac033d172bdeb17eb9439573d1
MD5 805ddefc7d5281c97594dc6938ef86d9
BLAKE2b-256 4873971b34b6be2a0e27629e9494582151ed2ee9d2dee3e7f80ffe326e77ef74

See more details on using hashes here.

Provenance

The following attestation bundles were made for dj_paypal_checkout-0.3.0.tar.gz:

Publisher: publish.yml on otto-torino/dj-paypal-checkout

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dj_paypal_checkout-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for dj_paypal_checkout-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 310ce6fc3ad8fa5124950e11556c4dd08bba544a8cfe28af5e93f6acb424af41
MD5 0513926784ea23658396121963301033
BLAKE2b-256 690391e9d4531c93b585ba4a7c2d7cca3cb8b906e34c70a6edfd88b996118770

See more details on using hashes here.

Provenance

The following attestation bundles were made for dj_paypal_checkout-0.3.0-py3-none-any.whl:

Publisher: publish.yml on otto-torino/dj-paypal-checkout

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page