Campaigns

Integrate Campaigns

This guide shows you how to integrate CashIn's Campaign endpoints to create viral marketing campaigns that reward sharing and buying, turning customers into advocates.

Campaign Management Endpoints

Endpoint

Method

Purpose

Key Parameters

Response Data

/partner/v1/campaigns

GET

List all campaigns

pagination, filters

campaigns array, pagination

/partner/v1/campaigns/{id}

GET

Get campaign details

campaign_id (URL param)

campaign object, campaign_json

/partner/v1/campaigns

POST

Create new campaign

campaign_data, campaign_image

campaign object

/partner/v1/campaigns/{id}

PUT

Update campaign

campaign_id, updates, optional image

Updated campaign object

/partner/v1/campaigns/{id}

DELETE

Delete campaign

campaign_id (URL param)

Success confirmation

/partner/v1/campaigns/{id}/publish

POST

Publish campaign

campaign_id (URL param)

Published campaign status

Campaign Activation Endpoints

Endpoint

Method

Purpose

Key Parameters

Response Data

/partner/v1/campaigns/activate

POST

Activate campaign code

code, session, products

temp_purchase_id, discounts, totals

/partner/v1/campaigns/activate/verify/{purchase_id}

POST

Verify purchase

purchase_id, is_purchased

Purchase confirmation

/partner/v1/campaigns/activate/test

GET

Test activation service

None

Service status

Campaign Sharing Endpoint

Endpoint

Method

Purpose

Key Parameters

Response Data

/partner/v1/campaigns/share

POST

Generate share link

insider_id, campaign_id

share_url, insider_code, campaign_slug

Authentication Setup

const headers = {
  'Authorization': 'Bearer sk_live_abc123def456...',
  'Content-Type': 'application/json'
};

Quick Start: Campaign Management

List All Campaigns

async function getCampaigns(options = {}) {
  const queryParams = new URLSearchParams({
    limit: options.limit || 20,
    offset: options.offset || 0,
    sortBy: options.sortBy || 'created_at',
    sortOrder: options.sortOrder || 'DESC'
  });

  if (options.status) queryParams.append('status', options.status);
  if (options.search) queryParams.append('search', options.search);

  const response = await fetch(`/partner/v1/campaigns?${queryParams}`, {
    method: 'GET',
    headers
  });

  const result = await response.json();
  return result.success ? result.data : [];
}

// Usage examples
const allCampaigns = await getCampaigns();
const publishedCampaigns = await getCampaigns({ status: 'published' });
const searchResults = await getCampaigns({ search: 'summer' });

Get Campaign Details

async function getCampaign(campaignId) {
  const response = await fetch(`/partner/v1/campaigns/${campaignId}`, {
    method: 'GET',
    headers
  });

  const result = await response.json();
  
  if (result.success) {
    return result.data;
  }
  
  throw new Error(result.message);
}

// Usage
const campaign = await getCampaign('campaign-id');
console.log('Campaign:', campaign.campaign_name);
console.log('Status:', campaign.status);
console.log('Requirements:', campaign.requirements);

Create Viral Campaigns

Simple Campaign Creation

async function createCampaign(campaignData, imageFile) {
  const formData = new FormData();
  
  // Add campaign configuration
  formData.append('campaign_data', JSON.stringify(campaignData));
  
  // Add campaign image
  if (imageFile) {
    formData.append('campaign_image', imageFile);
  }

  const response = await fetch('/partner/v1/campaigns', {
    method: 'POST',
    headers: {
      'Authorization': headers.Authorization
      // Don't set Content-Type for FormData
    },
    body: formData
  });

  const result = await response.json();
  
  if (result.success) {
    return result.data;
  }
  
  throw new Error(result.message);
}

// Example: Friend Referral Campaign
const friendReferralCampaign = {
  start: {
    campaign_name: "Friend Referral Bonus",
    campaign_slug: "friend-referral-bonus",
    display_name: "Share & Save Together",
    description: "Both you and your friend get rewards when they make their first purchase",
    applies_to: ["everyone"],
    requires_authentication: false,
    start_date: "2024-01-01T00:00:00.000Z",
    end_date: "2024-12-31T23:59:59.000Z",
    requirements: [
      {
        title: "Friend must be new customer",
        tracker_id: "new-customer-tracker-id"
      },
      {
        title: "Minimum order $25",
        tracker_id: "min-order-tracker-id"
      }
    ]
  },
  switch: "priority_order",
  paths: [
    {
      conditions: {
        logic: "AND",
        rules: [
          {
            field: "cart_value",
            operator: ">=",
            value: 25,
            currency: "USD"
          },
          {
            field: "user_type",
            operator: "==",
            value: "new_customer"
          }
        ]
      },
      actions: [
        {
          action: "discount",
          discount_type: "fixed_amount",
          value: 10,
          currency: "USD"
        }
      ]
    }
  ]
};

