C# Web Forms集成PayPal Smart Button时购物车总价传入OrderRequest失败
问题根因
- 初始化顺序错位:你将
OrderRequest定义成了类级别的字段初始化器,C#的类字段初始化逻辑早于Page_Load事件执行,这时候给price赋值的代码还没运行,price为空自然传不进值;加上PayPal SDK对金额字段的空值校验是静默忽略不抛错,所以你看不到任何报错提示。 - 金额格式不兼容:你用
String.Format("{0:c}")生成的总价是带本地货币符号(如$、¥)的本地化字符串,PayPal接口的Money.Value字段只接受不带货币符号、固定两位小数、以英文点为小数点的纯数字字符串,带格式化符号的内容就算传进去也会被接口丢弃。
修复方案
- 调整金额生成逻辑
保留页面展示用的带货币符号的格式,单独生成符合PayPal要求的纯数字金额:// 页面展示用的格式化文本,保持原有逻辑 Lbl01.Text = String.Format("{0:c}", cartTotal); // PayPal接口用的金额文本,用固定格式生成避免本地化问题 price = cartTotal.ToString("F2", System.Globalization.CultureInfo.InvariantCulture); - 调整
OrderRequest的初始化时机
不要在类定义时直接初始化OrderRequest对象,先声明空对象,等Page_Load中拿到有效总价之后,再手动构造订单请求实例,把对应金额字段替换成动态值:// 类内字段先声明,不直接初始化 public OrderRequest orderRequest; protected void Page_Load(object sender, EventArgs e) { // 原有购物车总价计算逻辑保持不变 using (ShoppingCartActions usersShoppingCart = new ShoppingCartActions()) { decimal cartTotal = usersShoppingCart.GetTotal(); Lbl01.Text = String.Format("{0:c}", cartTotal); price = cartTotal.ToString("F2", System.Globalization.CultureInfo.InvariantCulture); } // 拿到有效价格后再初始化订单请求 orderRequest = new OrderRequest() { CheckoutPaymentIntent = "CAPTURE", // 原有ApplicationContext配置完全保留 ApplicationContext = new ApplicationContext { BrandName = "EXAMPLE INC", LandingPage = "BILLING", CancelUrl = "https://www.example.com", ReturnUrl = "https://www.example.com", UserAction = "CONTINUE", ShippingPreference = "SET_PROVIDED_ADDRESS" }, PurchaseUnits = new List<PurchaseUnitRequest> { new PurchaseUnitRequest{ ReferenceId = "ReferenceId1", Description = "Description1", CustomId = "CustomId1", SoftDescriptor = "SoftDescriptor1", AmountWithBreakdown = new AmountWithBreakdown { CurrencyCode = Currency, // 总金额必须和下方所有分项加总一致,否则会被校验拦截 Value = (cartTotal + 15 + 5 + 10 - 10).ToString("F2", System.Globalization.CultureInfo.InvariantCulture), AmountBreakdown = new AmountBreakdown { ItemTotal = new Money { CurrencyCode = Currency, Value = price // 此时可以正常取到计算好的购物车总价 }, // 原有运费、处理费、税费、折扣的配置保持不变 Shipping = new Money { CurrencyCode = Currency, Value = "15.00" }, Handling = new Money { CurrencyCode = Currency, Value = "5.00" }, TaxTotal = new Money { CurrencyCode = Currency, Value = "10.00" }, ShippingDiscount = new Money { CurrencyCode = Currency, Value = "10.00" } } }, // 原有Items、ShippingDetail配置保持不变,需要动态替换的商品单价也用同样的格式处理 Items = new List<Item> { new Item { Name = "Product 1", Description = "Product 1 Description", Sku = "Sku1", UnitAmount = new Money { CurrencyCode = Currency, Value = "100.00" // 如果要动态替换成购物车商品单价,同样用固定格式转字符串即可 }, Tax = new Money { CurrencyCode = Currency, Value = "10.00" }, Quantity = "1", Category = "PHYSICAL_GOODS" }, }, ShippingDetail = new ShippingDetail { Name = new Name { FullName = "" }, AddressPortable = new AddressPortable { AddressLine1 = "", AdminArea2 = "", AdminArea1 = "", PostalCode = "", CountryCode = "" } } } } }; } - 额外校验规则:PayPal接口要求
AmountWithBreakdown的顶层总金额,必须严格等于所有分项金额的计算和(商品总金额+运费+处理费+税费-运费折扣),金额对不上也会被接口静默拦截不返回报错。
内容的提问来源于stack exchange,提问作者Arachai
相关产品推荐
相关产品推荐

