ソースを参照

Merge branch 'llp_yunfeixian' into dev

llp 2 日 前
コミット
28f756ee77
39 ファイル変更1236 行追加122 行削除
  1. 82 80
      bootstrap/cache/services.php
  2. 1 0
      bootstrap/providers.php
  3. 1 0
      composer.json
  4. 37 0
      packages/Longyi/Gift/src/Database/Migrations/2026_08_11_000003_add_invoiced_fields_to_orders_table.php
  5. 6 2
      packages/Longyi/Gift/src/Repositories/CustomInvoiceRepository.php
  6. 15 11
      packages/Longyi/Gift/src/Repositories/CustomOrderRepository.php
  7. 28 0
      packages/Longyi/Member/src/Database/Migrations/2026_08_10_000000_add_previous_expire_date_to_member_log_table.php
  8. 41 26
      packages/Longyi/Member/src/Listeners/OrderPlacedHandler.php
  9. 107 0
      packages/Longyi/Member/src/Listeners/VipRevokeHandler.php
  10. 2 0
      packages/Longyi/Member/src/Models/MemberLog.php
  11. 3 1
      packages/Longyi/Member/src/Providers/EventServiceProvider.php
  12. 10 0
      packages/Longyi/ShippingInsurance/src/Config/acl.php
  13. 11 0
      packages/Longyi/ShippingInsurance/src/Config/admin-menu.php
  14. 38 0
      packages/Longyi/ShippingInsurance/src/Database/Migrations/2026_08_08_000000_add_shipping_insurance_to_cart_table.php
  15. 32 0
      packages/Longyi/ShippingInsurance/src/Database/Migrations/2026_08_08_000001_add_shipping_insurance_meta_to_cart_table.php
  16. 26 0
      packages/Longyi/ShippingInsurance/src/Database/Migrations/2026_08_08_000002_add_use_shipping_insurance_to_cart_table.php
  17. 32 0
      packages/Longyi/ShippingInsurance/src/Database/Migrations/2026_08_08_000003_add_shipping_insurance_type_value_to_cart_table.php
  18. 29 0
      packages/Longyi/ShippingInsurance/src/Database/Migrations/2026_08_11_000000_add_shipping_insurance_to_orders_table.php
  19. 29 0
      packages/Longyi/ShippingInsurance/src/Database/Migrations/2026_08_11_000001_add_shipping_insurance_to_invoices_table.php
  20. 29 0
      packages/Longyi/ShippingInsurance/src/Database/Migrations/2026_08_11_000002_add_shipping_insurance_invoiced_to_orders_table.php
  21. 65 0
      packages/Longyi/ShippingInsurance/src/Http/Controllers/Admin/ShippingInsuranceController.php
  22. 42 0
      packages/Longyi/ShippingInsurance/src/Http/Controllers/Shop/ShippingInsuranceController.php
  23. 77 0
      packages/Longyi/ShippingInsurance/src/Listeners/ShippingInsuranceHandler.php
  24. 28 0
      packages/Longyi/ShippingInsurance/src/Providers/EventServiceProvider.php
  25. 49 0
      packages/Longyi/ShippingInsurance/src/Providers/ShippingInsuranceServiceProvider.php
  26. 27 0
      packages/Longyi/ShippingInsurance/src/Resources/lang/en/app.php
  27. 27 0
      packages/Longyi/ShippingInsurance/src/Resources/lang/zh_CN/app.php
  28. 102 0
      packages/Longyi/ShippingInsurance/src/Resources/views/admin/index.blade.php
  29. 89 0
      packages/Longyi/ShippingInsurance/src/Resources/views/components/shipping-insurance-cartsummary.blade.php
  30. 11 0
      packages/Longyi/ShippingInsurance/src/Routes/admin-routes.php
  31. 9 0
      packages/Longyi/ShippingInsurance/src/Routes/shop-routes.php
  32. 44 0
      packages/Longyi/ShippingInsurance/src/Services/ShippingInsuranceService.php
  33. 42 0
      packages/Webkul/BagistoApi/src/Dto/CartData.php
  34. 5 0
      packages/Webkul/BagistoApi/src/Dto/SaveCheckoutCartInput.php
  35. 5 2
      packages/Webkul/BagistoApi/src/Providers/BagistoApiServiceProvider.php
  36. 32 0
      packages/Webkul/BagistoApi/src/State/SaveCheckoutCartProcessor.php
  37. 4 0
      packages/Webkul/BagistoApi/src/Transformers/ExpressOrderResource.php
  38. 4 0
      packages/Webkul/Sales/src/Transformers/OrderResource.php
  39. 15 0
      packages/Webkul/Shop/src/Http/Resources/CartResource.php

+ 82 - 80
bootstrap/cache/services.php

@@ -60,46 +60,47 @@
     56 => 'Longyi\\RewardPoints\\Providers\\RewardPointsServiceProvider',
     57 => 'Longyi\\Member\\Providers\\MemberServiceProvider',
     58 => 'Longyi\\Gift\\Providers\\GiftServiceProvider',