// Create the campaign
const imageFile = document.getElementById('campaign-image').files[0];
const newCampaign = await createCampaign(friendReferralCampaign, imageFile);
console.log('Campaign created:', newCampaign.campaign_id);

Dynamic Reward Campaigns

// Create campaign with multiple reward tiers
const tieredRewardsCampaign = {
  start: {
    campaign_name: "Loyalty Tier Rewards",
    campaign_slug: "loyalty-tier-rewards",
    display_name: "More You Spend, More You Save",
    description: "Dynamic rewards based on cart value and customer loyalty",
    applies_to: ["everyone"],
    requires_authentication: true,
    start_date: "2024-01-01T00:00:00.000Z",
    requirements: [
      {
        title: "Authenticated users only",
        tracker_id: "auth-tracker-id"
      },
      {
        title: "Minimum purchase required",
        tracker_id: "purchase-tracker-id"
      }
    ]
  },
  switch: "priority_order",
  paths: [
    // VIP tier (>$200)
    {
      conditions: {
        logic: "AND",
        rules: [
          {
            field: "cart_value",
            operator: ">",
            value: 200,
            currency: "USD"
          },
          {
            field: "user_tier",
            operator: "==",
            value: "vip"
          }
        ]
      },
      actions: [
        {
          action: "discount",
          discount_type: "percentage",
          value: 25,
          currency: "USD"
        }
      ]
    },
    // Premium tier ($100-$200)
    {
      conditions: {
        logic: "AND",
        rules: [
          {
            field: "cart_value",
            operator: ">=",
            value: 100,
            currency: "USD"
          }
        ]
      },
      actions: [
        {
          action: "discount",
          discount_type: "percentage",
          value: 15,
          currency: "USD"
        }
      ]
    },
    // Standard tier ($50+)
    {
      conditions: {
        logic: "AND",
        rules: [
          {
            field: "cart_value",
            operator: ">=",
            value: 50,
            currency: "USD"
          }
        ]
      },
      actions: [
        {
          action: "discount",
          discount_type: "percentage",
          value: 10,
          currency: "USD"
        }
      ]
    }
  ]
};

Campaign Management

Update Campaign

async function updateCampaign(campaignId, updates, newImageFile = null) {
  if (newImageFile) {
    // Update with new image
    const formData = new FormData();
    if (updates) {
      formData.append('campaign_data', JSON.stringify(updates));
    }
    formData.append('campaign_image', newImageFile);

    const response = await fetch(`/partner/v1/campaigns/${campaignId}`, {
      method: 'PUT',
      headers: {
        'Authorization': headers.Authorization
      },
      body: formData
    });

    return response.json();
  } else {
    // Update JSON only
    const response = await fetch(`/partner/v1/campaigns/${campaignId}`, {
      method: 'PUT',
      headers,
      body: JSON.stringify(updates)
    });

    return response.json();
  }
}

// Example: Update campaign dates
const updatedCampaign = await updateCampaign('campaign-id', {
  start: {
    ...existingCampaign.start,
    end_date: "2024-12-31T23:59:59.000Z"
  }
});

// Example: Update campaign image only
const newImage = document.getElementById('new-image').files[0];
await updateCampaign('campaign-id', null, newImage);

Publish Campaign

async function publishCampaign(campaignId) {
  const response = await fetch(`/partner/v1/campaigns/${campaignId}/publish`, {
    method: 'POST',
    headers
  });

  const result = await response.json();
  
  if (result.success) {
    console.log('Campaign published successfully');
    return result.data;
  }
  
  throw new Error(result.message);
}

// Usage
try {
  await publishCampaign('campaign-id');
  console.log('Campaign is now live!');
} catch (error) {
  console.error('Failed to publish:', error.message);
}

Delete Campaign

async function deleteCampaign(campaignId) {
  const response = await fetch(`/partner/v1/campaigns/${campaignId}`, {
    method: 'DELETE',
    headers
  });

  const result = await response.json();
  
  if (result.success) {
    console.log('Campaign deleted successfully');
    return true;
  }
  
  throw new Error(result.message);
}

Campaign Sharing System

Generate Share Links

