Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/linting.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ jobs:
key: ${{ runner.os }}-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-${{ matrix.php }}-composer-

- name: Configure Flux Pro auth
run: composer config http-basic.composer.fluxui.dev "${{ secrets.FLUX_EMAIL }}" "${{ secrets.FLUX_LICENSE_KEY }}"

- name: Install Dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ jobs:
key: ${{ runner.os }}-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-${{ matrix.php }}-composer-

- name: Configure Flux Pro auth
run: composer config http-basic.composer.fluxui.dev "${{ secrets.FLUX_EMAIL }}" "${{ secrets.FLUX_LICENSE_KEY }}"

- name: Install Dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist

Expand Down
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ The Laravel Boost guidelines are specifically curated by Laravel maintainers for
## Foundational Context
This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions.

- php - 8.4.18
- filament/filament (FILAMENT) - v3
- php - 8.4.19
- filament/filament (FILAMENT) - v5
- laravel/cashier (CASHIER) - v15
- laravel/framework (LARAVEL) - v12
- laravel/horizon (HORIZON) - v5
Expand All @@ -18,7 +18,7 @@ This application is a Laravel application and its main Laravel ecosystems packag
- laravel/prompts (PROMPTS) - v0
- laravel/sanctum (SANCTUM) - v4
- laravel/socialite (SOCIALITE) - v5
- livewire/livewire (LIVEWIRE) - v3
- livewire/livewire (LIVEWIRE) - v4
- laravel/mcp (MCP) - v0
- laravel/pint (PINT) - v1
- laravel/sail (SAIL) - v1
Expand Down
21 changes: 20 additions & 1 deletion app/Http/Controllers/DeveloperOnboardingController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

use App\Models\DeveloperAccount;
use App\Services\StripeConnectService;
use App\Support\StripeConnectCountries;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\View\View;

class DeveloperOnboardingController extends Controller
Expand All @@ -32,16 +34,33 @@ public function start(Request $request): RedirectResponse
{
$request->validate([
'accepted_plugin_terms' => ['required', 'accepted'],
'country' => ['required', 'string', 'size:2', Rule::in(StripeConnectCountries::supportedCountryCodes())],
'payout_currency' => ['required', 'string', 'size:3'],
], [
'accepted_plugin_terms.required' => 'You must accept the Plugin Developer Terms and Conditions.',
'accepted_plugin_terms.accepted' => 'You must accept the Plugin Developer Terms and Conditions.',
'country.required' => 'Please select your country.',
'country.in' => 'The selected country is not supported for Stripe Connect.',
'payout_currency.required' => 'Please select a payout currency.',
]);

$country = strtoupper($request->input('country'));
$payoutCurrency = strtoupper($request->input('payout_currency'));

if (! StripeConnectCountries::isValidCurrencyForCountry($country, $payoutCurrency)) {
return back()->withErrors(['payout_currency' => 'The selected currency is not available for your country.']);
}

$user = $request->user();
$developerAccount = $user->developerAccount;

if (! $developerAccount) {
$developerAccount = $this->stripeConnectService->createConnectAccount($user);
$developerAccount = $this->stripeConnectService->createConnectAccount($user, $country, $payoutCurrency);
} else {
$developerAccount->update([
'country' => $country,
'payout_currency' => $payoutCurrency,
]);
}

if (! $developerAccount->hasAcceptedCurrentTerms()) {
Expand Down
52 changes: 52 additions & 0 deletions app/Livewire/Customer/Developer/Onboarding.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Livewire\Customer\Developer;

use App\Support\StripeConnectCountries;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
Expand All @@ -11,13 +12,31 @@
#[Title('Developer Onboarding')]
class Onboarding extends Component
{
public string $country = '';

public string $payoutCurrency = '';

public function mount(): void
{
$developerAccount = auth()->user()->developerAccount;

if ($developerAccount && $developerAccount->hasCompletedOnboarding()) {
$this->redirect(route('customer.developer.dashboard'), navigate: true);
}

if ($developerAccount) {
$this->country = $developerAccount->country ?? '';
$this->payoutCurrency = $developerAccount->payout_currency ?? '';
}
}

public function updatedCountry(string $value): void
{
if (StripeConnectCountries::isSupported($value)) {
$this->payoutCurrency = StripeConnectCountries::defaultCurrency($value);
} else {
$this->payoutCurrency = '';
}
}

#[Computed]
Expand All @@ -32,6 +51,39 @@ public function hasExistingAccount(): bool
return $this->developerAccount !== null;
}

/**
* @return array<string, array{name: string, flag: string, default_currency: string, currencies: list<string>}>
*/
#[Computed]
public function countries(): array
{
$countries = StripeConnectCountries::all();

uasort($countries, fn (array $a, array $b) => $a['name'] <=> $b['name']);

return $countries;
}

/**
* @return array<string, string>
*/
#[Computed]
public function availableCurrencies(): array
{
if (! $this->country || ! StripeConnectCountries::isSupported($this->country)) {
return [];
}

$currencies = StripeConnectCountries::availableCurrencies($this->country);

$named = [];
foreach ($currencies as $code) {
$named[$code] = StripeConnectCountries::currencyName($code);
}

return $named;
}

public function render()
{
return view('livewire.customer.developer.onboarding');
Expand Down
8 changes: 6 additions & 2 deletions app/Services/StripeConnectService.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,17 @@
*/
class StripeConnectService
{
public function createConnectAccount(User $user): DeveloperAccount
public function createConnectAccount(User $user, string $country, string $payoutCurrency): DeveloperAccount
{
$account = Cashier::stripe()->accounts->create([
'type' => 'express',
'country' => $country,
'email' => $user->email,
'metadata' => [
'user_id' => $user->id,
],
'capabilities' => [
'card_payments' => ['requested' => true],
'transfers' => ['requested' => true],
],
]);
Expand All @@ -38,6 +40,8 @@ public function createConnectAccount(User $user): DeveloperAccount
'stripe_connect_status' => StripeConnectStatus::Pending,
'payouts_enabled' => false,
'charges_enabled' => false,
'country' => $country,
'payout_currency' => $payoutCurrency,
]);
}

Expand Down Expand Up @@ -109,7 +113,7 @@ public function processTransfer(PluginPayout $payout): bool
try {
$transferParams = [
'amount' => $payout->developer_amount,
'currency' => 'usd',
'currency' => strtolower($developerAccount->payout_currency ?? 'usd'),
'destination' => $developerAccount->stripe_connect_account_id,
'metadata' => [
'payout_id' => $payout->id,
Expand Down
Loading
Loading