Skill: ivangdavila/ecommerce (version 1.0.0)

--- name: Ecommerce slug: ecommerce version: 1.0.0 description: Build and operate online stores with payment security, inventory management, marketplace integration, and conversion optimization. metadata: {"clawdbot":{"emoji":"🛒","requires":{"bins":[]},"os":["linux","darwin","win32"]}} --- ## Quick Reference | Topic | File | |-------|------| | Code traps that break production | `code-traps.md` | | Platform comparison (costs, features) | `platforms.md` | | Operations (stock, shipping, returns) | `operations.md` | | Growth (CRO, upsells, LTV, benchmarks) | `growth.md` | ## Critical Code Traps These break production and cost real money. See `code-traps.md` for full patterns. 1. **Payment idempotency** — Store `payment_intent_id`, check before processing. Webhooks retry. 2. **Inventory race conditions** — `UPDATE ... WHERE stock > 0` with `rowsAffected` check, not read-then-write. 3. **Frontend price trust** — Backend recalculates everything. Never trust client totals. 4. **Webhook signatures** — Verify `stripe-signature` or equivalent. Reject unsigned requests. 5. **Stock validation timing** — Verify at payment moment, not just add-to-cart. ## Core Rules ### When Building Stores - Calculate ALL prices server-side — discounts, shipping, taxes, totals - Queue transactional emails — never inline in checkout flow - Add structured data (Schema.org Product) and canonical URLs from day one - Implement webhook signature verification before going live ### When Operating Stores - Monitor stock thresholds, not just zero — alert at reorder point - Track orders stuck in "processing" >24h — detect before customer complains - Log payment failures with context — card decline reasons matter for recovery ### When Optimizing - Checkout recovery: 1h, 24h, 72h sequence — discount on email 3, not 1 - Free shipping threshold: current AOV + 20-30% - Mobile: sticky add-to-cart, Apple Pay/Google Pay, LCP <2.5s ## Platform Decision Tree - **Budget <€500/mo, <100 SKUs**: Shopify Basic or WooCommerce self-hosted - **Multi-marketplace**: Dedicated sync tool (not manual updates) - **>1000 SKUs or ERP**: WooCommerce/custom with PIM integration For Spain-specific costs (IVA, OSS, carriers), see `platforms.md`. ## Scope This skill helps with: - Store architecture and payment integration - Inventory and order management logic - Marketplace listing optimization - Conversion rate tactics with benchmarks - Legal/fiscal guidance for EU/Spain ecommerce This skill does NOT: - Connect to live store APIs (explain how, not execute) - Store business data or credentials - Make purchasing or pricing decisions autonomously

path: code-traps.md
content: # Code Traps — Ecommerce Production Failures

## 1. Payment Idempotency

**Problem:** Webhook arrives twice (retry), order processes twice, customer charged twice.

**Wrong:**
```javascript
app.post('/webhook', async (req, res) => {
  const order = await createOrder(req.body);
  await chargePayment(order);
  res.sendStatus(200);
});
```

**Correct:**
```javascript
app.post('/webhook', async (req, res) => {
  const paymentIntentId = req.body.data.object.id;
  
  // Check if already processed
  const existing = await db.orders.findOne({ paymentIntentId });
  if (existing) return res.sendStatus(200);
  
  // Process with unique constraint as backup
  await db.orders.create({ paymentIntentId, ...orderData });
  res.sendStatus(200);
});
```

## 2. Inventory Race Conditions

**Problem:** Two users buy last item simultaneously, both succeed, stock goes negative.

**Wrong:**
```javascript
const product = await db.products.findById(id);
if (product.stock > 0) {
  await db.products.update(id, { stock: product.stock - 1 });
}
```

**Correct:**
```sql
UPDATE products 
SET stock = stock - 1 
WHERE id = $1 AND stock > 0
RETURNING stock;
-- Check rowsAffected/returning to confirm success
```

## 3. Frontend Price Trust

**Problem:** User modifies JavaScript, sends total: €0.01, backend trusts it.

**Rule:** Backend calculates everything from scratch:
- Fetch product prices from DB (not request)
- Apply discounts from DB rules (not request)
- Calculate shipping from weight/destination (not request)
- Sum taxes from jurisdiction rules (not request)
- Compare final total — reject if client total differs

