feat(billing): end-to-end Stripe subscription signup with platform enforcement
Move core signup service from marketplace to billing module, add automatic Stripe product/price sync for tiers, create loyalty-specific signup wizard, and enforce that platform is always explicitly known (no silent defaulting to primary/hardcoded ID). Key changes: - New billing SignupService with separated account/store creation steps - Stripe auto-sync on tier create/update (new prices, archive old) - Loyalty signup template (Plan → Account → Store → Payment) - platform_code is now required throughout the signup flow - Pricing/signup pages return 404 if platform not detected - OMS-specific logic (Letzshop claiming) stays in marketplace module - Bootstrap script: scripts/seed/sync_stripe_products.py Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -93,6 +93,38 @@ class StripeService:
|
||||
)
|
||||
return customer.id
|
||||
|
||||
def create_customer_for_merchant(
|
||||
self,
|
||||
merchant,
|
||||
email: str,
|
||||
name: str | None = None,
|
||||
metadata: dict | None = None,
|
||||
) -> str:
|
||||
"""
|
||||
Create a Stripe customer for a merchant (before store exists).
|
||||
|
||||
Used during signup when the store hasn't been created yet.
|
||||
Returns the Stripe customer ID.
|
||||
"""
|
||||
self._check_configured()
|
||||
|
||||
customer_metadata = {
|
||||
"merchant_id": str(merchant.id),
|
||||
"merchant_name": merchant.name,
|
||||
**(metadata or {}),
|
||||
}
|
||||
|
||||
customer = stripe.Customer.create(
|
||||
email=email,
|
||||
name=name or merchant.name,
|
||||
metadata=customer_metadata,
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"Created Stripe customer {customer.id} for merchant {merchant.name}"
|
||||
)
|
||||
return customer.id
|
||||
|
||||
def get_customer(self, customer_id: str) -> stripe.Customer:
|
||||
"""Get a Stripe customer by ID."""
|
||||
self._check_configured()
|
||||
|
||||
Reference in New Issue
Block a user