-    59 => 'Longyi\\Pay\\AwxAfterpay\\Providers\\AwxAfterpayServiceProvider',
-    60 => 'Longyi\\Pay\\AwxKlarna\\Providers\\AwxKlarnaServiceProvider',
-    61 => 'Longyi\\Pay\\Applepay\\Providers\\ApplepayServiceProvider',
-    62 => 'Longyi\\Pay\\Airwallex\\Providers\\AirwallexServiceProvider',
-    63 => 'Longyi\\Pay\\Afterpay\\Providers\\AfterpayServiceProvider',
-    64 => 'Longyi\\Pay\\Klarna\\Providers\\KlarnaServiceProvider',
-    65 => 'Webkul\\Attribute\\Providers\\AttributeServiceProvider',
-    66 => 'Webkul\\BookingProduct\\Providers\\BookingProductServiceProvider',
-    67 => 'Webkul\\CMS\\Providers\\CMSServiceProvider',
-    68 => 'Webkul\\CartRule\\Providers\\CartRuleServiceProvider',
-    69 => 'Webkul\\CatalogRule\\Providers\\CatalogRuleServiceProvider',
-    70 => 'Webkul\\Category\\Providers\\CategoryServiceProvider',
-    71 => 'Webkul\\Checkout\\Providers\\CheckoutServiceProvider',
-    72 => 'Webkul\\Core\\Providers\\CoreServiceProvider',
-    73 => 'Webkul\\Core\\Providers\\EnvValidatorServiceProvider',
-    74 => 'Webkul\\Customer\\Providers\\CustomerServiceProvider',
-    75 => 'Webkul\\DataGrid\\Providers\\DataGridServiceProvider',
-    76 => 'Webkul\\DataTransfer\\Providers\\DataTransferServiceProvider',
-    77 => 'Webkul\\DebugBar\\Providers\\DebugBarServiceProvider',
-    78 => 'Webkul\\FPC\\Providers\\FPCServiceProvider',
-    79 => 'Webkul\\GDPR\\Providers\\GDPRServiceProvider',
-    80 => 'Webkul\\Installer\\Providers\\InstallerServiceProvider',
-    81 => 'Webkul\\Inventory\\Providers\\InventoryServiceProvider',
-    82 => 'Webkul\\MagicAI\\Providers\\MagicAIServiceProvider',
-    83 => 'Webkul\\Marketing\\Providers\\MarketingServiceProvider',
-    84 => 'Webkul\\Notification\\Providers\\NotificationServiceProvider',
-    85 => 'Webkul\\Payment\\Providers\\PaymentServiceProvider',
-    86 => 'Webkul\\Paypal\\Providers\\PaypalServiceProvider',
-    87 => 'Webkul\\Product\\Providers\\ProductServiceProvider',
-    88 => 'Webkul\\Rule\\Providers\\RuleServiceProvider',
-    89 => 'Webkul\\Sales\\Providers\\SalesServiceProvider',
-    90 => 'Webkul\\Shipping\\Providers\\ShippingServiceProvider',
-    91 => 'Webkul\\Shop\\Providers\\ShopServiceProvider',
-    92 => 'Webkul\\Sitemap\\Providers\\SitemapServiceProvider',
-    93 => 'Webkul\\SocialLogin\\Providers\\SocialLoginServiceProvider',
-    94 => 'Webkul\\SocialShare\\Providers\\SocialShareServiceProvider',
-    95 => 'Webkul\\Tax\\Providers\\TaxServiceProvider',
-    96 => 'Webkul\\Theme\\Providers\\ThemeServiceProvider',
-    97 => 'Webkul\\User\\Providers\\UserServiceProvider',
-    98 => 'Webkul\\BagistoApi\\Providers\\BagistoApiServiceProvider',
+    59 => 'Longyi\\ShippingInsurance\\Providers\\ShippingInsuranceServiceProvider',
+    60 => 'Longyi\\Pay\\AwxAfterpay\\Providers\\AwxAfterpayServiceProvider',
+    61 => 'Longyi\\Pay\\AwxKlarna\\Providers\\AwxKlarnaServiceProvider',
+    62 => 'Longyi\\Pay\\Applepay\\Providers\\ApplepayServiceProvider',
+    63 => 'Longyi\\Pay\\Airwallex\\Providers\\AirwallexServiceProvider',
+    64 => 'Longyi\\Pay\\Afterpay\\Providers\\AfterpayServiceProvider',
+    65 => 'Longyi\\Pay\\Klarna\\Providers\\KlarnaServiceProvider',
+    66 => 'Webkul\\Attribute\\Providers\\AttributeServiceProvider',
+    67 => 'Webkul\\BookingProduct\\Providers\\BookingProductServiceProvider',
+    68 => 'Webkul\\CMS\\Providers\\CMSServiceProvider',
+    69 => 'Webkul\\CartRule\\Providers\\CartRuleServiceProvider',
+    70 => 'Webkul\\CatalogRule\\Providers\\CatalogRuleServiceProvider',
+    71 => 'Webkul\\Category\\Providers\\CategoryServiceProvider',
+    72 => 'Webkul\\Checkout\\Providers\\CheckoutServiceProvider',
+    73 => 'Webkul\\Core\\Providers\\CoreServiceProvider',
+    74 => 'Webkul\\Core\\Providers\\EnvValidatorServiceProvider',
+    75 => 'Webkul\\Customer\\Providers\\CustomerServiceProvider',
+    76 => 'Webkul\\DataGrid\\Providers\\DataGridServiceProvider',
+    77 => 'Webkul\\DataTransfer\\Providers\\DataTransferServiceProvider',
+    78 => 'Webkul\\DebugBar\\Providers\\DebugBarServiceProvider',
+    79 => 'Webkul\\FPC\\Providers\\FPCServiceProvider',
+    80 => 'Webkul\\GDPR\\Providers\\GDPRServiceProvider',
+    81 => 'Webkul\\Installer\\Providers\\InstallerServiceProvider',
+    82 => 'Webkul\\Inventory\\Providers\\InventoryServiceProvider',
+    83 => 'Webkul\\MagicAI\\Providers\\MagicAIServiceProvider',
+    84 => 'Webkul\\Marketing\\Providers\\MarketingServiceProvider',
+    85 => 'Webkul\\Notification\\Providers\\NotificationServiceProvider',
+    86 => 'Webkul\\Payment\\Providers\\PaymentServiceProvider',
+    87 => 'Webkul\\Paypal\\Providers\\PaypalServiceProvider',
+    88 => 'Webkul\\Product\\Providers\\ProductServiceProvider',
+    89 => 'Webkul\\Rule\\Providers\\RuleServiceProvider',
+    90 => 'Webkul\\Sales\\Providers\\SalesServiceProvider',
+    91 => 'Webkul\\Shipping\\Providers\\ShippingServiceProvider',
+    92 => 'Webkul\\Shop\\Providers\\ShopServiceProvider',
+    93 => 'Webkul\\Sitemap\\Providers\\SitemapServiceProvider',
+    94 => 'Webkul\\SocialLogin\\Providers\\SocialLoginServiceProvider',
+    95 => 'Webkul\\SocialShare\\Providers\\SocialShareServiceProvider',
+    96 => 'Webkul\\Tax\\Providers\\TaxServiceProvider',
+    97 => 'Webkul\\Theme\\Providers\\ThemeServiceProvider',
+    98 => 'Webkul\\User\\Providers\\UserServiceProvider',
+    99 => 'Webkul\\BagistoApi\\Providers\\BagistoApiServiceProvider',
   ),
   'eager' => 
   array (
@@ -145,46 +146,47 @@
     39 => 'Longyi\\RewardPoints\\Providers\\RewardPointsServiceProvider',
     40 => 'Longyi\\Member\\Providers\\MemberServiceProvider',
     41 => 'Longyi\\Gift\\Providers\\GiftServiceProvider',
-    42 => 'Longyi\\Pay\\AwxAfterpay\\Providers\\AwxAfterpayServiceProvider',
-    43 => 'Longyi\\Pay\\AwxKlarna\\Providers\\AwxKlarnaServiceProvider',
-    44 => 'Longyi\\Pay\\Applepay\\Providers\\ApplepayServiceProvider',
-    45 => 'Longyi\\Pay\\Airwallex\\Providers\\AirwallexServiceProvider',
-    46 => 'Longyi\\Pay\\Afterpay\\Providers\\AfterpayServiceProvider',
-    47 => 'Longyi\\Pay\\Klarna\\Providers\\KlarnaServiceProvider',
-    48 => 'Webkul\\Attribute\\Providers\\AttributeServiceProvider',
-    49 => 'Webkul\\BookingProduct\\Providers\\BookingProductServiceProvider',
-    50 => 'Webkul\\CMS\\Providers\\CMSServiceProvider',
-    51 => 'Webkul\\CartRule\\Providers\\CartRuleServiceProvider',
-    52 => 'Webkul\\CatalogRule\\Providers\\CatalogRuleServiceProvider',
-    53 => 'Webkul\\Category\\Providers\\CategoryServiceProvider',
-    54 => 'Webkul\\Checkout\\Providers\\CheckoutServiceProvider',
-    55 => 'Webkul\\Core\\Providers\\CoreServiceProvider',
-    56 => 'Webkul\\Core\\Providers\\EnvValidatorServiceProvider',
-    57 => 'Webkul\\Customer\\Providers\\CustomerServiceProvider',
-    58 => 'Webkul\\DataGrid\\Providers\\DataGridServiceProvider',
-    59 => 'Webkul\\DataTransfer\\Providers\\DataTransferServiceProvider',
-    60 => 'Webkul\\DebugBar\\Providers\\DebugBarServiceProvider',
-    61 => 'Webkul\\FPC\\Providers\\FPCServiceProvider',
-    62 => 'Webkul\\GDPR\\Providers\\GDPRServiceProvider',
-    63 => 'Webkul\\Installer\\Providers\\InstallerServiceProvider',
-    64 => 'Webkul\\Inventory\\Providers\\InventoryServiceProvider',
-    65 => 'Webkul\\MagicAI\\Providers\\MagicAIServiceProvider',
-    66 => 'Webkul\\Marketing\\Providers\\MarketingServiceProvider',
-    67 => 'Webkul\\Notification\\Providers\\NotificationServiceProvider',
-    68 => 'Webkul\\Payment\\Providers\\PaymentServiceProvider',
-    69 => 'Webkul\\Paypal\\Providers\\PaypalServiceProvider',
-    70 => 'Webkul\\Product\\Providers\\ProductServiceProvider',
-    71 => 'Webkul\\Rule\\Providers\\RuleServiceProvider',
-    72 => 'Webkul\\Sales\\Providers\\SalesServiceProvider',
-    73 => 'Webkul\\Shipping\\Providers\\ShippingServiceProvider',
-    74 => 'Webkul\\Shop\\Providers\\ShopServiceProvider',
-    75 => 'Webkul\\Sitemap\\Providers\\SitemapServiceProvider',
-    76 => 'Webkul\\SocialLogin\\Providers\\SocialLoginServiceProvider',
-    77 => 'Webkul\\SocialShare\\Providers\\SocialShareServiceProvider',
-    78 => 'Webkul\\Tax\\Providers\\TaxServiceProvider',
-    79 => 'Webkul\\Theme\\Providers\\ThemeServiceProvider',
-    80 => 'Webkul\\User\\Providers\\UserServiceProvider',
-    81 => 'Webkul\\BagistoApi\\Providers\\BagistoApiServiceProvider',
+    42 => 'Longyi\\ShippingInsurance\\Providers\\ShippingInsuranceServiceProvider',
+    43 => 'Longyi\\Pay\\AwxAfterpay\\Providers\\AwxAfterpayServiceProvider',
+    44 => 'Longyi\\Pay\\AwxKlarna\\Providers\\AwxKlarnaServiceProvider',
+    45 => 'Longyi\\Pay\\Applepay\\Providers\\ApplepayServiceProvider',
+    46 => 'Longyi\\Pay\\Airwallex\\Providers\\AirwallexServiceProvider',
+    47 => 'Longyi\\Pay\\Afterpay\\Providers\\AfterpayServiceProvider',
+    48 => 'Longyi\\Pay\\Klarna\\Providers\\KlarnaServiceProvider',
+    49 => 'Webkul\\Attribute\\Providers\\AttributeServiceProvider',
+    50 => 'Webkul\\BookingProduct\\Providers\\BookingProductServiceProvider',
+    51 => 'Webkul\\CMS\\Providers\\CMSServiceProvider',
+    52 => 'Webkul\\CartRule\\Providers\\CartRuleServiceProvider',
+    53 => 'Webkul\\CatalogRule\\Providers\\CatalogRuleServiceProvider',
+    54 => 'Webkul\\Category\\Providers\\CategoryServiceProvider',
+    55 => 'Webkul\\Checkout\\Providers\\CheckoutServiceProvider',
+    56 => 'Webkul\\Core\\Providers\\CoreServiceProvider',
+    57 => 'Webkul\\Core\\Providers\\EnvValidatorServiceProvider',
+    58 => 'Webkul\\Customer\\Providers\\CustomerServiceProvider',
+    59 => 'Webkul\\DataGrid\\Providers\\DataGridServiceProvider',
+    60 => 'Webkul\\DataTransfer\\Providers\\DataTransferServiceProvider',
+    61 => 'Webkul\\DebugBar\\Providers\\DebugBarServiceProvider',
+    62 => 'Webkul\\FPC\\Providers\\FPCServiceProvider',
+    63 => 'Webkul\\GDPR\\Providers\\GDPRServiceProvider',
+    64 => 'Webkul\\Installer\\Providers\\InstallerServiceProvider',
+    65 => 'Webkul\\Inventory\\Providers\\InventoryServiceProvider',
+    66 => 'Webkul\\MagicAI\\Providers\\MagicAIServiceProvider',
+    67 => 'Webkul\\Marketing\\Providers\\MarketingServiceProvider',
+    68 => 'Webkul\\Notification\\Providers\\NotificationServiceProvider',
+    69 => 'Webkul\\Payment\\Providers\\PaymentServiceProvider',
+    70 => 'Webkul\\Paypal\\Providers\\PaypalServiceProvider',
+    71 => 'Webkul\\Product\\Providers\\ProductServiceProvider',
+    72 => 'Webkul\\Rule\\Providers\\RuleServiceProvider',
+    73 => 'Webkul\\Sales\\Providers\\SalesServiceProvider',
+    74 => 'Webkul\\Shipping\\Providers\\ShippingServiceProvider',
+    75 => 'Webkul\\Shop\\Providers\\ShopServiceProvider',
+    76 => 'Webkul\\Sitemap\\Providers\\SitemapServiceProvider',
+    77 => 'Webkul\\SocialLogin\\Providers\\SocialLoginServiceProvider',
+    78 => 'Webkul\\SocialShare\\Providers\\SocialShareServiceProvider',
+    79 => 'Webkul\\Tax\\Providers\\TaxServiceProvider',
+    80 => 'Webkul\\Theme\\Providers\\ThemeServiceProvider',
+    81 => 'Webkul\\User\\Providers\\UserServiceProvider',
+    82 => 'Webkul\\BagistoApi\\Providers\\BagistoApiServiceProvider',
   ),
   'deferred' => 
   array (

+ 1 - 0
bootstrap/providers.php

@@ -17,6 +17,7 @@ return [
     Longyi\RewardPoints\Providers\RewardPointsServiceProvider::class,
     Longyi\Member\Providers\MemberServiceProvider::class,
     Longyi\Gift\Providers\GiftServiceProvider::class,
+    Longyi\ShippingInsurance\Providers\ShippingInsuranceServiceProvider::class,
     Longyi\Pay\AwxAfterpay\Providers\AwxAfterpayServiceProvider::class,
     Longyi\Pay\AwxKlarna\Providers\AwxKlarnaServiceProvider::class,
     Longyi\Pay\Applepay\Providers\ApplepayServiceProvider::class,

+ 1 - 0
composer.json

@@ -84,6 +84,7 @@
             "Longyi\\RewardPoints\\": "packages/Longyi/RewardPoints/src/",
             "Longyi\\Member\\": "packages/Longyi/Member/src/",
             "Longyi\\Gift\\": "packages/Longyi/Gift/src/",
+            "Longyi\\ShippingInsurance\\": "packages/Longyi/ShippingInsurance/src/",
             "Longyi\\Pay\\Airwallex\\": "packages/Longyi/Pay/Airwallex/src/",
             "Longyi\\Pay\\Applepay\\": "packages/Longyi/Pay/Applepay/src/",
             "Longyi\\Pay\\AwxKlarna\\": "packages/Longyi/Pay/AwxKlarna/src/",

+ 37 - 0
packages/Longyi/Gift/src/Database/Migrations/2026_08_11_000003_add_invoiced_fields_to_orders_table.php

@@ -0,0 +1,37 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::table('orders', function (Blueprint $table) {
+            $table->decimal('giftcard_invoiced', 10, 2)->default(0)->nullable()->after('base_giftcard_amount');
+            $table->decimal('base_giftcard_invoiced', 10, 2)->default(0)->nullable()->after('giftcard_invoiced');
+            $table->decimal('vip_plus_invoiced', 10, 2)->default(0)->nullable()->after('base_giftcard_invoiced');
+            $table->decimal('base_vip_plus_invoiced', 10, 2)->default(0)->nullable()->after('vip_plus_invoiced');
+            $table->decimal('vip_discount_invoiced', 10, 2)->default(0)->nullable()->after('base_vip_plus_invoiced');
+            $table->decimal('base_vip_discount_invoiced', 10, 2)->default(0)->nullable()->after('vip_discount_invoiced');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::table('orders', function (Blueprint $table) {
+            $table->dropColumn([
+                'giftcard_invoiced', 'base_giftcard_invoiced',
+                'vip_plus_invoiced', 'base_vip_plus_invoiced',
+                'vip_discount_invoiced', 'base_vip_discount_invoiced',
+            ]);
+        });
+    }
+};

+ 6 - 2
packages/Longyi/Gift/src/Repositories/CustomInvoiceRepository.php

@@ -18,6 +18,7 @@ class CustomInvoiceRepository extends BaseInvoiceRepository
         $invoice->base_giftcard_amount = $invoice->base_giftcard_amount = 0;
         $invoice->vip_plus_amount = $invoice->base_vip_plus_amount = 0;
         $invoice->vip_discount_amount = $invoice->base_vip_discount_amount = 0;
+        $invoice->shipping_insurance_amount = $invoice->base_shipping_insurance_amount = 0;
 
         foreach ($invoice->items as $item) {
             $invoice->tax_amount += $item->tax_amount;
@@ -51,6 +52,9 @@ class CustomInvoiceRepository extends BaseInvoiceRepository
         $invoice->vip_discount_amount += $invoice->order->vip_discount_amount;
         $invoice->base_vip_discount_amount += $invoice->order->base_vip_discount_amount;
 
+        $invoice->shipping_insurance_amount += $invoice->order->shipping_insurance_amount;
+        $invoice->base_shipping_insurance_amount += $invoice->order->base_shipping_insurance_amount;
+
         if ($invoice->order->shipping_tax_amount) {
             $invoice->shipping_tax_amount = $invoice->order->shipping_tax_amount;
 
@@ -85,8 +89,8 @@ class CustomInvoiceRepository extends BaseInvoiceRepository
             }
         }
 
-        $invoice->grand_total = $invoice->sub_total + $invoice->tax_amount + $invoice->shipping_amount - $invoice->discount_amount - $invoice->giftcard_amount + $invoice->vip_plus_amount - $invoice->vip_discount_amount;
-        $invoice->base_grand_total = $invoice->base_sub_total + $invoice->base_tax_amount + $invoice->base_shipping_amount - $invoice->base_discount_amount - $invoice->base_giftcard_amount + $invoice->base_vip_plus_amount - $invoice->base_vip_discount_amount;
+        $invoice->grand_total = $invoice->sub_total + $invoice->tax_amount + $invoice->shipping_amount - $invoice->discount_amount - $invoice->giftcard_amount + $invoice->vip_plus_amount - $invoice->vip_discount_amount + $invoice->shipping_insurance_amount;
+        $invoice->base_grand_total = $invoice->base_sub_total + $invoice->base_tax_amount + $invoice->base_shipping_amount - $invoice->base_discount_amount - $invoice->base_giftcard_amount + $invoice->base_vip_plus_amount - $invoice->base_vip_discount_amount + $invoice->base_shipping_insurance_amount;
 
         $invoice->save();
         return $invoice;

+ 15 - 11
packages/Longyi/Gift/src/Repositories/CustomOrderRepository.php

@@ -13,9 +13,10 @@ class CustomOrderRepository extends BaseOrderRepository
         $order->shipping_invoiced = $order->base_shipping_invoiced = 0;
         $order->tax_amount_invoiced = $order->base_tax_amount_invoiced = 0;
         $order->discount_invoiced = $order->base_discount_invoiced = 0;
-        $order->giftcard_amount = $order->base_giftcard_amount = 0;
-        $order->vip_plus_amount = $order->base_vip_plus_amount = 0;
-        $order->vip_discount_amount = $order->base_vip_discount_amount = 0;
+        $order->giftcard_invoiced = $order->base_giftcard_invoiced = 0;
+        $order->vip_plus_invoiced = $order->base_vip_plus_invoiced = 0;
+        $order->vip_discount_invoiced = $order->base_vip_discount_invoiced = 0;
+        $order->shipping_insurance_invoiced = $order->base_shipping_insurance_invoiced = 0;
 
         foreach ($order->invoices as $invoice) {
             $order->sub_total_invoiced += $invoice->sub_total;
@@ -30,18 +31,21 @@ class CustomOrderRepository extends BaseOrderRepository
             $order->discount_invoiced += $invoice->discount_amount;
             $order->base_discount_invoiced += $invoice->base_discount_amount;
 
-            $order->giftcard_amount += $invoice->giftcard_amount;
-            $order->base_giftcard_amount += $invoice->base_giftcard_amount;
+            $order->giftcard_invoiced += $invoice->giftcard_amount;
+            $order->base_giftcard_invoiced += $invoice->base_giftcard_amount;
 
-            $order->vip_plus_amount += $invoice->vip_plus_amount;
-            $order->base_vip_plus_amount += $invoice->base_vip_plus_amount;
+            $order->vip_plus_invoiced += $invoice->vip_plus_amount;
+            $order->base_vip_plus_invoiced += $invoice->base_vip_plus_amount;
 
-            $order->vip_discount_amount += $invoice->vip_discount_amount;
-            $order->base_vip_discount_amount += $invoice->base_vip_discount_amount;
+            $order->vip_discount_invoiced += $invoice->vip_discount_amount;
+            $order->base_vip_discount_invoiced += $invoice->base_vip_discount_amount;
+
+            $order->shipping_insurance_invoiced += $invoice->shipping_insurance_amount;
+            $order->base_shipping_insurance_invoiced += $invoice->base_shipping_insurance_amount;
         }
 
-        $order->grand_total_invoiced = $order->sub_total_invoiced + $order->shipping_invoiced + $order->tax_amount_invoiced - $order->discount_invoiced - $order->giftcard_amount + $order->vip_plus_amount - $order->vip_discount_amount;
-        $order->base_grand_total_invoiced = $order->base_sub_total_invoiced + $order->base_shipping_invoiced + $order->base_tax_amount_invoiced - $order->base_discount_invoiced - $order->base_giftcard_amount + $order->base_vip_plus_amount - $order->base_vip_discount_amount;
+        $order->grand_total_invoiced = $order->sub_total_invoiced + $order->shipping_invoiced + $order->tax_amount_invoiced - $order->discount_invoiced - $order->giftcard_invoiced + $order->vip_plus_invoiced - $order->vip_discount_invoiced + $order->shipping_insurance_invoiced;
+        $order->base_grand_total_invoiced = $order->base_sub_total_invoiced + $order->base_shipping_invoiced + $order->base_tax_amount_invoiced - $order->base_discount_invoiced - $order->base_giftcard_invoiced + $order->base_vip_plus_invoiced - $order->base_vip_discount_invoiced + $order->base_shipping_insurance_invoiced;
 
         // order refund total
         $order->sub_total_refunded = $order->base_sub_total_refunded = 0;

+ 28 - 0
packages/Longyi/Member/src/Database/Migrations/2026_08_10_000000_add_previous_expire_date_to_member_log_table.php

@@ -0,0 +1,28 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::table('member_log', function (Blueprint $table) {
+            $table->dateTime('previous_expire_date')->nullable()->after('expirationdate')->comment('购买前的VIP过期时间');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::table('member_log', function (Blueprint $table) {
+            $table->dropColumn('previous_expire_date');
+        });
+    }
+};

+ 41 - 26
packages/Longyi/Member/src/Listeners/OrderPlacedHandler.php

@@ -3,8 +3,6 @@
 namespace Longyi\Member\Listeners;
 
 use Longyi\Member\Models\MemberLog;
-use Webkul\Paypal\Payment\SmartButton;
-use Webkul\Sales\Repositories\OrderTransactionRepository;
 use Webkul\Customer\Models\Customer;
 use Carbon\Carbon;
 
@@ -12,52 +10,69 @@ class OrderPlacedHandler
 {
     protected const MEMBER_DISCOUNT_AMOUNT = 19.9;
 
-
     protected const VIP_EXTENSION_DAYS = 180;
-    /**
-     * Create a new listener instance.
-     *
-     * @return void
-     */
-    public function __construct(
-        protected SmartButton $smartButton,
-        protected OrderTransactionRepository $orderTransactionRepository
-    ) {}
 
     /**
-     * Apply member discount to cart.
+     * 订单支付完成后激活 VIP 会员
+     * 监听 sales.invoice.save.after 事件
      *
-     * @param  \Webkul\Checkout\Models\Cart  $cart
+     * @param  \Webkul\Sales\Models\Invoice  $invoice
      * @return void
      */
-    public function afterPlaceOrder($order)
+    public function afterInvoicePaid($invoice)
     {
-        if (!$order || !$order->customer_id) {
+        // 只处理已支付的发票
+        if ($invoice->state !== 'paid') {
             return;
         }
-        if (!$order->vip_plus_amount || $order->vip_plus_amount <= 0) {
+
+        $order = $invoice->order;
+
+        if (! $order || ! $order->customer_id) {
             return;
         }
+
+        if (! $order->vip_plus_amount || $order->vip_plus_amount <= 0) {
+            return;
+        }
+
+        // 防止重复激活:检查是否已为该订单激活过 VIP
+        $existingLog = MemberLog::where('order_id', $order->increment_id)
+            ->where('type', 1)
+            ->first();
+
+        if ($existingLog) {
+            return;
+        }
+
         $customer = Customer::find($order->customer_id);
-        if (!$customer) {
+
+        if (! $customer) {
             return;
         }
-        $currentExpireDate = $customer->vip_expire_date ? Carbon::parse($customer->vip_expire_date) : now();
+
+        $previousExpireDate = $customer->vip_expire_date;
+        $currentExpireDate = $customer->vip_expire_date
+            ? Carbon::parse($customer->vip_expire_date)
+            : now();
+
         if ($currentExpireDate->isPast()) {
             $newExpireDate = now()->addDays(self::VIP_EXTENSION_DAYS);
         } else {
             $newExpireDate = $currentExpireDate->addDays(self::VIP_EXTENSION_DAYS);
         }
+
         $customer->vip_expire_date = $newExpireDate;
         $customer->save();
-        // 记录
+
+        // 记录购买日志(含购买前的过期时间,用于退款时回退)
         MemberLog::create([
-            'customer_id' => $order->customer_id,
-            'order_id' => $order->increment_id,
-            'amount' => self::MEMBER_DISCOUNT_AMOUNT,
-            'type' => 1,
-            'expirationdate' => $newExpireDate
+            'customer_id'          => $order->customer_id,
+            'order_id'             => $order->increment_id,
+            'amount'               => self::MEMBER_DISCOUNT_AMOUNT,
+            'type'                 => 1,
+            'previous_expire_date' => $previousExpireDate,
+            'expirationdate'       => $newExpireDate,
         ]);
     }
-
 }

+ 107 - 0
packages/Longyi/Member/src/Listeners/VipRevokeHandler.php

@@ -0,0 +1,107 @@
+<?php
+
+namespace Longyi\Member\Listeners;
+
+use Longyi\Member\Models\MemberLog;
+use Webkul\Customer\Models\Customer;
+use Carbon\Carbon;
+
+class VipRevokeHandler
+{
+    /**
+     * 订单取消时撤销 VIP 会员
+     * 监听 sales.order.cancel.after 事件
+     *
+     * @param  \Webkul\Sales\Models\Order  $order
+     * @return void
+     */
+    public function onOrderCancel($order)
+    {
+        $this->revokeVip($order, 2);
+    }
+
+    /**
+     * 订单退款时撤销 VIP 会员
+     * 监听 sales.refund.save.after 事件
+     *
+     * @param  \Webkul\Sales\Models\Refund  $refund
+     * @return void
+     */
+    public function onRefund($refund)
+    {
+        $order = $refund->order;
+
+        if (! $order || ! $order->customer_id) {
+            return;
+        }
+
+        // 只有包含 VIP Plus 费用的订单才处理
+        if (! $order->vip_plus_amount || $order->vip_plus_amount <= 0) {
+            return;
+        }
+
+        // 检查是否为全额退款(退款金额 >= 订单总额),避免部分退款误撤销
+        if (bccomp((string) $refund->base_grand_total, (string) $order->base_grand_total, 2) < 0) {
+            return;
+        }
+
+        $this->revokeVip($order, 3);
+    }
+
+    /**
+     * 执行 VIP 撤销逻辑
+     *
+     * @param  \Webkul\Sales\Models\Order  $order
+     * @param  int  $revokeType  2=取消撤销, 3=退款撤销
+     * @return void
+     */
+    protected function revokeVip($order, int $revokeType)
+    {
+        if (! $order || ! $order->customer_id) {
+            return;
+        }
+
+        if (! $order->vip_plus_amount || $order->vip_plus_amount <= 0) {
+            return;
+        }
+
+        // 防止重复撤销
+        $existingRevokeLog = MemberLog::where('order_id', $order->increment_id)
+            ->whereIn('type', [2, 3])
+            ->first();
+
+        if ($existingRevokeLog) {
+            return;
+        }
+
+        // 查找该订单的激活记录
+        $activationLog = MemberLog::where('order_id', $order->increment_id)
+            ->where('type', 1)
+            ->first();
+
+        if (! $activationLog) {
+            // 没有激活记录,说明可能是在支付之前就取消了,无需处理
+            return;
+        }
+
+        $customer = Customer::find($order->customer_id);
+
+        if (! $customer) {
+            return;
+        }
+
+        // 恢复到购买前的 VIP 过期时间
+        $customer->vip_expire_date = $activationLog->previous_expire_date;
+        $customer->save();
+
+        // 记录撤销日志
+        MemberLog::create([
+            'customer_id'          => $order->customer_id,
+            'order_id'             => $order->increment_id,
+            'amount'               => $activationLog->amount,
+            'type'                 => $revokeType,
+            'previous_expire_date' => $activationLog->expirationdate,
+            'expirationdate'       => $activationLog->previous_expire_date,
+        ]);
+    }
+}

+ 2 - 0
packages/Longyi/Member/src/Models/MemberLog.php

@@ -21,6 +21,7 @@ class MemberLog extends Model implements MemberLogContract
         'order_id',
         'type',
         'amount',
+        'previous_expire_date',
         'expirationdate'
     ];
 
@@ -34,6 +35,7 @@ class MemberLog extends Model implements MemberLogContract
         'order_id' => 'integer',
         'type' => 'integer',
         'amount' => 'decimal:2',
+        'previous_expire_date' => 'date',
         'expirationdate' => 'date',
     ];
 }

+ 3 - 1
packages/Longyi/Member/src/Providers/EventServiceProvider.php

@@ -27,7 +27,9 @@ class EventServiceProvider extends ServiceProvider
         Event::listen('bagisto.admin.sales.order.view.giftcard.before', function($viewRenderEventManager) {
             $viewRenderEventManager->addTemplate('member::sales.orders.view');
         });
-        Event::listen('checkout.order.save.after', 'Longyi\Member\Listeners\OrderPlacedHandler@afterPlaceOrder');
+        Event::listen('sales.invoice.save.after', 'Longyi\Member\Listeners\OrderPlacedHandler@afterInvoicePaid');
+        Event::listen('sales.order.cancel.after', 'Longyi\Member\Listeners\VipRevokeHandler@onOrderCancel');
+        Event::listen('sales.refund.save.after', 'Longyi\Member\Listeners\VipRevokeHandler@onRefund');
         Event::listen('bagisto.shop.customers.account.orders.view.information.discount.after', 'Longyi\Member\Listeners\OrderViewHandler@renderMemberInfo');
     }
 }

