Skip to content

Stripe Charges API (Deprecated): Legacy One-Time Payment Method

DodaTech Updated 2026-06-28 2 min read

In this tutorial, you will learn about Stripe Charges API (Deprecated): Legacy One. We cover key concepts, practical examples, and best practices to help you master this topic.

The Charges API is Stripe's original one-time payment method, now deprecated in favor of Payment Intents which support Strong Customer Authentication (SCA) and modern payment methods.

What You'll Learn

How the legacy Charges API works, when you might still encounter it, why it's deprecated, and how to migrate existing Charge-based code to Payment Intents.

Why It Matters

Existing codebases may still use Charges. Understanding them helps you maintain legacy code and plan Migration. DodaTech migrated from Charges to Payment Intents in 2024 to support 3D Secure authentication.

Real-World Use

A legacy subscription system uses stripe.Charge.create() for one-time payments. New requirements for 3D Secure mandate migration to Payment Intents.

flowchart LR
    A["Legacy Code\nstripe.Charge.create()"] --> B["No SCA Support\nFails in Europe"]
    B --> C["Migration Needed"]
    C --> D["New Code\nstripe.PaymentIntent.create()"]
    D --> E["3D Secure\nAuthentication"]
    D --> F["Saves Card\nfor Later"]
    style A fill:#fecaca,stroke:#dc2626
    style D fill:#bbf7d0,stroke:#16a34a

Creating a Charge

import stripe
stripe.api_key = os.environ["STRIPE_SECRET_KEY"]

def create_charge(amount, currency, source, description):
    charge = stripe.Charge.create(
        amount=amount,
        currency=currency,
        source=source,
        description=description,
        metadata={"order_id": "ORD-12345"}
    )

    print(f"Charge: {charge.id}")
    print(f"Amount: ${charge.amount/100:.2f}")
    print(f"Status: {charge.status}")
    print(f"Paid: {charge.paid}")
    print(f"Outcome: {charge.outcome['seller_message']}")

    return charge

charge = create_charge(
    amount=2999,
    currency="usd",
    source="tok_visa",
    description="Pro Plan Subscription"
)
# Expected output:
# Charge: ch_3Mqwerty19QfG5XG0gTzFz1L
# Amount: $29.99
# Status: succeeded
# Paid: True

Common Mistakes

1. Using Charges for New Integrations

Always use Payment Intents for new code. Charges are deprecated and don't support SCA, which is required in Europe and many other regions.

2. Passing Raw Card Numbers

Charges can accept raw card numbers, but this expands your PCI scope. Use Stripe Elements or Checkout to avoid handling card data directly.

3. Not Handling SCA Decline

Charges fail with authentication_required when SCA is needed. Payment Intents handle this automatically with 3D Secure flows.

4. Confusing source with payment_method

Charges use source (tokens/IDs). Payment Intents use payment_method. Migration requires updating all references.

Practice Questions

  1. Why are Charges deprecated?
  2. How do Charges differ from Payment Intents?
  3. What happens when a Charge requires authentication?
  4. How do you migrate from Charges to Payment Intents?

Answers:

  1. Charges don't support Strong Customer Authentication (SCA), dynamic payment methods, or modern fraud detection.
  2. Payment Intents support SCA, multiple payment methods, dynamic confirmation, and saved payment methods. Charges are simpler but limited.
  3. The Charge fails with authentication_required. Your app must catch this and create a PaymentIntent with the same amount.
  4. Replace stripe.Charge.create() with stripe.PaymentIntent.create(), handle requires_action status for 3D Secure, and use payment_method instead of source.

FAQ

Can I still use the Charges API?

Technically yes, but Stripe recommends migration. Charges won't support new payment methods or regulatory requirements.

When will Charges be removed?

Stripe hasn't announced a removal date, but new features are only available on Payment Intents.

Do Charges work with 3D Secure?

No. Charges fail with authentication_required when SCA is needed. You must handle this manually or migrate to Payment Intents.

Mini Project

Review a legacy codebase using Charges. Identify all Charge.create() calls, test with a card requiring authentication (4000002500003155), observe the failure, and write a migration plan to Payment Intents.

What's Next

Payment Intents — the modern payment API for one-time charges.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro