Home  >  Article  >  Backend Development  >  The supplied client_secret does not match any associated SetupIntent on this account

The supplied client_secret does not match any associated SetupIntent on this account

王林
王林forward
2024-02-10 14:18:19713browse

提供的 client_secret 与此帐户上的任何关联的 SetupIntent 不匹配

php editor Yuzai edited a concise and clear article to explain the problems that may be encountered during the use of SetupIntent. Among them, one possible error is "The provided client_secret does not match any associated SetupIntent on this account", which may cause the operation to fail. The article explains the cause and solution of this error in simple and clear language, helping readers to quickly solve the problem and improve the efficiency of using SetupIntent.

Question content

I'm trying to link an external bank account to a Stripe connected account. Account types are custom. I successfully created the SetupIntent associated with the connected account (shown below) and received the client key:

params := &stripe.SetupIntentParams{
    AttachToSelf: stripe.Bool(true),
    FlowDirections: stripe.StringSlice([]string{
        *stripe.String(string(stripe.SetupIntentFlowDirectionInbound)),
        *stripe.String(string(stripe.SetupIntentFlowDirectionOutbound)),
    }),
    PaymentMethodOptions: &stripe.SetupIntentPaymentMethodOptionsParams{
        USBankAccount: &stripe.SetupIntentPaymentMethodOptionsUSBankAccountParams{
            FinancialConnections: &stripe.SetupIntentPaymentMethodOptionsUSBankAccountFinancialConnectionsParams{
                Permissions: stripe.StringSlice([]string{*stripe.String("balances"), *stripe.String("payment_method")}),
            },
            VerificationMethod: stripe.String("instant"),
        },
    },
    PaymentMethodTypes: stripe.StringSlice([]string{
        *stripe.String(string(stripe.PaymentMethodTypeUSBankAccount)),
    }),
}

params.SetStripeAccount(connectedId)
resp, err := setupintent.New(params)
if err != nil {
    return nil, fmt.Errorf("failed to setup intent: %w", err)
}

return resp, nil

client_secret is passed to the frontend where we initiate the authorization process to collect banking information to be able to link external accounts.

const publishableKey = process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY || ''
if (!publishableKey) {
    throw new Error('missing stripe publishable key')
}

export default function Page() {
const [clientSecret, setClientSecret] = useState('')
const [showModal, setShowModal] = useState(false)
const [stripeInstance, setStripeInstance] = useState<Stripe | null>(null)
const [linkingBankLoading, setLinkingBankLoading] = useState(false)
    useEffect(() => {
        const loadAndSetStripe = async () => {
            try {
                const loadedStripe = await loadStripe(publishableKey)
                setStripeInstance(loadedStripe)
            } catch (err) {
                console.error('stripe publishable key failed to load', err)
            }
        }

        loadAndSetStripe()
    }, [])

    const linkExternalBank = async () => {
    setLinkingBankLoading(true)

    try {
        const { data } = await linkExternalBankMutation({
            context: {
                headers: { authorization: `Bearer ${accessToken}` },
            },
        })

        if (data?.linkExternalBank.clientSecret) {
            setClientSecret(data.linkExternalBank.clientSecret)
            setShowStripeModal(true)
        }
    } catch (err) {
        console.error('error linking external bank', err)
    } finally {
        setLinkingBankLoading(false)
    }
}

<div className="flex flex-col gap-3 md:flex-row">
                        <AddFinancialConnectionCard
                            linkExternalBank={linkExternalBank}
                            linkingBankLoading={linkingBankLoading}
                        />
                        {showModal && stripeInstance && clientSecret && (
                            <Modal
                                isOpen={showModal}
                                onClose={() => setShowModal(false)}
                                clientSecret={clientSecret}
                                stripe={stripeInstance}
                            />
                        )}
                    </div>
}

Finally in the modal:

interface ModalProps {
    isOpen: boolean
    onClose: () => void
    clientSecret: string
    stripe: Stripe | null
}
export const Modal = ({ isOpen, onClose, clientSecret, stripe }: ModalProps) => {
    if (!isOpen || !stripe || !clientSecret) {
        return null
    }

    return (
        <div className="fixed inset-0 z-50 flex items-center justify-center">
            <div className="w-full max-w-lg rounded bg-white p-4 shadow-lg">
                <button onClick={onClose}>Close</button>
                <Elements stripe={stripe} options={{ clientSecret }}>
                    <BankDetailsForm clientSecret={clientSecret} />
                </Elements>
            </div>
        </div>
    )
}

It tries to load the element and display it quickly for a second before crashing. When I look at the Network tab we get the error: The provided client_secret does not match any associated SetupIntent on this account.

And when I run the curl command to retrieve the SetupIntent, I can successfully see that it is created for the account. I'm confused why this error occurs.

Also, I double-checked the generated API key and the correct key was used.

I've read the Stripe documentation but still have this problem. Also tried hardcoding the client key and making it publishable when generated via Curl, but still got the same error.

Fails when passing client secret to Element component.

Workaround

You are making a server-side call on behalf of a connected account:

params.SetStripeAccount(connectedId)

But on the front end, you are not:

const loadedStripe = await loadStripe(publishableKey)

So Stripe is looking for the intent on your account for confirmation, not the connected account.

You must authenticate everything the same way - in your case this means authenticating your frontend on behalf of the account ID you are connecting from:

const stripePromise = loadStripe('{{PLATFORM_PUBLISHABLE_KEY}}', {
  stripeAccount: '{{CONNECTED_STRIPE_ACCOUNT_ID}}',
});

RelatedStripe Documentation.

The above is the detailed content of The supplied client_secret does not match any associated SetupIntent on this account. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete