Skip to content

Stripe Customer Management — Customers, Payment Methods, and Tax IDs

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about Stripe Customer Management. We cover key concepts, practical examples, and best practices to help you master this topic.

Stripe Customer objects represent your users in Stripe, storing payment methods, subscription history, invoices, and metadata used across all Stripe operations.

What You'll Learn

By the end of this lesson you will understand how to create and manage customers, attach payment methods, set default payment methods, handle tax IDs, and retrieve customer history.

Why It Matters

Customer management is central to Stripe -- subscriptions, invoices, charges, and payment methods are all associated with a Customer. Proper customer management ensures accurate billing and good customer experience.

Real-World Use

DodaZIP creates a Stripe Customer for each user during signup. The customer ID is stored in the application database and used for all subsequent Stripe operations.

flowchart LR
    U[User Signup] --> C[Create Stripe Customer]
    C --> PM[Attach Payment Method]
    PM --> S[Create Subscription]
    C --> I[Generate Invoices]
    C --> H[View Payment History]
    style C fill:#6772e5,color:#fff

Creating Customers

Create a Customer when a user signs up or before their first payment.

import stripe
import os

stripe.api_key = os.environ.get("STRIPE_SECRET_KEY", "sk_test_placeholder")

def create_customer(email, name, metadata=None):
    customer = stripe.Customer.create(
        email=email,
        name=name,
        metadata=metadata or {},
    )
    print(f"Created customer: {customer.id}")
    return customer

stripe.api_key = "sk_test_placeholder"

class MockCustomer:
    id = "cus_test_abc123"

stripe.Customer.create = lambda **kwargs: MockCustomer()

customer = create_customer("alice@example.com", "Alice Smith", {"signup_source": "website"})
print(f"Customer ID: {customer.id}")

Expected output:

Created customer: cus_test_abc123
Customer ID: cus_test_abc123

Managing Payment Methods

Attach payment methods to customers and set defaults.

# payment_methods.py
# Managing customer payment methods

def attach_payment_method(customer_id, pm_id):
    print(f"Attaching payment method {pm_id} to {customer_id}")
    print(f"  -> Payment method attached")
    return {"id": pm_id, "customer": customer_id, "type": "card"}

def set_default_payment_method(customer_id, pm_id):
    print(f"Setting {pm_id} as default for {customer_id}")
    print(f"  -> Default payment method updated")

def list_payment_methods(customer_id):
    methods = [
        {"id": "pm_card_visa", "brand": "Visa", "last4": "4242", "exp": "12/28", "default": True},
        {"id": "pm_card_mastercard", "brand": "Mastercard", "last4": "4444", "exp": "08/27", "default": False},
    ]
    
    print(f"Payment methods for {customer_id}:")
    for m in methods:
        default = " (default)" if m["default"] else ""
        print(f"  {m['brand']} ending in {m['last4']} exp {m['exp']}{default}")
    return methods

attach_payment_method("cus_abc", "pm_card_visa")
set_default_payment_method("cus_abc", "pm_card_visa")
list_payment_methods("cus_abc")

Updating Customers

Update customer information and metadata.

# update_customer.py
# Updating customer details

def update_customer(customer_id, updates):
    print(f"Updating customer {customer_id}")
    for key, value in updates.items():
        print(f"  {key}: {value}")
    
    print(f"  -> Customer updated successfully")
    return {"id": customer_id, **updates}

update_customer("cus_abc", {
    "email": "newemail@example.com",
    "name": "Alice Johnson",
    "metadata": {"plan": "premium", "tier": "vip"}
})

Common Mistakes

  1. Creating duplicate customers: Always check if a Customer already exists for a user before creating a new one.

  2. Not storing Stripe customer ID: Store the Stripe customer ID in your database to avoid recreating customers.

  3. Setting customer email after creation: Changing the customer email in Stripe does not change it in your database. Keep them in sync.

  4. Attaching payment methods without setting default: Attached payment methods are not automatically set as default. Set invoice_settings.default_payment_method.

  5. Ignoring metadata for organization: Use metadata to store internal IDs and tags for easy customer lookup.

Practice Questions

  1. What is a Stripe Customer? A Customer object represents a buyer in Stripe, storing payment methods, subscriptions, invoices, and metadata.

  2. How do you attach a payment method to a customer? Create a SetupIntent or use the PaymentMethod.attach API to associate a payment method with a customer.

  3. Why store the Stripe customer ID in your database? To reference the customer in future Stripe API calls without searching by email or other criteria.

  4. What is metadata used for? Storing internal application data like user IDs, plan information, or tags for organization.

  5. Challenge: Create a customer management service that syncs user profiles from your database to Stripe, handling creation, updates, and deletion.

FAQ

Can I search for customers?

Yes. Use the Customer search API to find customers by email, name, or metadata values.

How many payment methods can a customer have?

A customer can have up to 10 payment methods attached.

Can I delete a customer?

Yes, but all associated subscriptions and payment methods are also deleted.

What happens to a customer's subscriptions if I delete them?

All active subscriptions are canceled immediately.

Can I migrate customers between Stripe accounts?

No, customers are account-specific. Use the Stripe migration guide for moving data.

Mini Project

Create a customer management endpoint that creates a customer, attaches a payment method from Checkout, and sets up a subscription.

import json

def lambda_handler(event, context):
    body = json.loads(event.get("body", "{}"))
    email = body.get("email", "test@example.com")
    name = body.get("name", "Test User")
    
    customer_id = f"cus_{hash(email)}"
    print(f"Created customer: {customer_id}")
    print(f"Email: {email}")
    print(f"Name: {name}")
    
    return {
        "statusCode": 200,
        "body": json.dumps({
            "customer_id": customer_id,
            "email": email,
            "name": name
        })
    }

print(json.loads(lambda_handler({"body": json.dumps({"email": "alice@example.com", "name": "Alice"})}, None)["body"]))

What's Next

Next: Refunds and Disputes for handling post-payment issues.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro