From 48022f38d4e6d137e19d524a1025983981d7fcc6 Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 3 Nov 2025 21:58:14 +0100 Subject: [PATCH] Add comprehensive API documentation for QR Code Generation API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Document QR Code Generation API with three calculation types (fuel, distance, custom) - Include PNG vs SVG format comparison table with use case recommendations - Provide usage examples in cURL, JavaScript, Python, and HTML - Document Checkout API endpoints - Add best practices, error handling, and future enhancements section - Clarify that vessel metadata in QR codes is informational only (not stored in orders) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- API_DOCUMENTATION.md | 417 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 417 insertions(+) create mode 100644 API_DOCUMENTATION.md diff --git a/API_DOCUMENTATION.md b/API_DOCUMENTATION.md new file mode 100644 index 0000000..ce90a22 --- /dev/null +++ b/API_DOCUMENTATION.md @@ -0,0 +1,417 @@ +# Puffin Offset API Documentation + +## Table of Contents +- [QR Code Generation API](#qr-code-generation-api) + - [Endpoint](#endpoint) + - [Request Format](#request-format) + - [Calculation Types](#calculation-types) + - [Response Format](#response-format) + - [Format Comparison (PNG vs SVG)](#format-comparison-png-vs-svg) + - [Usage Examples](#usage-examples) +- [Checkout API](#checkout-api) +- [Best Practices](#best-practices) +- [Error Handling](#error-handling) + +## QR Code Generation API + +### Endpoint +``` +POST /api/qr-code/generate +``` + +Generate QR codes that encode carbon calculation parameters. The QR code directs users to the Puffin Offset calculator with pre-filled calculation data. + +### Request Format + +The API accepts three types of calculations: + +#### 1. Fuel-Based Calculation +Calculate carbon offset based on fuel consumption: + +```json +{ + "calculationType": "fuel", + "fuelAmount": 1000, + "fuelUnit": "liters", + "vessel": { + "imo": "1234567", + "name": "Sample Yacht", + "type": "Motor Yacht", + "enginePower": 2250 + }, + "timestamp": "2025-03-15T10:00:00Z", + "source": "marina-api" +} +``` + +**Fields:** +- `calculationType`: Must be `"fuel"` +- `fuelAmount`: Number of fuel units consumed +- `fuelUnit`: Either `"liters"` or `"gallons"` +- `vessel`: Optional vessel metadata (for informational purposes only) +- `timestamp`: Optional ISO timestamp +- `source`: Optional identifier (e.g., "marina-api", "broker-portal") + +#### 2. Distance-Based Calculation +Calculate carbon offset based on trip distance and vessel characteristics: + +```json +{ + "calculationType": "distance", + "distance": 150, + "speed": 12, + "fuelRate": 85, + "vessel": { + "imo": "1234567", + "name": "Sample Yacht", + "type": "Motor Yacht", + "enginePower": 2250 + }, + "timestamp": "2025-03-15T10:00:00Z", + "source": "marina-api" +} +``` + +**Fields:** +- `calculationType`: Must be `"distance"` +- `distance`: Distance in nautical miles +- `speed`: Average speed in knots +- `fuelRate`: Fuel consumption rate in liters per hour +- `vessel`: Optional vessel metadata +- `timestamp`: Optional ISO timestamp +- `source`: Optional identifier + +#### 3. Custom Amount +Direct monetary amount for carbon offsetting: + +```json +{ + "calculationType": "custom", + "customAmount": 250.00, + "vessel": { + "name": "Corporate Event", + "type": "Conference" + }, + "timestamp": "2025-03-15T10:00:00Z", + "source": "event-organizer" +} +``` + +**Fields:** +- `calculationType`: Must be `"custom"` +- `customAmount`: Dollar amount (USD) for direct offset purchase +- `vessel`: Optional context information +- `timestamp`: Optional ISO timestamp +- `source`: Optional identifier + +### Response Format + +The API returns both PNG and SVG formats of the QR code: + +```json +{ + "success": true, + "data": { + "qrCodeDataURL": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...", + "qrCodeSVG": "...", + "url": "https://puffinoffset.com/calculator?qr=eyJjYWxjdWxhdGlvblR5cGUiOi...", + "expiresAt": "2025-04-14T10:00:00.000Z" + } +} +``` + +**Response Fields:** +- `qrCodeDataURL`: Base64-encoded PNG image as data URL (ready for `` src) +- `qrCodeSVG`: SVG markup string (ready for direct HTML injection) +- `url`: The full URL that the QR code points to +- `expiresAt`: ISO timestamp when the QR code expires (30 days from generation) + +### Format Comparison (PNG vs SVG) + +| Feature | PNG (qrCodeDataURL) | SVG (qrCodeSVG) | +|---------|---------------------|-----------------| +| **Format** | Base64-encoded PNG as data URL | SVG markup string | +| **Use Case** | Email, printing, basic displays | Web, scaling, professional prints | +| **File Size** | Larger (~5-10 KB) | Smaller (~2-4 KB) | +| **Scalability** | Pixelated when enlarged | Perfect at any size | +| **Browser Support** | Universal | Universal (all modern browsers) | +| **Best For** | Quick implementation, emails | Websites, responsive design, high-DPI displays | +| **Embedding** | `` | Direct HTML injection or `` | + +**When to Use PNG:** +- Email campaigns (better compatibility) +- Print materials with fixed sizes +- Quick prototyping +- When exact pixel dimensions are known + +**When to Use SVG:** +- Responsive web design +- High-resolution displays (Retina, 4K) +- Professional print materials (scales to any size) +- When minimizing file size is important +- Dynamic styling with CSS + +### Usage Examples + +#### cURL +```bash +curl -X POST https://puffinoffset.com/api/qr-code/generate \ + -H "Content-Type: application/json" \ + -d '{ + "calculationType": "distance", + "distance": 150, + "speed": 12, + "fuelRate": 85, + "vessel": { + "imo": "1234567", + "name": "Sample Yacht" + } + }' +``` + +#### JavaScript (Fetch API) +```javascript +const response = await fetch('https://puffinoffset.com/api/qr-code/generate', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + calculationType: 'fuel', + fuelAmount: 1000, + fuelUnit: 'liters', + vessel: { + name: 'Sample Yacht', + imo: '1234567' + } + }) +}); + +const { data } = await response.json(); +console.log('QR Code URL:', data.url); + +// Use PNG format +document.getElementById('qr-png').src = data.qrCodeDataURL; + +// Use SVG format +document.getElementById('qr-svg-container').innerHTML = data.qrCodeSVG; +``` + +#### Python +```python +import requests + +response = requests.post( + 'https://puffinoffset.com/api/qr-code/generate', + json={ + 'calculationType': 'custom', + 'customAmount': 250.00, + 'source': 'python-client' + } +) + +data = response.json()['data'] +print(f"QR Code URL: {data['url']}") +print(f"Expires at: {data['expiresAt']}") + +# Save PNG to file +import base64 +png_data = data['qrCodeDataURL'].split(',')[1] +with open('qr-code.png', 'wb') as f: + f.write(base64.b64decode(png_data)) + +# Save SVG to file +with open('qr-code.svg', 'w') as f: + f.write(data['qrCodeSVG']) +``` + +#### HTML Embedding + +**PNG Format:** +```html + +Carbon Offset QR Code +``` + +**SVG Format:** +```html + +
+ + + +
+ + +Carbon Offset QR Code +``` + +**Dynamic Sizing with SVG:** +```css +/* SVG automatically scales to container */ +#qr-container { + width: 100%; + max-width: 500px; + margin: 0 auto; +} + +#qr-container svg { + width: 100%; + height: auto; +} +``` + +## Checkout API + +### Create Checkout Session +``` +POST /api/checkout/create-session +``` + +Create a Stripe checkout session for carbon offset purchase. + +**Request Body:** +```json +{ + "tons": 2.5, + "portfolioId": 123, + "pricePerTon": 20.00, + "customerEmail": "customer@example.com" +} +``` + +**Response:** +```json +{ + "sessionId": "cs_test_...", + "url": "https://checkout.stripe.com/...", + "orderId": "order_abc123" +} +``` + +**Note:** Vessel information is NOT included in checkout sessions or stored in orders. Vessel metadata in QR codes is for informational purposes only. + +### Get Order Details +``` +GET /api/checkout/session/{sessionId} +``` + +Retrieve order details by Stripe session ID. + +**Response:** +```json +{ + "order": { + "id": "order_abc123", + "tons": 2.5, + "portfolioId": 123, + "baseAmount": 5000, + "processingFee": 180, + "totalAmount": 5180, + "currency": "USD", + "status": "paid", + "wrenOrderId": "wren_xyz789", + "stripeSessionId": "cs_test_...", + "createdAt": "2025-03-15T10:00:00.000Z" + }, + "session": { + "paymentStatus": "paid", + "customerEmail": "customer@example.com" + } +} +``` + +## Best Practices + +### QR Code Generation + +1. **Choose the Right Format:** + - Use **PNG** for emails, fixed-size prints, and quick prototypes + - Use **SVG** for websites, responsive designs, and high-quality prints + +2. **Include Metadata:** + - Always include `source` field to track where QR codes originate + - Include `timestamp` for auditing and expiration tracking + - Use descriptive `vessel` names for context + +3. **Handle Expiration:** + - QR codes expire after 30 days + - Check `expiresAt` timestamp in response + - Regenerate QR codes if needed for long-term use + +4. **Error Handling:** + - Validate input data before sending to API + - Handle network failures gracefully + - Display user-friendly error messages + +### Integration Recommendations + +1. **Marinas & Brokers:** + - Generate QR codes after trip logging + - Print QR codes on receipts or invoices + - Include vessel details for tracking + +2. **Event Organizers:** + - Use `custom` calculation type for flat-rate offsets + - Generate bulk QR codes for attendee packets + - Track source with `source` field + +3. **Mobile Apps:** + - Use SVG format for responsive display + - Cache QR codes locally to reduce API calls + - Implement QR code scanning for peer-to-peer sharing + +## Error Handling + +### Error Response Format +```json +{ + "success": false, + "error": "Invalid calculation type" +} +``` + +### Common Errors + +| Error | Cause | Solution | +|-------|-------|----------| +| "Invalid calculation type" | `calculationType` not "fuel", "distance", or "custom" | Use valid calculation type | +| "Missing required fields" | Required fields for calculation type not provided | Check calculation type requirements | +| "Invalid fuel unit" | `fuelUnit` not "liters" or "gallons" | Use valid fuel unit | +| "Invalid amount" | Negative or zero values | Provide positive values | +| 500 Server Error | Server-side issue | Retry request, contact support if persistent | + +### HTTP Status Codes + +- **200 OK**: QR code generated successfully +- **400 Bad Request**: Invalid request data (check error message) +- **500 Internal Server Error**: Server-side error (retry or contact support) + +## Future Enhancements + +The following features are planned for future releases: + +1. **Authentication:** API key authentication for rate limiting and analytics +2. **Batch Generation:** Generate multiple QR codes in a single request +3. **Custom Branding:** Add logos or custom colors to QR codes +4. **Analytics Dashboard:** Track QR code scans and conversion rates +5. **Webhook Support:** Receive notifications when QR codes are scanned or orders completed + +## Changelog + +### Version 1.0 (Current) +- Initial release +- Support for fuel-based, distance-based, and custom amount calculations +- PNG and SVG format outputs +- 30-day expiration +- No authentication required + +--- + +**Support:** For questions or issues, contact [support@puffinoffset.com](mailto:support@puffinoffset.com) + +**API Base URL:** `https://puffinoffset.com/api`