async function generateShareLink(insiderId, campaignId) {
  const response = await fetch('/partner/v1/campaigns/share', {
    method: 'POST',
    headers,
    body: JSON.stringify({
      insider_id: insiderId,
      campaign_id: campaignId
    })
  });

  const result = await response.json();
  
  if (result.success) {
    return {
      shareUrl: result.data.share_url,
      insiderCode: result.data.insider_code,
      campaignSlug: result.data.campaign_slug,
      campaignName: result.data.campaign_display_name,
      expiresAt: result.data.expires_at
    };
  }
  
  throw new Error(result.message);
}

// Usage example
const shareLink = await generateShareLink('insider-uuid', 'campaign-uuid');
console.log('Share URL:', shareLink.shareUrl);
// Output: https://yourstore.com/sarah2024/summer-sale-2024

Sharing Integration Class

class CampaignSharingManager {
  constructor(secretKey) {
    this.secretKey = secretKey;
    this.headers = {
      'Authorization': `Bearer ${secretKey}`,
      'Content-Type': 'application/json'
    };
  }

  async createShareLink(insiderId, campaignId) {
    try {
      const response = await fetch('/partner/v1/campaigns/share', {
        method: 'POST',
        headers: this.headers,
        body: JSON.stringify({
          insider_id: insiderId,
          campaign_id: campaignId
        })
      });

      const result = await response.json();
      
      if (result.success) {
        return {
          success: true,
          shareData: result.data
        };
      }
      
      return { success: false, error: result.message };
    } catch (error) {
      console.error('Share link generation failed:', error);
      return { success: false, error: 'Network error during share link generation' };
    }
  }

  async generateMultipleShareLinks(campaignId, insiderIds) {
    const shareResults = await Promise.all(
      insiderIds.map(insiderId => this.createShareLink(insiderId, campaignId))
    );

    const successful = shareResults.filter(result => result.success);
    const failed = shareResults.filter(result => !result.success);

    return {
      successful,
      failed,
      totalGenerated: successful.length,
      totalFailed: failed.length
    };
  }

  generateSocialMediaShareUrls(shareUrl, campaignName) {
    const encodedUrl = encodeURIComponent(shareUrl);
    const encodedText = encodeURIComponent(`Check out this amazing deal: ${campaignName}`);

    return {
      facebook: `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`,
      twitter: `https://twitter.com/intent/tweet?url=${encodedUrl}&text=${encodedText}`,
      whatsapp: `https://wa.me/?text=${encodedText}%20${encodedUrl}`,
      instagram: shareUrl, // For Instagram Stories/Posts
      email: `mailto:?subject=${encodedText}&body=Check out this deal: ${encodedUrl}`,
      sms: `sms:?body=${encodedText} ${shareUrl}`
    };
  }

  async enableCampaignSharing(campaignId, insiderIds, options = {}) {
    // Generate share links for all insiders
    const shareResults = await this.generateMultipleShareLinks(campaignId, insiderIds);
    
    // Create sharing interface data
    const sharingData = shareResults.successful.map(result => {
      const shareData = result.shareData;
      const socialUrls = this.generateSocialMediaShareUrls(
        shareData.share_url,
        shareData.campaign_display_name
      );

      return {
        insiderCode: shareData.insider_code,
        insiderName: shareData.insider_name,
        shareUrl: shareData.share_url,
        campaignName: shareData.campaign_display_name,
        socialMediaUrls: socialUrls,
        expiresAt: shareData.expires_at
      };
    });

    return {
      campaignId,
      totalShareLinks: shareResults.totalGenerated,
      sharingData,
      failedGenerations: shareResults.failed
    };
  }
}

// Usage example
const sharingManager = new CampaignSharingManager('your_secret_key');

// Generate sharing links for a campaign
const sharingResults = await sharingManager.enableCampaignSharing(
  'campaign-uuid',
  ['insider1-uuid', 'insider2-uuid', 'insider3-uuid']
);

console.log(`Generated ${sharingResults.totalShareLinks} share links`);
sharingResults.sharingData.forEach(data => {
  console.log(`${data.insiderName}: ${data.shareUrl}`);
});

Social Media Integration

