#-cypher_api
1 messages ¡ Page 1 of 1 (latest)
đ Welcome to your new thread!
â˛ď¸ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.
âąď¸ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.
đ This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1433802491283378227
đ Have more to share? Add more details, code, screenshots, videos, etc. below.
i am also on other pages using hosted checkout/redirecting them to stripe checkout
and this cant be right or
Hi there! Looking into this now. Are there any failed payment errors associated with this?
thank you very much, these are the last logs, that had some more events
should i send any event or id spcifically in
maybe this helps? that was on charge failed event ``` "calculated_statement_descriptor":
null,
"captured":
true,
"created":
1761896615
,
"currency":
"usd",
"customer":
"cus_TKrntH5IGF6Lyl"
,
"description":
"Subscription creation",
"destination":
null,
"dispute":
null,
"disputed":
false,
"failure_balance_transaction":
null,
"failure_code":
"payment_intent_payment_attempt_expired",
"failure_message":
"The latest payment attempt of this PaymentIntent has expired. You can provide payment_method_data or a new PaymentMethod to attempt to fulfill this PaymentIntent again.",
"fraud_details": {},
"livemode":
true,
"metadata": {},
"on_behalf_of":
null,
"order":
null,
"outcome": {
"advice_code":
Yes, this helps! Can you paste the payment intent ID here (the one that starts with pi_)
yes "object": { "id": "pi_3SOC3dD5euO8UD6n1g3Pa7az" , "object": "payment_intent", "amount": 356400, "amount_capturable": 0, "amount_details": { "tip": {},
Sorry, juggling a couple of threads, looking into what would cause this expiration error
all good appreciate it
if i can give you any more info / code snippet that would help please just say
For additional context, is this the only Checkout Session where this is happening, or do you see it with others? Also, can you share your code you're using to make the Checkout Session?
to be honest, im not getting payments through fro a few days now, neither on hosted nor custom ui, thats what i use
// Backend: Create Checkout Session (src/app/api/create-checkout-session/route.ts)
export async function POST(request: NextRequest) {
const session = await auth.api.getSession({ headers: request.headers });
if (!session?.user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const body = await request.json();
const { tier, isYearly = true, uiMode = 'hosted' } = body;
const priceId = getStripePriceId(tier, isYearly);
const origin = request.headers.get('origin') || 'https://percify.io';
const user = session.user;
// Get or validate existing Stripe customer
let stripeCustomerId: string | null = null;
const userResult = await db.query(
'SELECT stripe_customer_id FROM "user" WHERE id = $1',
[user.id]
);
if (userResult.rows.length > 0 && userResult.rows[0].stripe_customer_id) {
try {
await stripe.customers.retrieve(userResult.rows[0].stripe_customer_id);
stripeCustomerId = userResult.rows[0].stripe_customer_id;
} catch (error) {
stripeCustomerId = null;
}
}
// Configure checkout session
const sessionConfig: Record<string, unknown> = {
mode: 'subscription',
line_items: [{ price: priceId, quantity: 1 }],
metadata: {
userId: user.id,
tier: tier,
isYearly: isYearly.toString(),
},
subscription_data: {
metadata: {
userId: user.id,
tier: tier,
isYearly: isYearly.toString(),
},
},
allow_promotion_codes: true,
automatic_tax: { enabled: true },
tax_id_collection: { enabled: true },
payment_method_collection: 'always',
};
// Customer configuration
if (stripeCustomerId) {
sessionConfig.customer = stripeCustomerId;
sessionConfig.customer_update = {
name: 'auto',
address: 'auto',
};
} else {
sessionConfig.customer_email = user.email;
}
// UI mode configuration
if (uiMode === 'custom') {
// Custom UI with embedded checkout
sessionConfig.ui_mode = 'custom';
sessionConfig.return_url = ${origin}/dashboard?checkout_return=true&session_id={CHECKOUT_SESSION_ID};
sessionConfig.cancel_url = ${origin}/dashboard?checkout_cancel=true&session_id={CHECKOUT_SESSION_ID};
} else {
// Hosted checkout
sessionConfig.success_url = ${origin}/dashboard?upgrade=success&tier=${tier};
sessionConfig.cancel_url = ${origin}/pricing;
sessionConfig.billing_address_collection = 'required';
}
// Create session with idempotency
const customerStrategy = stripeCustomerId ? 'existing' : 'new';
const idempotencyKey = cs_${user.id}_${tier}_${isYearly}_${customerStrategy}_${Math.floor(Date.now() / 60000)};
const checkoutSession = await stripe.checkout.sessions.create(
sessionConfig,
{ idempotencyKey }
);
if (uiMode === 'custom') {
return NextResponse.json({
clientSecret: checkoutSession.client_secret,
sessionId: checkoutSession.id,
});
} else {
return NextResponse.json({
url: checkoutSession.url,
sessionId: checkoutSession.id,
});
}
}
--------------------- and for frontend
// Frontend: Payment Confirmation (src/app/dashboard/components/payments/payment-form.tsx)
import { useCheckout } from '@stripe/react-stripe-js/checkout';
import { CheckoutProvider } from '@stripe/react-stripe-js/checkout';
export default function PaymentForm({ onPaymentError, setIsProcessing }) {
const checkoutState = useCheckout();
const handleSubmit = async () => {
if (checkoutState.type !== 'success') {
onPaymentError('Payment system not ready. Please wait...');
return;
}
const { checkout } = checkoutState;
setIsProcessing(true);
try {
// Validate total amount (Stripe requirement)
const totalAmount = checkout.total?.total?.amount;
if (!totalAmount) {
onPaymentError('Unable to retrieve payment amount. Please refresh.');
return;
}
// Check all required data is present
if (!checkout.canConfirm) {
setIsProcessing(false);
onPaymentError('Please complete all required fields before continuing.');
return;
}
// Confirm payment with automatic redirect handling
const result = await checkout.confirm({
redirect: 'always' // Handles 3DS, Amazon Pay, etc.
});
if (result && 'error' in result && result.error) {
setIsProcessing(false);
onPaymentError(result.error.message || 'Payment failed. Please try again.');
return;
}
// Success - Stripe will redirect to return_url
console.log('Payment confirmed, redirecting...');
} catch (err) {
setIsProcessing(false);
onPaymentError('An unexpected error occurred. Please try again.');
}
};
return (
<form onSubmit={(e) => { e.preventDefault(); handleSubmit(); }}>
<PaymentElement
options={{
fields: {
billingDetails: {
email: 'never',
name: 'auto',
address: {
country: 'auto',
postalCode: 'auto',
city: 'auto',
line1: 'auto',
line2: 'auto',
state: 'auto',
},
},
},
}}
/>
</form>
);
}
---------- and return handler
// Return URL Handler (src/app/dashboard/DashboardClient.tsx)
useEffect(() => {
const params = new URLSearchParams(window.location.search);
const checkoutReturn = params.get('checkout_return');
const sessionId = params.get('session_id');
if (checkoutReturn === 'true' && sessionId) {
window.history.replaceState({}, '', '/dashboard');
// Verify payment status
const verifyPayment = async () => {
const response = await fetch(`/api/verify-checkout-session?session_id=${sessionId}`);
const result = await response.json();
if (result.status === 'complete' && result.paymentStatus === 'paid') {
// Payment succeeded
console.log('Payment confirmed');
} else if (result.status === 'open' || result.paymentStatus === 'unpaid') {
// Payment failed - create NEW session
window.dispatchEvent(new CustomEvent('createNewCheckoutSession', {
detail: { reason: 'payment_failed_or_cancelled' }
}));
}
};
verifyPayment();
}
}, []);
Using ui_mode: 'custom' with embedded CheckoutProvider
return_url and cancel_url are both configured
Using checkout.confirm({ redirect: 'always' }) to handle authentication
Checking checkout.canConfirm before confirmation
Not specifying payment_method_types (auto-enabled based on Dashboard settings)
Issue: Sessions timing out or PaymentIntents getting stuck in requires_action state ```
Looking over the code, nothing stands out right away but still investigating, thanks for your patience. Do you have an example of a Payment Intent that failed from a 3DS issue (you mentioned there were different types of failures)?
this is like requires_action
{
"object": {
"id":
"pi_3SOC3dD5euO8UD6n1g3Pa7az"
,
"object":
"payment_intent",
"amount":
356400,
"amount_capturable":
0,
"amount_details": {
"tip": {},
},
"amount_received":
0,
"application":
null,
"application_fee_amount":
null,
"automatic_payment_methods":
null,
"canceled_at":
null,
"cancellation_reason":
null,
"capture_method":
"automatic",
"client_secret":
"pi_3SOC3dD5euO8UD6n1g3Pa7az_secret_nQ5Bg23rclihp6zPElYe2aSid",
"confirmation_method":
"automatic",
"created":
1761893013
,
"currency":
"usd",
"customer":
"cus_TKrntH5IGF6Lyl"
,
"description":
"Subscription creation",
"excluded_payment_method_types":
null,
"last_payment_error":
null,
"latest_charge":
null,
"livemode":
true,
"metadata": {},
"next_action": {
"redirect_to_url": {
"return_url":
"https://checkout.stripe.com/c/pay/cs_live_b1fAT57bvsIwecSvNNduQOpjr6ea1sy6AAcv4MoOo5BBsv969mwsa8GlrF?returned_from_redirect=true&ui_mode=custom&return_url=https%3A%2F%2Fpercify.io%2Fdashboard%3Fcheckout_return%3Dtrue%26session_id%3Dcs_live_b1fAT57bvsIwecSvNNduQOpjr6ea1sy6AAcv4MoOo5BBsv969mwsa8GlrF#fid1d2BpamRhQ2prcSc%2FJ0xrcWB3JyknZ2p3YWB3VnF8aWAnPydhYGNkcGlxJykndnBndmZ3bHVxbGprUGtsdHBga2B2dkBrZGdpYGEnP2NkaXZgKSdkdWxOYHwnPyd1blppbHNgWjA0VkZTcDVBMGBwSj1QQTNrU3VAZFxgY3dRf0lzazFOM0xLPEEyUjNSQFxMYEBtSzJkTXJrSk5CQTFrVUxyUmROYndTQF9WRmlMfDxpQ0dtYF1tMVEyYkpwNTVuPUlMYUhgdycpJ2N3amhWYHdzYHcnP3F3cGApJ2dkZm5id2pwa2FGamlqdyc%2FJyY1NTU1NTUnKSdpZHxqcHFRfHVgJz8naHBpcWxabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl",
"url":
"https://pm-redirects.stripe.com/authorize/acct_1SCVu0D5euO8UD6n/pa_nonce_TKrnjA4lQYWD2plCikPDWCXTxIZ4lYZ",
},
"type":
"redirect_to_url",
},
"on_behalf_of":
null,
"payment_details": {
"customer_reference":
null,
"order_reference":
"cs_live_b1fAT57bvsIwecSvN",
},
"payment_method":
"pm_1SOC3bD5euO8UD6nlfWXt9et"
,
"payment_method_configuration_details":
null,
"payment_method_options": {
"amazon_pay": {
"express_checkout_element_session_id":
null,
"setup_future_usage":
"off_session",
},
},
"payment_method_types": [
"amazon_pay",
],
"processing":
null,
"receipt_email":
"edixreyz@gmail.com",
"review":
null,
"setup_future_usage":
null,
"shipping":
null,
"source":
null,
"statement_descriptor":
null,
"statement_descriptor_suffix":
null,
"status":
"requires_action",
"transfer_data":
null,
"transfer_group":
null,
},
"previous_attributes":
null,
----and after that its like an hour that goes by till payment intent failed
and charge failed
and for the pi failed, its ```
{
"object": {
"id":
"pi_3SOC3dD5euO8UD6n1g3Pa7az"
,
"object":
"payment_intent",
"amount":
356400,
"amount_capturable":
0,
"amount_details": {
"tip": {},
},
"amount_received":
0,
"application":
null,
"application_fee_amount":
null,
"automatic_payment_methods":
null,
"canceled_at":
null,
"cancellation_reason":
null,
"capture_method":
"automatic",
"client_secret":
"pi_3SOC3dD5euO8UD6n1g3Pa7az_secret_nQ5Bg23rclihp6zPElYe2aSid",
"confirmation_method":
"automatic",
"created":
1761893013
,
"currency":
"usd",
"customer":
"cus_TKrntH5IGF6Lyl"
,
"description":
"Subscription creation",
"excluded_payment_method_types":
null,
"last_payment_error": {
"code":
"payment_intent_payment_attempt_failed",
"decline_code":
"payment_intent_payment_attempt_expired",
"doc_url":
"https://stripe.com/docs/error-codes/payment-intent-payment-attempt-failed",
"message":
"The latest payment attempt of this PaymentIntent has expired. You can provide payment_method_data or a new PaymentMethod to attempt to fulfill this PaymentIntent again.",
"payment_method": {
"id":
"pm_1SOC3bD5euO8UD6nlfWXt9et"
,
"object":
"payment_method",
"allow_redisplay":
"limited",
"amazon_pay": {},
"billing_details": {
"address": {
"city":
null,
"country":
"UG",
"line1":
null,
"line2":
null,
"postal_code":
null,
"state":
null,
},
"email":
"edixreyz@gmail.com",
"name":
null,
"phone":
null,
"tax_id":
null,
},
"created":
1761893011
,
"customer":
null,
"livemode":
true,
"metadata": {},
"type":
"amazon_pay",
},
"type":
"card_error",
},
"latest_charge":
"py_3SOC3dD5euO8UD6n1Hui1deI"
,
"livemode":
true,
"metadata": {},
"next_action":
null,
"on_behalf_of":
null,
"payment_details": {
"customer_reference":
null,
"order_reference":
"cs_live_b1fAT57bvsIwecSvN",
},
"payment_method":
null,
"payment_method_configuration_details":
null,
"payment_method_options": {
"amazon_pay": {
"express_checkout_element_session_id":
null,
"setup_future_usage":
"off_session",
},
},
"payment_method_types": [
"amazon_pay",
],
"processing":
null,
"receipt_email":
"edixreyz@gmail.com",
"review":
null,
"setup_future_usage":
null,
"shipping":
null,
"source":
null,
"statement_descriptor":
null,
"statement_descriptor_suffix":
null,
"status":
"requires_payment_method",
"transfer_data":
null,
"transfer_group":
null,
},
"previous_attributes":
null,
}
i dont know if this might help
alright i removed cancel url from custom ui mode now
Right, I was going to mention that I saw those errors. Still, it sounds like the issue you were describing was happening before this, correct?
basically, it was either no event happend after "action_required"
or the session just immedialtey expired, without even any events before
it used to work with payments intents api, but i switched because of subscriptions i think
like still so many session expired, but there werent that many payment intent events, or customer created events
Hi, taking over as my teammate needs to step away. Let me catch up.
hey thank you very much
On pi_3SOC3dD5euO8UD6n1g3Pa7az, that payment intent failed as the customer failed to authenticate the amazon pay. After they are redirected, https://docs.stripe.com/payments/amazon-pay#payment-flow they are not ocnfirming the payment.
This checkout session, cs_live_b1fAT57bvsIwecSvNNduQOpjr6ea1sy6AAcv4MoOo5BBsv969mwsa8GlrF still has not expired yet.
Can you share a checkout session id that expired please?
It's likely the authentication failed and we waited for 24 hours which expires then
that was the last checkout.session.expired id "cs_live_b173fD1pVBkE754WvBNW7JibBtQsJmsdIAHIbE6MWbS8kfGLRfv7Is6dXt"
event id "evt_1SOJVhD5euO8UD6noPM6H48O"
Looking
Yeah that is because CheckoutSession expires in 24 hours: https://docs.stripe.com/payments/checkout/how-checkout-works?payment-ui=stripe-hosted#expiration. That Checkout, https://dashboard.stripe.com/acct_1SCVu0D5euO8UD6n/logs/req_nY2SPqFAORNtiy was created at 2025-10-30 14:41:01 UTC and at 2025-10-31 14:41:01 UTC it expired evt_1SOJVhD5euO8UD6noPM6H48O as there was not a succeeful transaction as the authentication failed: evt_3SNx2mD5euO8UD6n0TNl7ise
It looks like your integration is working as expected but your end users are not authenticated.
meaning like it works, they are just not authenticated during the checkout session, or when they comeback from 3ds or amazon pay/paypal
That is correct
so what should i do next - should i just remove paypal and amazon pay, maybe that fixes it
That is up to you, do you know why your customers are not going through with the payment? Like, are they coming back and choosing another payment method?
i think they might be changing billing cycles, but it should be handled, that when they cancel 3ds, come back, choose a new billing cycle, that it doesnt pick up the old line item
like that was the last payment that went through, after that i just get failed
What does 'but it should be handled' mean? They are existing out of the checkout or Cancelling them to go through the flow again.
You're creating the CheckoutSession each time
we are doing "State resets on billing cycle change, Cache is cleared,
New idempotency key generated (includes billing cycle), New Stripe session created with correct line item, Old session cannot be reused"
I do not follow, are you able to add more context please?
im not wuite sure, because the last time the checkout worked successfuly, was , after that, im at idk 300 failed transactions due to the checkoutSesstions with subscriptions and custom ui, payment element
but youre saying everything looks fine, and its just a user not completing 3ds or paypal/amazon pay auth?
Did you offer the same payment methods? If you offerred different payment methods, that is plausible. If not, you'd want to perform some analysis on your end.
yes the successful payments
show only allowed payment method "card"
i wanted to add paypal, amazon pay
after that everything went south
now i reverted back to only 'card'
Yeah, so your customers might not be used to how these payment methods work and how they need to authenticate.
This is how these payment methods work
alright i will try it with only " sessionConfig.payment_method_types = ['card'];" again
hope that solves it
I think the real solution is sending clear communications to your customers so they can choose between various payment methods. If offerring card works, sure.
but they choose the payment methods themselves
in the stripe payment form element
tabs style
like im not hiding the payment methods, they initiate the choice themselves
Yes, and they need to understand the authentication piece is important