Shopify Integration Guide

This comprehensive guide walks you through integrating Tajo with your Shopify store to unlock powerful customer engagement, loyalty programs, and marketing automation capabilities.

Overview

The Tajo-Shopify integration enables you to:

  • Sync customer data automatically from your Shopify store
  • Track orders and products for personalized marketing
  • Run loyalty programs with points, tiers, and rewards
  • Automate marketing campaigns via Brevo (email, SMS, WhatsApp)
  • Segment customers by purchase behavior and engagement
  • Recover abandoned carts with automated sequences

Prerequisites

Before starting the integration, ensure you have:

  • Shopify store on any plan (Basic, Shopify, Advanced, or Plus)
  • Tajo account with an active subscription
  • Brevo account (optional, for marketing automation)
  • Admin access to your Shopify store

Step 1: Install the Tajo App

From Shopify App Store

  1. Go to the Shopify App Store
  2. Search for “Tajo”
  3. Click Add app
  4. Review the permissions and click Install app
  5. You’ll be redirected to the Tajo setup wizard

Manual Installation

If you prefer manual setup:

Terminal window
# Clone the Tajo Shopify app
git clone https://github.com/tajo/shopify-app.git
# Install dependencies
cd shopify-app
npm install
# Configure environment
cp .env.example .env

Configure your .env file:

SHOPIFY_API_KEY=your_api_key
SHOPIFY_API_SECRET=your_api_secret
SHOPIFY_SCOPES=read_customers,write_customers,read_orders,read_products
TAJO_API_KEY=your_tajo_api_key
BREVO_API_KEY=your_brevo_api_key

Step 2: Configure Data Sync

Customer Sync Settings

In your Tajo dashboard, configure which customer data to sync:

{
"sync_settings": {
"customers": {
"enabled": true,
"sync_frequency": "real-time",
"fields": [
"email",
"first_name",
"last_name",
"phone",
"accepts_marketing",
"tags",
"total_spent",
"orders_count",
"created_at",
"addresses"
]
},
"orders": {
"enabled": true,
"sync_frequency": "real-time",
"include_line_items": true,
"include_fulfillments": true
},
"products": {
"enabled": true,
"sync_frequency": "hourly",
"include_variants": true,
"include_images": true
}
}
}

Webhook Configuration

Tajo automatically registers these Shopify webhooks:

WebhookPurpose
customers/createSync new customers to Tajo & Brevo
customers/updateKeep customer profiles current
orders/createTrack purchases, award loyalty points
orders/paidTrigger post-purchase campaigns
orders/fulfilledSend shipping notifications
carts/createTrack abandoned cart data
carts/updateUpdate cart abandonment sequences
products/updateKeep product catalog synced

Initial Data Import

For existing stores, import historical data:

// Import existing customers
async function importShopifyCustomers() {
const shopify = new Shopify({
shopName: process.env.SHOP_NAME,
apiKey: process.env.SHOPIFY_API_KEY,
password: process.env.SHOPIFY_PASSWORD
});
let customers = [];
let params = { limit: 250 };
do {
const batch = await shopify.customer.list(params);
customers = customers.concat(batch);
params = batch.nextPageParameters;
} while (params);
// Sync to Tajo
for (const customer of customers) {
await tajo.customers.upsert({
email: customer.email,
firstName: customer.first_name,
lastName: customer.last_name,
phone: customer.phone,
totalSpent: customer.total_spent,
ordersCount: customer.orders_count,
tags: customer.tags,
source: 'shopify',
externalId: customer.id
});
}
console.log(`Imported ${customers.length} customers`);
}

Step 3: Set Up Loyalty Program

Configure Points System

Define how customers earn points:

const pointsConfig = {
// Points per dollar spent
purchasePoints: {
enabled: true,
rate: 1, // 1 point per $1
roundingMode: 'floor'
},
// Bonus actions
bonusPoints: {
accountCreation: 100,
firstPurchase: 200,
reviewSubmitted: 50,
referralMade: 500,
birthdayBonus: 100,
socialShare: 25
},
// Tier multipliers
tierMultipliers: {
Bronze: 1.0,
Silver: 1.25,
Gold: 1.5,
Platinum: 2.0
}
};

Define Loyalty Tiers

