# Partner Pages System Guide

**Last Updated:** 2026-01-19

Comprehensive guide to the partner landing page system, including architecture, configuration, tracking, and maintenance.

## Overview

The partner pages system allows partners to send traffic to Ordio landing pages with custom branding and tracking. Partners can use URL parameters to display their logos, customize titles, and track conversions.

### Key Features

- **Centralized Configuration**: Single source of truth for all partner data
- **Logo Display**: Partner logos displayed in hero section ("In Zusammenarbeit mit:")
- **Special Pricing**: Support for partner-specific pricing codes
- **Tracking Integration**: Full UTM and partner parameter tracking through HubSpot
- **URL Generator**: Tool for creating partner URLs with all parameters

## Architecture

### File Structure

```
v2/
├── config/
│   └── partner-config.php          # Centralized partner configuration
├── pages/
│   ├── landingpage.php              # Main landing page
│   ├── landingpage_v2-alt.php      # Alternative version
│   ├── landingpage_v3.php           # Version 3
│   ├── landingpage_v4.php           # Version 4
│   ├── kostenlos-testen.php         # Test page
│   ├── kostenlos_testen_neu.php     # New test page
│   └── landingpageurlgenerator.php  # URL generator tool
├── scripts/
│   └── dev-helpers/
│       └── test-partner-pages.php  # Validation script
└── img/partner/                     # Partner logo assets (new location)
html/images/partner/                 # Partner logo assets (legacy location)
```

### Data Flow

```
URL Parameter (partner=gastroberatung)
    ↓
Landing Page (extracts partner parameter)
    ↓
Partner Config (gets logo path and class)
    ↓
Display Logo in Hero Section
    ↓
UTM Tracking (captures partner in cookies)
    ↓
Form Submission (includes partner parameter)
    ↓
HubSpot API (stores in partner__c field)
```

## Partner Configuration

### Configuration File

All partner data is centralized in `v2/config/partner-config.php`. This eliminates duplication and ensures consistency across all landing page versions.

### Partner Data Structure

Each partner has the following configuration:

```php
'slug' => [
    'slug' => 'partner-slug',              // URL slug (e.g., 'kassenprofis')
    'name' => 'Partner Display Name',      // Display name (e.g., 'Kassenprofis')
    'logo_path' => '/path/to/logo.webp',   // Logo file path
    'logo_class' => 'w-40',                // Tailwind CSS width class
    'special_pricing' => null,             // Special pricing code or null
]
```

### Current Partners

**Active Partners (10 total):**

1. **3POS** - Special pricing: `3POS`
2. **Der Paritätische Gesamtverband** - Special pricing: `49+79+99`
3. **Gastro Beratung**
4. **Hitzel IT Solutions**
5. **Kassenprofis**
6. **LUUC Academy** - ✅ Logo added
7. **Madame Croissant** - ✅ Logo added
8. **MConsultings**
9. **Top Magazin**
10. **UYMI Coaching** - ✅ Logo added

### Helper Functions

The configuration file provides several helper functions:

#### `getPartnerConfig($slug)`

Get full partner configuration by slug.

```php
$config = getPartnerConfig('kassenprofis');
// Returns: ['slug' => 'kassenprofis', 'name' => 'Kassenprofis', ...]
```

#### `getPartnerLogo($slug)`

Get partner logo path and CSS class. Returns `[logo_path, logo_class]` or `['', '']` if not found.

```php
$logo = getPartnerLogo('gastroberatung');
// Returns: ['/html/images/partner/gastro-beratung.png', 'w-40']
```

#### `getAllPartners()`

Get all partner configurations.

```php
$partners = getAllPartners();
// Returns: ['kassenprofis' => [...], 'gastroberatung' => [...], ...]
```

#### `isValidPartner($slug)`

Validate if a partner slug exists.

```php
if (isValidPartner('kassenprofis')) {
    // Partner exists
}
```

#### `getPartnerSpecialPricing($slug)`

Get special pricing code for a partner.

```php
$pricing = getPartnerSpecialPricing('3POS');
// Returns: '3POS' or null
```

#### `getPartnerName($slug)`

Get partner display name.

```php
$name = getPartnerName('gastroberatung');
// Returns: 'Gastro Beratung'
```

## URL Parameters

