1. Go to this page and download the library: Download climactic/laravel-credits library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
climactic / laravel-credits example snippets
return [
// Allow negative balances
'allow_negative_balance' => false,
// Table name for credit transactions (change if you've updated the migration table name)
'table_name' => 'credits',
];
use Climactic\Credits\Traits\HasCredits;
class User extends Model
{
use HasCredits;
}
// Add credits
$user->creditAdd(100.00, 'Subscription Activated');
// Deduct credits
$user->creditDeduct(50.00, 'Purchase Made');
// Get current balance
$balance = $user->creditBalance();
// Check if user has enough credits
if ($user->hasCredits(30.00)) {
// Proceed with transaction
}
$sender->creditTransfer($recipient, 100.00, 'Paying to user for their service');
// Get last 10 transactions
$history = $user->creditHistory();
// Get last 20 transactions in ascending order
$history = $user->creditHistory(20, 'asc');
$date = new DateTime('2023-01-01');
$balanceAsOf = $user->creditBalanceAt($date);
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
return new class extends Migration
{
public function up()
{
$tableName = config('credits.table_name', 'credits');
// Add virtual columns for frequently queried metadata keys
DB::statement("
ALTER TABLE {$tableName}
ADD COLUMN metadata_source VARCHAR(255)
GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(metadata, '$.source'))) VIRTUAL
");
DB::statement("
ALTER TABLE {$tableName}
ADD COLUMN metadata_order_id BIGINT
GENERATED ALWAYS AS (JSON_EXTRACT(metadata, '$.order_id')) VIRTUAL
");
// Add indexes on virtual columns
Schema::table($tableName, function (Blueprint $table) {
$table->index('metadata_source');
$table->index('metadata_order_id');
});
// Optional: Composite indexes for common query combinations
Schema::table($tableName, function (Blueprint $table) {
$table->index(['metadata_source', 'created_at']);
$table->index(['creditable_id', 'creditable_type', 'metadata_order_id']);
});
}
public function down()
{
$tableName = config('credits.table_name', 'credits');
Schema::table($tableName, function (Blueprint $table) {
$table->dropIndex(['metadata_source', 'created_at']);
$table->dropIndex(['creditable_id', 'creditable_type', 'metadata_order_id']);
$table->dropIndex(['metadata_source']);
$table->dropIndex(['metadata_order_id']);
});
DB::statement("ALTER TABLE {$tableName} DROP COLUMN metadata_source");
DB::statement("ALTER TABLE {$tableName} DROP COLUMN metadata_order_id");
}
};
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
public function up()
{
$tableName = config('credits.table_name', 'credits');
// GIN index supports all JSON operators (@>, ?, ?&, ?|, etc.)
DB::statement("
CREATE INDEX {$tableName}_metadata_gin_idx
ON {$tableName} USING GIN (metadata)
");
// Optional: Add specific path indexes for even faster queries
DB::statement("
CREATE INDEX {$tableName}_metadata_source_idx
ON {$tableName} ((metadata->>'source'))
");
DB::statement("
CREATE INDEX {$tableName}_metadata_order_id_idx
ON {$tableName} ((metadata->'order_id'))
");
}
public function down()
{
$tableName = config('credits.table_name', 'credits');
DB::statement("DROP INDEX IF EXISTS {$tableName}_metadata_gin_idx");
DB::statement("DROP INDEX IF EXISTS {$tableName}_metadata_source_idx");
DB::statement("DROP INDEX IF EXISTS {$tableName}_metadata_order_id_idx");
}
};
// If you often query by source
$user->credits()->whereMetadata('source', 'purchase')->get();
// → Index: metadata_source
// If you filter by order_id
$user->credits()->whereMetadata('order_id', 12345)->get();
// → Index: metadata_order_id
// If you query by tags array
$user->credits()->whereMetadataContains('tags', 'premium')->get();
// → MySQL: Index on virtual column for tags
// → PostgreSQL: GIN index handles this automatically