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 |
|---|---|---|---|---|
|
|
GET |
List all campaigns |
pagination, filters |
campaigns array, pagination |
|
|
GET |
Get campaign details |
campaign_id (URL param) |
campaign object, campaign_json |
|
|
POST |
Create new campaign |
campaign_data, campaign_image |
campaign object |
|
|
PUT |
Update campaign |
campaign_id, updates, optional image |
Updated campaign object |
|
|
DELETE |
Delete campaign |
campaign_id (URL param) |
Success confirmation |
|
|
POST |
Publish campaign |
campaign_id (URL param) |
Published campaign status |
Campaign Activation Endpoints
|
Endpoint |
Method |
Purpose |
Key Parameters |
Response Data |
|---|---|---|---|---|
|
|
POST |
Activate campaign code |
code, session, products |
temp_purchase_id, discounts, totals |
|
|
POST |
Verify purchase |
purchase_id, is_purchased |
Purchase confirmation |
|
|
GET |
Test activation service |
None |
Service status |
Campaign Sharing Endpoint
|
Endpoint |
Method |
Purpose |
Key Parameters |
Response Data |
|---|---|---|---|---|
|
|
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.