# HubSpot Integration Setup Guide

**Last Updated:** 2026-02-12

Complete step-by-step guide for setting up HubSpot integration for the affiliate partner system.

## Overview

The affiliate partner system integrates with HubSpot CRM to:

- Store partner data in custom objects
- Track leads (contacts) attributed to partners
- Track deals and calculate MRR (Monthly Recurring Revenue)
- Sync data hourly for dashboard display

## Prerequisites

- HubSpot account with Enterprise tier (required for custom objects)
- Private app access (super admin required)
- API token with required scopes
- PHP CLI access for running setup scripts

## Required API Scopes

Your HubSpot private app must have these scopes:

- `crm.objects.custom.read` - Read custom objects
- `crm.objects.custom.write` - Write custom objects
- `crm.schemas.custom.read` - Read custom object schemas
- `crm.schemas.custom.write` - Write custom object schemas
- `crm.objects.contacts.read` - Read contacts
- `crm.objects.contacts.write` - Write contacts
- `crm.objects.deals.read` - Read deals
- `crm.objects.deals.write` - Write deals

## Step 1: Configure API Token

### Option A: Environment Variable (Recommended for Production)

**For Production Server:**

Choose the appropriate method for your server setup:

**1. Apache/.htaccess (if supported):**
```apache
SetEnv HUBSPOT_API_TOKEN pat-eu1-your-token-here
```

**2. PHP-FPM Pool Configuration:**
```ini
env[HUBSPOT_API_TOKEN] = pat-eu1-your-token-here
```

**3. System Environment (Linux):**
```bash
# Add to /etc/environment or server startup script
export HUBSPOT_API_TOKEN=pat-eu1-your-token-here
```

**4. cPanel/Shared Hosting:**
- Use cPanel Environment Variables section
- Add `HUBSPOT_API_TOKEN` with token value

**5. Docker/Container:**
```dockerfile
ENV HUBSPOT_API_TOKEN=pat-eu1-your-token-here
```

**For Development (Local):**

Set the environment variable:

```bash
export HUBSPOT_API_TOKEN=pat-eu1-your-token-here
```

For persistent setup, add to `~/.zshrc` or `~/.bashrc`:

```bash
echo 'export HUBSPOT_API_TOKEN=pat-eu1-your-token-here' >> ~/.zshrc
source ~/.zshrc
```

### Option B: Config File (Development Only)

The system will use the fallback token in `v2/config/hubspot-config.php` for development. **Never use fallback token in production.**

**Note:** Read-only affiliate dashboard APIs (`affiliate-dashboard-data.php`, `affiliate-levels.php`) will temporarily work with fallback token even in production, but you should set the environment variable for proper operation.

### Verify Token Configuration

**Check token is set and accessible:**

```bash
php v2/scripts/affiliate/check-hubspot-token.php
```

This script will:
- Verify `HUBSPOT_API_TOKEN` environment variable is set
- Validate token format
- Check if config file can load successfully
- Provide setup instructions if token is missing

**Test token connectivity and scopes:**

```bash
php v2/scripts/hubspot/test-api-token-scopes.php
```

## Step 2: Verify API Token Scopes

Before proceeding, verify your API token has all required scopes:

```bash
php v2/scripts/hubspot/test-api-token-scopes.php
```

If any scopes are missing:

1. Go to HubSpot Settings → Integrations → Private Apps
2. Find your private app and click "Edit"
3. Go to the "Scopes" tab
4. Search for and select the missing scopes
5. Click "Save"
6. Re-run the scope test script

## Step 3: Create Property Group (Manual)

**Note:** HubSpot API does not support property group creation. This must be done manually.

### For Contacts

1. Go to HubSpot Settings → Properties → Contact Properties
2. Click "Create property group" (or "Add group")
3. Name: `affiliate_info`
4. Click "Create"

### For Deals

1. Go to HubSpot Settings → Properties → Deal Properties
2. Click "Create property group" (or "Add group")
3. Name: `affiliate_info`
4. Click "Create"

### Verify Property Group

```bash
php v2/scripts/hubspot/create-affiliate-property-group.php --check-only
```

## Step 4: Create Custom Object

Create the `affiliate_partner` custom object:

```bash
php v2/scripts/hubspot/create-affiliate-custom-object.php
```

**What this creates:**

- Custom object type: `affiliate_partner`
- Properties:
  - `partner_id` (text, unique, required)
  - `name` (text, required)
  - `email` (text, required)
  - `level` (enum: starter/partner/pro)
  - `mrr_share_percent` (number)
  - `status` (enum: active/inactive/suspended)
  - `registration_date` (date)

**Note:** The script checks if the object already exists and verifies all properties.

## Step 5: Create Custom Properties

Create properties on contacts and deals:

```bash
php v2/scripts/hubspot/setup-affiliate-properties.php
```

**Contact Properties Created:**

- `affiliate_partner_id` (text) - Partner ID who referred this contact
- `affiliate_referral_date` (date) - Date when contact was referred

**Deal Properties Created:**

- `affiliate_partner_id` (text) - Partner ID who referred this deal
- `affiliate_mrr` (number) - Deal MRR amount
- `affiliate_subscription_status` (enum: active/paused/cancelled) - Subscription status

**Note:** The script checks if properties already exist and verifies them after creation.

## Step 6: Verify Complete Setup

Run the comprehensive verification script:

