Use casesRecipes

Returns & Refund Processing Agent

Handle return requests, check eligibility against your order management system, track refund status, and schedule replacements.

DifficultyIntermediate
TrackBuilder Track or Developer Track
ChannelsWhatsAppWeb Chat
IntegrationsOrder management system (API)Stripe / payment gateway

What you'll build

An agent that guides customers through return requests, checks their order eligibility against your OMS, tracks refund status via Stripe, and schedules replacements — all without a human in the loop for standard cases.

Customer journey

A customer contacts you on WhatsApp or Web Chat about a return. The agent checks eligibility against the returns policy KB, initiates the return in your OMS integration, and confirms refund timing — escalating edge cases outside the 30-day window.

Loading diagram…

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
  • An order management system and Stripe account already connected in the Console dashboard (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: "returns refund" });
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="returns refund")
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: "Returns agent",
  system_prompt: "You process return requests, check order eligibility, track refund status, and schedule replacements.",
});
console.log(workflow.id);
workflow = client.workflows.create(
    name="Returns agent",
    system_prompt="You process return requests, check order eligibility, track refund status, and schedule replacements.",
)
print(workflow.id)

2. Create the agent

const agent = await bimpe.agents.create(
  {
    name: "Returns agent",
    description: "Processes return requests, checks eligibility, and initiates refunds via Stripe.",
    workflow_id: workflow.id,
  },
  { idempotencyKey: "create-returns-agent-v1" },
);

console.log(agent.id);
agent = client.agents.create(
    name="Returns agent",
    description="Processes return requests, checks eligibility, and initiates refunds via Stripe.",
    workflow_id=workflow.id,
    idempotency_key="create-returns-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.

Add your returns policy so the agent can answer eligibility questions before touching the OMS.

await bimpe.agents.knowledgeBases.create(agent.id, {
  type: "text",
  name: "Returns policy",
  content: `
    Items can be returned within 30 days of delivery in original condition.
    Perishables and personalised items are non-returnable.
    Refunds are issued to the original payment method within 5–7 business days.
    Replacement orders ship within 2 business days of return receipt.
  `,
});
client.agents.knowledge_bases.create(agent.id, {
    "type": "text",
    "name": "Returns policy",
    "content": (
        "Items can be returned within 30 days of delivery in original condition.\n"
        "Perishables and personalised items are non-returnable.\n"
        "Refunds are issued to the original payment method within 5-7 business days.\n"
        "Replacement orders ship within 2 business days of return receipt."
    ),
})

4. Connect channels and integrations (dashboard)

Channels, Stripe, and the OMS 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 plus your order management system on the Integrations screen of the Console dashboard. The SDK lists what is active but cannot modify channel connections.

  1. In the Console dashboard, pick your agent from the switcher at the top, then open Deploy.
  2. Under Messaging & Chat, click Connect on the WhatsApp card and follow the prompts to link your WhatsApp Business number.
  3. Under Messaging & Chat, click Connect on the Web Chat Widget card to add the widget to your site.
  4. Open Integrations, find Stripe, and click Connect so the agent can track refund status and issue refunds.
  5. On Integrations, open the Custom API tab to wire up your order management system, so the agent can check return eligibility against your orders.

Connect WhatsApp

Customers message your WhatsApp Business number for support and transactions.

  1. Open the Deploy screen in the Console dashboard and select your agent.
  2. Under Messaging & Chat, click Connect on the WhatsApp card.
  3. Follow the prompts to link your WhatsApp Business number.
  4. Once connected, customers can message your business number and the agent replies within WhatsApp's 24-hour session window.

Full reference: Deploying and testing channels.

Connect Web Chat

Visitors use the chat widget embedded on your website or app.

  1. Open Deploy and select your agent.
  2. Under Messaging & Chat, click Connect on the Web Chat Widget card.
  3. Copy the embed snippet and paste it into your site's HTML before the closing body tag.
  4. Publish your site — the chat bubble appears in the corner and routes messages to this agent.

Full reference: Deploying and testing channels.

Also on Instagram and Messenger: the same Deploy → Connect flow applies. Testers use the Deploy panel links or getTestCode deep links for each network. Instagram · Messenger

5. Test your agent

Before going live, exercise the agent on a test channel. Fetch the test code (created on first request), then test on WhatsApp — share the deep link or start message with a human tester, or inject a message from your server.

Test WhatsApp

Human tester: fetch the test code with agents.getTestCode (or use the Deploy panel). Share the deep link or start <code> message with a tester.

SDK injection: call conversations.send with is_test_channel: true and the matching channel_type.

Full reference: Deploying and testing channels.

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.

const { channels } = await bimpe.agents.getTestCode(agent.id);
// A tester opens channels.whatsapp.url, or sends channels.whatsapp.start_message
// to channels.whatsapp.phone_number, to open a 24-hour test window.
console.log(channels.whatsapp.start_message, channels.whatsapp.url);

// Or inject a test message yourself:
await bimpe.conversations.send(agent.id, {
  message: "I'd like to return a jacket I ordered last week — is it eligible?",
  channel_type: "whatsapp",
  channel_user_id: "<tester-whatsapp-number>",
  is_test_channel: true,
});
test_code = client.agents.get_test_code(agent.id)
# A tester opens .url, or sends .start_message to .phone_number, to open a 24-hour window.
print(test_code.channels.whatsapp.start_message, test_code.channels.whatsapp.url)

# Or inject a test message yourself:
client.conversations.send(
    agent.id,
    message="I'd like to return a jacket I ordered last week — is it eligible?",
    channel_type="whatsapp",
    channel_user_id="<tester-whatsapp-number>",
    is_test_channel=True,
)

See Test your agent for the other test channels and the pause-AI rule.

6. Go live

Verify that your integrations are visible before opening to customers:

const integrations = await bimpe.agents.integrations.list(agent.id);
console.log("Integrations:", integrations.map((i) => i.type));
integrations = client.agents.integrations.list(agent.id)
print("Integrations:", [i.type for i in integrations])

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: "returns refund" });
const workflow = page.data[0];

