You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Stripe .NET SDK 48.2.0中Invoice扩展功能失效问题咨询

Stripe .NET SDK 48.2.0 调用Invoice.List时扩展属性无法通过强类型访问的解决方法

在调用Stripe发票服务的List方法时,尝试通过Expand参数一次性获取PaymentIntent(卡品牌、last4位)及Charge相关扩展信息,但使用Stripe .NET SDK 48.2.0时,返回的Invoice对象中没有直接暴露这些扩展属性。即使使用官网推荐的代码(如下),也无法通过invoice.PaymentIntent直接访问:

var invoiceService = new InvoiceService();
var options = new InvoiceListOptions
{
    Limit = 10,
    Expand = new List<string>
    {
        "data.payment_intent",
        "data.payment_intent.payment_method",
        "data.charge",
        "data.charge.payment_method_details"
    }
};

var invoices = invoiceService.List(options);

但在Stripe Shell中执行相同请求,JSON响应里能正常显示扩展的信息。

问题原因

Stripe .NET SDK的强类型模型并不会自动将所有扩展的嵌套资源映射为类的直接属性。对于List接口返回的集合类资源,扩展路径data.*对应的对象会被存储在每个Invoice实例的ExpandedObjects字典中,而非直接生成强类型属性。

解决方案

方法1:通过ExpandedObjects字典访问扩展资源

SDK为每个Stripe对象提供了ExpandedObjects字典,用于存储扩展加载的嵌套资源。可以通过键名(如payment_intentcharge)获取对应的对象,再转换为强类型实例:

var invoiceService = new InvoiceService();
var options = new InvoiceListOptions
{
    Limit = 10,
    Expand = new List<string>
    {
        "data.payment_intent",
        "data.payment_intent.payment_method",
        "data.charge",
        "data.charge.payment_method_details"
    }
};

var invoices = invoiceService.List(options);

foreach (var invoice in invoices.Data)
{
    // 读取扩展的PaymentIntent及关联的PaymentMethod
    if (invoice.ExpandedObjects.TryGetValue("payment_intent", out var piObj))
    {
        var paymentIntent = piObj as PaymentIntent;
        if (paymentIntent != null && paymentIntent.ExpandedObjects.TryGetValue("payment_method", out var pmObj))
        {
            var paymentMethod = pmObj as PaymentMethod;
            if (paymentMethod?.Card != null)
            {
                string cardBrand = paymentMethod.Card.Brand;
                string last4 = paymentMethod.Card.Last4;
                // 业务逻辑处理
            }
        }
    }

    // 读取扩展的Charge及支付方式详情
    if (invoice.ExpandedObjects.TryGetValue("charge", out var chargeObj))
    {
        var charge = chargeObj as Charge;
        if (charge?.PaymentMethodDetails?.Card != null)
        {
            string cardBrand = charge.PaymentMethodDetails.Card.Brand;
            string last4 = charge.PaymentMethodDetails.Card.Last4;
            // 业务逻辑处理
        }
    }
}

方法2:直接解析原始JSON响应

如果需要更灵活的处理,可以获取请求的原始JSON响应,手动解析扩展字段:

var invoiceService = new InvoiceService();
var options = new InvoiceListOptions
{
    Limit = 10,
    Expand = new List<string>
    {
        "data.payment_intent",
        "data.payment_intent.payment_method",
        "data.charge",
        "data.charge.payment_method_details"
    }
};

var requestOptions = new RequestOptions();
var invoices = invoiceService.List(options, requestOptions);

// 获取原始JSON响应内容
string rawResponse = requestOptions.StripeResponse.Content;

// 使用JSON库(如Newtonsoft.Json)解析
var invoiceList = Newtonsoft.Json.JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(rawResponse);
var dataArray = invoiceList["data"] as Newtonsoft.Json.Linq.JArray;

foreach (var invoiceJson in dataArray)
{
    // 提取PaymentIntent中的卡信息
    var paymentIntent = invoiceJson["payment_intent"];
    if (paymentIntent != null)
    {
        string cardBrand = paymentIntent["payment_method"]["card"]["brand"].ToString();
        string last4 = paymentIntent["payment_method"]["card"]["last4"].ToString();
        // 业务逻辑处理
    }

    // 提取Charge中的卡信息
    var charge = invoiceJson["charge"];
    if (charge != null)
    {
        string cardBrand = charge["payment_method_details"]["card"]["brand"].ToString();
        string last4 = charge["payment_method_details"]["card"]["last4"].ToString();
        // 业务逻辑处理
    }
}

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

火山引擎 最新活动