如何确保含/不含menu_options的订单项均能加入Stripe订单数组?
订单转Stripe数组的兼容修复方案
问题
我正在创建一个订单数组用于传递给Stripe,代码中使用了多层foreach循环。当前存在的问题是:如果订单项($orderItem)没有menu_options,就无法被加入到目标数组中。需要修改代码,确保无论订单项是否包含itemOption/menu_options,每个$orderItem都能被加入数组,同时保留itemOption->order_option_name的信息。
原有相关代码
Blade视图代码
@foreach ($order->getOrderMenusWithOptions() as $orderItem) <div class="cart-items pt-2"> <ul> @foreach ($order->getOrderMenusWithOptions() as $orderItem) <li> <span class="price pull-right">{{ currency_format($orderItem->subtotal) }}</span> <span class="name fw-bold"> @if ($orderItem->quantity > 1) <span class="quantity"> {{ $orderItem->quantity }} @lang('igniter.cart::default.text_times') </span> @endif {{ $orderItem->name }} </span> @php $itemOptionGroup = $orderItem->menu_options->groupBy('order_option_category') @endphp @if ($itemOptionGroup->isNotEmpty()) <ul class="list-unstyled small"> @foreach ($itemOptionGroup as $itemOptionGroupName => $itemOptions) <li> <u class="text-muted">{{ $itemOptionGroupName }}:</u> <ul class="list-unstyled"> @foreach ($itemOptions as $itemOption) <li> @if ($itemOption->quantity > 1) {{ $itemOption->quantity }} @lang('igniter.cart::default.text_times') @endif {{ $itemOption->order_option_name }} @if ($itemOption->order_option_price > 0) ({{ currency_format($itemOption->quantity * $itemOption->order_option_price) }}) @endif </li> @endforeach </ul> </li> @endforeach </ul> @endif @if (!empty($orderItem->comment)) <p class="comment text-muted small"> {!! $orderItem->comment !!} </p> @endif </li> @endforeach </ul> </div>
初始PHP转换函数(仅处理带选项的订单项)
private function convertCartToOrderLines($order) { $lines = []; foreach ($order->getOrderMenusWithOptions() as $orderItem) { foreach ($orderItem->menu_options as $itemOptionGroup ) { $itemOptionGroup = $orderItem->menu_options->groupBy('order_option_category'); foreach ($itemOptionGroup as $itemOptionGroupName => $itemOptions) { foreach ($itemOptions as $itemOption) { $test1 = "Qty: x".$orderItem->quantity." | ".$itemOption->order_option_name; array_push($lines, [ 'price_data' => [ 'currency' => currency()->getUserCurrency(), 'unit_amount_decimal' => number_format($orderItem->subtotal, 2, '.', '') * 100, 'product_data' => [ 'name' => $orderItem->name, 'description' => $test1, ], ], 'quantity' => 1, ]); } } } } return $lines; }
可显示所有订单项但缺少选项信息的PHP函数
private function convertCartToOrderLines(object $order): array { $currency = currency()->getUserCurrency(); $lines = []; foreach ($order->getOrderMenusWithOptions() as $orderItem) { $subtotal = number_format($orderItem->subtotal, 2, '.', '') * 100; $lines[] = [ 'price_data' => [ 'currency' => $currency, 'unit_amount_decimal' => $subtotal, 'product_data' => [ 'name' => $orderItem->name, 'description' => sprintf( "Qty: x%d", $orderItem->quantity, ) ], ], 'quantity' => 1, ]; } return $lines; }
修复后的PHP函数
private function convertCartToOrderLines(object $order): array { $currency = currency()->getUserCurrency(); $lines = []; foreach ($order->getOrderMenusWithOptions() as $orderItem) { $subtotal = number_format($orderItem->subtotal, 2, '.', '') * 100; // 初始化描述文本为数量信息 $description = sprintf("Qty: x%d", $orderItem->quantity); // 如果存在菜单选项,拼接选项信息 if ($orderItem->menu_options->isNotEmpty()) { $itemOptionGroup = $orderItem->menu_options->groupBy('order_option_category'); $optionTexts = []; foreach ($itemOptionGroup as $itemOptionGroupName => $itemOptions) { $optionItems = []; foreach ($itemOptions as $itemOption) { $optionText = $itemOption->order_option_name; if ($itemOption->quantity > 1) { $optionText = sprintf("%d x %s", $itemOption->quantity, $optionText); } $optionItems[] = $optionText; } $optionTexts[] = sprintf("%s: %s", $itemOptionGroupName, implode(', ', $optionItems)); } // 将选项信息追加到描述中 $description .= " | " . implode('; ', $optionTexts); } // 添加当前订单项到数组 $lines[] = [ 'price_data' => [ 'currency' => $currency, 'unit_amount_decimal' => $subtotal, 'product_data' => [ 'name' => $orderItem->name, 'description' => $description, ], ], 'quantity' => 1, ]; } return $lines; }
关键修改说明
- 移除了依赖
menu_options的外层foreach循环,确保每个$orderItem都会被处理,无论是否有选项 - 单独处理菜单选项:先分组,再生成格式化的选项文本,最后拼接到描述中
- 保持Stripe要求的数组结构不变,同时兼容无选项的订单项,完整保留数量和选项信息
内容的提问来源于stack exchange,提问作者George Richardson
相关产品推荐
相关产品推荐