+ 10 - 0
packages/Longyi/ShippingInsurance/src/Config/acl.php

@@ -0,0 +1,10 @@
+<?php
+
+return [
+    [
+        'key'   => 'shipping_insurance',
+        'name'  => 'shippinginsurance::app.admin.acl-title',
+        'route' => 'admin.shipping_insurance.index',
+        'sort'  => 102
+    ]
+];

+ 11 - 0
packages/Longyi/ShippingInsurance/src/Config/admin-menu.php

@@ -0,0 +1,11 @@
+<?php
+
+return [
+    [
+        'key'   => 'shipping_insurance',
+        'name'  => 'shippinginsurance::app.admin.menu-title',
+        'route' => 'admin.shipping_insurance.index',
+        'sort'  => 102,
+        'icon'  => 'icon-settings',
+    ]
+];

+ 38 - 0
packages/Longyi/ShippingInsurance/src/Database/Migrations/2026_08_08_000000_add_shipping_insurance_to_cart_table.php

@@ -0,0 +1,38 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::table('cart', function (Blueprint $table) {
+            if (! Schema::hasColumn('cart', 'shipping_insurance_amount')) {
+                $table->decimal('shipping_insurance_amount', 12, 4)->default(0)->after('vip_discount_amount');
+            }
+            if (! Schema::hasColumn('cart', 'base_shipping_insurance_amount')) {
+                $table->decimal('base_shipping_insurance_amount', 12, 4)->default(0)->after('shipping_insurance_amount');
+            }
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::table('cart', function (Blueprint $table) {
+            if (Schema::hasColumn('cart', 'shipping_insurance_amount')) {
+                $table->dropColumn('shipping_insurance_amount');
+            }
+            if (Schema::hasColumn('cart', 'base_shipping_insurance_amount')) {
+                $table->dropColumn('base_shipping_insurance_amount');
+            }
+        });
+    }
+};

