🚀 Executive Summary
TL;DR: This guide addresses the problem of fragmented customer data between Stripe and Intercom, which hinders efficient support. It provides a step-by-step Python-based solution to automatically sync Stripe customer and subscription details into Intercom’s custom attributes, enabling support agents with immediate, comprehensive context.
🎯 Key Takeaways
- Securely obtain and manage Stripe Secret API Keys and Intercom Personal Access Tokens using environment variables and
python-dotenv. - Utilize Python virtual environments (
venv) and installstripe,intercom-python, andpython-dotenvfor dependency management. - Fetch all Stripe customers efficiently using
stripe.Customer.list().auto\_paging\_iter()to handle pagination automatically. - Map Stripe customer IDs to Intercom’s
external\_idfor robust upsert operations (create or update) and link customer profiles across platforms. - Enrich Intercom user profiles with Stripe data (e.g.,
balance,currency,livemode,subscription\_status,plan\_name) by mapping them to custom attributes. - Implement comprehensive error handling for both Stripe and Intercom API calls to ensure script robustness and graceful failure.
- Be aware of API rate limits for both Stripe and Intercom; for large datasets, consider batching or introducing delays to prevent HTTP 429 errors.
- Enhance the solution with Stripe Webhooks for real-time updates, integrate more data sources, or deploy as a scheduled job (e.g.,
cron, AWS Lambda) for continuous synchronization.
Syncing Stripe Customers to Intercom for Better Support Context
As a DevOps Engineer, you know the value of connected systems. Fragmented data across different platforms is a common pain point, especially when it comes to customer support. Imagine a customer reaching out to your support team on Intercom, but your agents have no immediate access to their subscription status, payment history, or recent activity from Stripe. This lack of context leads to slower resolution times, frustrated customers, and inefficient support operations. Manually looking up customer details in separate dashboards is not only tedious but also prone to human error and simply doesn’t scale.
At TechResolve, we believe in automating away these inefficiencies. This tutorial will guide you through building a robust, automated solution to sync your Stripe customer data directly into Intercom. By integrating these two critical platforms, your support agents will gain immediate access to comprehensive customer profiles, enabling them to provide faster, more personalized, and effective support. No more tab-switching, no more guesswork – just streamlined support with all the context you need, right where you need it.
Prerequisites
Before we dive into the integration, ensure you have the following:
- A Stripe Account with access to your secret API keys.
- An Intercom Account with developer permissions to generate a Personal Access Token.
- Python 3.7+ installed on your system.
- pip (Python package installer), usually included with Python 3.
- A basic understanding of Python programming and API concepts.
- Familiarity with environment variables for securely storing API keys.
Step-by-Step Guide: Integrating Stripe and Intercom
We’ll break down the integration into four clear steps: obtaining credentials, setting up your environment, fetching data from Stripe, and finally, pushing that data to Intercom.
Step 1: Obtain API Credentials
Security is paramount. Your API keys grant programmatic access to sensitive data, so treat them like passwords and never expose them in your code or public repositories. We’ll use environment variables for this.
Stripe Secret Key
Log in to your Stripe Dashboard. Navigate to the “Developers” section (usually on the left sidebar), then click on “API Keys.” You’ll see a “Publishable key” and a “Secret key.” We need the Secret key. If it’s hidden, click “Reveal test key” or “Reveal live key” to copy it. For this tutorial, using a test key is recommended first.
Intercom Personal Access Token
Log in to your Intercom workspace. Go to “Settings” (bottom left gear icon) > “Developers” > “Developer Hub.” From there, click on “Your apps,” then select an existing app or “New app.” Under “Authentication,” you’ll find “Personal Access Tokens.” Generate a new token and ensure it has the necessary permissions (e.g., read_users, write_users) to manage users. Copy this token.
Create a file named .env in your project directory to store these keys:
STRIPE_SECRET_KEY="sk_test_YOUR_STRIPE_SECRET_KEY"
INTERCOM_ACCESS_TOKEN="dGhpcyBpcyBhIHNhbXBsZSB0b2tlbiBhbmQgbm90IGEgbGl2ZSBvbmU="
Step 2: Set Up Your Python Environment
It’s always best practice to work within a virtual environment to manage project dependencies without conflicts.
- Create a virtual environment:
python3 -m venv venv
-
Activate the virtual environment:
- On macOS/Linux:
source venv/bin/activate
-
On Windows:
.\venv\Scripts\activate
- Install necessary libraries:
We’ll use stripe for Stripe API interaction, intercom-python for Intercom API interaction, and python-dotenv to load our environment variables.
pip install stripe intercom-python python-dotenv
Step 3: Fetch Customers from Stripe
Now, let’s write the Python code to fetch your customer data from Stripe. We’ll iterate through all customers to ensure we get a complete list.
Create a file named sync_stripe_intercom.py:
import os
import stripe
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
# Initialize Stripe API key
stripe.api_key = os.environ.get("STRIPE_SECRET_KEY")
def get_stripe_customers():
"""
Fetches all customers from Stripe using auto-pagination.
Returns a list of Stripe Customer objects.
"""
customers = []
try:
# Use auto_paging_iter to handle pagination automatically for large datasets
for customer in stripe.Customer.list(limit=100).auto_paging_iter():
customers.append(customer)
print(f"Successfully fetched {len(customers)} customers from Stripe.")
except stripe.error.StripeError as e:
print(f"Error fetching Stripe customers: {e}")
exit(1)
return customers
if __name__ == "__main__":
print("Starting Stripe customer fetch process...")
stripe_customers = get_stripe_customers()
if stripe_customers:
print("First 5 Stripe customers (for preview):")
for customer in stripe_customers[:5]:
print(f" ID: {customer.id}, Email: {customer.email}, Name: {customer.name}")
else:
print("No customers found in Stripe or an error occurred.")
Logic Explanation:
- We import
osto interact with environment variables,stripefor the Stripe API, andload_dotenvto load our.envfile. -
stripe.api_keyis set using the secret key from your environment. - The
get_stripe_customersfunction usesstripe.Customer.list(). Crucially,.auto_paging_iter()ensures that if you have more than the default 100 customers, it automatically fetches all subsequent pages of results, saving you from manual pagination logic. - Error handling for Stripe API issues is included to make the script more robust.
Step 4: Sync Customers to Intercom
With our Stripe customer data in hand, the next step is to push it to Intercom. Intercom allows you to create or update users based on their email or a unique external_id. We’ll use the Stripe customer ID as the external_id in Intercom for robust linking and the customer’s email.
Extend your sync_stripe_intercom.py file with the Intercom integration logic:
import os
import stripe
import intercom
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
# Initialize Stripe API key
stripe.api_key = os.environ.get("STRIPE_SECRET_KEY")
# Initialize Intercom Client
intercom_client = intercom.Client(personal_access_token=os.environ.get("INTERCOM_ACCESS_TOKEN"))
def get_stripe_customers():
"""
Fetches all customers from Stripe using auto-pagination.
Returns a list of Stripe Customer objects.
"""
customers = []
try:
for customer in stripe.Customer.list(limit=100).auto_paging_iter():
customers.append(customer)
print(f"Successfully fetched {len(customers)} customers from Stripe.")
except stripe.error.StripeError as e:
print(f"Error fetching Stripe customers: {e}")
# Depending on criticality, you might want to log and continue or exit
exit(1)
return customers
def sync_customer_to_intercom(stripe_customer):
"""
Syncs a single Stripe customer to Intercom, creating or updating them.
"""
if not stripe_customer.email:
print(f" Skipping Stripe customer {stripe_customer.id} as no email address was found.")
return
# Prepare data for Intercom.
# Intercom's `save` method acts as an upsert based on email or external_id.
intercom_data = {
"email": stripe_customer.email,
"name": stripe_customer.name or stripe_customer.email.split('@')[0], # Use email prefix if name is missing
"external_id": stripe_customer.id, # Link Stripe Customer ID to Intercom
"signed_up_at": stripe_customer.created, # Unix timestamp of creation
"custom_attributes": {
"stripe_customer_id": stripe_customer.id,
"stripe_balance": stripe_customer.balance,
"stripe_currency": stripe_customer.currency,
"livemode": stripe_customer.livemode,
"stripe_created": stripe_customer.created # Duplicate for clarity if desired
}
}
# Fetch subscriptions to add more context
try:
subscriptions = stripe.Subscription.list(customer=stripe_customer.id, status='active').data
if subscriptions:
# Taking the first active subscription for summary attributes
first_sub = subscriptions[0]
intercom_data["custom_attributes"]["stripe_subscription_status"] = first_sub.status
intercom_data["custom_attributes"]["stripe_subscription_id"] = first_sub.id
intercom_data["custom_attributes"]["stripe_subscription_plan"] = first_sub.plan.name if first_sub.plan else "N/A"
intercom_data["custom_attributes"]["stripe_current_period_end"] = first_sub.current_period_end
intercom_data["custom_attributes"]["stripe_cancel_at_period_end"] = first_sub.cancel_at_period_end
else:
intercom_data["custom_attributes"]["stripe_subscription_status"] = "no_active_subscription"
except stripe.error.StripeError as e:
print(f" Warning: Could not fetch subscriptions for {stripe_customer.id}: {e}")
# Continue syncing the customer even if subscription fetch fails
try:
user = intercom_client.users.save(**intercom_data)
print(f" Successfully synced/updated Stripe customer {stripe_customer.id} as Intercom User ID: {user.id}")
except intercom.errors.IntercomError as e:
print(f" Error syncing Stripe customer {stripe_customer.id} ({stripe_customer.email}): {e}")
if __name__ == "__main__":
print("Starting Stripe customer to Intercom sync process...")
all_stripe_customers = get_stripe_customers()
if all_stripe_customers:
print(f"Initiating sync for {len(all_stripe_customers)} Stripe customers to Intercom...")
for customer in all_stripe_customers:
sync_customer_to_intercom(customer)
print("Sync process completed.")
else:
print("No customers to sync.")
Logic Explanation:
- We initialize the
intercom_clientusing your Personal Access Token. - The
sync_customer_to_intercomfunction takes a Stripe customer object. - It constructs a dictionary
intercom_data.-
emailandnameare standard Intercom fields. We provide a fallback fornameif it’s not present in Stripe. -
external_idis crucial. We map the Stripe customer ID here. This allows Intercom to uniquely identify the user across systems, even if their email changes, and enables the upsert functionality (create if not exists, update if exists). -
signed_up_atis set fromstripe_customer.created, which is a Unix timestamp. -
custom_attributesis where the magic happens for support context. You can map any relevant Stripe customer properties (like balance, live mode, and importantly, subscription details) to Intercom custom attributes. These will appear on the user’s profile in Intercom.
-
- We also fetch active subscriptions for each customer to enrich the Intercom profile with current subscription status and plan details.
-
intercom_client.users.save(**intercom_data)is the core Intercom API call. This method automatically handles creating a new user or updating an existing one based on the providedemailandexternal_id. - Comprehensive error handling for both Stripe and Intercom API calls ensures that the script can gracefully handle issues without crashing.
To run your sync script:
python sync_stripe_intercom.py
Watch the output as your customers are synced. Then, check your Intercom workspace; you should see new or updated users with rich Stripe data in their custom attributes!
Common Pitfalls
Even with careful planning, integrations can sometimes hit bumps. Here are a couple of common issues to be aware of:
-
API Rate Limits: Both Stripe and Intercom have API rate limits to prevent abuse.
-
Stripe: Generally generous (e.g., 100 requests per second for most endpoints). Our script uses
auto_paging_iter, which handles multiple requests internally, but if you’re making many other calls, you might hit limits. -
Intercom: Can be stricter, especially for write operations (e.g., 5 requests per second burst, 2 sustained for some endpoints). For large customer bases, a batch update API or adding small delays (e.g.,
time.sleep(0.5)after each Intercom call) might be necessary to avoid hitting limits. Theintercom-pythonlibrary often has built-in retry mechanisms, but it’s good to be aware.
-
Stripe: Generally generous (e.g., 100 requests per second for most endpoints). Our script uses
If you encounter rate limit errors (often HTTP 429), consider implementing exponential backoff and retries, or processing customers in smaller batches over time.
- Authentication Errors / Incorrect API Keys: A common oversight is using an incorrect API key (e.g., a publishable key instead of a secret key, or a test key for a live environment without realizing it). Ensure your environment variables are correctly loaded and contain the right credentials. Double-check permissions on your Intercom Personal Access Token.
- Data Mismatches and Missing Fields: Not all Stripe customers will have a name, or even an email in rare cases. Our script handles missing names by falling back to a part of the email address. However, if your Intercom workflow strictly requires certain fields, ensure your data mapping logic accounts for potential nulls or provides sensible defaults.
Conclusion
Congratulations! You’ve successfully built an automated system to sync Stripe customer data to Intercom. Your support team now has a richer, more comprehensive view of each customer, directly within their Intercom conversations. This translates to faster issue resolution, more personalized interactions, and a significantly improved customer experience. By eliminating manual data lookups, you free up valuable time for your support agents to focus on what they do best: helping your customers.
This solution is just the beginning. Consider enhancing it by:
- Implementing Stripe Webhooks to trigger real-time updates to Intercom whenever a customer’s subscription changes or a new customer is created.
- Adding more custom attributes from Stripe, such as recent invoice details or specific product purchases, to Intercom.
- Integrating other data sources (e.g., your CRM, product usage data) into Intercom to build an even more holistic customer profile.
- Deploying this script as a scheduled job using
cron, a cloud function (like AWS Lambda or Azure Functions), or a containerized service to keep your data regularly updated.
At TechResolve, we empower you to build intelligent, connected systems. Keep automating, and keep resolving!
👉 Read the original article on TechResolve.blog
☕ Support my work
If this article helped you, you can buy me a coffee:

Top comments (0)