Add all files

This commit is contained in:
root
2025-11-30 11:57:22 +01:00
parent 2ee51cac4f
commit 044271db3d
1476 changed files with 142544 additions and 0 deletions

View File

@@ -0,0 +1,165 @@
<?php
/**
* DiscordPlus Extension for Paymenter
*
* Created by: Exp (Discord: exp_yt)
* Company: ExpHost - https://www.exphost.net/
*
* This code is the intellectual property of Exp and ExpHost.
* Unauthorized copying, modification, or distribution is prohibited.
*/
namespace Paymenter\Extensions\Others\DiscordPlus;
use App\Classes\Extension\Extension;
use App\Events\Invoice\Finalized as InvoiceCreated;
use App\Events\Invoice\Paid as InvoicePaid;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\URL;
class DiscordPlus extends Extension
{
public function getName(): string
{
return 'DiscordPlus';
}
public function getDescription(): string
{
return 'Sends Discord DMs to users when invoices are created or paid.';
}
public function getVersion(): string
{
return '1.0.0';
}
public function getAuthor(): string
{
return 'Exp_YT';
}
public function boot(): void
{
$botToken = $this->config('discord_bot_token');
if (!$botToken) return;
app()->bind(\App\Http\Controllers\SocialLoginController::class, function () {
return new \Paymenter\Extensions\Others\DiscordPlus\SocialLoginController();
});
Event::listen(InvoiceCreated::class, function ($event) use ($botToken) {
$this->sendDm($event->invoice, 'invoice_created', $botToken);
});
Event::listen(InvoicePaid::class, function ($event) use ($botToken) {
$this->sendDm($event->invoice, 'invoice_paid', $botToken);
});
}
public function getConfig($values = [])
{
return [
[
'name' => 'discord_bot_token',
'type' => 'text',
'label' => 'Discord Bot Token',
'required' => true,
'encrypted' => true,
],
];
}
private function sendDm($invoice, $type, $botToken)
{
if (!$invoice || !$invoice->user) {
return;
}
$user = $invoice->user;
$discordId = $user->discord_id;
$botToken = trim($botToken);
if (empty($discordId) || !is_string($discordId) || !ctype_digit((string)$discordId)) {
return;
}
$company = \Config::get('app.name', 'Paymenter');
$invoiceUrl = \URL::to("/invoices/{$invoice->id}");
$amount = (string)$invoice->formattedTotal;
$dueDate = $invoice->due_at ? $invoice->due_at->format('d M Y') : 'N/A';
if ($type === 'invoice_created') {
$embed = [
'embeds' => [[
'title' => '🧾 New Invoice Created',
'color' => 0x7289DA,
'description' => "A new invoice has been generated for your account.\n[View & Pay Invoice]({$invoiceUrl})",
'fields' => [
[ 'name' => 'Invoice #', 'value' => "#{$invoice->number}", 'inline' => true ],
[ 'name' => 'Amount Due', 'value' => $amount, 'inline' => true ],
[ 'name' => 'Due Date', 'value' => ($dueDate !== 'N/A' ? "`{$dueDate}`" : '*N/A*'), 'inline' => false ],
],
'footer' => [ 'text' => $company ],
]]
];
} else {
$embed = [
'embeds' => [[
'title' => '✅ Invoice Paid',
'color' => 0x43B581,
'description' => "Thank you for your payment!\n[View Invoice]({$invoiceUrl})",
'fields' => [
[ 'name' => 'Invoice #', 'value' => "#{$invoice->number}", 'inline' => true ],
[ 'name' => 'Amount', 'value' => $amount, 'inline' => true ],
],
'footer' => [ 'text' => $company ],
]]
];
}
$dmResponse = \Http::withHeaders([
'Authorization' => 'Bot ' . $botToken,
'Content-Type' => 'application/json',
])
->post('https://discord.com/api/v10/users/@me/channels', [
'recipient_id' => $discordId,
]);
if ($dmResponse->failed()) {
\Log::error('[DiscordPlus] Failed to create DM channel for discord_id: ' . $discordId . '. Response: ' . $dmResponse->body());
return;
}
$channelId = $dmResponse->json('id');
if (!$channelId) {
\Log::error('[DiscordPlus] No channel ID returned for discord_id: ' . $discordId . '. Response: ' . $dmResponse->body());
return;
}
$msgResponse = \Http::withHeaders([
'Authorization' => 'Bot ' . $botToken,
'Content-Type' => 'application/json',
])
->post("https://discord.com/api/v10/channels/{$channelId}/messages", $embed);
if ($msgResponse->failed()) {
\Log::error('[DiscordPlus] Failed to send DM to channel: ' . $channelId . '. Response: ' . $msgResponse->body());
}
}
public function enabled(): void
{
if (!\Schema::hasColumn('users', 'discord_id')) {
\Artisan::call('migrate', [
'--path' => 'extensions/Others/DiscordPlus/migrations/2025_08_27_000000_add_discord_id_to_users_table.php',
'--force' => true,
]);
}
}
public function disabled(): void {}
public function updated(): void {}
public function install(): void {}
}

