#javascript #reactjs #stripe-payments #netlify #netlify-function
#javascript #reactjs #stripe-платежи #netlify #netlify-функция
Вопрос:
Я пытаюсь внедрить платежные намерения Stripe Elements в свое приложение React, используя функции Netlify. Отправка формы оплаты возвращает ошибку: Unhandled Rejection (IntegrationError): Invalid value for stripe.confirmCardPayment intent secret: value should be a client secret of the form ${id}_secret_${secret}. You specified: .
Я вижу значение client_secret в объекте PaymentIntent, поэтому бессерверная функция возвращает client_secret, но я не должен реализовывать его соответствующим образом в клиенте. Если я передаю data.clientSecret
в качестве параметра в stripe.confirmCardPayment
, то мой платеж завершается успешно, но форма элементов не сбрасывается, что указывает мне на наличие проблемы с этой реализацией.
setClientSecret не обновляет состояние clientSecret?
Вот моя функция Netlify:
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
exports.handler = async (event) => {
const paymentObject = JSON.parse(event.body);
const amount = paymentObject.amount;
const donorName = paymentObject.metadata.donorName;
const address = paymentObject.metadata.address;
const city = paymentObject.metadata.city;
const state = paymentObject.metadata.state;
const zip = paymentObject.metadata.zip;
const email = paymentObject.metadata.email
try {
const paymentIntent = await stripe.paymentIntents.create({
amount,
currency: 'usd',
description: 'USS Idaho Donation',
receipt_email: email,
metadata: {
donorName,
address,
city,
state,
zip,
email,
},
});
return {
statusCode: 200,
body: JSON.stringify({
paymentIntent,
clientSecret: paymentIntent.client_secret
})
};
} catch (error) {
console.log({ error });
return {
statusCode: 400,
body: JSON.stringify({ error }),
};
}
};
Функция handleSubmit:
const handleSubmit = async ev => {
ev.preventDefault();
setProcessing(true);
window
.fetch("/.netlify/functions/charge", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
amount,
receipt_email: email,
metadata: {
donorName: donorName,
address: address,
city: city,
state: state,
zip: zip,
email: email
}
}
)
})
.then(res => {
return res.json();
})
.then(data => {
setClientSecret(data.clientSecret)
console.log(`clientSecret: ${clientSecret}`)
const payload = stripe.confirmCardPayment(data.clientSecret, {
payment_method: {
card: elements.getElement(CardElement)
}
});
if (payload.error) {
setError(`Payment failed: ${payload.error.message}`);
setProcessing(false);
} else {
setError(null);
setProcessing(false);
setSucceeded(true);
reset();
}
})
};
Ответ №1:
stripe.confirmCardPayment
Функция возвращает обещание, поэтому вам нужно дождаться разрешения этого обещания, прежде чем обновлять состояние вашего компонента:
- https://stripe.com/docs/js/payment_intents/confirm_card_payment (Прокрутите вниз до раздела «Возврат»)
В вашем коде это будет выглядеть примерно так:
const handleSubmit = async ev => {
ev.preventDefault();
setProcessing(true);
window
.fetch("/.netlify/functions/charge", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
amount,
receipt_email: email,
metadata: {
donorName: donorName,
address: address,
city: city,
state: state,
zip: zip,
email: email
}
}
)
})
.then(res => {
return res.json();
})
.then(data => {
setClientSecret(data.clientSecret);
return stripe.confirmCardPayment(data.clientSecret, {
payment_method: {
card: elements.getElement(CardElement)
}
});
})
.then((paymentResult) => {
if (paymentResult.error) {
setError(`Payment failed: ${payload.error.message}`);
setProcessing(false);
} else {
if (paymentResult.paymentIntent.status === 'succeeded') {
setError(null);
setProcessing(false);
setSucceeded(true);
reset();
}
}
});
};