function createSharingInterface(shareData) {
  const container = document.getElementById('sharing-container');
  
  container.innerHTML = `
    <div class="campaign-sharing">
      <h3>Share "${shareData.campaignName}"</h3>
      <div class="share-url">
        <input type="text" value="${shareData.shareUrl}" readonly>
        <button onclick="copyToClipboard('${shareData.shareUrl}')">Copy Link</button>
      </div>
      
      <div class="social-sharing">
        <h4>Share on Social Media</h4>
        <div class="social-buttons">
          <a href="${shareData.socialMediaUrls.facebook}" target="_blank" class="social-btn facebook">
            Facebook
          </a>
          <a href="${shareData.socialMediaUrls.twitter}" target="_blank" class="social-btn twitter">
            Twitter
          </a>
          <a href="${shareData.socialMediaUrls.whatsapp}" target="_blank" class="social-btn whatsapp">
            WhatsApp
          </a>
          <a href="${shareData.socialMediaUrls.email}" class="social-btn email">
            Email
          </a>
          <a href="${shareData.socialMediaUrls.sms}" class="social-btn sms">
            SMS
          </a>
        </div>
      </div>
      
      <div class="sharing-stats">
        <p>Your unique code: <strong>${shareData.insiderCode}</strong></p>
        <p>Expires: ${new Date(shareData.expiresAt).toLocaleDateString()}</p>
      </div>
    </div>
  `;
}

function copyToClipboard(text) {
  navigator.clipboard.writeText(text).then(() => {
    alert('Share link copied to clipboard!');
  }).catch(err => {
    console.error('Failed to copy: ', err);
  });
}

// Usage
const shareData = {
  campaignName: "Summer Sale 2024",
  shareUrl: "https://yourstore.com/sarah2024/summer-sale-2024",
  insiderCode: "sarah2024",
  socialMediaUrls: {
    facebook: "https://www.facebook.com/sharer/...",
    twitter: "https://twitter.com/intent/tweet/...",
    // ... other social URLs
  },
  expiresAt: "2024-08-31T23:59:59.000Z"
};

createSharingInterface(shareData);

Campaign Activation System

Activate Campaign Code

async function activateCampaignCode(code, cartData, sessionData) {
  const activationData = {
    code: code,
    session: sessionData,
    timestamp: new Date().toISOString(),
    products: cartData.products
  };

  const response = await fetch('/partner/v1/campaigns/activate', {
    method: 'POST',
    headers,
    body: JSON.stringify(activationData)
  });

  const result = await response.json();
  
  if (result.success) {
    return {
      success: true,
      tempPurchaseId: result.temp_purchase_id,
      discounts: result.discounts,
      originalTotal: result.original_total,
      discountedTotal: result.discounted_total,
      expiresAt: result.expires_at
    };
  }
  
  throw new Error(result.message);
}

// Usage in checkout flow
async function handleCampaignCode(code) {
  const sessionData = {
    id: localStorage.getItem('cashin_instance_id'),
    user_id: getCurrentUserId(),
    merchant_id: 'your-merchant-id',
    created_at: new Date().toISOString()
  };

  const cartData = {
    products: getCartProducts() // Your cart products
  };

  try {
    const activation = await activateCampaignCode(code, cartData, sessionData);
    
    // Show discount to user
    displayDiscount(activation.discounts);
    updateCartTotal(activation.discountedTotal);
    
    // Store temp purchase ID for verification
    localStorage.setItem('temp_purchase_id', activation.tempPurchaseId);
    
    return activation;
  } catch (error) {
    showError(`Invalid code: ${error.message}`);
    return null;
  }
}

Verify Purchase

async function verifyPurchase(tempPurchaseId, isPurchased) {
  const response = await fetch(`/partner/v1/campaigns/activate/verify/${tempPurchaseId}`, {
    method: 'POST',
    headers,
    body: JSON.stringify({
      purchase_id: tempPurchaseId,
      is_purchased: isPurchased
    })
  });

  const result = await response.json();
  
  if (result.success) {
    return result.data;
  }
  
  throw new Error(result.message);
}

// Usage after payment completion
async function handlePaymentSuccess() {
  const tempPurchaseId = localStorage.getItem('temp_purchase_id');
  
  if (tempPurchaseId) {
    try {
      await verifyPurchase(tempPurchaseId, true);
      console.log('Campaign purchase verified successfully');
      
      // Clean up
      localStorage.removeItem('temp_purchase_id');
    } catch (error) {
      console.error('Failed to verify purchase:', error.message);
    }
  }
}

// Usage when payment fails or is cancelled
async function handlePaymentFailure() {
  const tempPurchaseId = localStorage.getItem('temp_purchase_id');
  
  if (tempPurchaseId) {
    try {
      await verifyPurchase(tempPurchaseId, false);
      console.log('Campaign purchase cancelled');
      
      // Clean up
      localStorage.removeItem('temp_purchase_id');
    } catch (error) {
      console.error('Failed to cancel purchase:', error.message);
    }
  }
}

Complete Campaign Integration

Unified Campaign System