+ 32 - 0
packages/Longyi/ShippingInsurance/src/Database/Migrations/2026_08_08_000001_add_shipping_insurance_meta_to_cart_table.php

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    public function up(): void
+    {
+        Schema::table('cart', function (Blueprint $table) {
+            if (! Schema::hasColumn('cart', 'shipping_insurance_name')) {
+                $table->string('shipping_insurance_name', 255)->default('')->after('base_shipping_insurance_amount');
+            }
+            if (! Schema::hasColumn('cart', 'shipping_insurance_enabled')) {
+                $table->boolean('shipping_insurance_enabled')->default(false)->after('shipping_insurance_name');
+            }
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('cart', function (Blueprint $table) {
+            if (Schema::hasColumn('cart', 'shipping_insurance_enabled')) {
+                $table->dropColumn('shipping_insurance_enabled');
+            }
+            if (Schema::hasColumn('cart', 'shipping_insurance_name')) {
+                $table->dropColumn('shipping_insurance_name');
+            }
+        });
+    }
+};

+ 26 - 0
packages/Longyi/ShippingInsurance/src/Database/Migrations/2026_08_08_000002_add_use_shipping_insurance_to_cart_table.php

@@ -0,0 +1,26 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    public function up(): void
+    {
+        Schema::table('cart', function (Blueprint $table) {
+            if (! Schema::hasColumn('cart', 'use_shipping_insurance')) {
+                $table->boolean('use_shipping_insurance')->default(false)->after('shipping_insurance_enabled');
+            }
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('cart', function (Blueprint $table) {
+            if (Schema::hasColumn('cart', 'use_shipping_insurance')) {
+                $table->dropColumn('use_shipping_insurance');
+            }
+        });
+    }
+};

+ 32 - 0
packages/Longyi/ShippingInsurance/src/Database/Migrations/2026_08_08_000003_add_shipping_insurance_type_value_to_cart_table.php

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    public function up(): void
+    {
+        Schema::table('cart', function (Blueprint $table) {
+            if (! Schema::hasColumn('cart', 'shipping_insurance_type')) {
+                $table->string('shipping_insurance_type', 20)->default('fixed')->after('shipping_insurance_enabled');
+            }
+            if (! Schema::hasColumn('cart', 'shipping_insurance_value')) {
+                $table->decimal('shipping_insurance_value', 12, 4)->default(0)->after('shipping_insurance_type');
+            }
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('cart', function (Blueprint $table) {
+            if (Schema::hasColumn('cart', 'shipping_insurance_value')) {
+                $table->dropColumn('shipping_insurance_value');
+            }
+            if (Schema::hasColumn('cart', 'shipping_insurance_type')) {
+                $table->dropColumn('shipping_insurance_type');
+            }
+        });
+    }
+};

+ 29 - 0
packages/Longyi/ShippingInsurance/src/Database/Migrations/2026_08_11_000000_add_shipping_insurance_to_orders_table.php

@@ -0,0 +1,29 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::table('orders', function (Blueprint $table) {
+            $table->decimal('shipping_insurance_amount', 12, 4)->default(0)->nullable()->after('base_vip_discount_amount');
+            $table->decimal('base_shipping_insurance_amount', 12, 4)->default(0)->nullable()->after('shipping_insurance_amount');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::table('orders', function (Blueprint $table) {
+            $table->dropColumn(['shipping_insurance_amount', 'base_shipping_insurance_amount']);
+        });
+    }
+};

+ 29 - 0
packages/Longyi/ShippingInsurance/src/Database/Migrations/2026_08_11_000001_add_shipping_insurance_to_invoices_table.php

@@ -0,0 +1,29 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::table('invoices', function (Blueprint $table) {
+            $table->decimal('shipping_insurance_amount', 12, 4)->default(0)->nullable()->after('base_vip_discount_amount');
+            $table->decimal('base_shipping_insurance_amount', 12, 4)->default(0)->nullable()->after('shipping_insurance_amount');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::table('invoices', function (Blueprint $table) {
+            $table->dropColumn(['shipping_insurance_amount', 'base_shipping_insurance_amount']);
+        });
+    }
+};

+ 29 - 0
packages/Longyi/ShippingInsurance/src/Database/Migrations/2026_08_11_000002_add_shipping_insurance_invoiced_to_orders_table.php

@@ -0,0 +1,29 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::table('orders', function (Blueprint $table) {
+            $table->decimal('shipping_insurance_invoiced', 12, 4)->default(0)->nullable()->after('base_shipping_insurance_amount');
+            $table->decimal('base_shipping_insurance_invoiced', 12, 4)->default(0)->nullable()->after('shipping_insurance_invoiced');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::table('orders', function (Blueprint $table) {
+            $table->dropColumn(['shipping_insurance_invoiced', 'base_shipping_insurance_invoiced']);
+        });
+    }
+};

+ 65 - 0
packages/Longyi/ShippingInsurance/src/Http/Controllers/Admin/ShippingInsuranceController.php

@@ -0,0 +1,65 @@
+<?php
+
+namespace Longyi\ShippingInsurance\Http\Controllers\Admin;
+
+use Illuminate\Http\RedirectResponse;
+use Illuminate\View\View;
+use Webkul\Admin\Http\Controllers\Controller;
+use Webkul\Core\Repositories\CoreConfigRepository;
+
+class ShippingInsuranceController extends Controller
+{
+    /**
+     * Create a new controller instance.
+     */
+    public function __construct(
+        protected CoreConfigRepository $coreConfigRepository,
+    ) {
+    }
+
+    /**
+     * Display the shipping insurance configuration.
+     */
+    public function index(): View
+    {
+        $config = [
+            'enable' => (bool) core()->getConfigData('sales.checkout.shipping_insurance.enable'),
+            'name'   => core()->getConfigData('sales.checkout.shipping_insurance.name') ?: '运费险',
+            'type'   => core()->getConfigData('sales.checkout.shipping_insurance.type') ?: 'fixed',
+            'value'  => core()->getConfigData('sales.checkout.shipping_insurance.value') ?: 0,
+        ];
+
+        return view('shippinginsurance::admin.index', compact('config'));
+    }
+
+    /**
+     * Store the shipping insurance configuration.
+     */
+    public function store(): RedirectResponse
+    {
+        $validated = request()->validate([
+            'enable' => 'nullable|boolean',
+            'name'   => 'nullable|string|max:50',
+            'type'   => 'required|in:fixed,percentage',
+            'value'  => 'required|numeric|min:0',
+        ]);
+
+        $values = [
+            'sales.checkout.shipping_insurance.enable' => ($validated['enable'] ?? false) ? 1 : 0,
+            'sales.checkout.shipping_insurance.name'   => $validated['name'] ?? '运费险',
+            'sales.checkout.shipping_insurance.type'   => $validated['type'],
+            'sales.checkout.shipping_insurance.value'  => $validated['value'],
+        ];
+
+        foreach ($values as $code => $value) {
+            $this->coreConfigRepository->updateOrCreate(
+                ['code' => $code],
+                ['value' => $value]
+            );
+        }
+
+        session()->flash('success', trans('shippinginsurance::app.admin.save-success'));
+
+        return redirect()->route('admin.shipping_insurance.index');
+    }
+}

+ 42 - 0
packages/Longyi/ShippingInsurance/src/Http/Controllers/Shop/ShippingInsuranceController.php

@@ -0,0 +1,42 @@
+<?php
+
+namespace Longyi\ShippingInsurance\Http\Controllers\Shop;
+
+use Illuminate\Http\JsonResponse;
+use Webkul\Checkout\Facades\Cart;
+use Webkul\Shop\Http\Controllers\Controller;
+use Webkul\Shop\Http\Resources\CartResource;
+
+class ShippingInsuranceController extends Controller
+{
+    /**
+     * Toggle shipping insurance on/off for the current cart.
+     */
+    public function toggle(): JsonResponse
+    {
+        $cart = Cart::getCart();
+
+        if (! $cart) {
+            return response()->json([
+                'message' => '购物车为空',
+            ], 404);
+        }
+
+        $useInsurance = ! $cart->use_shipping_insurance;
+
+        $cart->update([
+            'use_shipping_insurance' => $useInsurance,
+        ]);
+
+        // Recalculate cart totals with/without insurance
+        Cart::collectTotals();
+
+        return response()->json([
+            'data'    => new CartResource(Cart::getCart()),
+            'message' => $useInsurance
+                ? trans('shippinginsurance::app.shop.enabled')
+                : trans('shippinginsurance::app.shop.disabled'),
+            'cartId'  => $cart->id,
+        ]);
+    }
+}

+ 77 - 0
packages/Longyi/ShippingInsurance/src/Listeners/ShippingInsuranceHandler.php

@@ -0,0 +1,77 @@
+<?php
+
+namespace Longyi\ShippingInsurance\Listeners;
+
+class ShippingInsuranceHandler
+{
+    /**
+     * Apply shipping insurance to the cart.
+     *
+     * IMPORTANT: This handler modifies the $cart object passed by reference
+     * from the 'checkout.cart.collect.totals.after' event. It must operate on
+     * the same object instance (not re-fetch from DB) so that Cart::getCart()
+     * returns the updated values.
+     *
+     * @param  \Webkul\Checkout\Models\Cart  $cart
+     * @return void
+     */
+    public function applyShippingInsurance($cart): void
+    {
+        if (! $cart) {
+            return;
+        }
+
+        // Check if shipping insurance is enabled in admin configuration
+        if (! (bool) core()->getConfigData('sales.checkout.shipping_insurance.enable')) {
+            $cart->shipping_insurance_amount      = 0;
+            $cart->base_shipping_insurance_amount = 0;
+            $cart->shipping_insurance_name        = '';
+            $cart->shipping_insurance_enabled     = false;
+            $cart->shipping_insurance_type        = 'fixed';
+            $cart->shipping_insurance_value       = 0;
+            $cart->use_shipping_insurance         = false;
+            $cart->save();
+
+            return;
+        }
+
+        // Get insurance configuration
+        $name  = core()->getConfigData('sales.checkout.shipping_insurance.name') ?: '运费险';
+        $type  = core()->getConfigData('sales.checkout.shipping_insurance.type') ?: 'fixed';
+        $value = (float) core()->getConfigData('sales.checkout.shipping_insurance.value');
+
+        // Always write config metadata to the cart
+        $cart->shipping_insurance_name    = $name;
+        $cart->shipping_insurance_enabled = true;
+        $cart->shipping_insurance_type    = $type;
+        $cart->shipping_insurance_value   = $value;
+
+        // Only apply insurance if the customer has opted in AND value > 0
+        if (! $cart->use_shipping_insurance || $value <= 0) {
+            $cart->shipping_insurance_amount      = 0;
+            $cart->base_shipping_insurance_amount = 0;
+            $cart->save();
+
+            return;
+        }
+
+        // Calculate insurance premium
+        if ($type === 'percentage') {
+            $insuranceAmount = round($cart->sub_total * ($value / 100), 2);
+        } else {
+            $insuranceAmount = $value;
+        }
+
+        // Convert to base currency for base fields
+        $baseInsuranceAmount = core()->convertToBasePrice($insuranceAmount);
+
+        $cart->shipping_insurance_amount      = $insuranceAmount;
+        $cart->base_shipping_insurance_amount = $baseInsuranceAmount;
+
+        // Add insurance to grand total (respect currency distinction)
+        $cart->grand_total      = round($cart->grand_total + $insuranceAmount, 2);
+        $cart->base_grand_total = round($cart->base_grand_total + $baseInsuranceAmount, 2);
+
+        $cart->save();
+    }
+}

+ 28 - 0
packages/Longyi/ShippingInsurance/src/Providers/EventServiceProvider.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace Longyi\ShippingInsurance\Providers;
+
+use Illuminate\Support\Facades\Event;
+use Illuminate\Support\ServiceProvider;
+
+class EventServiceProvider extends ServiceProvider
+{
+    /**
+     * Bootstrap services.
+     */
+    public function boot()
+    {
+        // 运费险计算:监听购物车总计收集事件
+        Event::listen('checkout.cart.collect.totals.after', 'Longyi\ShippingInsurance\Listeners\ShippingInsuranceHandler@applyShippingInsurance');
+
+        // 购物车页面:在 tax 之后、grand total 之前显示运费险
+        Event::listen('bagisto.shop.checkout.cart.summary.tax.after', function ($viewRenderEventManager) {
+            $viewRenderEventManager->addTemplate('shippinginsurance::components.shipping-insurance-cartsummary');
+        });
+
+        // 结账页面:在 tax 之后、grand total 之前显示运费险
+        Event::listen('bagisto.shop.checkout.onepage.summary.tax.after', function ($viewRenderEventManager) {
+            $viewRenderEventManager->addTemplate('shippinginsurance::components.shipping-insurance-cartsummary');
+        });
+    }
+}

+ 49 - 0
packages/Longyi/ShippingInsurance/src/Providers/ShippingInsuranceServiceProvider.php

@@ -0,0 +1,49 @@
+<?php
+
+namespace Longyi\ShippingInsurance\Providers;
+
+use Illuminate\Support\Facades\Event;
+use Illuminate\Support\ServiceProvider;
+
+class ShippingInsuranceServiceProvider extends ServiceProvider
+{
+    /**
+     * Register services.
+     */
+    public function register(): void
+    {
+        $this->registerConfig();
+    }
+
+    /**
+     * Bootstrap services.
+     */
+    public function boot(): void
+    {
+        $this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
+
+        $this->loadRoutesFrom(__DIR__ . '/../Routes/admin-routes.php');
+
+        $this->loadRoutesFrom(__DIR__ . '/../Routes/shop-routes.php');
+
+        $this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'shippinginsurance');
+
+        $this->loadViewsFrom(__DIR__ . '/../Resources/views', 'shippinginsurance');
+
+        $this->app->register(EventServiceProvider::class);
+    }
+
+    /**
+     * Register package config.
+     */
+    protected function registerConfig(): void
+    {
+        $this->mergeConfigFrom(
+            dirname(__DIR__) . '/Config/admin-menu.php', 'menu.admin'
+        );
+
+        $this->mergeConfigFrom(
+            dirname(__DIR__) . '/Config/acl.php', 'acl'
+        );
+    }
+}

+ 27 - 0
packages/Longyi/ShippingInsurance/src/Resources/lang/en/app.php

@@ -0,0 +1,27 @@
+<?php
+
+return [
+    'shop' => [
+        'label'         => 'Shipping Insurance',
+        'description'   => 'Protect your shipment with insurance coverage',
+        'opt-in'        => 'Add Insurance',
+        'opt-out'       => 'Remove Insurance',
+        'enabled'       => 'Shipping insurance added',
+        'disabled'      => 'Shipping insurance removed',
+    ],
+    'admin' => [
+        'title'        => 'Shipping Insurance',
+        'menu-title'   => 'Shipping Insurance',
+        'acl-title'    => 'Shipping Insurance',
+        'enable'       => 'Enable Shipping Insurance',
+        'enable-info'  => 'When enabled, the shipping insurance item will be displayed on the cart page',
+        'name'         => 'Insurance Name',
+        'type'         => 'Charge Type',
+        'fixed'        => 'Fixed Amount',
+        'percentage'   => 'Percentage',
+        'value'        => 'Amount / Rate',
+        'value-info'   => 'For fixed amount, enter the value (e.g. 5). For percentage, enter the rate (e.g. 1 for 1%)',
+        'save'         => 'Save Configuration',
+        'save-success' => 'Shipping insurance configuration saved successfully!',
+    ],
+];

+ 27 - 0
packages/Longyi/ShippingInsurance/src/Resources/lang/zh_CN/app.php

@@ -0,0 +1,27 @@
+<?php
+
+return [
+    'shop' => [
+        'label'         => '运费险',
+        'description'   => '为您提供运费险保障,退货时可获得赔付',
+        'opt-in'        => '投保运费险',
+        'opt-out'       => '取消投保',
+        'enabled'       => '已投保运费险',
+        'disabled'      => '已取消运费险',
+    ],
+    'admin' => [
+        'title'        => '运费险配置',
+        'menu-title'   => '运费险',
+        'acl-title'    => '运费险',
+        'enable'       => '启用运费险',
+        'enable-info'  => '开启后购物车页面将展示运费险项',
+        'name'         => '运费险名称',
+        'type'         => '计费类型',
+        'fixed'        => '固定金额',
+        'percentage'   => '百分比',
+        'value'        => '金额 / 比例',
+        'value-info'   => '固定金额模式请输入金额(如 5),百分比模式请输入比例(如 1 表示 1%)',
+        'save'         => '保存配置',
+        'save-success' => '运费险配置保存成功!',
+    ],
+];

ファイルの差分が大きいため隠しています
+ 102 - 0
packages/Longyi/ShippingInsurance/src/Resources/views/admin/index.blade.php


+ 89 - 0
packages/Longyi/ShippingInsurance/src/Resources/views/components/shipping-insurance-cartsummary.blade.php

@@ -0,0 +1,89 @@
+{!! view_render_event('bagisto.shop.checkout.cart.summary.shipping_insurance.before') !!}
+
+<!-- Shipping Insurance Component -->
+<v-shipping-insurance :cart="cart"></v-shipping-insurance>
+
+@push('scripts')
+    <script type="text/x-template" id="v-shipping-insurance-template">
+        <div>
+            <!-- Insurance option row - always shown if enabled -->
+            <div
+                class="flex justify-between items-center border-b border-dashed border-gray-300 pb-[15px]"
+                v-if="cart.shipping_insurance && cart.shipping_insurance.enabled"
+            >
+                <label class="flex items-center gap-2.5 cursor-pointer">
+                    <input
+                        type="checkbox"
+                        :checked="cart.shipping_insurance.use_insurance"
+                        @change="toggle"
+                        class="w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 cursor-pointer"
+                    >
+                    <span class="text-base max-sm:text-xs text-[#6E6E6E]">
+                        @{{ label }}
+                    </span>
+                </label>
+
+                <p
+                    class="text-base max-sm:text-xs font-medium"
+                    v-if="cart.shipping_insurance.use_insurance && cart.shipping_insurance.amount > 0"
+                >
+                    +@{{ cart.shipping_insurance.formatted_amount }}
+                </p>
+            </div>
+        </div>
+    </script>
+
+    <script type="module">
+        app.component('v-shipping-insurance', {
+            template: '#v-shipping-insurance-template',
+
+            props: ['cart'],
+
+            computed: {
+                label() {
+                    const insurance = this.cart.shipping_insurance;
+                    const name = insurance.name || '{{ __('shippinginsurance::app.shop.label') }}';
+                    const type = insurance.type || 'fixed';
+                    const value = parseFloat(insurance.value || 0);
+
+                    if (type === 'percentage' && value > 0) {
+                        return `${name} ( ${value}% )`;
+                    }
+
+                    if (type === 'fixed' && value > 0) {
+                        return `${name} ( ${insurance.formatted_value || insurance.formatted_amount} )`;
+                    }
+
+                    return name;
+                }
+            },
+
+            methods: {
+                toggle() {
+                    this.$axios.post('{{ route('shop.api.checkout.cart.shipping_insurance.toggle') }}')
+                        .then((response) => {
+                            // Refresh cart data via parent's getCart method
+                            // Works for both cart page (shop.api.checkout.cart.index) 
+                            // and checkout page (shop.checkout.onepage.summary)
+                            if (typeof this.$parent.getCart === 'function') {
+                                this.$parent.getCart();
+                            }
+
+                            this.$emitter.emit('add-flash', {
+                                type: 'success',
+                                message: response.data.message,
+                            });
+                        })
+                        .catch((error) => {
+                            this.$emitter.emit('add-flash', {
+                                type: 'error',
+                                message: error.response?.data?.message || 'Error',
+                            });
+                        });
+                },
+            },
+        });
+    </script>
+@endpush
+
+{!! view_render_event('bagisto.shop.checkout.cart.summary.shipping_insurance.after') !!}

+ 11 - 0
packages/Longyi/ShippingInsurance/src/Routes/admin-routes.php

@@ -0,0 +1,11 @@
+<?php
+
+use Illuminate\Support\Facades\Route;
+use Longyi\ShippingInsurance\Http\Controllers\Admin\ShippingInsuranceController;
+
+Route::group(['middleware' => ['web', 'admin'], 'prefix' => 'admin/shipping-insurance'], function () {
+    Route::controller(ShippingInsuranceController::class)->group(function () {
+        Route::get('', 'index')->name('admin.shipping_insurance.index');
+        Route::post('', 'store')->name('admin.shipping_insurance.store');
+    });
+});

+ 9 - 0
packages/Longyi/ShippingInsurance/src/Routes/shop-routes.php

@@ -0,0 +1,9 @@
+<?php
+
+use Illuminate\Support\Facades\Route;
+use Longyi\ShippingInsurance\Http\Controllers\Shop\ShippingInsuranceController;
+
+Route::group(['prefix' => 'api', 'middleware' => ['api','web']], function () {
+    Route::post('cart/shipping-insurance/toggle', [ShippingInsuranceController::class, 'toggle'])
+        ->name('shop.api.checkout.cart.shipping_insurance.toggle');
+});

+ 44 - 0
packages/Longyi/ShippingInsurance/src/Services/ShippingInsuranceService.php

@@ -0,0 +1,44 @@
+<?php
+
+namespace Longyi\ShippingInsurance\Services;
+
+use Webkul\Checkout\Facades\Cart;
+
+class ShippingInsuranceService
+{
+    /**
+     * 启用运费险
+     */
+    public function activate(): void
+    {
+        $cart = Cart::getCart();
+
+        if (! $cart) {
+            throw new \Exception('Cart not found.');
+        }
+
+        $cart->update([
+            'use_shipping_insurance' => true,
+        ]);
+
+        Cart::collectTotals();
+    }
+
+    /**
+     * 移除运费险
+     */
+    public function remove(): void
+    {
+        $cart = Cart::getCart();
+
+        if (! $cart) {
+            throw new \Exception('Cart not found.');
+        }
+
+        $cart->update([
+            'use_shipping_insurance' => false,
+        ]);
+
+        Cart::collectTotals();
+    }
+}

+ 42 - 0
packages/Webkul/BagistoApi/src/Dto/CartData.php

@@ -150,6 +150,38 @@ class CartData
     #[ApiProperty(description: 'VIP Plus expiration date')]
     public ?string $vipExpireDate = null;
 
+    #[Groups(['query', 'mutation'])]
+    #[ApiProperty(description: 'Whether shipping insurance is used')]
+    public ?bool $useShippingInsurance = null;
+
+    #[Groups(['query', 'mutation'])]
+    #[ApiProperty(description: 'Whether shipping insurance is enabled in admin')]
+    public ?bool $shippingInsuranceEnabled = null;
+
+    #[Groups(['query', 'mutation'])]
+    #[ApiProperty(description: 'Shipping insurance name')]
+    public ?string $shippingInsuranceName = null;
+
+    #[Groups(['query', 'mutation'])]
+    #[ApiProperty(description: 'Shipping insurance type (fixed|percentage)')]
+    public ?string $shippingInsuranceType = null;
+
+    #[Groups(['query', 'mutation'])]
+    #[ApiProperty(description: 'Shipping insurance value (percentage or fixed amount)')]
+    public ?float $shippingInsuranceValue = null;
+
+    #[Groups(['query', 'mutation'])]
+    #[ApiProperty(description: 'Shipping insurance amount')]
+    public ?float $shippingInsuranceAmount = null;
+
+    #[Groups(['query', 'mutation'])]
+    #[ApiProperty(description: 'Base shipping insurance amount')]
+    public ?float $baseShippingInsuranceAmount = null;
+
+    #[Groups(['query', 'mutation'])]
+    #[ApiProperty(description: 'Formatted shipping insurance amount')]
+    public ?string $formattedShippingInsuranceAmount = null;
+
     #[Groups(['query', 'mutation'])]
     public ?bool $success = null;
 
@@ -348,6 +380,16 @@ class CartData
             }
         }
 
+        // Shipping insurance
+        $data->useShippingInsurance = (bool) ($cart->use_shipping_insurance ?? false);
+        $data->shippingInsuranceEnabled = (bool) ($cart->shipping_insurance_enabled ?? false);
+        $data->shippingInsuranceName = $cart->shipping_insurance_name ?? null;
+        $data->shippingInsuranceType = $cart->shipping_insurance_type ?? null;
+        $data->shippingInsuranceValue = (float) ($cart->shipping_insurance_value ?? 0);
+        $data->shippingInsuranceAmount = (float) ($cart->shipping_insurance_amount ?? 0);
+        $data->baseShippingInsuranceAmount = (float) ($cart->base_shipping_insurance_amount ?? 0);
+        $data->formattedShippingInsuranceAmount = core()->currency($cart->base_shipping_insurance_amount ?? 0);
+
         if ($cart->billing_address) {
             $data->billingAddress = [
                 'id'        => $cart->billing_address->id,

+ 5 - 0
packages/Webkul/BagistoApi/src/Dto/SaveCheckoutCartInput.php

@@ -40,4 +40,9 @@ class SaveCheckoutCartInput
     #[ApiProperty(description: 'Member discount toggle. Pass "-1" to leave unchanged, "1" to apply, empty string to remove.')]
     #[SerializedName('memberDiscount')]
     public ?string $memberDiscount = null;
+
+    #[Groups(['mutation'])]
+    #[ApiProperty(description: 'Shipping insurance toggle. Pass "-1" to leave unchanged, "1" to apply, empty string to remove.')]
+    #[SerializedName('useShippingInsurance')]
+    public ?string $useShippingInsurance = null;
 }

+ 5 - 2
packages/Webkul/BagistoApi/src/Providers/BagistoApiServiceProvider.php

@@ -41,6 +41,8 @@ use Webkul\BagistoApi\State\PaymentInitiateProcessor;
 use Webkul\BagistoApi\State\PaymentReplayProcessor;
 use Webkul\BagistoApi\State\SaveCheckoutCartProcessor;
 use Longyi\Member\Services\MemberDiscountService;
+use Longyi\Gift\Services\GiftCardService;
+use Longyi\ShippingInsurance\Services\ShippingInsuranceService;
 use Webkul\BagistoApi\State\BookingSlotProvider;
 use Webkul\BagistoApi\State\PageProvider;
 use Webkul\BagistoApi\State\AttributeCollectionProvider;
@@ -258,8 +260,9 @@ class BagistoApiServiceProvider extends ServiceProvider
         $this->app->singleton(SaveCheckoutCartProcessor::class, function ($app) {
             return new SaveCheckoutCartProcessor(
                 $app->make('Webkul\CartRule\Repositories\CartRuleCouponRepository'),
-                $app->make(\Longyi\Gift\Services\GiftCardService::class),
-                $app->make(MemberDiscountService::class)
+                $app->make(GiftCardService::class),
+                $app->make(MemberDiscountService::class),
+                $app->make(ShippingInsuranceService::class)
             );
         });
 

+ 32 - 0
packages/Webkul/BagistoApi/src/State/SaveCheckoutCartProcessor.php

@@ -18,6 +18,7 @@ use Webkul\Checkout\Facades\Cart;
 use Webkul\Shipping\Facades\Shipping;
 use Longyi\Gift\Services\GiftCardService;
 use Longyi\Member\Services\MemberDiscountService;
+use Longyi\ShippingInsurance\Services\ShippingInsuranceService;
 
 /**
  * GraphQL processor for the SaveCheckoutCart mutation.
@@ -37,6 +38,7 @@ class SaveCheckoutCartProcessor implements ProcessorInterface
         protected CartRuleCouponRepository $cartRuleCouponRepository,
         protected GiftCardService $giftCardService,
         protected MemberDiscountService $memberDiscountService,
+        protected ShippingInsuranceService $shippingInsuranceService,
     ) {}
 
     /**
@@ -84,6 +86,10 @@ class SaveCheckoutCartProcessor implements ProcessorInterface
                 $this->applyMemberDiscount((string) $data->memberDiscount);
             }
 
+            if ($this->shouldUpdate($data->useShippingInsurance)) {
+                $this->applyShippingInsurance((string) $data->useShippingInsurance);
+            }
+
             Cart::collectTotals();
         } catch (OperationFailedException $e) {
             throw $e;
@@ -225,4 +231,30 @@ class SaveCheckoutCartProcessor implements ProcessorInterface
 
         $this->memberDiscountService->apply();
     }
+
+    /**
+     * Apply or remove shipping insurance.
+     * "1" applies, empty string or "0" removes.
+     */
+    private function applyShippingInsurance(string $value): void
+    {
+        $value = trim($value);
+
+        $cart = Cart::getCart();
+
+        if (! $cart) {
+            throw new OperationFailedException(__('bagistoapi::app.graphql.cart.invalid-token'));
+        }
+
+        if ($value === '') {
+            $this->shippingInsuranceService->remove();
+            return;
+        }
+
+        if ($cart->use_shipping_insurance) {
+            return;
+        }
+
+        $this->shippingInsuranceService->activate();
+    }
 }