```bash
php v2/scripts/hubspot/verify-affiliate-setup.php
```

This checks:

- API token validity and connectivity
- All required scopes
- Custom object existence
- All properties existence
- Property groups
- End-to-end functionality

## Step 7: Run End-to-End Test

Test the complete integration:

```bash
php v2/scripts/hubspot/test-affiliate-integration.php
```

This test:

- Creates a test partner object
- Creates a test contact with affiliate properties
- Creates a test deal with affiliate properties
- Searches for contacts/deals by partner ID
- Calculates MRR
- Cleans up test data

**To keep test data for inspection:**

```bash
php v2/scripts/hubspot/test-affiliate-integration.php --no-cleanup
```

## Automated Setup

For convenience, run all setup steps automatically:

```bash
php v2/scripts/hubspot/setup-affiliate-hubspot-complete.php
```

This script:

1. Verifies API token and scopes
2. Checks property group (provides manual instructions if missing)
3. Creates custom object
4. Creates all properties
5. Runs verification
6. Runs end-to-end test
7. Generates setup report

**Dry run (validate without creating):**

```bash
php v2/scripts/hubspot/setup-affiliate-hubspot-complete.php --dry-run
```

## Verification Checklist

After setup, verify:

- [ ] API token is valid and has correct format
- [ ] API token has all required scopes
- [ ] Custom object `affiliate_partner` exists
- [ ] Object type ID matches config (`2-affiliate_partner`)
- [ ] Property group `affiliate_info` exists (contacts)
- [ ] Property group `affiliate_info` exists (deals)
- [ ] Contact property `affiliate_partner_id` exists
- [ ] Contact property `affiliate_referral_date` exists
- [ ] Deal property `affiliate_partner_id` exists
- [ ] Deal property `affiliate_mrr` exists
- [ ] Deal property `affiliate_subscription_status` exists
- [ ] Can create partner object via API
- [ ] Can read partner object via API
- [ ] Can update partner object via API
- [ ] Can create contact with affiliate properties
- [ ] Can create deal with affiliate properties
- [ ] Can search contacts by partner ID
- [ ] Can search deals by partner ID
- [ ] Partner registration creates HubSpot object
- [ ] Sync process fetches data correctly
- [ ] MRR calculation works
- [ ] Level calculation works

## Troubleshooting

### API Token Issues

**Error: "Authentication failed"**

- Verify token is correct and not expired
- Check token format: `pat-{region}-{hash}`
- Ensure token is set in environment variable or config

**Error: "Access forbidden"**

- Check private app scopes in HubSpot settings
- Verify all required scopes are selected
- Re-generate token if needed

### Custom Object Issues

**Error: "Object already exists"**

- This is OK if object was created previously
- Run verification script to check current state
- Object may have different type ID - update config if needed

**Error: "Schema validation failed"**

- Check HubSpot account tier (Enterprise required)
- Verify API token has `crm.schemas.custom.write` scope
- Review error message for specific validation issues

### Property Issues

**Error: "Property group does not exist"**

- Create property group manually in HubSpot UI
- Property group name must be exactly `affiliate_info`
- Apply to both Contacts and Deals

**Error: "Property already exists"**

- This is OK if property was created previously
- Script will verify property type matches expected type
- If type mismatch, update property manually in HubSpot

### Scope Issues

**Missing scopes detected**

1. Go to HubSpot Settings → Integrations → Private Apps
2. Edit your private app
3. Go to Scopes tab
4. Search for missing scopes and select them
5. Save changes
6. Re-run scope test script

### Sync Issues

**Sync fails to fetch data**

- Check API token is valid
- Verify custom object exists
- Check property names match config
- Review sync logs for specific errors

## Manual Verification in HubSpot UI

After setup, verify in HubSpot:

1. **Custom Object:**
   - Go to Settings → Objects → Custom Objects
   - Verify `affiliate_partner` object exists
   - Check all properties are present

2. **Contact Properties:**
   - Go to Settings → Properties → Contact Properties
   - Verify `affiliate_partner_id` and `affiliate_referral_date` exist
   - Check they are in `affiliate_info` group

3. **Deal Properties:**
   - Go to Settings → Properties → Deal Properties
   - Verify `affiliate_partner_id`, `affiliate_mrr`, and `affiliate_subscription_status` exist
   - Check they are in `affiliate_info` group

4. **Private App Scopes:**
   - Go to Settings → Integrations → Private Apps
   - Edit your private app
   - Verify all required scopes are selected

## Next Steps

After setup is complete:

1. Test partner registration flow
2. Test sync process: `php v2/cron/sync-affiliate-hubspot.php`
3. Monitor sync logs for errors
4. Set up cron job for hourly sync: `0 * * * * php /path/to/v2/cron/sync-affiliate-hubspot.php`
5. Test lead attribution flow

## Related Documentation

- [ARCHITECTURE.md](ARCHITECTURE.md) - System architecture
- [DEPLOYMENT_CHECKLIST.md](DEPLOYMENT_CHECKLIST.md) - Deployment checklist
- [API_REFERENCE.md](API_REFERENCE.md) - API endpoints reference

## Support

If you encounter issues:

1. Run verification script: `php v2/scripts/hubspot/verify-affiliate-setup.php`
2. Check setup report: `v2/scripts/hubspot/setup-report-*.json`
3. Review HubSpot API documentation
4. Check HubSpot account tier and permissions