// 2. Create agent
const agent = await bimpe.agents.create(
  {
    name: "Returns agent",
    description: "Processes return requests, checks eligibility, and initiates refunds via Stripe.",
    workflow_id: workflow.id,
  },
  { idempotencyKey: "create-returns-agent-v1" },
);

// 3. Add returns policy
await bimpe.agents.knowledgeBases.create(agent.id, {
  type: "text",
  name: "Returns policy",
  content:
    "Items can be returned within 30 days of delivery. Refunds process in 5-7 business days.",
});

// 4. Verify integrations (OMS + Stripe must be connected in the dashboard first)
const integrations = await bimpe.agents.integrations.list(agent.id);
console.log("Integrations:", integrations.map((i) => i.type));

// 5. Stream web chat 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="returns refund")
workflow = page.data[0]

# 2. Create agent
agent = client.agents.create(
    name="Returns agent",
    description="Processes return requests, checks eligibility, and initiates refunds via Stripe.",
    workflow_id=workflow.id,
    idempotency_key="create-returns-agent-v1",
)

# 3. Add returns policy
client.agents.knowledge_bases.create(agent.id, {
    "type": "text",
    "name": "Returns policy",
    "content": "Items can be returned within 30 days of delivery. Refunds process in 5-7 business days.",
})

# 4. Verify integrations (OMS + Stripe must be connected in the dashboard first)
integrations = client.agents.integrations.list(agent.id)
print("Integrations:", [i.type for i in integrations])

# 5. Stream web chat 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 Order management system appears in integrations.list or is connected in the dashboard.
  • Confirm Payment processor appears in integrations.list or is connected in the dashboard.
  • Verify WhatsApp is connected on the Deploy screen (agents.channels.list shows it enabled).
  • Verify Web Chat is connected on the Deploy screen (agents.channels.list shows it enabled).
  • Set Escalation Email under Settings → Agent if humans must take over.
  • Switch the agent to live with updateLiveStatus / update_live_status.
  • Monitor the Conversations screen (or stream via SDK) after launch.
  • Set escalation_email on agents.update for cases outside the return window.

After go-live

Verify both integrations appear before routing live traffic. Update returns policy KB when policy changes.

Variations

  • Add a second knowledge base entry for exchange policy to keep returns and exchanges in the same agent.
  • Update the returns policy knowledge base via knowledgeBases.update whenever your policy changes without recreating the agent.
  • Configure rules on the workflow (CreateWorkflowBody.rules / RuleInput) to hard-block refund confirmation on non-returnable SKU categories.

On this page