1 · Before you start
You need an agent already connected to COLVO — see connect your own agent or the n8n, Flowise and Voiceflow guides. Testing needs no Chargebee site: COLVO simulates one. For production you need a Chargebee site on Product Catalog 2.0 (item prices).
On Chargebee COLVO can refund (a refundable credit note on an invoice), cancel (now or at the end of the term — nothing is credited unless a refund is asked for), pause, resume, undo a scheduled cancellation, change plan and apply a coupon.
2 · Run the Chargebee scenarios
Open Test runs → Choose scenarios…, set Simulated provider to Chargebee, pick scenarios and start. Your agent’s tools don’t change — it still proposes to COLVO. What changes is the account behind it:
- A refund names an invoice. On Chargebee money goes back against an invoice (
INV-1042in the simulation), through the gateway that collected it. The agent may pass it asinvoice_idorpayment_id. - Plans are item prices such as
Basic-EUR-Monthly; a change at the end of the term is scheduled, not applied today. - Retries carry the same idempotency key. The scenario retry after a lost response checks that exactly one credit note exists at the end.
3 · Propose a refund and a plan change (Node and Python)
The same SDK calls as on Stripe — only the ids are Chargebee’s, and the refund names the invoice.
import { Colvo, messageFor } from '@colvo/sdk';
// Backend (backend key): the invoices this ticket may refund come from your systems.
const backend = new Colvo({ apiKey: process.env.COLVO_BACKEND_KEY });
const mandate = await backend.mandates.create({
project_id: process.env.COLVO_PROJECT_ID, source_request_id: ticket.id,
subject: { customer_id: 'AzZ9kUT8Lm3xQ2', payment_ids: ['1042'], subscription_ids: ['AzZ9kUT8Lm3xQ2-sub1'] },
actions: ['refund.create', 'subscription.cancel', 'subscription.change_plan'],
limits: { currency: 'eur', max_amount_minor: 4000, auto_allow_up_to_minor: 4000, max_operations: 1,
allowed_price_ids: ['Basic-EUR-Monthly'], change_plan_at: ['period_end'] },
});
// Agent (agent key): a Chargebee refund names the invoice.
const colvo = new Colvo({ apiKey: process.env.COLVO_AGENT_KEY });
const op = await colvo.operations.propose({
mandate_id: mandate.mandate_id, source_request_id: ticket.id, action: 'refund.create',
parameters: { invoice_id: '1042', amount_minor: 2900, currency: 'eur' },
});
reply(messageFor(op));import os
from colvo import Colvo, message_for
colvo = Colvo(os.environ["COLVO_AGENT_KEY"])
op = colvo.operations.propose({
"mandate_id": mandate_id, "source_request_id": ticket_id, "action": "subscription.change_plan",
"parameters": {"subscription_id": "AzZ9kUT8Lm3xQ2-sub1", "price_id": "Basic-EUR-Monthly", "at": "period_end"},
})
reply(message_for(op))4 · Connect your Chargebee site
Chargebee keys can’t be limited to some actions, so make one just for COLVO: Chargebee → Settings → Configure Chargebee → API Keys → a full-access key of the Write key type (create and update, no delete). In COLVO open your project → Add a connection → Chargebee, enter the site name (the first part of yoursite-test.chargebee.com) and the key, and press Check and connect. COLVO reads to check the key — nothing is created — refuses a read-only key and warns if the key can also delete.
COLVO then shows a webhook URL, username and password — the password only once. In Chargebee → Webhooks, add them with the events COLVO lists (credit notes, refunds, cancellations, pauses, plan changes). Remove the Chargebee key from your agent.
5 · What happens to a real refund
Guard checks the proposal against the mandate — the invoice must be one the mandate names. On ALLOW, COLVO refunds the invoice once with the operation id as Chargebee’s idempotency key, and reads Chargebee back: VERIFIED when the credit note is refunded. If the gateway is still processing, the operation waits and the reply should say “requested”. Chargebee keeps idempotency keys for 30 minutes, so COLVO never re-sends a write after that — an incident asks a person to check instead.
Next: set refund limits and read a FAIL.