Вопрос или проблема
Я следую онлайн-документации Stripe, чтобы создать встроенную форму оплаты для подключенных аккаунтов.
Мой тестовый API-ключ правильно установлен в Program.cs
Этот конечный пункт в моем контроллере в основном прямой из руководства API Stripe, и он с радостью возвращает секрет клиента:
[HttpGet]
[AllowAnonymous]
public ContentResult StripeCheckoutSession()
{
var options = new Stripe.Checkout.SessionCreateOptions
{
LineItems = new List<Stripe.Checkout.SessionLineItemOptions>
{
new Stripe.Checkout.SessionLineItemOptions
{
PriceData = new Stripe.Checkout.SessionLineItemPriceDataOptions
{
Currency = "aud",
ProductData = new Stripe.Checkout.SessionLineItemPriceDataProductDataOptions
{
Name = "Футболка",
},
UnitAmount = 1000,
},
Quantity = 1,
},
},
PaymentIntentData = new Stripe.Checkout.SessionPaymentIntentDataOptions
{
ApplicationFeeAmount = 123,
},
Mode = "payment",
UiMode = "embedded",
ReturnUrl = "abc={CHECKOUT_SESSION_ID}"
};
var requestOptions = new RequestOptions
{
StripeAccount = "acct_12345...";
};
var service = new SessionService();
Session session = service.Create(options, requestOptions);
return Content(JsonConvert.SerializeObject(session.ClientSecret));
}
В шапке моего представления .cshtml я добавил этот элемент скрипта:
<script src="https://js.stripe.com/v3/"></script>
В теле у меня есть этот разметка:
<div id="checkout">
</div>
Также в шапке я скопировал этот javascript из руководства API Stripe.
<script type="text/javascript">
// инициализация Stripe.js
const stripe = Stripe('pk_test_blah...', {
stripeAccount: {{CONNECTED_ACCOUNT_ID}},
});
initialize();
// получение сессии оплаты и извлечение секрета клиента
async function initialize() {
const fetchClientSecret = async () => {
const response = await fetch("/StripeCheckoutSession", {
method: "POST",
});
const { clientSecret } = await response.json();
return clientSecret;
};
// инициализация оплаты
const checkout = await stripe.initEmbeddedCheckout({
fetchClientSecret,
});
// монтирование оплаты
checkout.mount('#checkout');
}
</script>
Обратите внимание, я заменил {{CONNECTED_ACCOUNT_ID}} на ссылку на фактическое значение из модели представления следующим образом:
'@Model.StripeAccountID'
Когда я запускаю проект, ничего не происходит – пустой белый экран. Я наполовину ожидал этого, потому что не вижу, как вызывается initialize(). И я вижу, что он никогда не выполняется.
Поэтому я написал js так, как, по моему мнению, он должен работать следующим образом:
<script type="text/javascript">
// инициализация Stripe.js
const stripe = Stripe('pk_test_blah...', {
stripeAccount: '@Model.StripeAccountID',
});
$(document).ready(function () {
initialize();
})
// получение сессии оплаты и извлечение секрета клиента
async function initialize() {
try {
alert('Начало');
const fetchClientSecret = async () => {
const response = await fetch("StripeCheckoutSession", {
method: "GET",
});
const { clientSecret } = await response.json();
return clientSecret;
};
// инициализация оплаты
alert('Инициализация оплаты');
const checkout = await stripe.initEmbeddedCheckout({
fetchClientSecret,
});
// монтирование оплаты
alert('Завершение монтирования');
checkout.mount('#checkout');
}
catch (err) {
alert(err);
}
}
</script>
Я вижу alert(‘Начало’) и потом alert(‘Завершение монтирования’), но не вижу alert(‘Инициализация оплаты’)
Я также пробовал использовать отдельную функцию с вызовом AJAX для получения секрета клиента. Сама функция работала, но затем инициализация оплаты не сработала.
Что я делаю не так? Может кто-то помочь мне с этим?
Их пример использует index.js + index.html, что будет работать немного иначе, чем MVC/Razor страница. Одна из вещей – асинхронная обработка немного некорректна. Вместо того чтобы оборачивать новый асинхронный метод, попробуйте следующее:
async function initialize() {
try {
alert('Начало');
await fetch("StripeCheckoutSession", {
method: "GET",
headers: {
'Content-Type': 'application/json'
},
}).then (response => {
if (response.ok) {
return response.json();
} else { /* обработка исключения сервера */ }
}).then (data => {
// инициализация оплаты
alert('Инициализация оплаты');
const checkout = await stripe.initEmbeddedCheckout({
data.clientSecret
});
// монтирование оплаты
alert('Завершение монтирования');
checkout.mount('#checkout');
});
} catch (err) {
alert(err);
}
}
Кроме того, включите инструменты отладки браузера и проверьте наличие ошибок в консоли, а также подумайте о том, чтобы установить точки останова в JS, чтобы проверить, все ли вызывается так, как вы ожидаете.
Ответ или решение
Решение проблемы с встроенной платежной формой Stripe в проекте ASP.NET 8 MVC
Введение
При разработке приложений, использующих платежную систему Stripe, разработчики могут столкнуться с рядом проблем, особенно когда речь идет о внедрении форм для проведения платежей. В данном случае мы рассмотрим фрагменты кода из проекта ASP.NET MVC, который не отображает встроенную платежную форму, и предоставим пошаговое руководство по устранению этих неполадок.
Шаг 1: Проверка настроек API
Убедитесь, что ваш тестовый API-ключ правильно настроен в Program.cs
. Это критически важно для успешного взаимодействия с REST API Stripe. Пример настройки:
public class Program
{
public static void Main(string[] args)
{
StripeConfiguration.ApiKey = "sk_test_XXXXXXXXXXXXXXXXXXXX";
// остальная конфигурация
}
}
Шаг 2: Корректное создание сессии
Ваш контроллер, который создает сессию для чекаута, должен быть настроен верно. Убедитесь, что возвращается корректный client_secret
. Проверьте возвращаемый JSON-ответ с клиента:
[HttpGet]
[AllowAnonymous]
public ContentResult StripeCheckoutSession()
{
var options = new Stripe.Checkout.SessionCreateOptions
{
LineItems = new List<Stripe.Checkout.SessionLineItemOptions>
{
new Stripe.Checkout.SessionLineItemOptions
{
PriceData = new Stripe.Checkout.SessionLineItemPriceDataOptions
{
Currency = "aud",
ProductData = new Stripe.Checkout.SessionLineItemPriceDataProductDataOptions
{
Name = "Футболка",
},
UnitAmount = 1000,
},
Quantity = 1,
},
},
Mode = "payment",
PaymentIntentData = new Stripe.Checkout.SessionPaymentIntentDataOptions
{
ApplicationFeeAmount = 123,
},
ReturnUrl = "http://ваш_адрес_возврата",
};
var requestOptions = new RequestOptions
{
StripeAccount = "acct_12345..."
};
var service = new SessionService();
Session session = service.Create(options, requestOptions);
return Content(JsonConvert.SerializeObject(new { clientSecret = session.ClientSecret }));
}
Шаг 3: Обновление JavaScript
Обратите внимание на код JavaScript, который инициализирует Stripe. Первоначальная реализация имеет несколько проблем, включая неявное указание метода GET
вместо POST
. Исправленный код мог бы выглядеть так:
<script type="text/javascript">
const stripe = Stripe('pk_test_blah...', {
stripeAccount: '@Model.StripeAccountID',
});
$(document).ready(function () {
initialize();
});
async function initialize() {
try {
alert('Start');
const response = await fetch("StripeCheckoutSession", {
method: "GET",
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error('Ошибка HTTP: ' + response.status);
}
const { clientSecret } = await response.json();
alert('Init checkout');
const checkout = await stripe.initEmbeddedCheckout({
fetchClientSecret: () => Promise.resolve(clientSecret),
});
alert('Finish mount');
checkout.mount('#checkout');
}
catch (error) {
alert('Ошибка: ' + error.message);
}
}
</script>
Шаг 4: Проверка браузерных инструментов разработчика
При возникновении проблем, связанных с JavaScript и сетевыми запросами, всегда полезно использовать инструменты разработчика в браузере (обычно вызываются клавишей F12
). Обратите внимание на вкладки "Console" и "Network", чтобы:
- Убедиться, что запрос к вашему серверу (
StripeCheckoutSession
) выполняется корректно и возвращает ожидаемый ответ. - Проверить наличие ошибок JavaScript, например, если функция
initialize
не вызывается.
Шаг 5: Проверка разметки
Убедитесь, что HTML разметка корректна и содержит все необходимые элементы:
<div id="checkout"></div>
Заключение
Следуя вышеуказанным шагам и рекомендациям, вы сможете устранить проблемы с интеграцией встроенной платежной формы Stripe в ваш проект ASP.NET MVC. Убедитесь, что все ключевые моменты, касающиеся API-ключей, запросов и инициализации JavaScript, соблюдены. Если возникнут дополнительные проблемы, рассмотрите возможность обращения в службу поддержки Stripe или на их форумы для получения дополнительной помощи.