Skip to main content

SDK for easily creating/managing Apple and Google wallet passes.

Project description

py-wallet-pass

PyPI version License: CC BY-NC 4.0

A Python SDK for easily creating and managing digital wallet passes across multiple platforms:

  • Apple Wallet (.pkpass files)
  • Google Wallet (formerly Google Pay)
  • Samsung Wallet

📱 Overview

This SDK provides a unified API to create, update, and manage digital wallet passes for multiple platforms with a single codebase. It handles all the complexities of each platform's APIs, allowing you to focus on your application logic.

✨ Features

  • Multi-platform Support:

    • Apple Wallet (.pkpass files)
    • Google Wallet (JSON format)
    • Samsung Wallet
  • All Pass Types:

    • 🎫 Event tickets
    • 🏷️ Coupons and offers
    • 💳 Loyalty and membership cards
    • ✈️ Boarding passes
    • 🏪 Store cards
    • 🎁 Gift cards
  • Flexible Storage:

    • File system storage (default)
    • In-memory storage (for testing)
    • Custom storage support (Redis, databases, etc.)
  • Developer Experience:

    • Simple unified API for all platforms
    • Helper utilities for common pass types
    • Rich documentation and examples
    • Command-line interface
    • Comprehensive test suite

💾 Installation

Using pip

# Basic installation
pip install py-wallet-pass

# With Google Wallet support
pip install py-wallet-pass[google]

# With Apple Wallet support
pip install py-wallet-pass[apple]

# With all extras
pip install py-wallet-pass[all]

Using Poetry

# Basic installation
poetry add py-wallet-pass

# With Google Wallet support
poetry add "py-wallet-pass[google]"

# With all platforms support
poetry add "py-wallet-pass[all]"

📃 Requirements

Base Requirements

  • Python 3.10+
  • pydantic (2.x)
  • typer (for CLI support)

Platform-specific Requirements

  • Apple Wallet:

    • OpenSSL (PyOpenSSL)
    • Apple Developer account with Pass Type ID certificate
  • Google Wallet:

    • google-auth
    • google-api-python-client
    • Google Cloud service account with proper permissions
  • Samsung Wallet:

    • requests
    • Samsung Wallet developer account with API credentials

🚀 Quick Start

The SDK provides a simple, unified API for creating wallet passes across different platforms. Here's a basic example of how to create a pass:

Creating a Multi-platform Pass

import py_wallet_pass as pwp
import datetime

# 1. Configure the SDK
config = pwp.WalletConfig(
    # Apple configuration
    apple_pass_type_identifier="pass.com.example.ticket",
    apple_team_identifier="ABCDE12345",
    apple_certificate_path="path/to/certificate.pem",
    apple_private_key_path="path/to/key.pem",
    apple_wwdr_certificate_path="path/to/wwdr.pem",
    
    # Google configuration
    google_application_credentials="path/to/google_credentials.json",
    google_issuer_id="3388000000022195611",
    
    # Common configuration
    web_service_url="https://example.com/wallet",
    storage_path="passes"  # Where to store pass data
)

# 2. Create a pass manager
manager = pwp.create_pass_manager(config=config)

# 3. Create a pass template (this example is for an event ticket)
event_date = datetime.datetime(2025, 6, 15, 19, 30)
template = pwp.utils.create_event_pass_template(
    name="Summer Music Festival",
    organization_id="example-corp",
    platform="both",  # Create for both Apple and Google
    style=pwp.PassStyle(
        background_color="#FF5733",
        foreground_color="#FFFFFF",
        label_color="#FFCCCB"
    ),
    images=pwp.PassImages(
        logo="images/logo.png",
        icon="images/icon.png"
    )
)

# 4. Create pass data
pass_data = pwp.utils.create_pass_data(
    template_id=template.id,
    customer_id="customer123",
    barcode_message="TICKET123456",
    barcode_alt_text="TICKET123456",
    relevant_date=event_date,
    field_values={
        "event_name": "Summer Music Festival",
        "event_date": event_date.strftime("%B %d, %Y at %I:%M %p"),
        "event_location": "Central Park, New York",
        "ticket_type": "VIP Access",
        "event_details": "Please arrive 30 minutes before the show."
    }
)

# 5. Create the pass (works for both platforms)
response = manager.create_pass(pass_data, template)

# 6. Generate the pass files
pass_files = manager.generate_pass_files(response['apple'].id, template)

# 7. Save the pass files
with open("ticket_apple.pkpass", "wb") as f:
    f.write(pass_files['apple'])

with open("ticket_google.json", "wb") as f:
    f.write(pass_files['google'])

# 8. Print Google Wallet link (can be sent to users)
print(f"Google Wallet link: {response['google'].google_pass_url}")

Platform-Specific Examples

Creating an Apple Wallet Event Ticket

import py_wallet_pass as pwp

# Configure the SDK
config = pwp.WalletConfig(
    apple_pass_type_identifier="pass.com.example.eventticket",
    apple_team_identifier="ABCDE12345",
    apple_organization_name="Example Corp",
    apple_certificate_path="certificates/certificate.pem",
    apple_private_key_path="certificates/key.pem",
    apple_wwdr_certificate_path="certificates/wwdr.pem",
    web_service_url="https://example.com/wallet",
    storage_path="passes"
)

# Create a pass manager
manager = pwp.create_pass_manager(config=config)

# Create an event ticket template
template = pwp.utils.create_event_pass_template(
    name="Summer Music Festival",
    organization_id="example-corp",
    platform="apple"
)

# Create pass data
pass_data = pwp.utils.create_pass_data(
    template_id=template.id,
    customer_id="customer123",
    barcode_message="TICKET123456",
    field_values={
        "event_name": "Summer Music Festival",
        "event_date": "June 1, 2025 at 7:00 PM",
        "event_location": "Central Park, New York",
        "ticket_type": "VIP Access"
    }
)

# Create the pass
response = manager.create_pass(pass_data, template)

# Generate the .pkpass file
pass_file = manager.generate_pass_files(response['apple'].id, template)

# Save the .pkpass file
with open("concert_ticket.pkpass", "wb") as f:
    f.write(pass_file['apple'])

Creating a Google Wallet Loyalty Card

import py_wallet_pass as pwp

# Configure the SDK
config = pwp.WalletConfig(
    google_application_credentials="certificates/google_credentials.json",
    google_issuer_id="3388000000022195611",
    web_service_url="https://example.com/wallet",
    storage_path="passes"
)

# Create a pass manager
manager = pwp.create_pass_manager(config=config)

# Create a loyalty card template
template = pwp.utils.create_loyalty_pass_template(
    name="Coffee Rewards",
    organization_id="example-corp",
    platform="google"
)

# Create pass data
pass_data = pwp.utils.create_pass_data(
    template_id=template.id,
    customer_id="customer456",
    barcode_message="MEMBER456789",
    field_values={
        "member_name": "John Smith",
        "points": "450",
        "member_since": "January 15, 2023",
        "membership_level": "Gold"
    }
)

# Create the pass
response = manager.create_pass(pass_data, template)

# Print the Google Pay link for the pass
print(f"Google Pay link: {response['google'].google_pass_url}")

Creating a Samsung Wallet Membership Card

import py_wallet_pass as pwp

# Configure the SDK
config = pwp.WalletConfig(
    samsung_issuer_id="samsung-issuer-123",
    samsung_api_key="samsung-api-key-456",
    samsung_service_id="samsung-service-789",
    samsung_api_base_url="https://wallet-api.samsung.com/v1",
    web_service_url="https://example.com/wallet",
    storage_path="passes"
)

# Create a pass manager
manager = pwp.create_pass_manager(config=config)

# Create a membership card template
template = pwp.utils.create_template(
    name="Fitness Club Membership",
    organization_id="example-fitness",
    pass_type=pwp.PassType.SAMSUNG_MEMBERSHIP,
    description="Fitness Club Membership Card"
)

# Add fields to the template
pwp.utils.add_field_to_template(
    template, "header", "member_name", "Member", ""
)
pwp.utils.add_field_to_template(
    template, "primary", "member_id", "Member ID", ""
)

# Create pass data
pass_data = pwp.utils.create_pass_data(
    template_id=template.id,
    customer_id="member-9876",
    barcode_message="MEMBER9876543",
    field_values={
        "member_name": "Sarah Johnson",
        "member_id": "9876543"
    }
)

# Create the pass
response = manager.create_pass(pass_data, template, create_for=["samsung"])

# Generate and save the pass file
pass_file = manager.generate_pass_files(response['samsung'].id, template)
with open("membership_card.json", "wb") as f:
    f.write(pass_file['samsung'])

Using Custom Storage Backends

By default, the SDK uses the filesystem to store pass data. You can create a custom storage backend by implementing the StorageBackend interface:

import py_wallet_pass as pwp

# Create a custom storage backend
class RedisStorage(pwp.StorageBackend):
    def __init__(self, redis_client):
        self.client = redis_client
    
    def store_pass(self, provider, pass_id, pass_data):
        key = f"{provider}:{pass_id}"
        self.client.set(key, json.dumps(pass_data))
    
    def retrieve_pass(self, provider, pass_id):
        key = f"{provider}:{pass_id}"
        data = self.client.get(key)
        if not data:
            raise KeyError(f"Pass not found: {pass_id}")
        return json.loads(data)
    
    def delete_pass(self, provider, pass_id):
        key = f"{provider}:{pass_id}"
        return bool(self.client.delete(key))
    
    def list_passes(self, provider):
        pattern = f"{provider}:*"
        keys = self.client.keys(pattern)
        return [key.split(':', 1)[1] for key in keys]

