You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core 6.0 Web应用集成Stripe支付及触发逻辑改造咨询

在.NET Core 6 Web应用中集成Stripe支付功能

以下是针对需求的完整实现方案,点击Save按钮时将触发发票保存+信用卡支付的完整流程:

1. 安装Stripe.NET SDK

通过NuGet安装适配.NET 6的Stripe官方SDK:

Install-Package Stripe.net -Version 43.0.0 # 选择稳定兼容版本

2. 配置Stripe密钥

在appsettings.json中添加从Stripe控制台获取的密钥信息:

{
  "Stripe": {
    "SecretKey": "sk_test_你的私有密钥",
    "PublishableKey": "pk_test_你的公开密钥",
    "WebhookSecret": "whsec_你的Webhook密钥" // 可选,用于后续异步支付状态通知
  },
  "ConnectionStrings": {
    "DBConnection": "你的数据库连接字符串"
  }
}

3. 修改视图(View)

更新视图引入Stripe支付组件,替换同步表单提交为异步支付流程:

@model SalesInvoiceModel
<h2>Create Invoice</h2>
<!-- 引入Stripe.js -->
<script src="https://js.stripe.com/v3/"></script>
<script>
    // 初始化Stripe实例
    const stripe = Stripe('@Configuration["Stripe:PublishableKey"]');
    const elements = stripe.elements();

    // 渲染信用卡输入组件
    const cardElement = elements.create('card');
    cardElement.mount('#card-element');

    // 处理Save按钮点击事件
    document.getElementById('save-pay-btn').addEventListener('click', async (e) => {
        e.preventDefault();

        // 第一步:提交发票信息到后端创建发票并获取支付凭证
        const invoiceResponse = await fetch('/SalesInvoice/CreateInvoiceAndInitPayment', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]').value
            },
            body: JSON.stringify({
                Id: document.getElementById('Id').value,
                TotalAmount: document.getElementById('TotalAmount').value
            })
        });

        if (!invoiceResponse.ok) {
            alert('发票创建失败,请重试');
            return;
        }

        const paymentData = await invoiceResponse.json();

        // 第二步:唤起Stripe支付界面完成信用卡验证
        const { error, paymentIntent } = await stripe.confirmCardPayment(
            paymentData.clientSecret,
            {
                payment_method: {
                    card: cardElement,
                    billing_details: {
                        name: '客户姓名' // 可根据业务需求从表单获取
                    }
                }
            }
        );

        if (error) {
            alert(`支付失败:${error.message}`);
        } else if (paymentIntent.status === 'succeeded') {
            // 支付成功后跳转至发票列表页
            window.location.href = '/SalesInvoice/InvoiceList';
        }
    });
</script>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()
    @Html.HiddenFor(m => m.Id)
    <div class="form-group">
        <label asp-for="TotalAmount"></label>
        <input asp-for="TotalAmount" class="form-control" id="TotalAmount" readonly />
        <span asp-validation-for="TotalAmount" class="text-danger"></span>
    </div>
    <!-- Stripe信用卡输入区域 -->
    <div class="form-group mt-3">
        <label>信用卡信息</label>
        <div id="card-element" class="form-control"></div>
        <div id="card-errors" role="alert" class="text-danger mt-1"></div>
    </div>
    <br />
    <button type="button" id="save-pay-btn" class="btn btn-primary">Save & Pay</button>
}

4. 更新控制器(Controller)

新增Action处理发票创建+支付初始化逻辑,保留原有数据库操作:

using Stripe;

public class SalesInvoiceController : Controller
{
    private readonly IConfiguration _configuration;

    public SalesInvoiceController(IConfiguration configuration)
    {
        _configuration = configuration;
        // 全局初始化Stripe密钥
        StripeConfiguration.ApiKey = _configuration["Stripe:SecretKey"];
    }

    // 创建发票并生成Stripe支付凭证
    [HttpPost]
    public async Task<IActionResult> CreateInvoiceAndInitPayment(SalesInvoiceModel model)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        int invoiceId = 0;
        // 1. 将发票信息保存到数据库
        using (SqlConnection connection = new SqlConnection(_configuration.GetConnectionString("DBConnection")))
        {
            using (SqlCommand command = new SqlCommand("sp_AddInvoiceDetails", connection))
            {
                command.CommandType = CommandType.StoredProcedure;
                command.Parameters.AddWithValue("@Id", model.Id);
                command.Parameters.AddWithValue("@TotalAmount", model.TotalAmount);
                connection.Open();
                invoiceId = Convert.ToInt32(command.ExecuteScalar());
            }
        }

        // 2. 创建Stripe支付意向(PaymentIntent)
        var paymentOptions = new PaymentIntentCreateOptions
        {
            Amount = (long)(model.TotalAmount * 100), // Stripe金额单位为分
            Currency = "usd", // 按需修改为对应货币,如"cny"
            Metadata = new Dictionary<string, string>
            {
                { "InvoiceId", invoiceId.ToString() } // 关联发票ID,用于后续状态更新
            }
        };

        var paymentService = new PaymentIntentService();
        PaymentIntent paymentIntent = await paymentService.CreateAsync(paymentOptions);

        // 返回支付凭证给前端
        return Json(new { clientSecret = paymentIntent.ClientSecret });
    }

    // 原有CreateInvoice方法(可保留作为无支付场景备用)
    [HttpPost]
    public IActionResult CreateInvoice(SalesInvoiceModel model)
    {
        using (SqlConnection connection = new SqlConnection(_configuration.GetConnectionString("DBConnection")))
        {
            using (SqlCommand command = new SqlCommand("sp_AddInvoiceDetails", connection))
            {
                command.CommandType = CommandType.StoredProcedure;
                command.Parameters.AddWithValue("@Id", model.Id);
                command.Parameters.AddWithValue("@TotalAmount", model.TotalAmount);
                connection.Open();
                int userId = Convert.ToInt32(command.ExecuteScalar());
                TempData["SuccessMessage"] = "Invoice created successfully.";
                return RedirectToAction("InvoiceList", "SalesInvoice");
            }
        }
    }

    // 可选:Stripe Webhook处理(异步更新支付状态)
    [HttpPost]
    public async Task<IActionResult> StripeWebhook()
    {
        var json = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync();
        var stripeEvent = EventUtility.ConstructEvent(
            json,
            Request.Headers["Stripe-Signature"],
            _configuration["Stripe:WebhookSecret"]
        );

        if (stripeEvent.Type == Events.PaymentIntentSucceeded)
        {
            var paymentIntent = stripeEvent.Data.Object as PaymentIntent;
            var invoiceId = int.Parse(paymentIntent.Metadata["InvoiceId"]);

            // 更新数据库中发票的支付状态
            using (SqlConnection connection = new SqlConnection(_configuration.GetConnectionString("DBConnection")))
            {
                using (SqlCommand command = new SqlCommand("sp_UpdateInvoicePaymentStatus", connection))
                {
                    command.CommandType = CommandType.StoredProcedure;
                    command.Parameters.AddWithValue("@InvoiceId", invoiceId);
                    command.Parameters.AddWithValue("@IsPaid", true);
                    connection.Open();
                    command.ExecuteNonQuery();
                }
            }
        }

        return Ok();
    }
}

核心注意事项

  • Stripe金额单位为分,需将TotalAmount乘以100后传入
  • 生产环境必须使用HTTPS协议,否则Stripe支付组件无法正常工作
  • Webhook为可选但推荐配置,用于确保支付状态更新的可靠性(避免前端跳转导致的状态丢失)

内容的提问来源于stack exchange,提问作者Anisha Ramanuj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 20:05:42