Building Your First Extension
In this step-by-step guide, we will build a custom Loyalty Points Extension that awards reward coins to customers upon completed order payments.
Step 1: Scaffold Extension Directory
Create the directory structure under backend/extensions/loyalty-points/:
bash
mkdir -p backend/extensions/loyalty-points/src/{Actions,Data,Providers}Step 2: Define module.json
Create backend/extensions/loyalty-points/module.json:
json
{
"name": "loyalty-points",
"title": "Customer Loyalty Points",
"version": "1.0.0",
"description": "Awards reward coins on order completion.",
"providers": [
"Reyhan\\Extensions\\LoyaltyPoints\\Providers\\LoyaltyPointsServiceProvider"
],
"enabled": true
}Step 3: Implement Domain Action
Create backend/extensions/loyalty-points/src/Actions/AwardOrderPointsAction.php:
php
namespace Reyhan\Extensions\LoyaltyPoints\Actions;
use Reyhan\Core\Models\Order;
use Illuminate\Support\Facades\DB;
final class AwardOrderPointsAction
{
/**
* Calculate 1% cash-back coins on order total.
*/
public function execute(Order $order): int
{
$points = (int) ($order->total_amount * 0.01);
DB::table('customer_loyalty_wallets')
->updateOrInsert(
['user_id' => $order->user_id],
['points' => DB::raw("points + {$points}")]
);
return $points;
}
}Step 4: Register Service Provider & Event Listener
Create backend/extensions/loyalty-points/src/Providers/LoyaltyPointsServiceProvider.php:
php
namespace Reyhan\Extensions\LoyaltyPoints\Providers;
use Reyhan\Core\Support\Extensions\ReyhanExtensionServiceProvider;
use Illuminate\Support\Facades\Event;
use Reyhan\Core\Events\Payment\PaymentVerifiedEvent;
use Reyhan\Extensions\LoyaltyPoints\Actions\AwardOrderPointsAction;
class LoyaltyPointsServiceProvider extends ReyhanExtensionServiceProvider
{
public function boot(): void
{
// Listen to core framework payment settlement event
Event::listen(PaymentVerifiedEvent::class, function (PaymentVerifiedEvent $event) {
app(AwardOrderPointsAction::class)->execute($event->payment->order);
});
}
}Now, whenever an order is marked as paid across the system, your isolated plugin seamlessly awards loyalty points!