PayPal SDK自定义运费实现:Laravel 8按配送类型及各州设置运费计入订单总额
实现方案
你需要做两部分核心修改:一是在Laravel后端预配置州级别的配送规则,二是适配PayPal SDK的配送切换回调实现金额动态叠加,具体实现代码如下:
第一步:Laravel 后端配置配送规则
你可以根据业务复杂度选择用配置文件或者数据表存储运费规则,以下是轻量配置方案示例:
// config/shipping.php 新建运费配置文件 return [ // 键为州缩写,值为对应配送方式的运费 'CA' => [ // 加州 'economy' => 3.99, 'priority' => 7.99, 'pickup' => 0 ], 'NY' => [ // 纽约州 'economy' => 4.99, 'priority' => 8.99, 'pickup' => 0 ], // 按需求补充其他州的规则 ];
在结算页控制器中,根据当前用户收货地址的州,生成对应配送选项传给视图:
// 结算页控制器逻辑 $userState = auth()->user()->shipping_address_state ?? 'CA'; // 取不到地址时默认走加州规则 $shippingOptions = [ [ 'id' => 'SHIP_ECONOMY', 'label' => '经济快递', 'type' => 'SHIPPING', 'selected' => true, 'amount' => [ 'value' => config("shipping.{$userState}.economy"), 'currency_code' => 'USD' ] ], [ 'id' => 'SHIP_PRIORITY', 'label' => '优先邮件', 'type' => 'SHIPPING', 'selected' => false, 'amount' => [ 'value' => config("shipping.{$userState}.priority"), 'currency_code' => 'USD' ] ], [ 'id' => 'SHIP_PICKUP', 'label' => '到店自提', 'type' => 'PICKUP', 'selected' => false, 'amount' => [ 'value' => 0, 'currency_code' => 'USD' ] ] ]; // 把购物车总金额、配送选项传给Blade视图 return view('checkout', compact('cartTotal', 'shippingOptions'));
第二步:修改PayPal JS代码适配动态运费
你原有代码的问题是默认不会叠加运费,也没有监听配送选项切换事件,修改后的代码如下:
// 从Blade获取基础数据 const cartTotal = parseFloat("{{ $cartTotal }}"); const shippingOptions = @json($shippingOptions); // 初始化默认选中的运费 let selectedShippingFee = parseFloat(shippingOptions.find(opt => opt.selected).amount.value); paypal.Buttons({ createOrder: function(data, actions) { return actions.order.create({ purchase_units: [{ amount: { value: (cartTotal + selectedShippingFee).toFixed(2), // 总金额=商品金额+运费 currency_code: "USD", breakdown: { // 新增金额明细,PayPal会展示对应类目 item_total: { value: cartTotal.toFixed(2), currency_code: "USD" }, shipping: { value: selectedShippingFee.toFixed(2), currency_code: "USD" } } }, shipping: { options: shippingOptions // 直接使用后端生成的配送选项 } }] }); }, // 监听用户切换配送选项的事件,动态更新金额 onShippingChange: function(data, actions) { const newShippingOpt = data.shipping_options.find(opt => opt.selected); selectedShippingFee = parseFloat(newShippingOpt.amount.value); // 调用补丁接口更新订单金额 return actions.order.patch([ { op: 'replace', path: '/purchase_units/0/amount', value: { value: (cartTotal + selectedShippingFee).toFixed(2), currency_code: "USD", breakdown: { item_total: { value: cartTotal.toFixed(2), currency_code: "USD" }, shipping: { value: selectedShippingFee.toFixed(2), currency_code: "USD" } } } } ]); }, onApprove: function(data, actions) { return actions.order.capture().then(function(details) { // 这里必须把交易数据传给Laravel后端做二次校验:根据用户实际选择的配送方式、收货州重新计算总金额,和PayPal返回的交易金额比对一致后再标记订单支付成功 alert('交易完成,付款人:' + details.payer.name.given_name); // 后续补充跳转到订单成功页等逻辑 }); } }).render('#paypal-button-container');
内容的提问来源于stack exchange,提问作者D.T
相关产品推荐
相关产品推荐

