Skip to content
Insights · Engineering

Which session did that checkout open?

Name the session that checkout opened: the id and the statuses. A different session can finish another payment, and another account does not list this one.

Scroll
EngineeringOct 30, 202612 min readBy Salman Naqvi, Founder & CEO
Which session did that checkout open?

A customer says they paid, or says the page died before they could. Tonight, three proofs, in a console you administer. Name the Checkout Session that payment opened: the session id, the status, and the payment status. Show a different session whose status or payment status is not this one. Show another account's list that does not contain this session. If any of the three needs the person who wired checkout, you have not shown the session. You have a cart total and a guess.

This is the session the hosted page, or the embedded page, was. It is not the card on a charge. Which card did that charge use? is a brand and a last four on a charge id. A session can be complete while the card on the charge is a different question, and a brand can be visa while this session is still open. It is not the price they were shown. Show the price they accepted is the figure on the screen and the figure that was taken. A price can be right while the session expired before the funds were available. It is not the status of a subscription. Which status is that subscription in? is one of the names a subscription stores. A session in subscription mode can create a subscription, and the session's status is still not the subscription's status. It is not which endpoint an event reached. Which webhook did that event hit? is a delivery. A delivery can name a session and still not be the session object you stored.

None of what follows is a conversion rate for this product, and none of it is legal advice. The fields below are one processor's current description of a Checkout Session. The percentages below that are a compiled list of other people's abandonment studies, plus one institute's own reasons. A status enum is not a census of your customers. An average of fifty studies cannot name the session you opened tonight. They do tell you which numbers people mix up when they try to sound precise about a checkout they have not opened.

Stripe's Checkout Session object says the status is one of open, complete, or expired. Three names. open means the session is still in progress and payment processing has not started. complete means the session is complete and payment processing may still be in progress. expired means no further processing will occur. complete is not paid. open is not unpaid. The payment status is a second field, one of paid, unpaid, or no_payment_required. paid means the funds are available in your account. For a subscription with a free trial, paid means the trial invoice of $0 was processed. $0 is not unpaid, and it is not the sample amount below. unpaid means the funds are not yet available. no_payment_required is for setup mode, or for a billing-cycle anchor with no proration where payment is collected later. A payment status of paid is not a status of complete. A status of expired is not a payment status of unpaid (Stripe, The Checkout Session object).

The mode is a third enum: payment, setup, or subscription. Three names, and none of them is a status. payment accepts a one-time payment. setup saves a payment method to charge later. subscription sets up a fixed-price subscription. The sample object prints mode payment, status open, and payment_status unpaid, with livemode false, so the object is an example, not a live payment on your account. Its id is cs_test_a11YYufWQzNY63zpQ6QSNRQhkUpVph4WRmzW0zWJO2znZKdVujZ0N0S22u. That string is an identifier. It is not a charge id, and the cs_test_ prefix is the sample's, not a rule you can paste onto a live id you have not copied. customer on the sample is null. customer_email is null. invoice is null. A null customer is not a customer you forgot to expand.

The sample's amount_subtotal is 2198 and its amount_total is 2198. Both are integers in the smallest currency unit. The page does not print a dollar sign beside them. currency is usd. total_details prints amount_discount 0, amount_shipping 0, and amount_tax 0. 0 plus 0 plus 0 is 0, which is why the two 2198s match on this sample. A discount that is not zero would make amount_total differ from amount_subtotal. Do not treat the match as a law. 2198 is not 2198 dollars, and it is not a count of sessions. created is the integer 1679600215. expires_at is 1679686615. The difference is 86400 seconds. 86400 seconds is 24 hours on a clock. The field text says expires_at is the timestamp at which the session will expire. It does not print the words 24 hours next to the sample. Do not promote the sample's arithmetic into a default the page did not state.