+ 4 - 0
packages/Webkul/BagistoApi/src/Transformers/ExpressOrderResource.php

@@ -69,6 +69,10 @@ class ExpressOrderResource extends JsonResource
             'applied_cart_rule_ids'    => $this->applied_cart_rule_ids,
             'discount_amount'          => $discount,
             'base_discount_amount'     => $baseDiscount,
+            $this->mergeWhen($this->shipping_insurance_amount && $this->shipping_insurance_amount > 0, [
+                'shipping_insurance_amount'      => $this->shipping_insurance_amount,
+                'base_shipping_insurance_amount' => $this->base_shipping_insurance_amount,
+            ]),
             'billing_address'          => $billing,
             'shipping_address'         => $shipping,
             'payment'                  => (new OrderPaymentResource($this->payment))->jsonSerialize(),

+ 4 - 0
packages/Webkul/Sales/src/Transformers/OrderResource.php

@@ -86,6 +86,10 @@ class OrderResource extends JsonResource
                 'base_vip_discount_amount'      => $this->base_vip_discount_amount,
                 'formatted_vip_discount_amount' => core()->formatPrice($this->vip_discount_amount),
             ]),
+            $this->mergeWhen($this->shipping_insurance_amount && $this->shipping_insurance_amount > 0, [
+                'shipping_insurance_amount'      => $this->shipping_insurance_amount,
+                'base_shipping_insurance_amount' => $this->base_shipping_insurance_amount,
+            ]),
         ];
     }
 }