class CashInCampaignSystem {
  constructor(secretKey) {
    this.secretKey = secretKey;
    this.headers = {
      'Authorization': `Bearer ${secretKey}`,
      'Content-Type': 'application/json'
    };
    this.sharingManager = new CampaignSharingManager(secretKey);
  }

  async createAndPublishCampaign(campaignData, imageFile, insiderIds = []) {
    try {
      // Step 1: Create campaign
      const campaign = await createCampaign(campaignData, imageFile);
      console.log('Campaign created:', campaign.campaign_name);

      // Step 2: Publish campaign
      await publishCampaign(campaign.campaign_id);
      console.log('Campaign published and live');

      // Step 3: Generate share links if insiders provided
      let sharingResults = null;
      if (insiderIds.length > 0) {
        sharingResults = await this.sharingManager.enableCampaignSharing(
          campaign.campaign_id,
          insiderIds
        );
        console.log(`Generated ${sharingResults.totalShareLinks} share links`);
      }

      return {
        success: true,
        campaign,
        sharingResults
      };
    } catch (error) {
      console.error('Campaign creation and setup failed:', error);
      return { success: false, error: error.message };
    }
  }

  async getCampaignPerformance(campaignId) {
    const campaign = await getCampaign(campaignId);
    
    // This would be enhanced with actual analytics data
    return {
      campaignId,
      name: campaign.campaign_name,
      status: campaign.status,
      createdAt: campaign.created_at,
      shareLinks: 0, // Would come from analytics
      activations: 0, // Would come from analytics
      conversions: 0, // Would come from analytics
      revenue: 0 // Would come from analytics
    };
  }

  async manageCampaignLifecycle(campaignId, action, options = {}) {
    switch (action) {
      case 'publish':
        return await publishCampaign(campaignId);
      
      case 'update':
        return await updateCampaign(campaignId, options.updates, options.imageFile);
      
      case 'delete':
        return await deleteCampaign(campaignId);
      
      case 'generate_shares':
        return await this.sharingManager.enableCampaignSharing(
          campaignId,
          options.insiderIds
        );
      
      default:
        throw new Error(`Unknown action: ${action}`);
    }
  }
}

// Usage example
const campaignSystem = new CashInCampaignSystem('your_secret_key');

// Create, publish, and enable sharing for a campaign
const result = await campaignSystem.createAndPublishCampaign(
  friendReferralCampaign,
  imageFile,
  ['insider1-uuid', 'insider2-uuid']
);

if (result.success) {
  console.log('Campaign setup complete');
  console.log('Share links generated:', result.sharingResults?.totalShareLinks || 0);
}

Error Handling

Campaign Error Management

class CampaignErrorHandler {
  static handleCampaignError(error, operation) {
    console.error(`Campaign ${operation} error:`, error);
    
    switch (error.status) {
      case 400:
        return {
          userMessage: 'Invalid campaign configuration. Please check your settings.',
          retry: false
        };
        
      case 404:
        return {
          userMessage: 'Campaign not found or code expired.',
          retry: false
        };
        
      case 429:
        return {
          userMessage: 'Too many attempts. Please wait before trying again.',
          retry: true,
          delay: 60000
        };
        
      default:
        return {
          userMessage: 'Something went wrong. Please try again.',
          retry: true
        };
    }
  }

  static async handleWithRetry(campaignOperation, maxRetries = 3) {
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
      try {
        return await campaignOperation();
      } catch (error) {
        const handling = this.handleCampaignError(error, 'operation');
        
        if (!handling.retry || attempt === maxRetries) {
          throw error;
        }
        
        const delay = handling.delay || Math.pow(2, attempt) * 1000;
        await new Promise(resolve => setTimeout(resolve, delay));
      }
    }
  }
}

Testing Campaign System

Test Campaign Integration

async function testCampaignSystem() {
  try {
    // Test activation service
    const response = await fetch('/partner/v1/campaigns/activate/test', {
      method: 'GET',
      headers
    });

    const result = await response.json();
    
    if (result.success) {
      console.log('Campaign system is operational');
      return true;
    } else {
      console.error('Campaign system test failed:', result.message);
      return false;
    }
  } catch (error) {
    console.error('Campaign system test error:', error);
    return false;
  }
}

// Run test before going live
testCampaignSystem().then(isWorking => {
  if (isWorking) {
    console.log('✅ Campaign system ready');
  } else {
    console.log('❌ Campaign system issues detected');
  }
});

This integration guide enables you to create viral marketing campaigns with proper sharing functionality, protecting against deal aggregators and fraud while delivering personalized rewards that turn customers into advocates through authentic sharing.