#paulc7053_code
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/1217873911006625833
đ Have more to share? Add more details, code, screenshots, videos, etc. below.
Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.
- paulc7053_api, 2 hours ago, 79 messages
- paulc7053_code, 2 days ago, 114 messages
Hey!
Hello
Was that error cut off a bit in your first message? Our discord form is a bit restrictive on character length
yep
I didnt have enough space
Error: Element confirming payment is "expressCheckout", but stripe.confirmPayment() was not called within the "confirm" event. Please call stripe.confirmPayment() in the "confirm"
There you go
np
Can you show me your current code for submitting this payment with the ECE?
`const handlePaymentButtonClick = async (e) => {
e.preventDefault();
if (!stripe || !elements) {
return;
};
const { error: submitError } = await elements.submit();
if (submitError) {
// setErrorMessage(submitError.message);
return;
};
// create the customer
const stripeCustomerIdRes = await fetch('/api/stripe/findOrCreateCustomer', {
method: 'post',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: 'test@test.com',
}),
});
const stripeCustomerId = (await stripeCustomerIdRes.json()).stripeCustomerId;
// create the subscription
const subscriptionRes = await fetch('/api/stripe/createSubscription', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
priceId: 'price_1OuGSLJ4ILijjURSgay6C1iI',
stripeCustomerId: stripeCustomerId
}),
});
const clientSecret = (await subscriptionRes.json()).clientSecret;
// confirm the payment
const { error } = await stripe.confirmPayment({
elements,
clientSecret,
confirmParams: {
return_url: `${process.env.NEXT_PUBLIC_HOST}/payment-successful`,
},
});
console.log('error', error);
};`
And how are you calling handlePaymentButtonClick? From our express checkout element doc we show that you should do this inside an event for the element
const {error: submitError} = await elements.submit();
if (submitError) {
handleError(submitError);
return;
}
// Create the PaymentIntent and obtain clientSecret
...
const {error} = await stripe.confirmPayment({
// `elements` instance used to create the Express Checkout Element
elements,
// `clientSecret` from the created PaymentIntent
clientSecret,
confirmParams: {
return_url: 'https://example.com/order/123/complete',
},
});
...
});```
Which is the event that the error is referencing
https://docs.stripe.com/elements/express-checkout-element/accept-a-payment?client=html
So are you maybe calling that in an onclick function rather than the event?
like this <Button className="w-[80%] bg-soft-green h-12 rounded-2xl hover:bg-soft-green/80 text-white font-semibold text-lg 2xl:text-2xl" size="large" isDisabled={!showCheckout || !creditCardComplete || !cardExpirationComplete} onClick={(e) => handlePaymentButtonClick(e)} > PURCHASE {getCurrencySymbol(currency)}{totalPrice} </Button>
But this is not the ECE
This is using the elements
(although I have the same implementation for onConfirm for the express checkout)
Similar thing in React:
<div id="checkout-page">
<ExpressCheckoutElement onConfirm={onConfirm} />
{errorMessage && <div>{errorMessage}</div>}
</div>
Sorry, to be more specivic CreditCardElements
<CardNumberElement options={{ style: { base: { fontSize: windowSize.width > 375 ? '18px' : "16px", }, }, }} onChange={handleChange} /> <CardExpiryElement options={{ style: { base: { fontSize: windowSize.width > 375 ? '18px' : "16px", }, }, }} onChange={handleChange} />
Ah gotcha. Do you also have the express checkout element on the page? I see the error message mentions it. You should be able to have both on the page, just want to make sure I understand what you have here
Yes, I also got that on the page
For the card element, I think you are supposed to use confirmCardPayment. confirmPayment is for the PaymentElement or the Express Checkout Element. So I think when you call confirmPayment, Stripe.js is reaching for both but only finds the express checkout element.
Can you try updating your code to use confirmCardPayment instead and see if that helps? https://docs.stripe.com/js/payment_intents/confirm_card_payment
yes 1 sec
where cardElement is import {CardElement } from '@stripe/react-stripe-js'; const cardElement = elements.getElement(CardElement); ?
Because that throws Uncaught (in promise) IntegrationError: Invalid value for confirmCardPayment: payment_method.card should be an object or element. You specified: null.
// confirm the payment const cardElement = elements.getElement(CardElement); const { error } = await stripe.confirmCardPayment(clientSecret,{ payment_method: { card: cardElement, billing_details: { name: 'Jenny Rosen', }, }, });
IIRC you can pass in any of the pieces of the split card element
So you can pass in just the CardExpiryElement and we will find the other two and pull their data
using only the card number element throws "You must collect the security code (CVC) for this card from the cardholder before you can use it. For more information, see https://support.stripe.com/questions/cvc-collection-requirements"
okay, that's weird
Interesting, and I assume that that is despite the CVC being filled out?
that cardElement is always null
yes
Here's the entire event handler, iv it helps you
Sorry, to be clear that method does not need a card element specifically. If you are using split elements any of the individual elements can go where the card element is expected
I also tried with split elements (tried with the card number element), but it also threw an error
Thsi is the error object
{ "type": "invalid_request_error", "message": "You must collect the security code (CVC) for this card from the cardholder before you can use it. For more information, see https://support.stripe.com/questions/cvc-collection-requirements", "payment_intent": { "id": "pi_3OuHmvJ4ILijjURS14QFjw5S", "object": "payment_intent", "amount": 4900, "amount_details": { "tip": {} }, "automatic_payment_methods": null, "canceled_at": null, "cancellation_reason": null, "capture_method": "automatic", "client_secret": "pi_3OuHmvJ4ILijjURS14QFjw5S_secret_McT92qMAbTQuUQ6ZNCZmQKH6E", "confirmation_method": "automatic", "created": 1710436193, "currency": "gbp", "description": "Subscription creation", "last_payment_error": null, "livemode": false, "next_action": null, "payment_method": "pm_1OuHmwJ4ILijjURSThleig3f", "payment_method_configuration_details": null, "payment_method_types": [ "bacs_debit", "card", "link", "paypal" ], "processing": null, "receipt_email": null, "setup_future_usage": "off_session", "shipping": null, "source": null, "status": "requires_confirmation" }, "request_log_url": "https://dashboard.stripe.com/test/logs/req_IHMRGdS3P1d7MM?t=1710436194", "shouldRetry": false }
also the CVV is always valid
o wow...
I was confusing the expiry with CVV
So sorry for that!
Thnaks a lot for the help!