+ 15 - 0
packages/Webkul/Shop/src/Http/Resources/CartResource.php

@@ -68,6 +68,21 @@ class CartResource extends JsonResource
                 'base_vip_discount_amount'      => $this->base_vip_discount_amount,
                 'formatted_vip_discount_amount' => core()->formatPrice($this->vip_discount_amount),
             ]),
+            $this->mergeWhen($this->shipping_insurance_amount && $this->shipping_insurance_amount > 0, [
+                'shipping_insurance_amount'           => $this->shipping_insurance_amount,
+                'base_shipping_insurance_amount'      => $this->base_shipping_insurance_amount,
+                'formatted_shipping_insurance_amount' => core()->formatPrice($this->shipping_insurance_amount),
+            ]),
+            'shipping_insurance'                     => [
+                'enabled'           => (bool) ($this->shipping_insurance_enabled ?? false),
+                'name'              => $this->shipping_insurance_name ?: '运费险',
+                'type'              => $this->shipping_insurance_type ?: 'fixed',
+                'value'             => (float) ($this->shipping_insurance_value ?? 0),
+                'formatted_value'   => core()->formatPrice($this->shipping_insurance_value ?? 0),
+                'amount'            => $this->shipping_insurance_amount ?? 0,
+                'formatted_amount'  => core()->formatPrice($this->shipping_insurance_amount ?? 0),
+                'use_insurance'     => (bool) ($this->use_shipping_insurance ?? false),
+            ],
         ];
 
     }