As an e-commerce developer, I often encounter situations where clients require fine-grained control over payment methods for specific products. If you’re using the Laravel framework with packages like Laravel Cashier or Stripe Laravel SDK, you can easily achieve this by leveraging custom product attributes and conditional logic in your checkout process.
Understanding the Requirement
The goal is to hide all non-cash on delivery payment options for certain products while keeping them available for others. This requires a combination of database schema modifications and business logic implementation in your Laravel application.
Step 1: Create a Custom Product Attribute
First, let’s create a new attribute called allow_cash_on_delivery that can be enabled or disabled on a per-product basis.
// Open the migration file for your products table (e.g., app/database/migrations/2022_01_01_000000_create_products_table.php)
Schema::table('products', function (Blueprint $table) {
$table->boolean('allow_cash_on_delivery')->default(true);
});
This migration adds a new boolean column to your products table, with the default value set to true. This means that by default, all products will allow cash on delivery.
Step 2: Filter Products in Your Controller
Next, we’ll modify our product listing or checkout controller methods to filter out products based on this attribute.
// In your ProductController.php
public function index()
{
$products = App\Models\Product::where('allow_cash_on_delivery', true)->get();
return view('products.index', compact('products'));
}
In the example above, we’re only retrieving products where allow_cash_on_delivery is set to true. This ensures that products without this permission won’t be listed in our front-end product catalog.
Step 3: Conditional Payment Method Display
Now let’s modify our checkout process to conditionally display payment methods based on the current product’s settings.
// In your CheckoutController.php
public function payment()
{
$product = App\Models\Product::findOrFail(request()->route('product'));
if ($product->allow_cash_on_delivery) {
// Show only cash on delivery options
return view('checkout.payment', compact('product'));
} else {
// Show all available payment methods (e.g., Stripe, PayPal)
$paymentMethods = App\Models\PaymentMethod::all();
return view('checkout.payment', compact('product', 'paymentMethods'));
}
}
In this example, we’re checking if the current product allows cash on delivery. If it does, we only pass the product object to our payment view. If not, we fetch and pass all available payment methods.
Step 4: Customize Your Blade Templates
Finally, you’ll need to update your blade templates in resources/views/checkout/payment.blade.php to conditionally display payment options based on the data passed from the controller.
<!-- Check if $product->allow_cash_on_delivery is true -->
@if ($product->allow_cash_on_delivery)
<div class="cash-on-delivery">
Cash on Delivery
</div>
@else
<!-- Display all other payment methods here -->
@foreach ($paymentMethods as $method)
<div class="payment-method">
{{ $method->name }}
</div>
@endforeach
@endif
Conclusion
By following this approach, you can efficiently manage cash on delivery permissions for specific products in your Laravel application. The key lies in leveraging custom database attributes and implementing conditional logic based on those attributes in your controllers.
Remember to always test your business logic thoroughly and ensure that your payment gateways are properly configured to handle the selected payment methods.
If you’d like to learn more about e-commerce development with Laravel, check out our comprehensive guides at Laravel Company, where we cover everything from setting up your initial project to implementing advanced features like recurring payments and subscription management.