const loyaltyTiers = [
{
name: 'Bronze',
minPoints: 0,
benefits: [
'1 point per $1 spent',
'Birthday bonus points',
'Member-only promotions'
]
},
{
name: 'Silver',
minPoints: 1000,
benefits: [
'1.25x points multiplier',
'Free shipping on orders $50+',
'Early access to sales'
]
},
{
name: 'Gold',
minPoints: 5000,
benefits: [
'1.5x points multiplier',
'Free shipping on all orders',
'Exclusive product access',
'Priority customer support'
]
},
{
name: 'Platinum',
minPoints: 15000,
benefits: [
'2x points multiplier',
'Free express shipping',
'VIP experiences',
'Personal shopping assistant',
'Annual gift'
]
}
];

Create Rewards Catalog

const rewards = [
{
id: 'discount_5',
name: '$5 Off',
pointsCost: 500,
type: 'fixed_discount',
value: 5,
minPurchase: 25
},
{
id: 'discount_10',
name: '$10 Off',
pointsCost: 900,
type: 'fixed_discount',
value: 10,
minPurchase: 50
},
{
id: 'percent_10',
name: '10% Off',
pointsCost: 750,
type: 'percentage_discount',
value: 10,
maxDiscount: 50
},
{
id: 'free_shipping',
name: 'Free Shipping',
pointsCost: 300,
type: 'free_shipping'
},
{
id: 'free_product',
name: 'Free Gift',
pointsCost: 2000,
type: 'free_product',
productId: 'gid://shopify/Product/123456'
}
];

Step 4: Abandoned Cart Recovery

Configure Cart Tracking

// Track cart updates
shopify.webhooks.on('carts/update', async (cart) => {
if (cart.line_items.length === 0) return;
const customer = await getCustomerByCart(cart);
if (!customer?.email) return;
await tajo.carts.track({
customerId: customer.id,
cartToken: cart.token,
items: cart.line_items.map(item => ({
productId: item.product_id,
variantId: item.variant_id,
title: item.title,
quantity: item.quantity,
price: item.price,
image: item.image
})),
totalPrice: cart.total_price,
currency: cart.currency,
checkoutUrl: cart.checkout_url
});
});

Set Up Recovery Sequence

{
"abandoned_cart_sequence": {
"trigger": {
"event": "cart_abandoned",
"delay": "1 hour"
},
"emails": [
{
"delay": "1 hour",
"channel": "email",
"template": "cart_reminder_1",
"subject": "You left something behind!"
},
{
"delay": "24 hours",
"channel": "email",
"template": "cart_reminder_2",
"subject": "Your cart is waiting - 10% off inside"
},
{
"delay": "72 hours",
"channel": "sms",
"template": "cart_sms_final",
"message": "Last chance! Your cart expires soon. Complete your order: {{checkout_url}}"
}
],
"exit_conditions": [
"order_completed",
"cart_emptied",
"unsubscribed"
]
}
}

Step 5: Marketing Automation with Brevo

Customer Segments

Create powerful segments based on Shopify data:

const shopifySegments = [
// Purchase behavior
{
name: 'First-Time Buyers',
conditions: { orders_count: 1 }
},
{
name: 'Repeat Customers',
conditions: { orders_count: { $gte: 2 } }
},
{
name: 'VIP Customers',
conditions: { total_spent: { $gte: 500 } }
},
{
name: 'At-Risk Customers',
conditions: {
last_order_date: { $lt: '90 days ago' },
orders_count: { $gte: 2 }
}
},
// Product interest
{
name: 'Category: Electronics',
conditions: { purchased_categories: { $contains: 'Electronics' } }
},
// Engagement
{
name: 'Abandoned Cart',
conditions: { has_abandoned_cart: true }
},
{
name: 'Browse Abandoners',
conditions: {
viewed_products: { $gte: 3 },
orders_count: 0
}
}
];

Automated Campaign Triggers

// Order confirmation + upsell
shopify.webhooks.on('orders/paid', async (order) => {
const customer = await tajo.customers.get(order.customer.id);
// Update customer stats
await tajo.customers.update(customer.id, {
totalSpent: customer.totalSpent + order.total_price,
ordersCount: customer.ordersCount + 1,
lastOrderDate: order.created_at
});
// Award loyalty points
const pointsEarned = calculatePoints(order, customer);
await tajo.loyalty.awardPoints(customer.id, pointsEarned, {
reason: 'purchase',
orderId: order.id
});
// Send to Brevo for campaigns
await brevo.trackEvent(customer.email, 'order_completed', {
order_id: order.id,
order_total: order.total_price,
points_earned: pointsEarned,
loyalty_tier: customer.loyaltyTier,
products: order.line_items.map(i => i.title).join(', ')
});
});
// Post-purchase review request
const reviewRequestCampaign = {
trigger: 'order_delivered',
delay: '7 days',
template: 'review_request',
conditions: {
customer_tags: { $not: { $contains: 'no-review-request' } }
}
};
// Win-back campaign
const winBackCampaign = {
trigger: 'customer_inactive',
conditions: {
last_order_date: '90 days ago',
orders_count: { $gte: 1 }
},
sequence: [
{ delay: '0', template: 'we_miss_you', offer: '15% off' },
{ delay: '7 days', template: 'win_back_2', offer: '20% off' },
{ delay: '14 days', template: 'final_offer', offer: '25% off' }
]
};

Step 6: Product Recommendations

Configure Recommendation Engine

const recommendationConfig = {
algorithms: [
{
name: 'frequently_bought_together',
weight: 0.3
},
{
name: 'similar_products',
weight: 0.25
},
{
name: 'customer_also_viewed',
weight: 0.2
},
{
name: 'trending_in_category',
weight: 0.15
},
{
name: 'personalized_for_you',
weight: 0.1
}
],
filters: {
exclude_purchased: true,
exclude_out_of_stock: true,
min_rating: 3.5
}
};
// Get recommendations for email
async function getEmailRecommendations(customerId, limit = 4) {
const customer = await tajo.customers.get(customerId);
const recentOrders = await tajo.orders.list({
customerId,
limit: 5
});
return await tajo.recommendations.get({
customerId,
purchaseHistory: recentOrders,
browsingHistory: customer.recentlyViewed,
limit,
algorithms: recommendationConfig.algorithms
});
}

Step 7: Analytics & Reporting

Key Metrics Dashboard

const dashboardMetrics = {
// Customer metrics
customers: {
total: await tajo.analytics.count('customers'),
new_this_month: await tajo.analytics.count('customers', {
created_at: { $gte: 'this_month' }
}),
returning_rate: await tajo.analytics.returningCustomerRate()
},
// Revenue metrics
revenue: {
total: await tajo.analytics.sum('orders.total'),
average_order_value: await tajo.analytics.avg('orders.total'),
revenue_per_customer: await tajo.analytics.revenuePerCustomer()
},
// Loyalty metrics
loyalty: {
active_members: await tajo.analytics.count('loyalty_members', {
status: 'active'
}),
points_issued: await tajo.analytics.sum('points.awarded'),
points_redeemed: await tajo.analytics.sum('points.redeemed'),
redemption_rate: await tajo.analytics.pointsRedemptionRate()
},
// Campaign metrics
campaigns: {
emails_sent: await brevo.analytics.emailsSent('this_month'),
open_rate: await brevo.analytics.openRate('this_month'),
click_rate: await brevo.analytics.clickRate('this_month'),
revenue_attributed: await tajo.analytics.campaignRevenue('this_month')
}
};

Troubleshooting

Common Issues

Webhook Delivery Failures

// Verify webhook signature
function verifyShopifyWebhook(req) {
const hmac = req.headers['x-shopify-hmac-sha256'];
const body = req.rawBody;
const hash = crypto
.createHmac('sha256', process.env.SHOPIFY_WEBHOOK_SECRET)
.update(body)
.digest('base64');
return crypto.timingSafeEqual(
Buffer.from(hash),
Buffer.from(hmac)
);
}

Sync Conflicts

// Handle duplicate customers
async function resolveCustomerConflict(shopifyCustomer, tajoCustomer) {
// Merge data, preferring most recent updates
const merged = {
...tajoCustomer,
email: shopifyCustomer.email,
firstName: shopifyCustomer.first_name || tajoCustomer.firstName,
lastName: shopifyCustomer.last_name || tajoCustomer.lastName,
phone: shopifyCustomer.phone || tajoCustomer.phone,
// Keep Tajo loyalty data
loyaltyPoints: tajoCustomer.loyaltyPoints,
loyaltyTier: tajoCustomer.loyaltyTier
};
return await tajo.customers.update(tajoCustomer.id, merged);
}

Rate Limiting

// Implement exponential backoff
async function shopifyApiCall(fn, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
return await fn();
} catch (error) {
if (error.code === 429 && i < retries - 1) {
const delay = Math.pow(2, i) * 1000;
await new Promise(r => setTimeout(r, delay));
continue;
}
throw error;
}
}
}

Next Steps

  1. Configure Brevo Integration for email/SMS campaigns
  2. Set Up Webhooks for real-time events
  3. Create Customer Segments for targeted marketing
  4. Build Email Templates for automated campaigns

Support

AI-assistent

Hallo! Stel me vragen over de documentatie.

Start gratis met Brevo