customer_creation on the sample is if_required. The enum is always or if_required. always creates a Customer when confirmation is attempted. if_required creates one only when the session needs it. The page says that, currently, only subscription mode and payment mode with post-purchase invoices require a Customer. The sample is payment mode, invoice_creation.enabled is false, and customer is null. That combination is consistent with if_required. It is not proof that your live session also has a null customer. ui_mode defaults to hosted_page. The enum lists elements, embedded_page, and hosted_page. Three names. The custom_fields note says you cannot set custom fields if ui_mode is custom. custom is not in the enum list of three. Do not add a fourth mode because a prohibition named it. custom_fields supports up to 3 fields. The sample's array is empty. 3 is a maximum. It is not three proofs, and an empty array is not three blank fields.

submit_type can be set only in payment mode. If it is blank or auto, the page says pay is used. The auto value itself says pay is used for payment-mode sessions and subscribe is used for subscription-mode sessions. Those are two sentences. Do not collapse them into one rule. The pay value's button label is Buy, not Pay. The subscribe value's button label is Subscribe. book and donate are the other two. Five names. Buy is not a mode. customer_details.business_name and individual_name each have a maximum length of 150 characters. Two limits, two fields. 150 is not 150 customers. Address and name on customer_details are populated only for sessions on or after March 30, 2022. March 30, 2022 is not the sample's created integer. tax_exempt is exempt, none, or reverse. none is not null. Custom text messages, including the submit message, can be up to 1200 characters. 1200 is a string length. It is not 2198, and it is not 86400.

The study people reach for when they want a checkout rate is a different document, and it says it averaged other people's rates. Baymard Institute publishes a list of 50 cart-abandonment statistics and prints the average as 70.22%. The page was last updated September 22, 2025. 50 is a count of studies. It is not 50 of your sessions, and 70.22% is not the status open. The first row is Uptain 2025 at 71.72%, retrieved August 7, 2025. August 7 is not September 22. 71.72% is not 70.22%. SaleCycle 2020 is 84.27%. Fresh Relevance 2021 is 59.22%. Forrester Research 2010 is 55.00%. 84.27 is not 59.22, and 59.22 is not 55.00, and none of them is the average. The page spells SalesCycle on the 2023 and 2021 rows and SaleCycle on the 2020, 2018, 2017, 2016, 2015, and 2013 rows. Do not merge the two spellings into one firm (Baymard Institute, 50 Cart Abandonment Rate Statistics).

The reasons are a second study on the same page, and they do not use 70.22%. Baymard says 42% of US online shoppers have abandoned a cart because they were just browsing or not ready to buy. 42% is not 70.22%, and it is not 50 studies. After setting that segment aside, the page prints what it calls the remaining distribution: extra costs 40%, delivery too slow 20%, did not trust the site with a card 19%, the site wanted an account 18%, checkout too long or complicated 17%, the site had errors or crashed 17%, returns policy 13%, could not see the total up front 12%, the card was declined 10%, not enough payment methods 9%, and do not know 7%. Those eleven percentages sum to 182, not 100. The page calls them a distribution anyway. Do not rescale them so they add to 100. The two 17s are different sentences. A long checkout is not a crash.

The form-field sentences are a third set. The same 17% is repeated as shoppers who abandoned because checkout was too long. The usability note says an ideal flow can be as short as 12 to 14 form elements, or 7 to 8 if only fields are counted. The benchmark says the average US checkout shows 23.48 elements by default, or 14.88 if only fields are counted. 23.48 is not 14.88. 14 is not 14.88. 12 to 14 is not 7 to 8. They say a 20 to 60% reduction in elements is possible for most checkouts. 20 to 60 is not 35.26. The recoverable-order paragraph says better checkout design can gain 35.26% conversion, on combined US and EU ecommerce sales of $738 billion, which they translate to $260 billion. $260 billion is not $738 billion. 35.26% is not 70.22%. A benchmark of 60 sites shows 39 potential improvement areas, and they say the long-checkout point is 1 of 140 documented causes. 39 is not 42, and 140 is not 50. A phone number printed in the footer is not an abandonment rate. None of these figures is the session id on your account.

