diff --git a/app/Listeners/BtcPayWebhookListener.php b/app/Listeners/BtcPayWebhookListener.php new file mode 100644 index 000000000..73a2c1173 --- /dev/null +++ b/app/Listeners/BtcPayWebhookListener.php @@ -0,0 +1,50 @@ +payload; + if ($payload['event']['code'] === BtcPayConstants::INVOICE_WEBHOOK_CODES) { + // We have received a payment for an invoice and user should be upgraded to a paid plan based on order + try { + $invoice = LaravelBtcpay::getInvoice($payload['data']['id']); + $invoice_status = $invoice->getStatus(); + if ($invoice_status === 'Settled' ) { + preg_match('/(?P\w+(\+\+)?)[ ](?P\d+)/i', $invoice->getData()['metadata']['itemDesc'], $matches); + $user = User::query()->where('email', '=', $invoice->getData()['metadata']['buyerEmail'])->first(); + if ($user) { + User::updateUserRole($user->id, $matches['role']); + User::updateUserRoleChangeDate($user->id,null, $matches['addYears']); + } + } + } catch (BTCPayException $e) { + Log::error($e->getMessage()); + } + } + } +} diff --git a/app/Models/User.php b/app/Models/User.php index d6bd260ad..4b55a6b49 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -321,15 +321,19 @@ class User extends Authenticatable return self::whereEmail($email)->first(); } - public static function updateUserRole(int $uid, int $role): bool + public static function updateUserRole(int $uid, int|string $role): bool { - $roleQuery = Role::query()->where('id', $role)->first(); + if (is_int($role)) { + $roleQuery = Role::query()->where('id', $role)->first(); + } else { + $roleQuery = Role::query()->where('name', $role)->first(); + } $roleName = $roleQuery->name; $user = self::find($uid); $user->syncRoles([$roleName]); - return self::find($uid)->update(['roles_id' => $role]); + return self::find($uid)->update(['roles_id' => $roleQuery->id]); } public static function updateUserRoleChangeDate(int $uid, $date = '', int $addYear = 0): void diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 3bd786af3..ac32f12d1 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -4,11 +4,13 @@ namespace App\Providers; use App\Events\UserAccessedApi; use App\Events\UserLoggedIn; +use App\Listeners\BtcPayWebhookListener; use App\Listeners\UpdateUserAccessedApi; use App\Listeners\UpdateUserLoggedIn; use Illuminate\Auth\Events\Registered; use Illuminate\Auth\Listeners\SendEmailVerificationNotification; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; +use Petzsch\LaravelBtcpay\Events\BtcpayWebhookReceived; class EventServiceProvider extends ServiceProvider { @@ -29,6 +31,10 @@ class EventServiceProvider extends ServiceProvider UserAccessedApi::class => [ UpdateUserAccessedApi::class, ], + + BtcpayWebhookReceived::class => [ + BtcPayWebhookListener::class, + ], ]; /** diff --git a/composer.json b/composer.json index 5564b5620..55922d6cb 100644 --- a/composer.json +++ b/composer.json @@ -90,6 +90,7 @@ "nesbot/carbon": "^2.71", "opis/closure": "^3.6", "pear/net_nntp": "^1.6.0", + "petzsch/laravel-btcpay": "^6.0", "php-ffmpeg/php-ffmpeg": "^1.1", "php-http/guzzle7-adapter": "^1.0", "php-http/message": "^1.16", diff --git a/composer.lock b/composer.lock index 458a470f5..50f0e87a9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d3c7fdba6367788630b0ab603ce98914", + "content-hash": "4a0fb21059fdb63daac4c55491eb3317", "packages": [ { "name": "aharen/omdbapi", @@ -329,6 +329,60 @@ ], "time": "2023-01-15T23:15:59+00:00" }, + { + "name": "btcpayserver/btcpayserver-greenfield-php", + "version": "v2.3.0", + "source": { + "type": "git", + "url": "https://github.com/btcpayserver/btcpayserver-greenfield-php.git", + "reference": "9a01503ce9f395bdbb9326fd380650c8faf449f6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/btcpayserver/btcpayserver-greenfield-php/zipball/9a01503ce9f395bdbb9326fd380650c8faf449f6", + "reference": "9a01503ce9f395bdbb9326fd380650c8faf449f6", + "shasum": "" + }, + "require": { + "ext-bcmath": "*", + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "php": ">=8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", + "phpunit/phpunit": "^9.5", + "vimeo/psalm": "^4.8", + "vlucas/phpdotenv": "^5.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "BTCPayServer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Wouter Samaey", + "email": "wouter.samaey@storefront.be" + }, + { + "name": "Andreas Tasch", + "email": "andy.tasch@gmail.com" + } + ], + "description": "BTCPay Server Greenfield API PHP client library.", + "support": { + "issues": "https://github.com/btcpayserver/btcpayserver-greenfield-php/issues", + "source": "https://github.com/btcpayserver/btcpayserver-greenfield-php/tree/v2.3.0" + }, + "time": "2023-03-28T10:08:01+00:00" + }, { "name": "cache/adapter-common", "version": "1.3.0", @@ -6979,6 +7033,103 @@ }, "time": "2020-04-19T15:08:27+00:00" }, + { + "name": "petzsch/laravel-btcpay", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/petzsch/laravel-btcpay.git", + "reference": "8ec012319244a66286d6eebb15cece4f0a633341" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/petzsch/laravel-btcpay/zipball/8ec012319244a66286d6eebb15cece4f0a633341", + "reference": "8ec012319244a66286d6eebb15cece4f0a633341", + "shasum": "" + }, + "require": { + "btcpayserver/btcpayserver-greenfield-php": "^2.0", + "ext-json": "*", + "php": ">=8.0" + }, + "require-dev": { + "phpunit/phpunit": ">=9.5" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Petzsch\\LaravelBtcpay\\LaravelBtcpayServiceProvider" + ], + "aliases": { + "LaravelBtcpay": "Petzsch\\LaravelBtcpay\\LaravelBtcpayFacade" + } + } + }, + "autoload": { + "psr-4": { + "Petzsch\\LaravelBtcpay\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Vaibhavraj Roham", + "email": "vaibhavraj@vrajroham.me", + "homepage": "https://vrajroham.me", + "role": "Developer" + }, + { + "name": "Alex Stewart", + "email": "iamalexstewart@gmail.com", + "homepage": "https://github.com/alexstewartja", + "role": "Developer" + }, + { + "name": "Markus Petzsch", + "email": "markus@petzsch.eu", + "homepage": "https://www.petzsch.eu", + "role": "Developer" + } + ], + "description": "BtcPay wrapper for laravel", + "homepage": "https://github.com/petzsch/laravel-btcpay", + "keywords": [ + "btc", + "btcpay", + "laravel" + ], + "support": { + "issues": "https://github.com/petzsch/laravel-btcpay/issues", + "source": "https://github.com/petzsch/laravel-btcpay/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://bit.ly/asja_paypal_lara_bitpay", + "type": "custom" + }, + { + "url": "https://www.buymeacoffee.com/asja", + "type": "custom" + }, + { + "url": "https://github.com/alexstewartja", + "type": "github" + }, + { + "url": "https://github.com/vrajroham", + "type": "github" + }, + { + "url": "https://www.patreon.com/vrajroham", + "type": "patreon" + } + ], + "time": "2022-11-18T13:04:57+00:00" + }, { "name": "php-ffmpeg/php-ffmpeg", "version": "v1.1.0", diff --git a/routes/web.php b/routes/web.php index 881372736..28fc60d8e 100644 --- a/routes/web.php +++ b/routes/web.php @@ -374,3 +374,5 @@ Route::middleware('role_or_permission:Admin|Moderator|edit release')->prefix('ad Route::post('2faVerify', function () { return redirect()->to(URL()->previous()); })->name('2faVerify')->middleware('2fa'); + +Route::btcPayWebhook();