UNPKG

prices-as-code

Version:

Prices as Code (PaC) - Define your product pricing schemas with type-safe definitions

407 lines (356 loc) 12.2 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Getting Started - Prices as Code</title> <meta name="description" content="Getting started with the Prices as Code TypeScript library"> <link rel="stylesheet" href="../assets/css/main.css"> <link rel="icon" href="https://raw.githubusercontent.com/wickdninja/assets/refs/heads/main/PaC.webp"> </head> <body> <header class="site-header"> <div class="container"> <div class="header-content"> <div class="logo"> <a href="../index.html"> <img src="https://raw.githubusercontent.com/wickdninja/assets/refs/heads/main/PaC.webp" alt="Prices as Code" width="40"> <span>Prices as Code</span> </a> </div> <nav class="main-nav"> <ul> <li><a href="index.html">Guides</a></li> <li><a href="../api/index.html">API</a></li> <li><a href="../providers/index.html">Providers</a></li> <li><a href="https://github.com/wickdninja/prices-as-code" target="_blank">GitHub</a></li> <li><a href="https://www.npmjs.com/package/prices-as-code" target="_blank">NPM</a></li> </ul> </nav> </div> </div> </header> <main class="content"> <div class="container"> <h1>Getting Started with Prices as Code</h1> <p>This guide will walk you through setting up Prices as Code and creating your first pricing configuration.</p> <h2>Installation</h2> <p>Install the package using npm:</p> <div class="highlight"> <pre><code class="language-bash">npm install prices-as-code</code></pre> </div> <p>Or with yarn:</p> <div class="highlight"> <pre><code class="language-bash">yarn add prices-as-code</code></pre> </div> <p>Or with pnpm:</p> <div class="highlight"> <pre><code class="language-bash">pnpm add prices-as-code</code></pre> </div> <h2>Setup Environment Variables</h2> <p>Create a <code>.env</code> file in your project root with your API key:</p> <div class="highlight"> <pre><code># .env file STRIPE_SECRET_KEY=sk_test_your_stripe_key</code></pre> </div> <h2>Create a Configuration File</h2> <div class="tabs"> <div class="tab active" onclick="showTab('ts')">TypeScript</div> <div class="tab" onclick="showTab('yaml')">YAML</div> </div> <div id="ts-tab" class="tab-content"> <p>Create a <code>pricing.ts</code> file:</p> <div class="highlight"> <pre><code class="language-typescript">import { Config } from 'prices-as-code'; const config: Config = { products: [ { provider: 'stripe', name: 'Basic Plan', description: 'For individuals and small teams', features: ['5 projects', '10GB storage', 'Email support'], highlight: false, metadata: { displayOrder: 1 } }, { provider: 'stripe', name: 'Pro Plan', description: 'For growing businesses', features: ['Unlimited projects', '100GB storage', 'Priority support'], highlight: true, metadata: { displayOrder: 2 } } ], prices: [ { provider: 'stripe', name: 'Basic Monthly', nickname: 'Basic Monthly', unitAmount: 999, // $9.99 currency: 'usd', type: 'recurring', recurring: { interval: 'month', intervalCount: 1 }, productKey: 'basic_plan', metadata: { displayName: 'Basic Monthly' } }, { provider: 'stripe', name: 'Pro Monthly', nickname: 'Pro Monthly', unitAmount: 1999, // $19.99 currency: 'usd', type: 'recurring', recurring: { interval: 'month', intervalCount: 1 }, productKey: 'pro_plan', metadata: { displayName: 'Pro Monthly' } } ] }; export default config;</code></pre> </div> </div> <div id="yaml-tab" class="tab-content" style="display: none;"> <p>Create a <code>prices.yml</code> file:</p> <div class="highlight"> <pre><code class="language-yaml">products: - provider: stripe name: Basic Plan description: For individuals and small teams features: - 5 projects - 10GB storage - Email support highlight: false metadata: displayOrder: 1 - provider: stripe name: Pro Plan description: For growing businesses features: - Unlimited projects - 100GB storage - Priority support highlight: true metadata: displayOrder: 2 prices: - provider: stripe name: Basic Monthly nickname: Basic Monthly unitAmount: 999 currency: usd type: recurring recurring: interval: month intervalCount: 1 productKey: basic_plan metadata: displayName: Basic Monthly - provider: stripe name: Pro Monthly nickname: Pro Monthly unitAmount: 1999 currency: usd type: recurring recurring: interval: month intervalCount: 1 productKey: pro_plan metadata: displayName: Pro Monthly</code></pre> </div> <h2>Running the Synchronization</h2> <h3>Using the CLI</h3> <p>Sync your configuration using the command-line interface:</p> <div class="highlight"> <pre><code class="language-bash">npx prices-as-code pricing.ts</code></pre> </div> <p>Or for YAML:</p> <div class="highlight"> <pre><code class="language-bash">npx prices-as-code prices.yml</code></pre> </div> <h4>Push Model vs. Write-Back Model</h4> <p>By default, Prices as Code uses a <strong>Push Model</strong>, where it pushes your configuration to the provider but doesn't modify your local configuration files. This is useful when:</p> <ul> <li>You want to use the same configuration file to push to different environments (dev, staging, production)</li> <li>You're working with providers that don't allow setting IDs programmatically</li> <li>You want to maintain a clean separation between your configuration and provider-specific IDs</li> </ul> <p>If you prefer the original behavior where provider IDs are written back to your configuration file, use the <code>--write-back</code> flag:</p> <div class="highlight"> <pre><code class="language-bash">npx prices-as-code prices.yml --write-back</code></pre> </div> <h3>Using the JavaScript API</h3> <p>You can also use the JavaScript API in your own scripts:</p> <div class="highlight"> <pre><code class="language-typescript">import { pac } from 'prices-as-code'; async function syncPricing() { try { const result = await pac({ configPath: './pricing.ts', providers: [ { provider: 'stripe', options: { secretKey: process.env.STRIPE_SECRET_KEY, } } ], // Set to true to write updated IDs back to config file (legacy behavior) // Default is false - PUSH mode (push to provider without modifying source) writeBack: false }); console.log('Sync result:', result); } catch (error) { console.error('Sync failed:', error); } } syncPricing();</code></pre> </div> <h2>Sample Configuration</h2> <div class="sample-config"> <h3>Real-World Example</h3> <p>Here's a comprehensive example based on a tiered subscription model:</p> <div class="highlight"> <pre><code class="language-yaml">products: - name: Free description: Start your learning journey metadata: icon: Book color: blue key: free features: - Access to free content - Limited features - Core lessons - Ad-supported experience highlight: false provider: stripe key: free - name: Pro description: Help us shine bright with new features metadata: icon: Star color: purple key: pro features: - Support ongoing development - Supporter recognition - Early access to new features - Ad-free experience - Unlimited access highlight: true provider: stripe key: pro - name: Ultra description: The ultimate experience metadata: icon: Trophy color: amber key: ultra features: - All Pro perks - Ultra member recognition - Input on future features - Priority support - Personalized plans highlight: false provider: stripe key: ultra prices: - name: Free unitAmount: 0 currency: usd type: recurring recurring: interval: year intervalCount: 1 active: true metadata: plan_code: free display_price: $0 nickname: Free plan provider: stripe productKey: free - name: Pro Monthly unitAmount: 1000 currency: usd type: recurring recurring: interval: month intervalCount: 1 active: true metadata: plan_code: pro_monthly display_price: $10 nickname: Pro Monthly Plan provider: stripe productKey: pro - name: Pro Yearly unitAmount: 9600 currency: usd type: recurring recurring: interval: year intervalCount: 1 active: true metadata: plan_code: pro_yearly display_price: $96 nickname: Pro Yearly Plan provider: stripe productKey: pro </code></pre> </div> </div> <h2>Next Steps</h2> <ul> <li>Check out <a href="configuration-file.html">Configuration File Format</a> to learn more about config options</li> <li>Set up <a href="ci-cd.html">CI/CD Integration</a> to automate your pricing updates</li> <li>Learn about <a href="custom-pricing.html">Custom Pricing Logic</a> for more complex scenarios</li> <li>Explore <a href="metadata.html">Metadata Usage</a> for enhanced flexibility</li> </ul> </div> </main> <footer class="site-footer"> <div class="container"> <div class="footer-content"> <p>Copyright &copy; 2025 Nate Ross. Distributed by an <a href="https://github.com/wickdninja/prices-as-code/blob/main/LICENSE">MIT license.</a></p> <p><a href="#top" class="back-to-top">Back to top</a></p> </div> </div> </footer> <script src="../assets/js/main.js"></script> <script> function showTab(tabId) { // Hide all tab contents document.querySelectorAll('.tab-content').forEach(tab => { tab.style.display = 'none'; }); // Remove active class from all tabs document.querySelectorAll('.tab').forEach(tab => { tab.classList.remove('active'); }); // Show the selected tab content document.getElementById(tabId + '-tab').style.display = 'block'; // Add active class to the clicked tab document.querySelector(`.tab[onclick="showTab('${tabId}')"]`).classList.add('active'); } </script> </body> </html>