Browse Source

feat: add ShopRenter Payment API implementation plan #73

- Comprehensive implementation plan for ShopRenter Payment API integration
- Critical requirement: Payment API ONLY for ShopRenter stores
- Database schema for payment plans and transactions
- Backend Edge Functions implementation guide
- Store platform validation enforcement
- Payment flow and webhook handling
- Security considerations and testing strategy
- 7-week deployment timeline
- Complete with code examples and best practices
Claude 5 months ago
parent
commit
04aeba7
1 changed files with 1513 additions and 0 deletions
  1. 1513 0
      docs/shoprenter_payment_implementation_plan.md

+ 1513 - 0
docs/shoprenter_payment_implementation_plan.md

@@ -0,0 +1,1513 @@
+# ShopRenter Payment API Implementation Plan
+
+**Project:** ShopCall.ai - ShopRenter Payment Integration
+**Version:** 1.0
+**Date:** 2025-11-11
+**Status:** Planning Phase
+
+---
+
+## 📋 Table of Contents
+
+1. [Executive Summary](#executive-summary)
+2. [Background & Context](#background--context)
+3. [Critical Requirements](#critical-requirements)
+4. [Architecture Overview](#architecture-overview)
+5. [Database Schema](#database-schema)
+6. [Backend Implementation](#backend-implementation)
+7. [Payment Flow](#payment-flow)
+8. [Store Validation](#store-validation)
+9. [Security Considerations](#security-considerations)
+10. [Testing Strategy](#testing-strategy)
+11. [Deployment Plan](#deployment-plan)
+12. [Timeline & Milestones](#timeline--milestones)
+
+---
+
+## 🎯 Executive Summary
+
+This document outlines the implementation plan for integrating the ShopRenter Payment API into ShopCall.ai. The integration will enable **ShopRenter stores only** to subscribe to ShopCall.ai services and be billed directly through ShopRenter's payment infrastructure.
+
+### Key Objectives
+
+- ✅ Enable subscription-based billing for ShopRenter stores
+- ✅ Process payments exclusively through ShopRenter Payment API
+- ✅ Enforce strict store validation (ShopRenter stores only)
+- ✅ Implement automatic invoicing and VAT handling
+- ✅ Support both one-time and recurring payment plans
+- ✅ Maintain GDPR compliance and data security
+
+### Core Principle
+
+**⚠️ CRITICAL RULE:** The ShopRenter Payment API **MUST ONLY** be used with ShopRenter stores. Any non-ShopRenter store attempting to use this payment method must be rejected with appropriate error messages.
+
+---
+
+## 📖 Background & Context
+
+### What is ShopRenter Payment API?
+
+The ShopRenter Payment API is a comprehensive payment processing toolkit provided by ShopRenter for application developers. It enables:
+
+- **Card payment processing** (one-time and recurring)
+- **Automatic invoicing** with VAT calculation
+- **Subscription management** with payment plans
+- **Financial statistics** and income tracking
+- **Webhook notifications** for payment events
+
+### Current ShopCall.ai Integration Status
+
+ShopCall.ai already has a **fully implemented ShopRenter store integration** including:
+
+- ✅ OAuth 2.0 authentication flow
+- ✅ HMAC validation for security
+- ✅ Product, order, and customer data synchronization
+- ✅ Webhook handlers for data updates
+- ✅ Scheduled background sync (pg_cron)
+- ✅ Database tables for storing ShopRenter credentials and data
+
+**Reference:** See `docs/shoprenter_app_development.md` and `SHOPRENTER.md` for complete details.
+
+### Why Payment API Integration?
+
+Currently, ShopCall.ai uses a generic payment processor (e.g., Stripe) for all stores. Integrating ShopRenter Payment API provides:
+
+1. **Native billing** for ShopRenter merchants (billed through their ShopRenter account)
+2. **Simplified checkout** (no need to enter payment details separately)
+3. **Unified invoicing** (all invoices in one place - ShopRenter admin)
+4. **Better conversion** (trust and familiarity with ShopRenter billing)
+5. **Automatic VAT handling** (compliant with Hungarian tax laws)
+
+---
+
+## ⚠️ Critical Requirements
+
+### 1. Store Platform Validation (MANDATORY)
+
+**Rule:** The ShopRenter Payment API can **ONLY** be used with stores that have `platform_name = 'shoprenter'` in the `stores` table.
+
+**Enforcement Points:**
+- Payment page rendering (frontend)
+- Payment initiation API endpoint (backend)
+- Subscription creation endpoint (backend)
+- Webhook handlers (backend)
+
+**Validation Logic:**
+```typescript
+async function validateStoreForShopRenterPayment(storeId: string): Promise<boolean> {
+  const { data: store } = await supabase
+    .from('stores')
+    .select('platform_name, is_active')
+    .eq('id', storeId)
+    .single();
+
+  if (!store) {
+    throw new Error('Store not found');
+  }
+
+  if (!store.is_active) {
+    throw new Error('Store is inactive');
+  }
+
+  if (store.platform_name !== 'shoprenter') {
+    throw new Error('ShopRenter Payment API can only be used with ShopRenter stores');
+  }
+
+  return true;
+}
+```
+
+### 2. ShopRenter App Registration
+
+Before using the Payment API, the ShopCall.ai app must be:
+- ✅ Registered with ShopRenter Partner Support
+- ✅ Approved for use in production
+- ✅ Configured with Payment API access
+
+**Current Status:** ShopCall.ai is ready for registration (see `SHOPRENTER_REGISTRATION.md`).
+
+### 3. Required Credentials
+
+The Payment API will require additional credentials beyond the OAuth credentials:
+
+- `SHOPRENTER_CLIENT_ID` - OAuth client ID (already configured)
+- `SHOPRENTER_CLIENT_SECRET` - OAuth secret (already configured)
+- `SHOPRENTER_PAYMENT_API_KEY` - Payment API specific key (to be obtained)
+- `SHOPRENTER_PAYMENT_SECRET` - Payment API webhook secret (to be obtained)
+
+### 4. Scope Requirements
+
+The app must request payment-related scopes during OAuth:
+- `payment:read` - Read payment information
+- `payment:write` - Create payment plans and initiate charges
+- `billing:read` - Access billing data
+- `billing:write` - Update billing information
+
+---
+
+## 🏗️ Architecture Overview
+
+### System Components
+
+```
+┌─────────────────────┐
+│   ShopRenter        │
+│   Store Owner       │
+└──────────┬──────────┘
+           │
+           │ 1. Connect Store (OAuth)
+           ▼
+┌─────────────────────┐
+│   ShopCall.ai       │
+│   Frontend          │
+└──────────┬──────────┘
+           │
+           │ 2. Select Subscription Plan
+           ▼
+┌─────────────────────┐
+│   ShopCall.ai       │
+│   Backend           │
+│   (Edge Function)   │
+└──────────┬──────────┘
+           │
+           │ 3. Create Payment Plan
+           │    (via ShopRenter Payment API)
+           ▼
+┌─────────────────────┐
+│   ShopRenter        │
+│   Payment API       │
+└──────────┬──────────┘
+           │
+           │ 4. Process Payment
+           │    (Automatic Recurring Billing)
+           ▼
+┌─────────────────────┐
+│   ShopRenter        │
+│   Payment Gateway   │
+└──────────┬──────────┘
+           │
+           │ 5. Webhook Notification
+           │    (payment.success, payment.failed, etc.)
+           ▼
+┌─────────────────────┐
+│   ShopCall.ai       │
+│   Webhook Handler   │
+│   (Edge Function)   │
+└──────────┬──────────┘
+           │
+           │ 6. Update Subscription Status
+           ▼
+┌─────────────────────┐
+│   Supabase          │
+│   Database          │
+└─────────────────────┘
+```
+
+### Integration Flow
+
+1. **Store Connection**: Merchant connects ShopRenter store via OAuth (already implemented)
+2. **Subscription Selection**: Merchant selects a ShopCall.ai subscription plan
+3. **Platform Validation**: Backend validates `platform_name = 'shoprenter'`
+4. **Payment Plan Creation**: Backend creates payment plan via ShopRenter Payment API
+5. **Billing Data**: ShopRenter uses merchant's existing billing information
+6. **Automatic Billing**: ShopRenter charges merchant's card on schedule
+7. **Webhook Events**: ShopRenter sends payment status updates to ShopCall.ai
+8. **Subscription Management**: ShopCall.ai updates subscription status based on webhook events
+
+---
+
+## 💾 Database Schema
+
+### New Table: `shoprenter_payment_plans`
+
+Stores payment plans configured through ShopRenter Payment API.
+
+```sql
+CREATE TABLE shoprenter_payment_plans (
+  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+
+  -- Store reference
+  store_id UUID NOT NULL REFERENCES stores(id) ON DELETE CASCADE,
+
+  -- ShopRenter Payment API identifiers
+  payment_plan_id VARCHAR(255) NOT NULL, -- ID from ShopRenter Payment API
+  app_payment_id VARCHAR(255), -- Application-specific payment ID
+
+  -- Plan details
+  plan_name VARCHAR(255) NOT NULL, -- e.g., "Basic Plan", "Pro Plan"
+  plan_type VARCHAR(50) NOT NULL, -- "one_time", "recurring"
+  amount DECIMAL(10, 2) NOT NULL, -- Price in HUF
+  currency VARCHAR(3) DEFAULT 'HUF',
+  billing_frequency VARCHAR(50), -- "monthly", "yearly", "quarterly"
+
+  -- Status
+  status VARCHAR(50) NOT NULL DEFAULT 'pending', -- pending, active, cancelled, failed, expired
+
+  -- Timestamps from ShopRenter
+  trial_ends_at TIMESTAMPTZ, -- Trial period end (if applicable)
+  next_billing_date TIMESTAMPTZ, -- Next scheduled charge
+  activated_at TIMESTAMPTZ, -- When subscription became active
+  cancelled_at TIMESTAMPTZ, -- When subscription was cancelled
+  expires_at TIMESTAMPTZ, -- Expiration date
+
+  -- Metadata
+  raw_data JSONB, -- Full response from ShopRenter Payment API
+  created_at TIMESTAMPTZ DEFAULT NOW(),
+  updated_at TIMESTAMPTZ DEFAULT NOW(),
+
+  -- Constraints
+  UNIQUE(store_id, payment_plan_id)
+);
+
+-- Indexes
+CREATE INDEX idx_shoprenter_payment_plans_store ON shoprenter_payment_plans(store_id);
+CREATE INDEX idx_shoprenter_payment_plans_status ON shoprenter_payment_plans(status);
+CREATE INDEX idx_shoprenter_payment_plans_next_billing ON shoprenter_payment_plans(next_billing_date);
+
+-- Trigger for updated_at
+CREATE TRIGGER set_shoprenter_payment_plans_updated_at
+BEFORE UPDATE ON shoprenter_payment_plans
+FOR EACH ROW
+EXECUTE FUNCTION update_updated_at_column();
+```
+
+### New Table: `shoprenter_payment_transactions`
+
+Tracks individual payment transactions and webhook events.
+
+```sql
+CREATE TABLE shoprenter_payment_transactions (
+  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+
+  -- References
+  store_id UUID NOT NULL REFERENCES stores(id) ON DELETE CASCADE,
+  payment_plan_id UUID REFERENCES shoprenter_payment_plans(id) ON DELETE SET NULL,
+
+  -- ShopRenter identifiers
+  transaction_id VARCHAR(255) NOT NULL, -- Transaction ID from ShopRenter
+  charge_id VARCHAR(255), -- Charge ID from Payment API
+
+  -- Transaction details
+  transaction_type VARCHAR(50) NOT NULL, -- "charge", "refund", "update"
+  amount DECIMAL(10, 2) NOT NULL,
+  currency VARCHAR(3) DEFAULT 'HUF',
+  status VARCHAR(50) NOT NULL, -- "pending", "success", "failed", "refunded"
+
+  -- Payment method
+  payment_method VARCHAR(50), -- "card", "bank_transfer", etc.
+  card_last4 VARCHAR(4), -- Last 4 digits of card
+  card_brand VARCHAR(50), -- "visa", "mastercard", etc.
+
+  -- Invoice
+  invoice_number VARCHAR(255),
+  invoice_url TEXT,
+
+  -- Error handling
+  error_code VARCHAR(50),
+  error_message TEXT,
+
+  -- Timestamps
+  processed_at TIMESTAMPTZ,
+  refunded_at TIMESTAMPTZ,
+
+  -- Metadata
+  raw_data JSONB, -- Full webhook payload
+  created_at TIMESTAMPTZ DEFAULT NOW(),
+
+  -- Constraints
+  UNIQUE(transaction_id)
+);
+
+-- Indexes
+CREATE INDEX idx_shoprenter_transactions_store ON shoprenter_payment_transactions(store_id);
+CREATE INDEX idx_shoprenter_transactions_plan ON shoprenter_payment_transactions(payment_plan_id);
+CREATE INDEX idx_shoprenter_transactions_status ON shoprenter_payment_transactions(status);
+CREATE INDEX idx_shoprenter_transactions_date ON shoprenter_payment_transactions(created_at);
+```
+
+### Update Existing `stores` Table
+
+Add payment-related fields to track subscription status.
+
+```sql
+ALTER TABLE stores
+  ADD COLUMN IF NOT EXISTS shoprenter_payment_plan_id UUID REFERENCES shoprenter_payment_plans(id),
+  ADD COLUMN IF NOT EXISTS subscription_status VARCHAR(50) DEFAULT 'inactive',
+  ADD COLUMN IF NOT EXISTS subscription_started_at TIMESTAMPTZ,
+  ADD COLUMN IF NOT EXISTS subscription_ends_at TIMESTAMPTZ;
+
+-- Index for subscription queries
+CREATE INDEX IF NOT EXISTS idx_stores_subscription_status ON stores(subscription_status);
+```
+
+### Migration Script
+
+```sql
+-- Migration: Add ShopRenter Payment API support
+-- Version: 20251111_shoprenter_payment_api.sql
+
+BEGIN;
+
+-- Create payment plans table
+CREATE TABLE IF NOT EXISTS shoprenter_payment_plans (
+  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+  store_id UUID NOT NULL REFERENCES stores(id) ON DELETE CASCADE,
+  payment_plan_id VARCHAR(255) NOT NULL,
+  app_payment_id VARCHAR(255),
+  plan_name VARCHAR(255) NOT NULL,
+  plan_type VARCHAR(50) NOT NULL,
+  amount DECIMAL(10, 2) NOT NULL,
+  currency VARCHAR(3) DEFAULT 'HUF',
+  billing_frequency VARCHAR(50),
+  status VARCHAR(50) NOT NULL DEFAULT 'pending',
+  trial_ends_at TIMESTAMPTZ,
+  next_billing_date TIMESTAMPTZ,
+  activated_at TIMESTAMPTZ,
+  cancelled_at TIMESTAMPTZ,
+  expires_at TIMESTAMPTZ,
+  raw_data JSONB,
+  created_at TIMESTAMPTZ DEFAULT NOW(),
+  updated_at TIMESTAMPTZ DEFAULT NOW(),
+  UNIQUE(store_id, payment_plan_id)
+);
+
+CREATE INDEX idx_shoprenter_payment_plans_store ON shoprenter_payment_plans(store_id);
+CREATE INDEX idx_shoprenter_payment_plans_status ON shoprenter_payment_plans(status);
+CREATE INDEX idx_shoprenter_payment_plans_next_billing ON shoprenter_payment_plans(next_billing_date);
+
+-- Create payment transactions table
+CREATE TABLE IF NOT EXISTS shoprenter_payment_transactions (
+  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+  store_id UUID NOT NULL REFERENCES stores(id) ON DELETE CASCADE,
+  payment_plan_id UUID REFERENCES shoprenter_payment_plans(id) ON DELETE SET NULL,
+  transaction_id VARCHAR(255) NOT NULL,
+  charge_id VARCHAR(255),
+  transaction_type VARCHAR(50) NOT NULL,
+  amount DECIMAL(10, 2) NOT NULL,
+  currency VARCHAR(3) DEFAULT 'HUF',
+  status VARCHAR(50) NOT NULL,
+  payment_method VARCHAR(50),
+  card_last4 VARCHAR(4),
+  card_brand VARCHAR(50),
+  invoice_number VARCHAR(255),
+  invoice_url TEXT,
+  error_code VARCHAR(50),
+  error_message TEXT,
+  processed_at TIMESTAMPTZ,
+  refunded_at TIMESTAMPTZ,
+  raw_data JSONB,
+  created_at TIMESTAMPTZ DEFAULT NOW(),
+  UNIQUE(transaction_id)
+);
+
+CREATE INDEX idx_shoprenter_transactions_store ON shoprenter_payment_transactions(store_id);
+CREATE INDEX idx_shoprenter_transactions_plan ON shoprenter_payment_transactions(payment_plan_id);
+CREATE INDEX idx_shoprenter_transactions_status ON shoprenter_payment_transactions(status);
+CREATE INDEX idx_shoprenter_transactions_date ON shoprenter_payment_transactions(created_at);
+
+-- Update stores table
+ALTER TABLE stores
+  ADD COLUMN IF NOT EXISTS shoprenter_payment_plan_id UUID REFERENCES shoprenter_payment_plans(id),
+  ADD COLUMN IF NOT EXISTS subscription_status VARCHAR(50) DEFAULT 'inactive',
+  ADD COLUMN IF NOT EXISTS subscription_started_at TIMESTAMPTZ,
+  ADD COLUMN IF NOT EXISTS subscription_ends_at TIMESTAMPTZ;
+
+CREATE INDEX IF NOT EXISTS idx_stores_subscription_status ON stores(subscription_status);
+
+-- Create trigger for updated_at
+CREATE TRIGGER set_shoprenter_payment_plans_updated_at
+BEFORE UPDATE ON shoprenter_payment_plans
+FOR EACH ROW
+EXECUTE FUNCTION update_updated_at_column();
+
+COMMIT;
+```
+
+---
+
+## 🔧 Backend Implementation
+
+### File Structure
+
+```
+supabase/functions/
+├── shoprenter-payment-create/
+│   └── index.ts                    # Create payment plan endpoint
+├── shoprenter-payment-cancel/
+│   └── index.ts                    # Cancel subscription endpoint
+├── shoprenter-payment-update/
+│   └── index.ts                    # Update payment plan endpoint
+├── shoprenter-payment-webhook/
+│   └── index.ts                    # Payment webhook handler
+├── shoprenter-payment-status/
+│   └── index.ts                    # Check payment status endpoint
+└── _shared/
+    └── shoprenter-payment-client.ts # ShopRenter Payment API client
+```
+
+### 1. Payment API Client (`_shared/shoprenter-payment-client.ts`)
+
+```typescript
+import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
+
+interface PaymentPlanParams {
+  storeId: string;
+  planName: string;
+  planType: 'one_time' | 'recurring';
+  amount: number;
+  currency?: string;
+  billingFrequency?: 'monthly' | 'yearly' | 'quarterly';
+  trialDays?: number;
+}
+
+interface PaymentPlanResponse {
+  paymentPlanId: string;
+  status: string;
+  activatedAt?: string;
+  nextBillingDate?: string;
+  invoiceUrl?: string;
+}
+
+/**
+ * ShopRenter Payment API Client
+ * Handles all payment-related API calls to ShopRenter
+ */
+export class ShopRenterPaymentClient {
+  private apiKey: string;
+  private apiSecret: string;
+  private supabase: any;
+
+  constructor() {
+    this.apiKey = Deno.env.get('SHOPRENTER_PAYMENT_API_KEY')!;
+    this.apiSecret = Deno.env.get('SHOPRENTER_PAYMENT_SECRET')!;
+    this.supabase = createClient(
+      Deno.env.get('SUPABASE_URL')!,
+      Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
+    );
+  }
+
+  /**
+   * Validate that store is ShopRenter platform
+   */
+  async validateShopRenterStore(storeId: string): Promise<void> {
+    const { data: store, error } = await this.supabase
+      .from('stores')
+      .select('platform_name, is_active, store_name')
+      .eq('id', storeId)
+      .single();
+
+    if (error || !store) {
+      throw new Error('Store not found');
+    }
+
+    if (!store.is_active) {
+      throw new Error('Store is inactive');
+    }
+
+    if (store.platform_name !== 'shoprenter') {
+      throw new Error(
+        'ShopRenter Payment API can only be used with ShopRenter stores. ' +
+        `Current platform: ${store.platform_name}`
+      );
+    }
+  }
+
+  /**
+   * Get ShopRenter access token for store
+   */
+  async getAccessToken(storeId: string): Promise<string> {
+    const { data: store, error } = await this.supabase
+      .from('stores')
+      .select('api_key, token_expires_at, store_name')
+      .eq('id', storeId)
+      .single();
+
+    if (error || !store) {
+      throw new Error('Store credentials not found');
+    }
+
+    // Check if token needs refresh
+    const expiresAt = new Date(store.token_expires_at);
+    const now = new Date();
+    const bufferMinutes = 5;
+
+    if (expiresAt.getTime() - now.getTime() < bufferMinutes * 60 * 1000) {
+      // Token expired or expiring soon - refresh it
+      // Implementation depends on ShopRenter OAuth refresh flow
+      console.log(`[ShopRenter Payment] Token refresh needed for ${store.store_name}`);
+      // TODO: Implement token refresh
+    }
+
+    return store.api_key;
+  }
+
+  /**
+   * Create a payment plan via ShopRenter Payment API
+   */
+  async createPaymentPlan(params: PaymentPlanParams): Promise<PaymentPlanResponse> {
+    // 1. Validate store platform
+    await this.validateShopRenterStore(params.storeId);
+
+    // 2. Get store details
+    const { data: store } = await this.supabase
+      .from('stores')
+      .select('store_name, store_url')
+      .eq('id', params.storeId)
+      .single();
+
+    const accessToken = await this.getAccessToken(params.storeId);
+
+    // 3. Call ShopRenter Payment API
+    // NOTE: Actual API endpoint URL and structure to be confirmed with ShopRenter docs
+    const apiUrl = `https://${store.store_name}.api.shoprenter.hu/payment/plans`;
+
+    const response = await fetch(apiUrl, {
+      method: 'POST',
+      headers: {
+        'Authorization': `Bearer ${accessToken}`,
+        'Content-Type': 'application/json',
+        'X-ShopRenter-API-Key': this.apiKey,
+      },
+      body: JSON.stringify({
+        name: params.planName,
+        type: params.planType,
+        amount: params.amount,
+        currency: params.currency || 'HUF',
+        billing_frequency: params.billingFrequency,
+        trial_days: params.trialDays || 0,
+        return_url: `${Deno.env.get('FRONTEND_URL')}/billing/success`,
+        cancel_url: `${Deno.env.get('FRONTEND_URL')}/billing/cancel`,
+        notification_url: `${Deno.env.get('SUPABASE_URL')}/functions/v1/shoprenter-payment-webhook`,
+      }),
+    });
+
+    if (!response.ok) {
+      const error = await response.text();
+      console.error('[ShopRenter Payment] API error:', error);
+      throw new Error(`Payment plan creation failed: ${response.statusText}`);
+    }
+
+    const data = await response.json();
+    console.log('[ShopRenter Payment] Plan created:', data);
+
+    // 4. Store payment plan in database
+    await this.supabase
+      .from('shoprenter_payment_plans')
+      .insert({
+        store_id: params.storeId,
+        payment_plan_id: data.id,
+        plan_name: params.planName,
+        plan_type: params.planType,
+        amount: params.amount,
+        currency: params.currency || 'HUF',
+        billing_frequency: params.billingFrequency,
+        status: data.status || 'pending',
+        next_billing_date: data.next_billing_date,
+        raw_data: data,
+      });
+
+    return {
+      paymentPlanId: data.id,
+      status: data.status,
+      activatedAt: data.activated_at,
+      nextBillingDate: data.next_billing_date,
+      invoiceUrl: data.invoice_url,
+    };
+  }
+
+  /**
+   * Cancel a payment plan
+   */
+  async cancelPaymentPlan(storeId: string, paymentPlanId: string): Promise<void> {
+    // 1. Validate store platform
+    await this.validateShopRenterStore(storeId);
+
+    // 2. Get store details
+    const { data: store } = await this.supabase
+      .from('stores')
+      .select('store_name')
+      .eq('id', storeId)
+      .single();
+
+    const accessToken = await this.getAccessToken(storeId);
+
+    // 3. Call ShopRenter Payment API
+    const apiUrl = `https://${store.store_name}.api.shoprenter.hu/payment/plans/${paymentPlanId}/cancel`;
+
+    const response = await fetch(apiUrl, {
+      method: 'POST',
+      headers: {
+        'Authorization': `Bearer ${accessToken}`,
+        'Content-Type': 'application/json',
+        'X-ShopRenter-API-Key': this.apiKey,
+      },
+    });
+
+    if (!response.ok) {
+      const error = await response.text();
+      console.error('[ShopRenter Payment] Cancel error:', error);
+      throw new Error(`Payment plan cancellation failed: ${response.statusText}`);
+    }
+
+    // 4. Update database
+    await this.supabase
+      .from('shoprenter_payment_plans')
+      .update({
+        status: 'cancelled',
+        cancelled_at: new Date().toISOString(),
+        updated_at: new Date().toISOString(),
+      })
+      .eq('store_id', storeId)
+      .eq('payment_plan_id', paymentPlanId);
+
+    console.log(`[ShopRenter Payment] Plan cancelled: ${paymentPlanId}`);
+  }
+
+  /**
+   * Get payment plan status
+   */
+  async getPaymentPlanStatus(storeId: string, paymentPlanId: string): Promise<any> {
+    // 1. Validate store platform
+    await this.validateShopRenterStore(storeId);
+
+    // 2. Get store details
+    const { data: store } = await this.supabase
+      .from('stores')
+      .select('store_name')
+      .eq('id', storeId)
+      .single();
+
+    const accessToken = await this.getAccessToken(storeId);
+
+    // 3. Call ShopRenter Payment API
+    const apiUrl = `https://${store.store_name}.api.shoprenter.hu/payment/plans/${paymentPlanId}`;
+
+    const response = await fetch(apiUrl, {
+      method: 'GET',
+      headers: {
+        'Authorization': `Bearer ${accessToken}`,
+        'X-ShopRenter-API-Key': this.apiKey,
+      },
+    });
+
+    if (!response.ok) {
+      throw new Error(`Failed to fetch payment plan status: ${response.statusText}`);
+    }
+
+    return await response.json();
+  }
+}
+```
+
+### 2. Create Payment Plan Endpoint (`shoprenter-payment-create/index.ts`)
+
+```typescript
+import { serve } from 'https://deno.land/std@0.177.0/http/server.ts';
+import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
+import { ShopRenterPaymentClient } from '../_shared/shoprenter-payment-client.ts';
+
+serve(async (req) => {
+  // CORS headers
+  if (req.method === 'OPTIONS') {
+    return new Response(null, {
+      headers: {
+        'Access-Control-Allow-Origin': '*',
+        'Access-Control-Allow-Methods': 'POST, OPTIONS',
+        'Access-Control-Allow-Headers': 'authorization, content-type',
+      },
+    });
+  }
+
+  try {
+    // 1. Authenticate user
+    const authHeader = req.headers.get('Authorization');
+    if (!authHeader) {
+      return new Response(JSON.stringify({ error: 'Missing authorization header' }), {
+        status: 401,
+        headers: { 'Content-Type': 'application/json' },
+      });
+    }
+
+    const supabase = createClient(
+      Deno.env.get('SUPABASE_URL')!,
+      Deno.env.get('SUPABASE_ANON_KEY')!,
+      {
+        global: {
+          headers: { Authorization: authHeader },
+        },
+      }
+    );
+
+    const { data: { user }, error: authError } = await supabase.auth.getUser();
+    if (authError || !user) {
+      return new Response(JSON.stringify({ error: 'Unauthorized' }), {
+        status: 401,
+        headers: { 'Content-Type': 'application/json' },
+      });
+    }
+
+    // 2. Parse request body
+    const { store_id, plan_name, plan_type, amount, billing_frequency } = await req.json();
+
+    if (!store_id || !plan_name || !plan_type || !amount) {
+      return new Response(JSON.stringify({ error: 'Missing required fields' }), {
+        status: 400,
+        headers: { 'Content-Type': 'application/json' },
+      });
+    }
+
+    // 3. Verify store ownership
+    const { data: store } = await supabase
+      .from('stores')
+      .select('id, platform_name')
+      .eq('id', store_id)
+      .eq('user_id', user.id)
+      .single();
+
+    if (!store) {
+      return new Response(JSON.stringify({ error: 'Store not found or access denied' }), {
+        status: 403,
+        headers: { 'Content-Type': 'application/json' },
+      });
+    }
+
+    // 4. Validate ShopRenter platform (CRITICAL CHECK!)
+    if (store.platform_name !== 'shoprenter') {
+      return new Response(
+        JSON.stringify({
+          error: 'Invalid payment method',
+          message: 'ShopRenter Payment API can only be used with ShopRenter stores',
+          platform: store.platform_name,
+        }),
+        {
+          status: 400,
+          headers: { 'Content-Type': 'application/json' },
+        }
+      );
+    }
+
+    // 5. Create payment plan
+    const paymentClient = new ShopRenterPaymentClient();
+    const result = await paymentClient.createPaymentPlan({
+      storeId: store_id,
+      planName: plan_name,
+      planType: plan_type,
+      amount: amount,
+      billingFrequency: billing_frequency,
+    });
+
+    return new Response(
+      JSON.stringify({
+        success: true,
+        payment_plan_id: result.paymentPlanId,
+        status: result.status,
+        next_billing_date: result.nextBillingDate,
+        invoice_url: result.invoiceUrl,
+      }),
+      {
+        status: 200,
+        headers: { 'Content-Type': 'application/json' },
+      }
+    );
+  } catch (error) {
+    console.error('[ShopRenter Payment] Error:', error);
+    return new Response(
+      JSON.stringify({
+        error: 'Payment plan creation failed',
+        message: error.message,
+      }),
+      {
+        status: 500,
+        headers: { 'Content-Type': 'application/json' },
+      }
+    );
+  }
+});
+```
+
+### 3. Payment Webhook Handler (`shoprenter-payment-webhook/index.ts`)
+
+```typescript
+import { serve } from 'https://deno.land/std@0.177.0/http/server.ts';
+import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
+import { createHmac } from 'https://deno.land/std@0.177.0/node/crypto.ts';
+
+serve(async (req) => {
+  if (req.method !== 'POST') {
+    return new Response('Method not allowed', { status: 405 });
+  }
+
+  try {
+    // 1. Validate webhook signature (HMAC)
+    const body = await req.text();
+    const signature = req.headers.get('X-ShopRenter-Signature');
+    const secret = Deno.env.get('SHOPRENTER_PAYMENT_SECRET')!;
+
+    const expectedSignature = createHmac('sha256', secret)
+      .update(body)
+      .digest('hex');
+
+    if (signature !== expectedSignature) {
+      console.error('[ShopRenter Payment Webhook] Invalid signature');
+      return new Response('Invalid signature', { status: 403 });
+    }
+
+    // 2. Parse webhook payload
+    const payload = JSON.parse(body);
+    const { event, data } = payload;
+
+    console.log(`[ShopRenter Payment Webhook] Received: ${event}`, data);
+
+    const supabase = createClient(
+      Deno.env.get('SUPABASE_URL')!,
+      Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
+    );
+
+    // 3. Process webhook event
+    switch (event) {
+      case 'payment.success':
+        await handlePaymentSuccess(supabase, data);
+        break;
+
+      case 'payment.failed':
+        await handlePaymentFailed(supabase, data);
+        break;
+
+      case 'subscription.activated':
+        await handleSubscriptionActivated(supabase, data);
+        break;
+
+      case 'subscription.cancelled':
+        await handleSubscriptionCancelled(supabase, data);
+        break;
+
+      case 'subscription.expired':
+        await handleSubscriptionExpired(supabase, data);
+        break;
+
+      default:
+        console.log(`[ShopRenter Payment Webhook] Unhandled event: ${event}`);
+    }
+
+    return new Response(JSON.stringify({ success: true }), {
+      status: 200,
+      headers: { 'Content-Type': 'application/json' },
+    });
+  } catch (error) {
+    console.error('[ShopRenter Payment Webhook] Error:', error);
+    return new Response(JSON.stringify({ error: error.message }), {
+      status: 500,
+      headers: { 'Content-Type': 'application/json' },
+    });
+  }
+});
+
+async function handlePaymentSuccess(supabase: any, data: any) {
+  console.log('[ShopRenter Payment] Payment successful:', data);
+
+  // 1. Record transaction
+  await supabase.from('shoprenter_payment_transactions').insert({
+    store_id: data.store_id,
+    payment_plan_id: data.payment_plan_id,
+    transaction_id: data.transaction_id,
+    charge_id: data.charge_id,
+    transaction_type: 'charge',
+    amount: data.amount,
+    currency: data.currency || 'HUF',
+    status: 'success',
+    payment_method: data.payment_method,
+    card_last4: data.card_last4,
+    card_brand: data.card_brand,
+    invoice_number: data.invoice_number,
+    invoice_url: data.invoice_url,
+    processed_at: new Date().toISOString(),
+    raw_data: data,
+  });
+
+  // 2. Update payment plan status
+  await supabase
+    .from('shoprenter_payment_plans')
+    .update({
+      status: 'active',
+      next_billing_date: data.next_billing_date,
+      updated_at: new Date().toISOString(),
+    })
+    .eq('payment_plan_id', data.payment_plan_id);
+
+  // 3. Update store subscription status
+  await supabase
+    .from('stores')
+    .update({
+      subscription_status: 'active',
+      subscription_started_at: new Date().toISOString(),
+      updated_at: new Date().toISOString(),
+    })
+    .eq('id', data.store_id);
+}
+
+async function handlePaymentFailed(supabase: any, data: any) {
+  console.log('[ShopRenter Payment] Payment failed:', data);
+
+  // 1. Record failed transaction
+  await supabase.from('shoprenter_payment_transactions').insert({
+    store_id: data.store_id,
+    payment_plan_id: data.payment_plan_id,
+    transaction_id: data.transaction_id,
+    transaction_type: 'charge',
+    amount: data.amount,
+    currency: data.currency || 'HUF',
+    status: 'failed',
+    error_code: data.error_code,
+    error_message: data.error_message,
+    processed_at: new Date().toISOString(),
+    raw_data: data,
+  });
+
+  // 2. Update payment plan status
+  await supabase
+    .from('shoprenter_payment_plans')
+    .update({
+      status: 'failed',
+      updated_at: new Date().toISOString(),
+    })
+    .eq('payment_plan_id', data.payment_plan_id);
+
+  // 3. Update store subscription status
+  await supabase
+    .from('stores')
+    .update({
+      subscription_status: 'payment_failed',
+      updated_at: new Date().toISOString(),
+    })
+    .eq('id', data.store_id);
+}
+
+async function handleSubscriptionActivated(supabase: any, data: any) {
+  console.log('[ShopRenter Payment] Subscription activated:', data);
+
+  await supabase
+    .from('shoprenter_payment_plans')
+    .update({
+      status: 'active',
+      activated_at: new Date().toISOString(),
+      next_billing_date: data.next_billing_date,
+      updated_at: new Date().toISOString(),
+    })
+    .eq('payment_plan_id', data.payment_plan_id);
+
+  await supabase
+    .from('stores')
+    .update({
+      subscription_status: 'active',
+      subscription_started_at: new Date().toISOString(),
+      updated_at: new Date().toISOString(),
+    })
+    .eq('id', data.store_id);
+}
+
+async function handleSubscriptionCancelled(supabase: any, data: any) {
+  console.log('[ShopRenter Payment] Subscription cancelled:', data);
+
+  await supabase
+    .from('shoprenter_payment_plans')
+    .update({
+      status: 'cancelled',
+      cancelled_at: new Date().toISOString(),
+      updated_at: new Date().toISOString(),
+    })
+    .eq('payment_plan_id', data.payment_plan_id);
+
+  await supabase
+    .from('stores')
+    .update({
+      subscription_status: 'cancelled',
+      updated_at: new Date().toISOString(),
+    })
+    .eq('id', data.store_id);
+}
+
+async function handleSubscriptionExpired(supabase: any, data: any) {
+  console.log('[ShopRenter Payment] Subscription expired:', data);
+
+  await supabase
+    .from('shoprenter_payment_plans')
+    .update({
+      status: 'expired',
+      expires_at: new Date().toISOString(),
+      updated_at: new Date().toISOString(),
+    })
+    .eq('payment_plan_id', data.payment_plan_id);
+
+  await supabase
+    .from('stores')
+    .update({
+      subscription_status: 'expired',
+      subscription_ends_at: new Date().toISOString(),
+      updated_at: new Date().toISOString(),
+    })
+    .eq('id', data.store_id);
+}
+```
+
+---
+
+## 💳 Payment Flow
+
+### User Journey
+
+```
+1. Merchant connects ShopRenter store (OAuth) → Already implemented
+   ↓
+2. Merchant navigates to "Billing" page in ShopCall.ai
+   ↓
+3. Merchant selects subscription plan (Basic, Pro, Enterprise)
+   ↓
+4. Frontend checks store platform: if (platform_name !== 'shoprenter') → show Stripe payment
+   ↓
+5. If ShopRenter store → Show "Pay via ShopRenter" button
+   ↓
+6. Merchant clicks "Subscribe"
+   ↓
+7. Frontend calls: POST /functions/v1/shoprenter-payment-create
+   ↓
+8. Backend validates store platform (MANDATORY CHECK!)
+   ↓
+9. Backend creates payment plan via ShopRenter Payment API
+   ↓
+10. ShopRenter redirects merchant to payment page (card details)
+    ↓
+11. Merchant enters card details or confirms existing card
+    ↓
+12. ShopRenter processes first payment
+    ↓
+13. ShopRenter sends webhook: payment.success
+    ↓
+14. Backend updates subscription status → "active"
+    ↓
+15. Merchant redirected back to ShopCall.ai → Subscription active!
+```
+
+### Recurring Billing
+
+After initial payment:
+
+1. ShopRenter automatically charges the merchant's card on schedule (monthly/yearly)
+2. ShopRenter sends webhook: `payment.success` or `payment.failed`
+3. ShopCall.ai updates subscription status accordingly
+4. If payment fails:
+   - Send email notification to merchant
+   - Mark subscription as "payment_failed"
+   - Allow grace period (e.g., 3 days) before suspension
+   - ShopRenter retries payment automatically
+
+---
+
+## 🔒 Security Considerations
+
+### 1. Store Platform Validation (CRITICAL!)
+
+**Enforcement Strategy:**
+
+```typescript
+// Middleware for all payment endpoints
+async function validateShopRenterPayment(storeId: string, userId: string) {
+  const supabase = createClient(
+    Deno.env.get('SUPABASE_URL')!,
+    Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
+  );
+
+  // 1. Verify store exists and belongs to user
+  const { data: store, error } = await supabase
+    .from('stores')
+    .select('id, platform_name, is_active, user_id')
+    .eq('id', storeId)
+    .single();
+
+  if (error || !store) {
+    throw new Error('Store not found');
+  }
+
+  if (store.user_id !== userId) {
+    throw new Error('Access denied: You do not own this store');
+  }
+
+  if (!store.is_active) {
+    throw new Error('Store is inactive');
+  }
+
+  // 2. CRITICAL: Validate ShopRenter platform
+  if (store.platform_name !== 'shoprenter') {
+    throw new Error(
+      `Invalid payment method for platform: ${store.platform_name}. ` +
+      'ShopRenter Payment API can only be used with ShopRenter stores.'
+    );
+  }
+
+  return store;
+}
+```
+
+**Apply to ALL payment endpoints:**
+- ✅ `shoprenter-payment-create`
+- ✅ `shoprenter-payment-cancel`
+- ✅ `shoprenter-payment-update`
+- ✅ `shoprenter-payment-status`
+- ✅ `shoprenter-payment-webhook` (validate via payment_plan_id lookup)
+
+### 2. Webhook Signature Validation
+
+```typescript
+function validateWebhookSignature(body: string, signature: string): boolean {
+  const secret = Deno.env.get('SHOPRENTER_PAYMENT_SECRET')!;
+
+  const expectedSignature = createHmac('sha256', secret)
+    .update(body)
+    .digest('hex');
+
+  // Timing-safe comparison
+  try {
+    return timingSafeEqual(
+      new TextEncoder().encode(expectedSignature),
+      new TextEncoder().encode(signature)
+    );
+  } catch {
+    return false;
+  }
+}
+```
+
+### 3. Environment Variables
+
+```bash
+# Required for ShopRenter Payment API
+SHOPRENTER_PAYMENT_API_KEY=your_payment_api_key
+SHOPRENTER_PAYMENT_SECRET=your_webhook_secret
+
+# Existing ShopRenter OAuth (already configured)
+SHOPRENTER_CLIENT_ID=your_client_id
+SHOPRENTER_CLIENT_SECRET=your_client_secret
+
+# Supabase (already configured)
+SUPABASE_URL=https://ztklqodcdjeqpsvhlpud.supabase.co
+SUPABASE_ANON_KEY=your_anon_key
+SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
+
+# Frontend URL (already configured)
+FRONTEND_URL=https://shopcall.ai
+```
+
+### 4. Data Privacy & GDPR
+
+- ✅ Store minimal payment data (no full card numbers)
+- ✅ Log transactions for audit trail
+- ✅ Delete payment data on store deletion (CASCADE)
+- ✅ Provide data export for merchants
+- ✅ Handle refund requests properly
+
+---
+
+## 🧪 Testing Strategy
+
+### 1. Test Store Setup
+
+Use existing ShopRenter test store:
+- Store name: `shopcall-test-store`
+- URL: `shopcall-test-store.myshoprenter.hu`
+- Already connected via OAuth
+
+### 2. Test Cases
+
+#### Store Validation Tests
+
+```typescript
+describe('Store Platform Validation', () => {
+  it('should accept ShopRenter stores', async () => {
+    // Given: ShopRenter store
+    const store = { platform_name: 'shoprenter', is_active: true };
+
+    // When: Creating payment plan
+    const result = await createPaymentPlan({ storeId: store.id });
+
+    // Then: Should succeed
+    expect(result.success).toBe(true);
+  });
+
+  it('should reject non-ShopRenter stores', async () => {
+    // Given: Shopify store
+    const store = { platform_name: 'shopify', is_active: true };
+
+    // When: Creating payment plan
+    const result = await createPaymentPlan({ storeId: store.id });
+
+    // Then: Should fail with specific error
+    expect(result.error).toContain('ShopRenter Payment API can only be used with ShopRenter stores');
+  });
+
+  it('should reject WooCommerce stores', async () => {
+    // Given: WooCommerce store
+    const store = { platform_name: 'woocommerce', is_active: true };
+
+    // When: Creating payment plan
+    const result = await createPaymentPlan({ storeId: store.id });
+
+    // Then: Should fail
+    expect(result.error).toContain('ShopRenter Payment API');
+  });
+
+  it('should reject inactive stores', async () => {
+    // Given: Inactive ShopRenter store
+    const store = { platform_name: 'shoprenter', is_active: false };
+
+    // When: Creating payment plan
+    const result = await createPaymentPlan({ storeId: store.id });
+
+    // Then: Should fail
+    expect(result.error).toContain('inactive');
+  });
+});
+```
+
+#### Payment Flow Tests
+
+```typescript
+describe('Payment Plan Creation', () => {
+  it('should create one-time payment plan', async () => {
+    const params = {
+      storeId: 'test-store-id',
+      planName: 'Basic Plan',
+      planType: 'one_time',
+      amount: 9990,
+      currency: 'HUF',
+    };
+
+    const result = await paymentClient.createPaymentPlan(params);
+
+    expect(result.paymentPlanId).toBeDefined();
+    expect(result.status).toBe('pending');
+  });
+
+  it('should create recurring payment plan', async () => {
+    const params = {
+      storeId: 'test-store-id',
+      planName: 'Pro Plan',
+      planType: 'recurring',
+      amount: 29990,
+      currency: 'HUF',
+      billingFrequency: 'monthly',
+    };
+
+    const result = await paymentClient.createPaymentPlan(params);
+
+    expect(result.paymentPlanId).toBeDefined();
+    expect(result.nextBillingDate).toBeDefined();
+  });
+});
+```
+
+#### Webhook Tests
+
+```typescript
+describe('Payment Webhooks', () => {
+  it('should handle payment.success webhook', async () => {
+    const payload = {
+      event: 'payment.success',
+      data: {
+        store_id: 'test-store-id',
+        payment_plan_id: 'plan-123',
+        transaction_id: 'txn-456',
+        amount: 9990,
+        currency: 'HUF',
+        invoice_number: 'INV-2025-001',
+      },
+    };
+
+    const response = await handleWebhook(payload);
+
+    expect(response.status).toBe(200);
+
+    // Verify database updates
+    const plan = await getPlanFromDB('plan-123');
+    expect(plan.status).toBe('active');
+
+    const store = await getStoreFromDB('test-store-id');
+    expect(store.subscription_status).toBe('active');
+  });
+
+  it('should handle payment.failed webhook', async () => {
+    const payload = {
+      event: 'payment.failed',
+      data: {
+        store_id: 'test-store-id',
+        payment_plan_id: 'plan-123',
+        error_code: 'insufficient_funds',
+        error_message: 'Insufficient funds',
+      },
+    };
+
+    const response = await handleWebhook(payload);
+
+    expect(response.status).toBe(200);
+
+    const plan = await getPlanFromDB('plan-123');
+    expect(plan.status).toBe('failed');
+
+    const store = await getStoreFromDB('test-store-id');
+    expect(store.subscription_status).toBe('payment_failed');
+  });
+
+  it('should reject webhook with invalid signature', async () => {
+    const payload = { event: 'payment.success', data: {} };
+    const invalidSignature = 'invalid_hmac';
+
+    const response = await handleWebhook(payload, invalidSignature);
+
+    expect(response.status).toBe(403);
+  });
+});
+```
+
+### 3. Manual Testing Checklist
+
+- [ ] Connect test ShopRenter store via OAuth
+- [ ] Navigate to billing page
+- [ ] Select subscription plan
+- [ ] Verify "Pay via ShopRenter" option appears
+- [ ] Click subscribe button
+- [ ] Verify redirect to ShopRenter payment page
+- [ ] Complete test payment with test card
+- [ ] Verify redirect back to ShopCall.ai
+- [ ] Verify subscription status is "active"
+- [ ] Verify payment transaction recorded in database
+- [ ] Test cancellation flow
+- [ ] Test payment failure handling
+- [ ] Verify webhook events processed correctly
+- [ ] Test with non-ShopRenter store (should reject)
+
+---
+
+## 🚀 Deployment Plan
+
+### Phase 1: Preparation (Week 1)
+
+- [x] Review ShopRenter Payment API documentation
+- [ ] Create implementation plan (this document)
+- [ ] Design database schema
+- [ ] Set up test environment
+- [ ] Request Payment API credentials from ShopRenter
+
+### Phase 2: Development (Weeks 2-3)
+
+- [ ] Create database migration
+- [ ] Implement Payment API client library
+- [ ] Implement Edge Functions:
+  - [ ] `shoprenter-payment-create`
+  - [ ] `shoprenter-payment-cancel`
+  - [ ] `shoprenter-payment-status`
+  - [ ] `shoprenter-payment-webhook`
+- [ ] Implement store validation middleware
+- [ ] Add error handling and logging
+
+### Phase 3: Frontend Integration (Week 4)
+
+- [ ] Create billing page UI
+- [ ] Add subscription plan selection
+- [ ] Implement platform-specific payment method selection
+- [ ] Add ShopRenter payment button
+- [ ] Implement success/failure callbacks
+- [ ] Add subscription management UI
+
+### Phase 4: Testing (Week 5)
+
+- [ ] Unit tests for validation logic
+- [ ] Integration tests for payment flow
+- [ ] Webhook handler tests
+- [ ] Manual end-to-end testing
+- [ ] Security audit
+- [ ] Performance testing
+
+### Phase 5: Production Deployment (Week 6)
+
+- [ ] Deploy database migration
+- [ ] Deploy Edge Functions
+- [ ] Configure environment variables
+- [ ] Enable payment webhooks
+- [ ] Monitor logs for errors
+- [ ] Soft launch with beta users
+
+### Phase 6: Launch (Week 7)
+
+- [ ] Full production launch
+- [ ] Monitor payment success rates
+- [ ] Customer support readiness
+- [ ] Documentation updates
+- [ ] Marketing announcement
+
+---
+
+## 📅 Timeline & Milestones
+
+| Week | Milestone | Deliverables |
+|------|-----------|--------------|
+| 1 | Planning Complete | ✅ Implementation plan document |
+| 2 | Database & Backend Foundation | Schema migration, Payment client library |
+| 3 | Core Payment Features | Create/cancel/status Edge Functions |
+| 4 | Frontend Integration | Billing UI, Payment buttons, Callbacks |
+| 5 | Testing & QA | Test suite, Manual testing, Security audit |
+| 6 | Deployment | Production deployment, Monitoring setup |
+| 7 | Launch | Public launch, User documentation |
+
+**Total Duration:** 7 weeks
+
+---
+
+## 📚 References & Resources
+
+### ShopRenter Documentation
+
+- **Payment API Introduction**: `https://doc.shoprenter.hu/paymentapi/docs/a_introduce.html`
+- **Payment API Docs**: `https://doc.shoprenter.hu/paymentapi/`
+- **App Development Guide**: `https://doc.shoprenter.hu/development/app-development/`
+- **OAuth Documentation**: `docs/shoprenter_app_development.md`
+
+### Internal Documentation
+
+- **ShopRenter Integration Plan**: `SHOPRENTER.md`
+- **Registration Requirements**: `SHOPRENTER_REGISTRATION.md`
+- **API Resources**: `docs/shoprenter_api_resources.md`
+- **Payment Overview**: `docs/shoprenter_payment.md`
+
+### Project Documentation
+
+- **Project Overview**: `CLAUDE.md`
+- **Database Schema**: See Supabase migrations in `supabase/migrations/`
+- **Edge Functions**: `supabase/functions/`
+
+### Contact & Support
+
+- **ShopRenter Partner Support**: `partnersupport@shoprenter.hu`
+- **ShopRenter Developer Portal**: `https://doc.shoprenter.hu`
+
+---
+
+## ✅ Next Steps
+
+1. **Review this plan** with the team
+2. **Request Payment API credentials** from ShopRenter Partner Support
+3. **Create database migration** for new tables
+4. **Set up test environment** with test ShopRenter store
+5. **Begin Phase 2 development** (Backend implementation)
+
+---
+
+## 🔄 Change Log
+
+| Date | Version | Changes |
+|------|---------|---------|
+| 2025-11-11 | 1.0 | Initial implementation plan created |
+
+---
+
+**Document Status:** ✅ Ready for Review
+**Author:** Claude (AI Development Assistant)
+**Approved By:** _Pending_
+**Next Review Date:** _TBD_