Skip to main content

PayPal Subscription (Python) Library

License

This Python library allows you to interact with the PayPal REST API to manage subscriptions with variable pricing. It includes functionality for creating, updating, suspend and verifying subscriptions, as well as managing products and plans.

Note: When the subscription is approved the user receive an email from Paypal to inform that a new automatic payment is approved, and of course one about the payment itself.

Addendum

To simplify and avoid to use also the PayPal SDK this library implements methods like create_order and verify_payment so can be used also for single payments.

Usage Example

This example demonstrates how to create a CLI app that creates or updates a PayPal subscription and a FastAPI server with a webhook to save the PayPal identifier in an SQLite database. This setup allows you to check if a plan exists and in case update it automatically.

Dependencies

Install the required dependencies:

pip install fastapi uvicorn requests

Environment

Set up your environment variables in a .env file:

PAYPAL_CLIENT_ID=your_client_id
PAYPAL_CLIENT_SECRET=your_client_secret
PAYPAL_SANDBOX=True  # Set to False for production

Payment script

The payment script creates or updates a subscription and sends an email with a PayPal approval link to the user.
This script can be extended to use other library methods, such as suspend_subscription, to manage subscriptions further.

payment_request.py

#!/usr/bin/env python
import sqlite3
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from paypal_subscription import PayPalAPI

paypal_api = PayPalAPI()

# Define subscription details
identifier = ""
name = "Subscription Name"
description = "Subscription Description"
price = "10.00"
currency = "EUR"
subscriber_email = "user@example.com"
return_url = "http://localhost:8000/return_url/"
cancel_url = "http://localhost:8000/cancel_url/"

# Connect to SQLite database
conn = sqlite3.connect('subscriptions.db')
cursor = conn.cursor()

# Retrieve identifier from the database (assuming it's stored there)
cursor.execute("SELECT id FROM subscriptions WHERE email = ?", (subscriber_email,))
result = cursor.fetchone()

if result:
    identifier = result[0]
else:
    raise ValueError("Subscription identifier not found in the database.")

# Create or update the subscription
subscription = paypal_api.create_or_update_subscription(
    identifier=identifier,
    name=name,
    description=description,
    price=price,
    currency=currency,
    subscriber_email=subscriber_email,
    return_url=return_url,
    cancel_url=cancel_url
)

# Get the approval link
approval_link = subscription['links'][0]['href']

# Send email with the approval link
def send_email(to_address, subject, body):
    from_address = "your_email@example.com"
    password = "your_email_password"

    msg = MIMEMultipart()
    msg['From'] = from_address
    msg['To'] = to_address
    msg['Subject'] = subject

    msg.attach(MIMEText(body, 'plain'))

    server = smtplib.SMTP('smtp.example.com', 587)
    server.starttls()
    server.login(from_address, password)
    text = msg.as_string()
    server.sendmail(from_address, to_address, text)
    server.quit()

# Email details
subject = "Approve Your Subscription"
body = f"Please click the following link to approve your subscription: {approval_link}"

# Send the email
send_email(subscriber_email, subject, body)

print("Subscription approval link sent to the subscriber's email.")

FastAPI server

The FastAPI server handles the return URL webhook to save the subscription identifier in the SQLite database.
This server can be extended to save additional payment details.

from fastapi import FastAPI, Request
from paypal_subscription import PayPalAPI
import sqlite3

app = FastAPI()
paypal_api = PayPalAPI()

# Set up SQLite database
conn = sqlite3.connect('subscriptions.db')
cursor = conn.cursor()
cursor.execute('''
    CREATE TABLE IF NOT EXISTS subscriptions (
        id TEXT PRIMARY KEY,
        name TEXT,
        description TEXT,
        price TEXT,
        email TEXT,
        status TEXT
    )
''')
conn.commit()

def save_subscription_to_db(subscription_id: str, name: str, description: str, price: str, email: str, status: str):
    conn = sqlite3.connect('subscriptions.db')
    cursor = conn.cursor()
    cursor.execute('''
        INSERT INTO subscriptions (id, name, description, price, email, status)
        VALUES (?, ?, ?, ?, ?, ?)
    ''', (subscription_id, name, description, price, email, status))
    conn.commit()

@app.post("/return_url/")
async def return_url(request: Request):
    data = await request.json()
    subscription_id = data.get("subscription_id")
    subscription_details = paypal_api.verify_subscription(subscription_id=subscription_id, payer_id="email")

    if subscription_details["status"] == "success":
        save_subscription_to_db(
            subscription_id=subscription_id,
            name=subscription_details["name"],
            description=subscription_details["description"],
            price=subscription_details["price"],
            email=subscription_details["payer_email"],
            status=subscription_details["subscription_status"]
        )
        return {"message": "Subscription saved successfully"}
    else:
        return {"message": "Subscription verification failed"}

Run

Execute the payment request:

payment_request.py

Run the web server:

uvicorn main\:app --reload

Metadata

Release files for paypal-subscription 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for paypal-subscription 0.1.2
File Size Uploaded Provenance Actions
paypal_subscription-0.1.2.tar.gz 18.9 kB With provenance Details for paypal_subscription-0.1.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for paypal-subscription 0.1.2
File Interpreter ABI Platform Actions
paypal_subscription-0.1.2-py3-none-any.whl Python 3 none any Details for paypal_subscription-0.1.2-py3-none-any.whl

Total release size: 38.4 kB

Release files / paypal_subscription-0.1.2.tar.gz

Download URL paypal_subscription-0.1.2.tar.gz
Size 18.9 kB
Tags Source
SHA-256 checksum
How to use checksums
aff0802b7dd4c6c2fa44bd8bce9333a3f1cb33230c0f419652cc05ba1e80dfbb
BLAKE2b-256 checksum
How to use checksums
c6ee306012f896e73dd8976f0e17634818851a17897c9287c991df40d7f70ec3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 15, 2025.

Transparency log

Release files / paypal_subscription-0.1.2-py3-none-any.whl

Download URL paypal_subscription-0.1.2-py3-none-any.whl
Size 19.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2e43966dc27f52c45ab0050c878cc4cbdc6ff951c682b3617847f72f56adc5ee
BLAKE2b-256 checksum
How to use checksums
b2efb3c8202112472c0071bf524bd34b90cbc0c7e58c5d1af53dd4eaa7e332ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 15, 2025.

Transparency log

Security for paypal-subscription 0.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for paypal_subscription-0.1.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 15, 2025.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page