Do the three proofs on one real session, in the console that actually holds it. First, the binding. Copy the session id, the status, and the payment status. If status is complete and payment_status is unpaid, write both. Do not promote complete into paid. If the id is absent, write that it was not stored. Do not infer the sample's cs_test_ string because an example prints it. Second, the other session. A different session, with a different status or a different payment status, is not this one. A chart of abandonment is not that second session. If you cannot show a session that is not this one, you have a counter, not a record. Third, the other account. A list that belongs to someone else does not contain this session id. If the only list is a single shared table and you cannot say whose session it is, write that. A tenant you cannot name is the finding. It is not a reason to tell the customer the payment was paid.

Three moves feel like the proof and are a second problem. Expiring the session because the status was embarrassing, and then describing the missing row as a cleanup. Quoting 70.22% because it looks precise, while the complaint in front of you is one session, and the average was taken across 50 other studies. Asking a model which status it was. The model will pick a plausible name from the three. It will not open the session. A price you have not kept, while the customer is arguing about the amount, is show the price they accepted. Opening that screen does not name the session.

The path is ordinary when an operator can open one subscriber's checkout without opening the next subscriber's tender as the way to prove it. PassGlobe is a subscription platform with weekly billing through Stripe, a user dashboard, and a vendor dashboard, and one subscriber's redemption is not the next subscriber's. The shape that matters here is one checkout you can point at, in an account you administer, distinct from the next. That case is not a Checkout Session ledger. Nothing in the description is a headcount, a duration, or a result figure. If the only control on the billing screen changes every subscriber's session, you do not have this proof. You have a payment form.

There is a version of this afternoon where hiring the path is the wrong purchase. Nothing opens a checkout, because the product does not take money yet. You have no product. You are still choosing who will build, and the document in front of you is a term sheet. The criteria for that choice sit on the page written for a top SaaS development company. That page is criteria. It does not rank anyone, including us. The only fact in the room is a share from a list. 70.22% is not your session, and 2198 is not your session. A customer has already seen another customer's session. Naming a status does not close a leak. Or you wanted a lawyer to say whether a network rule applies. Hire the lawyer.

When the checkout is real and the console cannot name the session, the missing object is specific. An admin action, in an account you administer, that shows one session id, one status, and one payment status, shows a different session that is not that one, and shows another account's list without it. A startup software development company that expects this will have put that action next to the rest of the billing screen, before a stranger's complaint is the way you discover the vendor owns the session. One that needs a call in order for you to see which session is stored is telling you who holds the checkout. If the first slice is a fixed capability, an AI integration sprint is the shape where the acceptance sentence can include the three proofs. If you do not yet know which system stores the session, a two-week AI readiness assessment maps the systems. The findings are yours. They are not a promise that an average of fifty studies applies, and they are not 2198.

The cache a job restored, and the cache write a prompt recorded, are different objects: which cache did that job restore? and which write did that cache record?. Do not record either on this page. A workflow key is not a session id. A token write is not a payment status.

Before you tell them the checkout was fine, do the three proofs and write both statuses. Name the session, the status, and the payment status, or write that the session was not stored. Show a different session that is not that one. Show another account's list that does not hold it. Do not expire the row to avoid the status, and do not ask a model which of the three it was. A list of studies can tell you how far other people's rates sit from their own average. The binding is the session you can defend.

Questions

Three records, in a console you administer. The session id, the status, and the payment status. A different session whose status or payment status is not this one. Another account's list that does not contain this session. If any of the three needs the person who wired checkout, you do not have the proof.

No. An average of 50 other studies is not the id on this session. A session you can defend is the id, the status, and the payment status, or a written line that the console does not store them. 70.22% is not open, and 2198 on a sample object is not your customer's amount.

When nothing opens a checkout, when you have no product, when you are still choosing a firm, when the only fact in the room is a list of rates, when a customer has already seen another customer's session, or when you wanted a lawyer.

Find this useful? Tell Google to show you more of it.

Let's put AI to work in your business.

A 30-minute call. You bring the workflow or the roadmap — we'll tell you what's feasible, what it costs, and what we'd build first.

Book a call→