View File

@@ -0,0 +1,111 @@
<?php
/**
* DiscordPlus Extension for Paymenter
*
* Created by: Exp (Discord: exp_yt)
* Company: ExpHost - https://www.exphost.net/
*
* This code is the intellectual property of Exp and ExpHost.
* Unauthorized copying, modification, or distribution is prohibited.
*/
namespace Paymenter\Extensions\Others\DiscordPlus;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Laravel\Socialite\Facades\Socialite;
use Laravel\Socialite\Two\GithubProvider;
use Laravel\Socialite\Two\GoogleProvider;
use SocialiteProviders\Discord\Provider as DiscordProvider;
class SocialLoginController extends \App\Http\Controllers\Controller
{
protected $discord_driver;
protected $github_driver;
protected $google_driver;
public function __construct()
{
$this->discord_driver = Socialite::buildProvider(DiscordProvider::class, [
'client_id' => config('settings.oauth_discord_client_id'),
'client_secret' => config('settings.oauth_discord_client_secret'),
'redirect' => '/oauth/discord/callback',
]);
$this->github_driver = Socialite::buildProvider(GithubProvider::class, [
'client_id' => config('settings.oauth_github_client_id'),
'client_secret' => config('settings.oauth_github_client_secret'),
'redirect' => '/oauth/github/callback',
]);
$this->google_driver = Socialite::buildProvider(GoogleProvider::class, [
'client_id' => config('settings.oauth_google_client_id'),
'client_secret' => config('settings.oauth_google_client_secret'),
'redirect' => '/oauth/google/callback',
]);
}
public function redirect($provider)
{
if (!config("settings.oauth_$provider")) {
abort(404);
}
return match ($provider) {
'discord' => $this->discord_driver->scopes(['email'])->redirect(),
'github' => $this->github_driver->scopes(['user:email'])->redirect(),
'google' => $this->google_driver->scopes(['email'])->redirect(),
default => abort(404)
};
}
public function handle($provider)
{
if ($provider == 'discord') {
$oauth_user = $this->discord_driver->user();
if (!($oauth_user->user['verified'] ?? true)) {
return redirect()->route('login')->with('error', __('auth.oauth.unverified_discord_account'));
}
$user = User::where('email', $oauth_user->email)->first();
if (!$user) {
return redirect()->route('register')->with('error', __('auth.oauth.account_not_registered'));
}
// Only set discord_id if it exists and is not already set
$discordId = $oauth_user->getId() ?? ($oauth_user->id ?? $oauth_user->user['id'] ?? null);
if ($discordId && (!$user->discord_id || $user->discord_id != $discordId)) {
$user->discord_id = $discordId;
$user->save();
}
Auth::login($user, true);
return redirect()->route('home');
} elseif ($provider == 'google') {
$oauth_user = $this->google_driver->user();
$user = User::where('email', $oauth_user->email)->first();
if (!$user) {
return redirect()->route('register')->with('error', __('auth.oauth.account_not_registered'));
}
Auth::login($user, true);
return redirect()->route('home');
} elseif ($provider == 'github') {
$oauth_user = $this->github_driver->user();
$user = User::where('email', $oauth_user->email)->first();
if (!$user) {
return redirect()->route('register')->with('error', __('auth.oauth.account_not_registered'));
}
Auth::login($user, true);
return redirect()->route('home');
} else {
return redirect()->route('login');
}
}
}

View File

@@ -0,0 +1,25 @@
<?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('users', function (Blueprint $table) {
if (!Schema::hasColumn('users', 'discord_id')) {
$table->string('discord_id')->nullable()->unique()->after('email');
}
});
}
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
if (Schema::hasColumn('users', 'discord_id')) {
$table->dropColumn('discord_id');
}
});
}
};