Welcome

Introduction

Introduction

Setup & Installation

Architecture & Design

Architecture

Features & Scenarios

Deployment

Deployment

API Reference

API Reference

Tools & Utilities

Scripts & UtilitiesTroubleshooting

Scripts & Utilities

Utility scripts for data syncing and maintenance

Scripts & Utilities

The backend/scripts directory contains utility scripts for SynapseAI to maintain and sync data across different services.

Voucherify to Commercetools Sync

Overview

The sync_voucherify_promotions.py script fetches all active promotions from Voucherify and synchronizes them to Commercetools as Cart Discounts and Discount Codes.

This enables promotions created in Voucherify to be automatically applied during checkout in Commercetools.

Use Case

When you create a promotion campaign in Voucherify (e.g., "10% off for bulk orders"), you need that promotion to be available in Commercetools so customers can use it during checkout. This script automates that synchronization.

Prerequisites

Required Environment Variables:

Add these to your .env file:

# CommerceTools
CT_API_URL=https://api.us-central1.gcp.commercetools.com
CT_PROJECT_KEY=your-project-key
CT_CLIENT_ID=your-client-id
CT_CLIENT_SECRET=your-client-secret
CT_AUTH_URL=https://auth.us-central1.gcp.commercetools.com
CT_SCOPES=manage_discount_codes manage_orders view_project_settings

# Voucherify
VOUCHERIFY_MCP_BASE_URL=http://localhost:3002
VOUCHERIFY_APP_ID=your-app-id
VOUCHERIFY_APP_TOKEN=your-app-token

Required Permissions:

  • Commercetools: manage_discount_codes
  • Voucherify: Read access to campaigns

Usage

Run the script from the project root:

cd backend
python scripts/sync_voucherify_promotions.py

What It Does

The script performs the following operations:

  1. Fetches Promotions: Retrieves all active promotions from Voucherify via the MCP client
  2. Checks Existing: Verifies if each promotion already exists in Commercetools (by discount code)
  3. Creates Discounts: For new promotions, creates:
    • Cart Discount in Commercetools
    • Discount Code linked to the Cart Discount
  4. Skips Duplicates: Avoids creating duplicate promotions
  5. Reports Summary: Provides detailed output of synced, skipped, and failed promotions

Promotion Mapping

The script maps Voucherify fields to Commercetools fields:

Voucherify FieldCommercetools FieldDescription
promotion.idDiscount Code codeUnique promotion identifier
redeemable_details.public_bannerCart Discount nameDisplay name
redeemable_details.alternative_descriptionCart Discount descriptionDetailed description
result.discount.type (PERCENT)relative discount typePercentage discount
result.discount.type (AMOUNT)absolute discount typeFixed amount discount
result.discount.percent_offpermyriad valuePercentage × 100
result.discount.amount_offcentAmount valueAmount in cents

Example Output

============================================================
Starting Voucherify → CommerceTools Promotion Sync
============================================================
Fetching promotions from Voucherify...
Found 5 promotions in Voucherify

[1/5] Processing promotion...
Processing promotion: Summer Sale (ID: promo_abc123)
  Type: PERCENT, Value: 10
  Status: SYNCED ✓

[2/5] Processing promotion...
Processing promotion: Winter Discount (ID: promo_def456)
  Type: AMOUNT, Value: 1000
Discount code 'promo_def456' already exists in CommerceTools
  Status: SKIPPED (already exists)

[3/5] Processing promotion...
Processing promotion: Bulk Order Discount (ID: promo_ghi789)
  Type: PERCENT, Value: 15
  Status: SYNCED ✓

[4/5] Processing promotion...
Processing promotion: Flash Sale (ID: promo_jkl012)
  Type: AMOUNT, Value: 500
  Status: SYNCED ✓

[5/5] Processing promotion...
Processing promotion: VIP Discount (ID: promo_mno345)
  Type: PERCENT, Value: 20
  Status: SYNCED ✓

============================================================
Sync Complete - Summary:
============================================================
Total promotions found: 5
Successfully synced:    4
Skipped (existing):     1
Failed:                 0
============================================================

Discount Types

Percentage Discount

Voucherify:

{
  "discount": {
    "type": "PERCENT",
    "percent_off": 10
  }
}

Commercetools:

{
  "value": {
    "type": "relative",
    "permyriad": 1000
  }
}

Fixed Amount Discount

Voucherify:

{
  "discount": {
    "type": "AMOUNT",
    "amount_off": 1000
  }
}

Commercetools:

{
  "value": {
    "type": "absolute",
    "money": [{
      "currencyCode": "USD",
      "centAmount": 1000
    }]
  }
}

Error Handling

The script includes comprehensive error handling:

Missing Credentials:

Error: Missing CommerceTools configuration
Please ensure CT_CLIENT_ID, CT_CLIENT_SECRET, and CT_PROJECT_KEY are set in .env

Existing Promotions:

Discount code 'promo_abc123' already exists in CommerceTools
Status: SKIPPED (already exists)

Individual Failures:

[3/5] Processing promotion...
Error creating discount: HTTP 403 Forbidden
Status: FAILED ✗
Continuing with remaining promotions...

Network Issues:

Error: Cannot connect to Voucherify MCP server
Please ensure VOUCHERIFY_MCP_BASE_URL is correct and server is running

Troubleshooting

Issue: "Missing CommerceTools configuration"

Cause: Environment variables not set

Solution:

# Check .env file exists
ls -la backend/.env

# Verify variables are set
cat backend/.env | grep CT_

Issue: "HTTP 403 Forbidden" when creating discounts

Cause: Missing manage_discount_codes scope

Solution:

# Update .env with correct scopes
CT_SCOPES=manage_products manage_orders manage_discount_codes view_project_settings

Issue: "No promotions found in Voucherify"

Cause:

  • Voucherify MCP server not running
  • Wrong base URL
  • No active campaigns in Voucherify

Solution:

# Check MCP server is running
curl http://localhost:3002/health

# Verify Voucherify credentials
# Check VOUCHERIFY_MCP_BASE_URL in .env

# Ensure you have active campaigns in Voucherify

Issue: "Promotion structure doesn't match expected format"

Cause: Voucherify API response format changed

Solution:

# The script handles multiple response structures
# Check logs for the actual response format
# Update fetch_voucherify_promotions() if needed

Issue: Script runs but promotions don't appear in Commercetools

Cause:

  • Wrong project key
  • Insufficient permissions
  • API endpoint incorrect

Solution:

# Verify CT connection
curl -X POST https://auth.us-central1.gcp.commercetools.com/oauth/token \
  -u "${CT_CLIENT_ID}:${CT_CLIENT_SECRET}" \
  -d "grant_type=client_credentials"

# Check project key
echo $CT_PROJECT_KEY

# Verify scopes include manage_discount_codes
echo $CT_SCOPES

Scheduling

For automated syncing, set up a cron job or scheduled task:

Cron Example (runs daily at 2 AM):

# Edit crontab
crontab -e

# Add line:
0 2 * * * cd /path/to/backend && /usr/bin/python scripts/sync_voucherify_promotions.py >> /var/log/voucherify-sync.log 2>&1

AWS EventBridge (for production):

resource "aws_cloudwatch_event_rule" "sync_promotions" {
  name                = "sync-voucherify-promotions"
  description         = "Trigger promotion sync daily"
  schedule_expression = "cron(0 2 * * ? *)"
}

resource "aws_cloudwatch_event_target" "sync_promotions" {
  rule      = aws_cloudwatch_event_rule.sync_promotions.name
  target_id = "SyncPromotionsLambda"
  arn       = aws_lambda_function.sync_promotions.arn
}

Advanced Usage

Dry Run Mode

Test the script without making changes:

# Add at the beginning of the script
DRY_RUN = True

# In create_discount function:
if DRY_RUN:
    print(f"[DRY RUN] Would create discount: {discount_data}")
    return

Filter by Campaign

Sync only specific campaigns:

# Add campaign filter
ALLOWED_CAMPAIGNS = ["summer-sale", "bulk-discount"]

# In main sync loop:
if promotion_id not in ALLOWED_CAMPAIGNS:
    continue

Custom Mapping

Modify the mapping logic for custom fields:

def map_voucherify_to_ct(voucherify_promotion):
    """Custom mapping logic"""
    # Add custom fields
    # Modify discount calculation
    # Apply business rules
    pass

Future Scripts

Planned Utilities

Product Sync Script (sync_products.py):

  • Sync products from external sources to Commercetools
  • Update product inventory levels
  • Sync product images and descriptions

Order Export Script (export_orders.py):

  • Export orders for accounting
  • Generate reports for analytics
  • Archive historical data

Customer Import Script (import_customers.py):

  • Bulk import customers from CSV
  • Migrate from legacy systems
  • Update customer segments

Cache Warm Script (warm_cache.py):

  • Pre-populate Redis cache
  • Warm up product catalog
  • Prepare for high-traffic events

Contributing

When creating new scripts:

  1. Follow naming convention: action_resource.py
  2. Add comprehensive error handling
  3. Include progress indicators
  4. Provide detailed logging
  5. Document in this guide
  6. Add example output
  7. Include troubleshooting section

Script Template

#!/usr/bin/env python3
"""
Script Name: action_resource.py
Description: Brief description of what this script does
Author: Your Name
Date: YYYY-MM-DD
"""

import os
import sys
from dotenv import load_dotenv

# Load environment variables
load_dotenv()

def validate_config():
    """Validate required configuration"""
    required = ["VAR1", "VAR2"]
    missing = [var for var in required if not os.getenv(var)]
    
    if missing:
        print(f"Error: Missing required variables: {', '.join(missing)}")
        sys.exit(1)

def main():
    """Main execution function"""
    print("=" * 60)
    print("Starting Script Name")
    print("=" * 60)
    
    validate_config()
    
    try:
        # Main logic here
        pass
    except Exception as e:
        print(f"Error: {e}")
        sys.exit(1)
    
    print("=" * 60)
    print("Script Complete")
    print("=" * 60)

if __name__ == "__main__":
    main()

Next Steps

  • Backend Setup - Set up the backend environment
  • Deployment - Deploy to production
  • Architecture - Understand the system

API Reference

API documentation for SynapseAI

Troubleshooting

Common issues and solutions

On this page

Scripts & UtilitiesVoucherify to Commercetools SyncOverviewUse CasePrerequisitesUsageWhat It DoesPromotion MappingExample OutputDiscount TypesPercentage DiscountFixed Amount DiscountError HandlingTroubleshootingIssue: "Missing CommerceTools configuration"Issue: "HTTP 403 Forbidden" when creating discountsIssue: "No promotions found in Voucherify"Issue: "Promotion structure doesn't match expected format"Issue: Script runs but promotions don't appear in CommercetoolsSchedulingAdvanced UsageDry Run ModeFilter by CampaignCustom MappingFuture ScriptsPlanned UtilitiesContributingScript TemplateNext Steps