TinyShip 2.6.0 Released
This release adds a complete Dynamic Pricing System to TinyShip. Admins can create, edit, reorder, and disable pricing plans in real time through the admin UI, adjusting pricing strategy without redeployment.
The system uses a dual-mode architecture: the default static mode keeps using the plans in config/payment.ts (zero changes for existing projects), while dynamic mode enables database-driven pricing management. All three frameworks are adapted in sync, with support for both PostgreSQL and SQLite/D1.
Core Additions
Dual-Mode Switching: Controlled by the PRICING_MODE environment variable — static (default) uses the config file plans, dynamic reads plans from the database. Switching takes effect immediately with no code changes
Admin Pricing Panel: A brand-new admin page at /admin/pricing supporting create / edit / delete for plans (subscription, lifetime, and credit pack types), drag-and-drop ordering, one-click enable/disable, and one-click import of existing plans from the static config
Multilingual Plan Content: Each plan supports per-language names, descriptions, and feature lists. Language tabs are extensible, and missing languages automatically fall back to the default language
Strikethrough Pricing and Markdown Features: Set originalPrice to show a strikethrough original price; the Features field supports Markdown for rich-text feature highlights
Locale Filtering: Plans can specify applicable locales, and the frontend filters them automatically based on the user's locale. Plans without a locale setting are visible to all users
Payment Provider Binding: Each plan independently binds a payment provider (Stripe / PayPal / Creem / Dodo / WeChat Pay / Alipay) with its Price ID / Product ID, matched automatically on the frontend
Database Changes
New pricing_plan table: 19 fields covering price, currency, type, sort order, active status, locale filtering, payment provider IDs, and multilingual content, with Drizzle migrations synced for both PG and SQLite/D1 dialects
Configuration and Environment Variables
Only one new environment variable is needed to enable dynamic pricing:
PRICING_MODE—"static"(default) or"dynamic"
Static mode has no behavior changes — zero impact on all existing deployments.
i18n
Complete Bilingual Coverage: All labels, buttons, hints, and descriptions on the admin pricing pages use i18n keys with no hard-coded text, under the new admin.pricing.* translation namespace
Testing and Stability
Full Lifecycle E2E Coverage: Added 14 E2E tests covering list loading, plan creation and editing (including multilingual fields), enable/disable toggling, soft and hard deletion, static config import, dynamic provider field display, and non-admin access blocking. All three frameworks pass
Documentation
User Guide: docs/user-guide/payment/dynamic-pricing.md documents dynamic pricing configuration, including enablement, admin operations, locale filtering, multilingual support, and the full migration path from static to dynamic
Implementation Docs: docs/implementation/dynamic-pricing.md covers architecture design, database schema, API design, and payment integration details