Проект ASP.NET 8 MVC – Встроенный платеж Stripe не работает

Вопрос или проблема

Я следую онлайн-документации Stripe, чтобы создать встроенную форму оплаты для подключенных аккаунтов.

https://docs.stripe.com/connect/direct-charges?platform=web&ui=embedded-form&client=html#mount-checkout

Мой тестовый 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 или на их форумы для получения дополнительной помощи.

Оцените материал
Добавить комментарий

Капча загружается...