## 4. Webhook Signature Verification

**Problem:** Anyone can POST to `/webhook`, mark orders as paid.

**Wrong:**
```javascript
app.post('/webhook', (req, res) => {
  if (req.body.type === 'payment_intent.succeeded') {
    markOrderPaid(req.body.data.object.id);
  }
});
```

**Correct:**
```javascript
app.post('/webhook', (req, res) => {
  const sig = req.headers['stripe-signature'];
  let event;
  try {
    event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
  } catch (err) {
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }
  // Now safe to process event
});
```

## 5. Stock Validation Timing

**Problem:** User adds to cart, waits 2 hours, pays — product sold out meanwhile.

**Correct flow:**
1. Add to cart — soft reserve (optional) or just allow
2. Begin checkout — verify stock, show warning if low
3. Create payment intent — **atomic stock decrement with transaction**
4. Payment fails — rollback stock
5. Payment succeeds — stock already decremented

## 6. Email Queue Failures

**Problem:** Email service down → checkout fails or email lost silently.

**Wrong:**
```javascript
const order = await createOrder(data);
await sendConfirmationEmail(order); // If this fails, what happens?
return order;
```

**Correct:**
```javascript
const order = await createOrder(data);
await emailQueue.add('order-confirmation', { orderId: order.id });
// Queue handles retries with exponential backoff
return order;
```

## 7. SEO Gaps

**Checklist for every product page:**
- [ ] Canonical URL (prevent duplicate content from filters/params)
- [ ] Schema.org Product markup (price, availability, reviews)
- [ ] Unique meta description with product name + key features
- [ ] Product in XML sitemap with lastmod date
- [ ] Image alt text with product name

**Structured data minimum:**
```json
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Product Name",
  "image": "https://...",
  "offers": {
    "@type": "Offer",
    "price": "29.99",
    "priceCurrency": "EUR",
    "availability": "https://schema.org/InStock"
  }
}
```


path: growth.md
content: # Growth — CRO, Upsells, Retention, Benchmarks

## Checkout Abandonment Recovery

### Email Sequence
| Email | Timing | Content | Discount |
|-------|--------|---------|----------|
| 1 | 1 hour | "You left items behind" + cart contents | None |
| 2 | 24 hours | "Still interested?" + social proof | None |
| 3 | 72 hours | "Last chance" + urgency | 10% or free shipping |

**Expected recovery rate:** 5-15% of abandoned carts

### Exit-Intent Popup
**Use when:** Cart >€30, not returning visitor
**Copy:** "Wait! Get 10% off your first order" (email capture)
**Don't:** Show every time, show to returning visitors, show on mobile (annoying)

## Upsells & Cross-sells

