DEV Community

Justin Michael for Stripe

Posted on

🍔 Single Slider: Payment Objects Overview

Learn how Stripe's payment objects relate to each other and determine the best objects to use for your project in this short video!

What is TSE?

TSE is short for Technical Solutions Engineering, a team of engineers at who help developers like you build amazing things with Stripe. We help people both inside and outside of Stripe by answering questions, investigating bugs, working on various projects, and teaching others what we know. (Perhaps you'd like to join us)?)

What's a 🍔 Single Slider?

🍔 Single Sliders are similar to one-pagers, except they take the form of a single-slide presentation and have a punny name.

🍔 Single Sliders originally started as short conversation starters at the beginning of our internal TSE Office Hours sessions. We eventually started to publish them internally as videos with transcripts so everyone at Stripe could view them without needing to attend Office Hours.

We realized some 🍔 Single Sliders would be valuable for everyone if we published them outside of Stripe as well, so here we are. 🙂


Welcome to another TSE Single Slider!

This time we're going to look at an overview of payment objects at Stripe, the roles these objects play, and how they relate to each other.


Let's start at the bottom, with Charges. Charges have IDs that start with either a ch_ or py_ prefix. Charges represent specific attempts to move money into a Stripe account. Typically a Charge represents an incoming payment from a customer, like a card payment or bank transfer, but Charges also represent money moving into a Stripe account from another Stripe account in Connect scenarios.

The ch_ prefix is used for card Charges, and py_ is used for all other Charges.

Payment Intents

Next we have Payment Intents, which have IDs that begin with a pi_ prefix. Payment Intents are state machines which facilitate synchronous and asynchronous payment flows. An example of a synchronous payment would be a card payment that succeeds immediately, and an asynchronous example would be a card payment which requires 3D Secure authentication before being authorized.

Payment Intents represent the current state of an overall intent to pay. Every time a Payment Intent attempts payment it creates a Charge to represent each specific payment attempt. For example, a Payment Intent may attempt payment twice, with the first attempt creating a Charge that fails, followed by a second attempt which creates a Charge that succeeds. In this scenario a single Payment Intent would have two Charges associated with it, but Payment Intents can generate as many Charges as needed until the Payment Intent succeeds or the attempt is canceled or abandoned.

Both Payment Intents and Charges are what I like to call low-level payment objects at Stripe. These objects are used to handle the mechanics of collecting a specified amount from a given Payment Method, but they lack many features provided by high-level payment objects, which we'll look at now.

Checkout Sessions

Let's start with Checkout Sessions, which have IDs that start with a cs_ prefix. Checkout Sessions are used to configure and track individual uses of Stripe Checkout, our hosted payment page. Checkout Sessions have many configuration options, but when configured to take a one-time payment a Checkout Session will create a Payment Intent to facilitate that payment.

Payment Links

The next high-level object is Payment Links, which have IDs that start with plink_. Payment Links are sharable and reusable URLs which generate Checkout Sessions as needed. Payment Links are great when you want to share the same link with many people, such as on social media, in a newsletter, or on your website.


Alongside Payment Links and Checkout Sessions we have Orders, which have IDs that start with an order_ prefix. Orders manage complex custom payment scenarios and allow you to use high-level Stripe features while still maintaining a high degree of control over your integration and payment flow. An Order will create a Payment Intent to facilitate payment, just as Checkout Sessions do.


Next we have Invoices, which have IDs that start with in_. Invoices are exactly what they sound like; detailed statements of amounts owed by a customer. An Invoice will also create a Payment Intent to facilitate the payment process.


The last high-level payment object we're going to look at are Subscriptions, which have IDs that start with sub_. Subscriptions are Invoice creation engines which facilitate recurring payments. An Invoice is created by the Subscription for each Subscription period, and each Invoice includes specific details of the payment due for the given period.

More about object relationships and features

Let's go back to Checkout Sessions for a moment. Earlier I mentioned Checkout Sessions have a lot of configuration options, and one of those options is to use Checkout to start a Subscription. Thus, Checkout Sessions can create Subscriptions in addition to Payment Intents.

All of these high level payment objects support cool features you don't get with low-level payment objects, including support for Products, Prices, line items, shipping, tax, and more.

Note that all of these high-level objects are built on the foundations provided by the low-level objects. Take a Checkout Session which creates a Subscription, for example. The Subscription created by the Checkout Session will create Invoices, those Invoices will create Payment Intents, and those Payment Intents will create Charges. This structure allows you to use high-level objects which provide great features and ease-of-use while still taking advantage of our powerful low-level objects.

Using low-level objects

Beyond Stripe's high-level objects you can also use Payment Intents directly as a foundation for custom high-level abstractions outside of Stripe. This allows for fully custom payment scenarios that use Stripe as a payment processor for those who do not want or need the high-level features we provide.

Note that creating Charges directly is also technically possible, but this approach is deprecated and not recommended. Creating Charges directly is quite limiting; you can't use as many methods of payment, you can't support asynchronous payment flows, and you can't take advantage of many of the newer features Stripe has to offer.


When building a Stripe integration you should use our high-level payment objects whenever possible. You can pick any high-level object shown here as your entry point. For example, you can create Payment Links and let those Payment Links generate Checkout Sessions for you, or you can bypass Payment Links all together and create your own Checkout Sessions as needed. The same is true for Subscriptions and Invoices; you can create one-off Invoices on demand or use Subscriptions to generate them periodically for you.

So there you have it, various high-level payment objects designed to meet almost every need, built on top of a powerful foundation of low-level objects you can also leverage directly if you need to.

Next steps

You can build amazing things with these payment objects right now! Dive into our docs and get started today:

📣 Follow us on Twitter
💬 Join the official Discord server
📺 Subscribe to our Youtube channel
📧 Sign up for the Dev Digest

About the author

An image of Justin Michael imitating the 🤔 emoji

Justin Michael helps developers like you build amazing things with Stripe as a Technical Solutions Engineer.

Top comments (0)