javascriptstripe-paymentspayment-gatewaycheckoutstripe-payments-js

Using "client_secret" returned by "'stripe checkout sessions create" API in the Elements Provider causing "Invalid value for elements()" issue


Can the client_secret returned by the stripe checkout sessions create API be used in the options of Elements Provider from "@stripe/react-stripe-js"?

If No, then what should be passed as a clientSecret in the options of Elements Provider, If PaymentElement is being embedded in it which requires the clientSecret in its wrapper Elements component?

If Yes, please suggest why I am still getting the issue even though my clientSecret format is in the correct format and directly copied from the Stripe::Checkout::Session.create API response body.

Following is the exact sample code in which I am getting errors in.

const stripePromise = loadStripe("MY Publishable key");

const ShippingAddress = () => {
  const clientSecret = 'cs_test_a1kvgZUVmZjJgvu49dSFV3HmLzH282TFslODk23jTFrn1buLPnMLstt097_secret_fidwbEhqYWAnPydgaGdgYWFgYScpJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ3dgYWx3YGZxSmtGamh1aWBxbGprJz8nZGlyZHx2J3gl';
   // clientSecret value is coming from the back-end and being set in the useEffect hook.

  return (
      <>
        {clientSecret && (
          <Elements stripe={stripePromise} options={{clientSecret}}>
           <CheckoutForm />
           {/* CheckoutForm component has PaymentElement and LinkAuthenticationElement mounted in it */}
          </Elements>)}
      </>
  );
}

export default ShippingAddress;

The browser dev console is giving me the following error but even in the error itelf, it can be seen that the value is in correct format.

React Router caught the following error during render IntegrationError: Invalid value for elements(): clientSecret should be a client secret of the form ${id}_secret_${secret}.
You specified: cs_test_a1kvgZUVmZjJgvu49dSFV3HmLzH282TFslODk23jTFrn1buLPnMLstt097_secret_fidwbEhqYWAnPydgaGdgYWFgYScpJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ3dgYWx3YGZxSmtGamh1aWBxbGprJz8nZGlyZHx2J3gl.

Please ignore the clientSecret value as it is created from test account api_keys.


Solution

  • Checkout Sessions and the Payment Element are two separate/different integration paths. You should not be using the Checkout Session's client_secret with the Payment Element.

    If you want to use the Payment Element, you can create either a PaymentIntent or SetupIntent and use the corresponding client_secret [0][1] which looks like pi_..._secret_... and seti_..._secret_... respectively.

    I suggest going through the below resources to better understand how to use the Payment Element :

    Note : if you want to collect payment method details before creating the Intent, you can refer to this guide instead : https://stripe.com/docs/payments/accept-a-payment-deferred