diff --git a/app/Models/User.php b/app/Models/User.php index 0f935505..f59d74c9 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -165,6 +165,16 @@ class User extends Authenticatable implements HasLocalePreference, MustVerifyEma return $this->subscribed('default'); } + /** + * The tax rates that should apply to the customer's subscriptions. + * + * @return array + */ + public function taxRates(): array + { + return config('subscriptions.tax_rates', []); + } + public function isDemoAccount(): bool { return $this->email === config('app.demo.email'); diff --git a/config/subscriptions.php b/config/subscriptions.php index da46dcba..09715959 100644 --- a/config/subscriptions.php +++ b/config/subscriptions.php @@ -131,6 +131,18 @@ return [ | */ + /* + |-------------------------------------------------------------------------- + | Tax Rates + |-------------------------------------------------------------------------- + | + | Stripe tax rate IDs applied to every subscription created via Cashier. + | Configure tax rates in your Stripe dashboard and reference them here. + | + */ + + 'tax_rates' => array_values(array_filter(explode(',', (string) env('STRIPE_TAX_RATES', 'txr_1TPfzrLRCmKA3oWMNWmkQeq2')))), + 'promo' => [ 'enabled' => env('PROMO_ENABLED', true), 'code' => 'FOUNDER', diff --git a/tests/Feature/SubscriptionTest.php b/tests/Feature/SubscriptionTest.php index 4a402553..f2b0b57d 100644 --- a/tests/Feature/SubscriptionTest.php +++ b/tests/Feature/SubscriptionTest.php @@ -272,6 +272,18 @@ test('paywall shows canUseFreePlan false when user has a bank connection', funct ); }); +test('taxRates returns configured stripe tax rate ids', function () { + config(['subscriptions.tax_rates' => ['txr_test_1', 'txr_test_2']]); + + $user = User::factory()->create(); + + expect($user->taxRates())->toBe(['txr_test_1', 'txr_test_2']); +}); + +test('taxRates config defaults to the production tax rate id', function () { + expect(config('subscriptions.tax_rates'))->toContain('txr_1TPfzrLRCmKA3oWMNWmkQeq2'); +}); + test('billing portal creates stripe customer when user has no stripe id', function () { $user = Mockery::mock(User::class)->shouldIgnoreMissing(); $user->shouldReceive('isDemoAccount')->andReturn(false);