### Placement Priority
1. **Cart page** — "Frequently bought together" (highest conversion)
2. **Post-purchase page** — One-click add (no re-enter payment)
3. **Checkout page** — Small add-ons only (don't distract from completing)
4. **Product page** — Related products (lower intent)

### What to Offer
| Strategy | Example | Expected lift |
|----------|---------|---------------|
| Complementary | Phone + case | +15-25% AOV |
| Upgrade | 64GB → 128GB | +10-20% AOV |
| Bundle discount | Buy 2, get 10% off | +20-30% AOV |
| Protection plan | Warranty | +5-10% revenue |

### Post-Purchase Upsell
Show on thank-you page:
- Related product at 15% discount
- One-click add to existing order
- Time-limited (10 min countdown)

**Conversion:** 2-5% of buyers add item

## Average Order Value (AOV)

### Tactics with Expected Impact
| Tactic | Implementation | Expected Impact |
|--------|----------------|-----------------|
| Free shipping threshold | AOV × 1.25 | +10-15% AOV |
| Bundle discounts | "Complete the look" | +15-25% AOV |
| Volume discounts | Buy 3+, save 15% | +20-30% AOV |
| Gift with purchase | Free item at €X | +8-12% AOV |
| Tiered pricing | Show "most popular" middle option | +10-20% AOV |

### Free Shipping Calculator
```
If current AOV = €40
Set threshold = €50 (AOV × 1.25)
Show progress bar: "Add €12 more for free shipping!"
```

## Customer Lifetime Value (LTV)

### Basic Calculation
```
LTV = AOV × Purchase Frequency × Customer Lifespan
```

**Example:**
- AOV: €50
- Purchases per year: 3
- Average customer stays: 2 years
- LTV = €50 × 3 × 2 = €300

### CAC Ratio
**Healthy:** LTV:CAC = 3:1 or better
- LTV €300, CAC should be ≤€100
- If CAC >€100, you're losing money acquiring customers

### Retention Tactics by Stage

| Stage | Timing | Tactic |
|-------|--------|--------|
| Post-purchase | Day 7 | "How's your purchase?" email |
| Post-purchase | Day 14 | Request review + discount for next |
| Nurture | Day 30 | Related products email |
| Nurture | Day 60 | "We miss you" + 15% off |
| Win-back | Day 90 | "Come back" + 20% off |
| Win-back | Day 180 | Last attempt + best offer |

### When is Customer "Lost"?
```
If no purchase in (3 × average purchase cycle):
  → Customer considered churned
  → Move to win-back sequence
```

## Product Page Conversion

### Must-Haves
- [ ] High-quality images (multiple angles, zoom)
- [ ] Price clearly visible (no "request quote")
- [ ] Stock status (creates urgency if low)
- [ ] Shipping estimate for visitor's location
- [ ] Reviews (minimum 5 for credibility)
- [ ] Clear CTA button (contrasting color)

### Trust Elements
| Element | Placement | Impact |
|---------|-----------|--------|
| Reviews with photos | Below main image | +15-25% conversion |
| "X people viewing" | Near CTA | +5-10% conversion |
| Money-back guarantee | Near CTA | +10-15% conversion |
| Secure payment badges | Near CTA | +3-5% conversion |
| Delivery date estimate | Near CTA | +5-10% conversion |

### Urgency/Scarcity
**Ethical use:**
- Real stock count ("Only 3 left")
- Real deadline ("Sale ends Sunday")
- Real demand ("12 sold today")

**Avoid:**
- Fake countdown timers that reset
- "Last one!" when you have 100
- Pressure tactics that erode trust

## A/B Testing

### What to Test (Priority Order)
1. **Headlines** — Biggest impact, fastest to test
2. **CTA button** — Color, text, size
3. **Price display** — With/without anchoring, payment plans
4. **Social proof** — Position, format, quantity
5. **Layout** — Only after above optimized

### Sample Size Calculator
```
Minimum visitors per variation:
n = (16 × p × (1-p)) / MDE²

p = baseline conversion rate
MDE = minimum detectable effect (e.g., 0.05 for 5% lift)
```

**Example:**
- Baseline conversion: 3% (p = 0.03)
- Want to detect 10% relative lift (MDE = 0.003)
- n = (16 × 0.03 × 0.97) / 0.003² ≈ 52,000 per variation

**Rule of thumb:** At least 100 conversions per variation before concluding.

### Duration
- Minimum: 1 full week (capture day-of-week effects)
- Maximum: 4 weeks (avoid sample pollution)
- Stop early only if >99% statistical significance

## Mobile Optimization

### Critical Elements
| Element | Requirement |
|---------|-------------|
| LCP (Largest Contentful Paint) | <2.5 seconds |
| Add to cart | Sticky/floating button |
| Checkout | Single page or minimal steps |
| Payment | Apple Pay / Google Pay enabled |
| Images | Lazy load, compressed, WebP |

### Mobile Checkout Checklist
- [ ] Auto-fill enabled (addresses, cards)
- [ ] Number keyboard for phone/card fields
- [ ] Progress indicator (step 1 of 3)
- [ ] Guest checkout option
- [ ] Express payment buttons above fold

### Mobile vs Desktop Benchmarks
| Metric | Desktop | Mobile |
|--------|---------|--------|
| Conversion rate | 3-4% | 1.5-2% |
| Bounce rate | 40-50% | 50-60% |
| AOV | Higher | 10-20% lower |
| Cart abandonment | 70% | 85% |

**Implication:** Mobile drives traffic, desktop closes sales. Optimize mobile for email capture and retargeting.


path: operations.md
content: # Operations — Stock, Orders, Shipping, Returns

## Inventory Management

### Stock Alerts
Don't alert at zero — alert at reorder point:

```
Reorder Point = (Daily Sales × Lead Time) + Safety Stock
```

**Example:**
- Sell 5 units/day
- Supplier takes 7 days to deliver
- Safety stock: 10 units (2 days buffer)
- Reorder point: (5 × 7) + 10 = 45 units

### Multi-channel Sync
**Problem:** Sell on Amazon + own store, stock out of sync, overselling.

**Solution hierarchy:**
1. **Single source of truth** — One system holds real stock
2. **Sync frequency** — Real-time for <100 SKUs, every 5-15 min for larger
3. **Reserve buffer** — Keep 10-20% reserve to absorb sync delays
4. **Oversell handling** — Automatic notification + refund workflow

### Stock Audit
Monthly check:
- [ ] Physical count vs system count
- [ ] Identify shrinkage (theft, damage, miscounts)
- [ ] Dead stock (no sales in 90+ days)
- [ ] Slow movers (bottom 20% by velocity)

## Order Management

### Order Statuses
Minimum states for visibility:
1. **Pending Payment** — Awaiting confirmation
2. **Processing** — Payment confirmed, preparing
3. **Shipped** — Handed to carrier, tracking available
4. **Delivered** — Carrier confirms delivery
5. **Completed** — Past return window

### Problem Detection
Alert on:
- Orders in "Processing" >24h (business hours)
- Orders in "Pending Payment" >1h (payment timeout)
- Shipping not scanned >48h after ship date
- Multiple failed delivery attempts

### Fraud Signals
Review manually when:
- Shipping ≠ billing address + high value
- Multiple orders same IP, different cards
- Express shipping + first-time buyer + high value
- Email domain doesn't match name pattern
- Shipping to freight forwarder

## Shipping

### Carrier Selection Logic
```
If weight < 1kg AND value < €50:
  Use economy carrier (Correos, GLS)
Else if value > €200:
  Use tracked + insured (SEUR, UPS)
Else if express requested:
  Use fastest available with tracking
Else:
  Use best rate with tracking
```

### Tracking Notifications
**Minimum touchpoints:**
1. Order confirmed (immediate)
2. Shipped (with tracking link)
3. Out for delivery (same day)
4. Delivered (request review)

### Shipping Cost Display
**Pre-checkout:** Show estimate based on cart weight/value
**Checkout:** Calculate exact based on address

**Free shipping threshold formula:**
```
Threshold = Current AOV × 1.25
```
If AOV is €40, free shipping at €50 pushes basket size up.

## Returns & Refunds

### Spain/EU Legal Requirements
- 14 days withdrawal right (no reason needed)
- Starts from delivery date
- Customer pays return shipping (unless you offered free)
- Refund within 14 days of receiving return
- Exceptions: custom items, sealed hygiene products opened

### Return Flow
```
1. Customer requests return (form/email)
2. Generate return label (or instructions)
3. Receive package
4. Inspect within 48h
5. Refund or partial refund (with justification)
6. Update inventory
```

### Handling Abuse
Track return rate per customer:
- <5% → Normal
- 5-15% → Monitor
- >15% → Review history, consider restrictions

**Never:**
- Block returns for legitimate requests
- Delay refunds past 14 days
- Require receipt when you have order history

### Partial Refund Scenarios
| Situation | Action |
|-----------|--------|
| Product damaged by customer | Refund minus repair/depreciation |
| Product used beyond "testing" | Refund minus value reduction |
| Missing parts | Refund minus parts cost |
| Product not returned after 30 days | No refund, email reminder |

## Customer Service

### Response Time Targets
| Channel | First Response | Resolution |
|---------|---------------|------------|
| Email | <4h (business hours) | <24h |
| Chat | <2 min | <15 min |
| Phone | <30 sec answer | <5 min |
| Social | <1h | <4h |

### Escalation Rules
Escalate to human when:
- Order value >€200
- Customer mentions "lawyer", "complaint", "chargeback"
- Third contact about same issue
- Refund request after return window
- Suspected fraud (either direction)

### Compensation Guidelines
| Issue | Compensation |
|-------|-------------|
| Late delivery (1-2 days) | Apology + 5% discount next order |
| Late delivery (3+ days) | Apology + shipping refund |
| Wrong item sent | Free return + correct item + 10% discount |
| Damaged in transit | Full refund or replacement + 10% discount |
| Out of stock after order | Full refund + 15% discount |

**Rule:** Cost of keeping customer < cost of acquiring new one.


path: platforms.md
content: # Platforms — Costs and Decision Framework

## Platform Comparison (Spain, 2024)

### Shopify
| Tier | Monthly | Transaction Fee | Best For |
|------|---------|-----------------|----------|
| Basic | €27 | 2% (+ payment processor) | Starting out, <€10k/mo |
| Shopify | €79 | 1% | Growing, €10-50k/mo |
| Advanced | €289 | 0.5% | €50k+/mo, need reports |

**Real cost for €5,000/mo revenue:** ~€77-127/mo (plan + fees)

**Pros:** Fast setup, hosted, good apps ecosystem
**Cons:** Transaction fees stack, limited customization, vendor lock-in

### WooCommerce
| Component | Monthly Cost |
|-----------|--------------|
| Hosting (decent) | €15-30 |
| SSL | Free (Let's Encrypt) |
| Essential plugins | €10-50 |
| Maintenance time | Your hours |

**Real cost:** €25-80/mo + your time

**Pros:** No transaction fees, full control, one-time plugin purchases
**Cons:** You handle security, updates, backups, scaling

### Marketplaces (Amazon, eBay, Miravia)

| Platform | Commission | Monthly Fee |
|----------|------------|-------------|
| Amazon | 7-15% by category | €39 (Pro) |
| eBay | 10-12% | Free to €30 |
| Miravia | 5-10% | Free (2024) |

**When to use:** Existing traffic, product validation, no marketing budget

## Payment Processors (Spain)

| Provider | Fee per transaction |
|----------|---------------------|
| Stripe | 1.4% + €0.25 (EU cards) |
| PayPal | 2.9% + €0.35 |
| Redsys (bank TPV) | Negotiable, typically 0.5-1% |

**For €30 sale:**
- Stripe: €0.67 fee → €29.33 net
- PayPal: €1.22 fee → €28.78 net
- Bank TPV: ~€0.30 fee → €29.70 net

**Recommendation:** Bank TPV for lowest fees once volume justifies setup.

## Shipping Carriers (Spain)

### Rates for 1kg package, peninsula
| Carrier | Retail Rate | Volume Rate (50+ pkgs/mo) |
|---------|-------------|---------------------------|
| Correos | €7-9 | €4-5 |
| SEUR | €8-12 | €4-6 |
| MRW | €7-10 | €3.50-5 |
| GLS | €6-9 | €3-4.50 |

**Aggregators (Packlink, Sendcloud):** Good for starting, rates between retail and volume.

## Legal Requirements (Spain)

### Mandatory documents
1. **Aviso Legal** — Company data, CIF/NIF
2. **Política de Privacidad** — GDPR compliant, cookies
3. **Condiciones de Venta** — Returns (14 days mandatory), warranties
4. **Cookies banner** — Consent before non-essential cookies

**Cost:** €50-150 for decent templates, €300-800 for lawyer review

### IVA / VAT
| Situation | Requirement |
|-----------|-------------|
| Sell only in Spain | Standard IVA (21%) |
| Sell to EU consumers <€10k/year | Your country's VAT |
| Sell to EU consumers >€10k/year | Register OSS (One-Stop Shop) |
| Sell outside EU | No IVA, but customs duties for buyer |

**OSS:** Single registration in Spain, report quarterly, pay VAT to each country.

### Autónomo
- **When:** Once you have regular income, or always if significant volume
- **Cost:** €80/mo (tarifa plana first 12 months), then €300+/mo
- **Alternative:** Start with "actividad económica" declaration without autónomo for very low volume

## Decision Checklist

### "Should I use Shopify or WooCommerce?"
- [ ] Do you have technical skills or access? → WooCommerce saves fees
- [ ] Need to launch in <1 week? → Shopify faster
- [ ] Budget <€30/mo? → WooCommerce
- [ ] Want zero maintenance? → Shopify
- [ ] Need heavy customization? → WooCommerce

### "Should I sell on marketplaces?"
- [ ] No existing audience? → Yes, for visibility
- [ ] High-margin products (>40%)? → Marketplaces viable
- [ ] Low-margin products? → Own store only (fees kill margin)
- [ ] Validating product-market fit? → Marketplaces first


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)