### Partner Parameters

Partner landing pages support the following URL parameters:

- **`partner`** - Partner slug (required for logo display)
  - Example: `?partner=gastroberatung`
- **`title`** - Custom page title
  - Example: `?title=Gastro%20Beratung%20empfiehlt%20Ordio`
- **`leadSource`** - Lead source attribution
  - Example: `?leadSource=Partner%20recommendation`
- **`typewriter`** - Typewriter animation text (comma-separated)
  - Example: `?typewriter=Schichtplanung,Zeiterfassung`
- **`pinkline`** / **`blueline`** - Custom text lines
  - Example: `?pinkline=Custom%20text`

### Example URLs

```
https://www.ordio.com/v2/?partner=gastroberatung&title=Gastro%20Beratung%20empfiehlt%20Ordio&leadSource=Partner%20recommendation

https://www.ordio.com/v2/?partner=kassenprofis&typewriter=Schichtplanung,Zeiterfassung

https://www.ordio.com/v2/?partner=3POS&title=3POS%20Partner%20Page
```

## Logo Display

### Logo Locations

Partner logos are stored in two locations:

1. **Legacy Location**: `/html/images/partner/` (PNG format)
2. **New Location**: `/v2/img/partner/` (WebP/SVG format preferred)

### Logo Sizing

Logos use Tailwind CSS width classes:

- **`w-24`** - Small logos (mconsultings, 3POS)
- **`w-40`** - Medium logos (gastroberatung, hitzel-it-solutions, top-magazin, LUUC Academy, Madame Croissant, UYMI Coaching)
- **`w-48`** - Large logos (kassenprofis, der-paritaetische-gesamtverband)

### Display Code

Partner logos are displayed in the hero section with the following structure:

```php
<?php
if (!empty($partner) && !empty($partnerlogo[0])) {
    echo '<div class="flex justify-center items-center mb-6">';
    echo '<div>';
    echo '<div class="text-[10px] text-gray text-center">In Zusammenarbeit mit:</div>';
    echo '<div class="mx-auto ' . $partnerlogo[1] . '">';
    echo "<img class='py-2' src='" . $partnerlogo[0] . "'>";
    echo '</div>';
    echo '</div>';
    echo '</div>';
}
?>
```

## Tracking Integration

### UTM Tracking

The `utm-tracking.js` script captures the `partner` parameter from the URL and stores it in cookies for session persistence.

**JavaScript:**

```javascript
// Partner parameter is extracted from URL
this.partner = urlParams.get("partner");

// Stored in cookies for persistence
document.cookie = `partner=${this.partner}; path=/; max-age=2592000`; // 30 days
```

### Form Submissions

Partner data flows through form submissions to HubSpot:

**API Endpoint (`collect-lead.php`):**

```php
// Extract partner from input or cookies
$partner = $input['partner'] ?? ($_COOKIE['partner'] ?? '');

// Send to HubSpot
[
    "name" => "partner__c",
    "value" => $partner
]
```

### HubSpot Field Mapping

Partner data is stored in HubSpot's `partner__c` custom field, allowing for:

- Partner attribution in reports
- Partner-specific conversion tracking
- Partner performance analysis

**CRITICAL: Partner Value Mapping**

The `partner__c` field in HubSpot is an enumeration (dropdown) with specific accepted values. Partner slugs from URL parameters must be mapped to HubSpot-accepted values.

**Mapping System:**

- Partner slugs (e.g., `gastroberatung`) are automatically mapped to HubSpot values (e.g., `Gastro Beratung`)
- Mapping is handled by `v2/config/partner-hubspot-mapping.php`
- Each partner config includes a `hubspot_value` field that specifies the exact HubSpot-accepted value
- If no `hubspot_value` is set, the partner's display name (`name` field) is used as fallback

**Example:**

```php
'gastroberatung' => [
    'slug' => 'gastroberatung',
    'name' => 'Gastro Beratung',
    'hubspot_value' => 'Gastro Beratung', // Must match HubSpot accepted value exactly
    // ...
]
```

**Adding New Partners:**

1. Add partner to `v2/config/partner-config.php` with `hubspot_value` field
2. Run `php v2/scripts/hubspot/sync-partner-values.php --dry-run` to check if value exists in HubSpot
3. If missing, add value to HubSpot manually or use `--add-missing` flag (requires API permissions)
4. Run `php v2/scripts/hubspot/test-partner-attribution.php` to validate mapping

