#chechu_confirmationtoken-error
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/1300494816500776972
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
Hey @shell wedge Can you provide your exact code and the exact error you get including the exact request id req_123 so I can help you?
chechu_confirmationtoken-error
Hey sure, this is the tutorial/doc I am following https://docs.stripe.com/payments/finalize-payments-on-the-server?platform=web&type=subscription&lang=go#additional-options
Im going for the code give me a sec
Option settings
{
mode: "subscription",
amount,
currency: "eur",
paymentMethodCreation: "manual",
customerSessionClientSecret: sessionToken,
// setupFutureUsage: "off_session", // same result with and without
appearance: {
variables: {
colorPrimary: "#60a5fa",
colorBackground: "#1f2937",
colorText: "#e5e7eb",
colorDanger: "#fb7185",
},
},
}
const handleSubmit = async (form: React.FormEvent) => {
if (!stripe || !elements) {
setError("Stripe is not loaded");
return;
}
form.preventDefault();
await save();
setLoading(true);
const { error: submitError } = await elements.submit();
if (submitError) {
setError(
submitError.message ||
"An error occurred while submitting elements",
);
setLoading(false);
return;
}
console.log(elements);
const { error, confirmationToken } =
await stripe.createConfirmationToken({
elements,
params: {
payment_method_data: {
billing_details: {
name: `${data.firstname} ${data.lastname}`,
email: data.email,
address: {
line1: data.address_line_1,
line2: data.address_line_2,
city: data.city,
postal_code: data.postal_code,
country: data.country,
},
},
},
},
});
if (error) {
setError(
error.message ||
"An error occurred while creating confirmationToken",
);
setLoading(false);
return;
}
console.log(confirmationToken);
const exec = await executeStripeFunction(
"/create-confirm-subscription",
JSON.stringify({
confirmationTokenId: confirmationToken.id,
plan,
ram,
discountCode: "discountCode",
}),
);
if (exec.error) {
setError(`An error occurred while confirming`); // the error happens here, I will send the backend code in a sec, but it's a stripe confirmation error
setLoading(false);
return;
}
console.log(exec.response);
const paymentIntent = JSON.parse(exec.response);
handleSubscription(paymentIntent);
};
func CreateConfirmSubscription(client client.Client, userId string, confirmationToken ConfirmationToken) (*stripe.PaymentIntent, error) {
customerId, error := GetCustomerId(client, userId)
if error != nil {
return nil, error
}
params := &stripe.SubscriptionParams{
Customer: stripe.String(customerId),
Items: []*stripe.SubscriptionItemsParams{
{
PriceData: &stripe.SubscriptionItemPriceDataParams{
Currency: stripe.String("eur"),
UnitAmount: stripe.Int64(275),
Product: stripe.String("prod_R6MjKerxnstPdP"),
Recurring: &stripe.SubscriptionItemPriceDataRecurringParams{
Interval: stripe.String("month"),
},
},
Quantity: stripe.Int64(int64(confirmationToken.Ram / 1024)),
},
},
PaymentBehavior: stripe.String("default_incomplete"),
PaymentSettings: &stripe.SubscriptionPaymentSettingsParams{
SaveDefaultPaymentMethod: stripe.String("on_subscription"),
},
Expand: stripe.StringSlice([]string{"latest_invoice.payment_intent"}),
}
sub, err := subscription.New(params)
if err != nil {
return nil, err
}
confirmParams := &stripe.PaymentIntentConfirmParams{
UseStripeSDK: stripe.Bool(true),
ReturnURL:stripe.String("https://lumenhosting.net/dashboard/billing/confirm"),
ConfirmationToken: stripe.String(confirmationToken.ConfirmationTokenId),
}
intent, err := paymentintent.Confirm(sub.LatestInvoice.PaymentIntent.ID, confirmParams) // error happens here
if err != nil {
return nil, err // and is returned here, it is sent directly
}
return intent, nil
}
Okay I need the exact error and request id please
the payment is "pi_3QEXH8RVQv6fuSiG00WvRTQ7"
error "message": "The provided setup_future_usage (off_session) does not match the setup_future_usage from the provided confirmation_token (on_session). Try confirming with a Payment Intent that is configured to use the same parameters as the ConfirmationToken." "type": "invalid_request_error"
there should be a request id req_123
yep give me a sec I have to find the failing one
found it I'm good
all right!
I'm confused because your ConfirmationToken creation clearly has setup_future_usage: 'on_session', see https://dashboard.stripe.com/test/logs/req_3KckkJFtBOYoda
it's in sandbox by the way if it has something to do with the error?
yes that's the problem
it should be off_session
so it looks like somewhere you are forcing that. You might not notice it but your code is what controls this
from what I read, when checking the checkbox stripe js should automatically set it to off session
not really no
well I can't manually set it either
I doesn't really make sense to use that checkbox at all for Subscriptions
sorry you dumped dozens of lines of code so trying to make sense of what you are doing
no it does not at all, but stripe js puts it there with PaymentElement
I mean it could be useful when the user subscribes to various services
can you remove customerSessionClientSecret: sessionToken,? Does it work without it?
yea it does work actually
okay so it's something weird with that feature. Let me try to repro
but shouldn't it be possible to use it with the secret?
how do you create your CustomerSession?
func CreateCustomerSession(client client.Client, userId string) (string, error) {
customerId, err := GetCustomerId(client, userId)
if err != nil {
return "", err
}
csParam := &stripe.CustomerSessionParams{
Customer: &customerId,
Components: &stripe.CustomerSessionComponentsParams{},
}
csParam.AddExtra("components[payment_element][enabled]", "true")
csParam.AddExtra(
"components[payment_element][features][payment_method_redisplay]",
"enabled",
)
csParam.AddExtra(
"components[payment_element][features][payment_method_save]",
"enabled",
)
csParam.AddExtra(
"components[payment_element][features][payment_method_save_usage]",
"on_session",
)
csParam.AddExtra(
"components[payment_element][features][payment_method_remove]",
"enabled",
)
customerSession, _ := customersession.New(csParam)
return customerSession.ClientSecret, nil
}
oh
that could be it
yup
yeah that doesn't make sense for Subscriptions. Sorry those docs are a mess if you ask me ๐
then it's probably an issue with the docs
hahah yea they are a bit
will change it and see, but maybe it should be put to off_session in the docs? or are subscriptions the only ones that require off_session?
yes I flagged to our Docs team to fix it. And Subscriptions charge async so they do need off_session permissions yes
oh all right I didn't notice that
but the subscriptions work when not checking the box in my case, with the on session
sure but you aren't configuring the payment method properly for future payments
Ultimately that feature doesn't really make sense for Subscriptions and you should remove it I think because it will automatically save the PaymentMethod