# Use the custom storage backend
import redis
redis_client = redis.Redis(host='localhost', port=6379, db=0)
storage = RedisStorage(redis_client)

config = pwp.WalletConfig(...)
manager = pwp.create_pass_manager(config=config, storage=storage)

Command Line Interface

The package includes a command-line interface for managing wallet passes:

# Create a template
wallet-pass create-template --config config.json --name "Event Ticket" --organization "example-corp" --type "event"

# Create a pass
wallet-pass create-pass --config config.json --template template.json --customer-id "customer123" --barcode "TICKET123456"

# Update a pass
wallet-pass update-pass --config config.json --pass-id "pass.com.example.123" --template template.json --customer-id "customer123"

# Void a pass
wallet-pass void-pass --config config.json --pass-id "pass.com.example.123" --template template.json

# Send a notification
wallet-pass send-notification --config config.json --pass-id "pass.com.example.123" --template template.json

Wallet Platform Requirements

Apple Wallet Pass Requirements

To create Apple Wallet passes, you need:

  1. An Apple Developer account
  2. A Pass Type ID certificate
  3. Your Team Identifier
  4. The WWDR certificate (Apple Worldwide Developer Relations Certificate)

Google Wallet Pass Requirements

To create Google Wallet passes, you need:

  1. A Google Cloud Platform account
  2. A service account with appropriate permissions
  3. An issuer ID from the Google Pay and Wallet Console

Samsung Wallet Pass Requirements

To create Samsung Wallet passes, you need:

  1. A Samsung Wallet developer account
  2. An issuer ID, API key, and service ID from the Samsung Wallet portal

Examples

For more detailed examples, check out the examples directory:

📝 Documentation

Comprehensive documentation is available in the docs directory.

💡 Advanced Usage

Custom Storage Backends

The SDK supports custom storage backends by implementing the StorageBackend interface. This allows you to store pass data in databases, cloud storage, or other systems:

import py_wallet_pass as pwp

# Create a custom Redis storage backend
class RedisStorage(pwp.StorageBackend):
    def __init__(self, redis_client):
        self.client = redis_client
    
    def store_pass(self, provider, pass_id, pass_data):
        key = f"{provider}:{pass_id}"
        self.client.set(key, json.dumps(pass_data))
    
    def retrieve_pass(self, provider, pass_id):
        key = f"{provider}:{pass_id}"
        data = self.client.get(key)
        if not data:
            raise KeyError(f"Pass not found: {pass_id}")
        return json.loads(data)
    
    # Implement other required methods...

# Use the custom storage
import redis
redis_client = redis.Redis(host='localhost', port=6379)
storage = RedisStorage(redis_client)
manager = pwp.create_pass_manager(config=config, storage=storage)

👨‍💻 Contributing

Contributions are welcome! Here's how you can help:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Commit your changes: git commit -am 'Add my feature'
  4. Push to the branch: git push origin feature/my-feature
  5. Submit a pull request

Development Setup

# Clone the repository
git clone https://github.com/yourusername/py-wallet-pass.git
cd py-wallet-pass

# Install dev dependencies
poetry install --with dev

# Run tests
poetry run pytest

🔒 License

CC BY-NC 4.0 License - See LICENSE for details.

Project details


Download files

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

Source Distribution

py_wallet_pass-0.1.1.tar.gz (35.1 kB view details)

Uploaded Source

Built Distribution

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

py_wallet_pass-0.1.1-py3-none-any.whl (40.0 kB view details)

Uploaded Python 3

File details

Details for the file py_wallet_pass-0.1.1.tar.gz.

File metadata

  • Download URL: py_wallet_pass-0.1.1.tar.gz
  • Upload date:
  • Size: 35.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.2 CPython/3.10.12 Linux/5.15.167.4-microsoft-standard-WSL2

File hashes

Hashes for py_wallet_pass-0.1.1.tar.gz
Algorithm Hash digest
SHA256 5268e38bf23d70290790c6673a3e56b2278ccdfe34fd57ca4d999ea4b933f602
MD5 da81e12c3acb7608030e4eb5f3475770
BLAKE2b-256 60f3915fe0710459f01392406f574d1e63ef9d414a931a8745ab9956b7e2f6b4

See more details on using hashes here.

File details

Details for the file py_wallet_pass-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: py_wallet_pass-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 40.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.2 CPython/3.10.12 Linux/5.15.167.4-microsoft-standard-WSL2

File hashes

Hashes for py_wallet_pass-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3106743d7daf88ffa592a3b8fb6c977c9595c5d075c22742029d0f7a48ebe0b2
MD5 36773688e4726ec3a93f873376492bba
BLAKE2b-256 c0515719bd4dfd72a24a6045e57fa20060913e40cfdd4543ec913c59faa485b7

See more details on using hashes here.

Supported by

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