Subscription Management Agent
Handle plan upgrades, downgrades, cancellations, billing queries, and payment method updates via web chat or inbound voice — backed by Stripe.
What you'll build
An agent that handles the full subscription lifecycle in conversation: plan comparisons, upgrade and downgrade requests, cancellation with a save flow, billing query resolution, and payment method update prompts — all through Stripe, with a human handoff via escalation email for failed payment disputes or multi-month billing discrepancies.
Customer journey
A subscriber opens Web Chat on your billing portal to change plans or cancel. The agent explains options from the plan comparison knowledge base, processes changes through Stripe, and offers retention deals. Complex enterprise accounts may call in for custom terms.
See Deploying and testing channels for connect and test steps per channel.
Prerequisites
- BimpeAI account with an API key (
sk_…) - Read Anatomy of a workflow agent first — this recipe skips steps covered there
- Stripe connected in the Console dashboard (see Step 4)
- Web chat widget and inbound voice phone number connected in the Console dashboard (see Step 4)
- Escalation email configured under Settings → Agent for billing disputes (see Step 4)
Steps
1. Find or create the workflow
import { BimpeAI } from "@bimpeai/sdk";
const bimpe = new BimpeAI({ apiKey: process.env.BIMPEAI_API_KEY! });
const page = await bimpe.workflows.list({ scope: "public", search: "subscription management" });
const workflow = page.data[0];
console.log(workflow.id, workflow.name);import os
from bimpeai import BimpeAI
client = BimpeAI(api_key=os.environ["BIMPEAI_API_KEY"])
page = client.workflows.list(scope="public", search="subscription management")
workflow = page.data[0]
print(workflow.id, workflow.name)Or build a new workflow from scratch with workflows.create instead of finding one. name and system_prompt are required; it returns the new Workflow whose id you bind the agent to. See Anatomy of a workflow agent for the full set of optional fields like rules and flows.
const workflow = await bimpe.workflows.create({
name: "Subscription management agent",
system_prompt: "You handle plan upgrades, downgrades, cancellations, billing queries, and payment method updates through Stripe, escalating disputes to a human.",
});
console.log(workflow.id);workflow = client.workflows.create(
name="Subscription management agent",
system_prompt="You handle plan upgrades, downgrades, cancellations, billing queries, and payment method updates through Stripe, escalating disputes to a human.",
)
print(workflow.id)2. Create the agent
const agent = await bimpe.agents.create(
{
name: "Subscription management agent",
description: "Handles plan upgrades, downgrades, cancellations, billing queries, and payment method updates, backed by Stripe.",
workflow_id: workflow.id,
},
{ idempotencyKey: "create-subscription-agent-v1" },
);
console.log(agent.id);agent = client.agents.create(
name="Subscription management agent",
description="Handles plan upgrades, downgrades, cancellations, billing queries, and payment method updates, backed by Stripe.",
workflow_id=workflow.id,
idempotency_key="create-subscription-agent-v1",
)
print(agent.id)3. Add knowledge bases (optional)
Knowledge bases are optional; an agent whose workflow and integrations already cover everything it needs to say can skip this step. This recipe uses one to ground the agent in the details it must quote accurately.
Three knowledge bases cover plan comparison, billing explanations, and the retention save flow.
// Plan comparison and pricing
await bimpe.agents.knowledgeBases.create(agent.id, {
type: "text",
name: "Plan comparison",
content:
"Starter — £12/month or £120/year: 1 user, 5 projects, 5 GB storage, email support.\n" +
"Pro — £39/month or £390/year: 5 users, unlimited projects, 50 GB storage, priority support, API access.\n" +
"Business — £99/month or £990/year: 20 users, unlimited everything, 500 GB storage, dedicated CSM, SSO.\n" +
"Enterprise — custom pricing: unlimited users, custom storage, SLA, on-premise option.\n" +
"Annual billing saves 17% versus monthly. Upgrades are prorated. Downgrades take effect at the next billing cycle.",
});
// Common billing line items
await bimpe.agents.knowledgeBases.create(agent.id, {
type: "text",
name: "Billing guide",
content:
"Monthly charge: your plan price on the same date each month.\n" +
"Annual charge: full year billed upfront on the anniversary of signup.\n" +
"Proration on upgrade: you are charged the difference for the remaining days in the current cycle.\n" +
"Proration on downgrade: credited amount applied to the next cycle — not refunded immediately.\n" +
"Failed payment: we retry on days 3, 5, and 7. After the third failure, the account is paused.",
});
// Retention save offers
await bimpe.agents.knowledgeBases.create(agent.id, {
type: "text",
name: "Retention offers",
content:
"Reason: too expensive → offer 20% off for 3 months (one-time per customer).\n" +
"Reason: not using it / too busy → offer a 1-month pause at no charge.\n" +
"Reason: missing a feature → log the feature request and offer a 2-week extension while it is reviewed.\n" +
"Reason: switching to a competitor → ask what the competitor offers and report back to the product team.\n" +
"Only one offer per cancellation attempt. Do not stack offers.",
});# Plan comparison and pricing
client.agents.knowledge_bases.create(agent.id, {
"type": "text",
"name": "Plan comparison",
"content": (
"Starter — £12/month or £120/year: 1 user, 5 projects, 5 GB storage, email support.\n"
"Pro — £39/month or £390/year: 5 users, unlimited projects, 50 GB storage, priority support, API access.\n"
"Business — £99/month or £990/year: 20 users, unlimited everything, 500 GB storage, dedicated CSM, SSO.\n"
"Enterprise — custom pricing: unlimited users, custom storage, SLA, on-premise option.\n"
"Annual billing saves 17% versus monthly. Upgrades are prorated. Downgrades take effect at the next billing cycle."
),
})
# Common billing line items
client.agents.knowledge_bases.create(agent.id, {
"type": "text",
"name": "Billing guide",
"content": (
"Monthly charge: your plan price on the same date each month.\n"
"Annual charge: full year billed upfront on the anniversary of signup.\n"
"Proration on upgrade: you are charged the difference for the remaining days in the current cycle.\n"
"Proration on downgrade: credited amount applied to the next cycle — not refunded immediately.\n"
"Failed payment: we retry on days 3, 5, and 7. After the third failure, the account is paused."
),
})
# Retention save offers
client.agents.knowledge_bases.create(agent.id, {
"type": "text",
"name": "Retention offers",
"content": (
"Reason: too expensive → offer 20% off for 3 months (one-time per customer).\n"
"Reason: not using it / too busy → offer a 1-month pause at no charge.\n"
"Reason: missing a feature → log the feature request and offer a 2-week extension while it is reviewed.\n"
"Reason: switching to a competitor → ask what the competitor offers and report back to the product team.\n"
"Only one offer per cancellation attempt. Do not stack offers."
),
})4. Connect channels and integrations (dashboard)
Channels and Stripe are connected in the dashboard
The API cannot create channel connections, but integrations can now be configured through it; see Configuring integrations. Connect your messaging channels on the Deploy screen and Stripe on the Integrations screen of the Console dashboard. The SDK lists what is active but cannot modify channel connections.
- In the Console dashboard, pick your agent from the switcher at the top, then open Deploy.
- Under Messaging & Chat, click Connect on the Web Chat Widget card to add the widget to your account settings page.
- Under Voice, click Set up on the Telephony card — it is an add-on with usage-based pricing. Provision or link a number under Team settings → Phone numbers, then set the agent's voice and greeting under Settings → Voice.
- Open Integrations, find Stripe, and click Connect. The agent reads subscription state, processes plan changes, and retrieves payment method update links through this integration.
- Under Settings → Agent, set the Escalation Email for failed payment disputes and multi-month discrepancies.
Connect Web Chat
Visitors use the chat widget embedded on your website or app.
- Open Deploy and select your agent.
- Under Messaging & Chat, click Connect on the Web Chat Widget card.
- Copy the embed snippet and paste it into your site's HTML before the closing body tag.
- Publish your site — the chat bubble appears in the corner and routes messages to this agent.
Full reference: Deploying and testing channels.
Connect Telephony (inbound)
Customers dial your published support or sales line.
- Open Deploy and click Set up on the Telephony card (usage-based add-on).
- Under Team settings → Phone numbers, provision or link a number and assign it to this agent.
- Under Settings → Voice, choose the voice profile and greeting callers hear.
- Share the published phone number — inbound calls route to the agent automatically.
Full reference: Deploying and testing channels.
5. Test your agent
Before going live, exercise the agent on the web chat test channel. Fetch the test code (created on first request), then inject a customer message from your server — or test the agent live in the Playground on the dashboard.
Test Web Chat
Playground: open Playground → Chat in the dashboard for a quick sanity check.
SDK injection: call conversations.send with channel_type: "webchat" and a stable channel_user_id, or set is_test_channel: true before go-live.
Full reference: Deploying and testing channels.
Test Telephony (inbound)
Human tester: dial the linked phone number from a mobile phone and walk through the script.
Playground: use Playground → Voice to hear the agent before publishing the number.
Full reference: Deploying and testing channels.
await bimpe.agents.getTestCode(agent.id); // creates the test code on first request
await bimpe.conversations.send(agent.id, {
message: "Can I upgrade from Starter to Pro and how much will I be charged today?",
channel_type: "webchat",
channel_user_id: "<tester-id>",
is_test_channel: true,
});client.agents.get_test_code(agent.id) # creates the test code on first request
client.conversations.send(
agent.id,
message="Can I upgrade from Starter to Pro and how much will I be charged today?",
channel_type="webchat",
channel_user_id="<tester-id>",
is_test_channel=True,
)To exercise the phone path too, place a test call with bimpe.calls.make(agent.id, { destination, is_test_call: true }) (Python: client.calls.make(agent.id, {"destination": ..., "is_test_call": True})).
See Test your agent for the other test channels and the pause-AI rule.
6. Verify and go live
const integrations = await bimpe.agents.integrations.list(agent.id);
const channels = await bimpe.agents.channels.list(agent.id);
console.log("Integrations:", integrations.map((i) => i.name));
console.log("Channels:", channels.map((c) => c.type));integrations = client.agents.integrations.list(agent.id)
channels = client.agents.channels.list(agent.id)
print("Integrations:", [i.name for i in integrations])
print("Channels:", [c.type for c in channels])Full example
import { BimpeAI } from "@bimpeai/sdk";
const bimpe = new BimpeAI({ apiKey: process.env.BIMPEAI_API_KEY! });
// 1. Find workflow
const page = await bimpe.workflows.list({ scope: "public", search: "subscription management" });
const workflow = page.data[0];
// 2. Create agent
const agent = await bimpe.agents.create(
{
name: "Subscription management agent",
description: "Handles plan upgrades, downgrades, cancellations, billing queries, and payment method updates, backed by Stripe.",
workflow_id: workflow.id,
},
{ idempotencyKey: "create-subscription-agent-v1" },
);
// 3. Add knowledge bases
await bimpe.agents.knowledgeBases.create(agent.id, {
type: "text",
name: "Plan comparison",
content:
"Starter £12/mo: 1 user, 5 projects. Pro £39/mo: 5 users, unlimited projects, API. " +
"Business £99/mo: 20 users, SSO, CSM. Annual saves 17%.",
});
await bimpe.agents.knowledgeBases.create(agent.id, {
type: "text",
name: "Billing guide",
content:
"Upgrades: prorated. Downgrades: credit next cycle. " +
"Failed payment: retried days 3, 5, 7 — account paused after third failure.",
});
await bimpe.agents.knowledgeBases.create(agent.id, {
type: "text",
name: "Retention offers",
content:
"Too expensive: 20% off 3 months. Not using: 1-month pause. Missing feature: 2-week extension. " +
"One offer per attempt only.",
});
// 4. Verify integrations (Stripe must be connected in dashboard)
const integrations = await bimpe.agents.integrations.list(agent.id);
const channels = await bimpe.agents.channels.list(agent.id);
console.log("Agent ID:", agent.id);
console.log("Integrations:", integrations.map((i) => i.name));
console.log("Channels:", channels.map((c) => c.type));
// 5. Stream web chat subscription conversations
const controller = new AbortController();
const conversations = await bimpe.conversations.list(agent.id, { channel: "webchat" });
const conv = conversations.data[0];
if (conv) {
for await (const event of bimpe.conversations.messages.stream(agent.id, conv.id, {
signal: controller.signal,
})) {
console.log(event.role, event.message);
}
}import os
from bimpeai import BimpeAI
client = BimpeAI(api_key=os.environ["BIMPEAI_API_KEY"])
# 1. Find workflow
page = client.workflows.list(scope="public", search="subscription management")
workflow = page.data[0]
# 2. Create agent
agent = client.agents.create(
name="Subscription management agent",
description="Handles plan upgrades, downgrades, cancellations, billing queries, and payment method updates, backed by Stripe.",
workflow_id=workflow.id,
idempotency_key="create-subscription-agent-v1",
)
# 3. Add knowledge bases
client.agents.knowledge_bases.create(agent.id, {
"type": "text",
"name": "Plan comparison",
"content": (
"Starter £12/mo: 1 user, 5 projects. Pro £39/mo: 5 users, unlimited projects, API. "
"Business £99/mo: 20 users, SSO, CSM. Annual saves 17%."
),
})
client.agents.knowledge_bases.create(agent.id, {
"type": "text",
"name": "Billing guide",
"content": (
"Upgrades: prorated. Downgrades: credit next cycle. "
"Failed payment: retried days 3, 5, 7 — account paused after third failure."
),
})
client.agents.knowledge_bases.create(agent.id, {
"type": "text",
"name": "Retention offers",
"content": (
"Too expensive: 20% off 3 months. Not using: 1-month pause. Missing feature: 2-week extension. "
"One offer per attempt only."
),
})
# 4. Verify integrations (Stripe must be connected in dashboard)
integrations = client.agents.integrations.list(agent.id)
channels = client.agents.channels.list(agent.id)
print("Agent ID:", agent.id)
print("Integrations:", [i.name for i in integrations])
print("Channels:", [c.type for c in channels])
# 5. Stream web chat subscription conversations
conversations = client.conversations.list(agent.id, channel="webchat")
if conversations.data:
conv = conversations.data[0]
for msg in client.conversations.messages.stream(agent.id, conv.id):
print(msg.role, msg.message)Deploy and go live
Go-live checklist
- Store your API key in
BIMPEAI_API_KEY(server-side only). - Confirm Stripe appears in
integrations.listor is connected in the dashboard. - Confirm Subscription billing system appears in
integrations.listor is connected in the dashboard. - Verify Web Chat is connected on the Deploy screen (
agents.channels.listshows it enabled). - Verify Telephony (inbound) is connected on the Deploy screen (
agents.channels.listshows it enabled). - Set Escalation Email under Settings → Agent if humans must take over.
- Switch the agent to
livewithupdateLiveStatus/update_live_status. - Monitor the Conversations screen (or stream via SDK) after launch.
After go-live
Confirm Stripe appears in integrations.list — plan changes fail without it. Never let the agent quote stale prices; update the plan comparison KB when pricing changes.
Variations
- Add an Enterprise inquiry path by extending the plan comparison knowledge base with an "Enterprise: contact sales" entry and routing those conversations to your sales team email.
- Use
conversations.messages.listafter each cancellation conversation to build a dataset of cancellation reasons for your product team. - Extend the save flow for annual subscribers by adding a pause offer that suspends rather than cancels, giving high-value customers a way back without full churn.