**Testing:**

- Test script: `php v2/scripts/hubspot/test-partner-attribution.php [partner-slug]`
- Sync script: `php v2/scripts/hubspot/sync-partner-values.php [--dry-run] [--add-missing]`

## Special Pricing

Some partners have special pricing codes that modify the pricing section:

- **Der Paritätische Gesamtverband**: `49+79+99`
- **3POS**: `3POS`

Special pricing is handled via the `getPartnerSpecialPricing()` function:

```php
$specialpricing = getPartnerSpecialPricing($partner);
// Returns: '49+79+99', '3POS', or null
```

## Adding New Partners

### Step 1: Add Partner Configuration

Edit `v2/config/partner-config.php` and add the new partner:

```php
'new-partner-slug' => [
    'slug' => 'new-partner-slug',
    'name' => 'New Partner Name',
    'logo_path' => '/v2/img/partner/new-partner-slug.webp',
    'logo_class' => 'w-40', // Choose appropriate size
    'special_pricing' => null, // Or add pricing code if needed
],
```

### Step 2: Add Logo Asset

1. Create logo file in WebP format (preferred) or PNG
2. Recommended sizes: 200px, 400px width
3. Transparent background preferred
4. Save to `/v2/img/partner/new-partner-slug.webp`
5. Ensure file naming matches slug exactly

### Step 3: Test Partner

1. Run validation script: `php v2/scripts/dev-helpers/test-partner-pages.php`
2. Test URL: `https://www.ordio.com/v2/?partner=new-partner-slug`
3. Verify logo displays correctly
4. Test form submission includes partner parameter
5. Verify HubSpot receives partner data

### Step 4: Update URL Generator

The URL generator automatically includes all partners from the centralized config, so no manual update needed.

## Maintenance

### Validation Script

Run the validation script to check system integrity:

```bash
php v2/scripts/dev-helpers/test-partner-pages.php
```

The script checks:

- Partner configuration completeness
- Logo file existence
- Helper function functionality
- Landing page integration
- URL generator integration

### Common Issues

#### Logo Not Displaying

1. Check partner slug matches configuration exactly
2. Verify logo file exists at specified path
3. Check file permissions
4. Verify logo path is correct (relative to web root)

#### Partner Not Tracking

1. Verify partner parameter in URL
2. Check UTM tracking script is loaded
3. Verify cookies are being set
4. Check form submission includes partner parameter
5. Verify HubSpot field mapping (`partner__c`)
6. **CRITICAL**: Verify partner slug is mapped to HubSpot-accepted value
   - Run: `php v2/scripts/hubspot/test-partner-attribution.php [partner-slug]`
   - Check logs for mapping warnings: `grep "Partner slug" v2/logs/*.log`
   - Ensure `hubspot_value` in partner config matches HubSpot accepted value exactly

#### Special Pricing Not Working

1. Verify partner has special pricing configured
2. Check `getPartnerSpecialPricing()` function
3. Verify pricing section includes special pricing logic

## Best Practices

### Logo Assets

- **Format**: Use WebP for new logos (better compression)
- **Size**: Optimize file size (aim for < 100KB)
- **Dimensions**: Provide multiple sizes if needed
- **Naming**: Use lowercase slug format (e.g., `luuc-academy.webp`)
- **Background**: Transparent preferred for flexibility

### Partner Slugs

- Use lowercase
- Use hyphens for word separation
- Keep slugs concise and descriptive
- Match partner's brand name when possible

### Testing

- Always test partner URLs on all landing page versions
- Verify logo display on mobile and desktop
- Test form submissions include partner data
- Verify HubSpot receives partner field correctly
- Test special pricing if applicable

## Related Documentation

- [UTM Tracking Documentation](../../development/UTM_TRACKING.md)
- [HubSpot Integration Guide](../../systems/hubspot/HUBSPOT_INTEGRATION.md)
- [Landing Page Patterns](../../guides/landing-pages/LANDING_PAGE_PATTERNS.md)

## Support

For questions or issues with the partner pages system:

1. Check this documentation
2. Run validation script
3. Review partner configuration
4. Contact development team
