1 · Before you start
You need a Flowise chatflow (or Agentflow) that answers billing questions, reachable over public HTTPS — Flowise Cloud or self-hosted. Remove any Stripe credentials or Stripe tools from it: with COLVO the chatflow only proposes a refund, and COLVO executes it.
2 · Create four Flowise variables
In Flowise open Variables and create colvo_operations_url, colvo_agent_key, colvo_mandate_id and colvo_source_request_id with any placeholder value. COLVO replaces them for every test conversation through the prediction API.
In the chatflow’s settings, allow override config for sessionId and vars — otherwise Flowise ignores what COLVO sends.
3 · Add the colvo_propose tool
Add a Custom Tool named colvo_propose with two string inputs, action and parameters, attach it to your agent, and paste:
// Custom Tool "colvo_propose" — inputs: action (string), parameters (string, JSON)
// refund: action "refund.create", parameters {"payment_id":"pi_…","amount_minor":5000,"currency":"eur"} (cents, a number)
// cancel: action "subscription.cancel", parameters {"subscription_id":"sub_…","mode":"period_end"} (or "immediate")
// pause: action "subscription.pause", parameters {"subscription_id":"sub_…","resumes_at":"2026-12-12"} (no resumes_at = no end date)
// resume: action "subscription.resume", parameters {"subscription_id":"sub_…"}
// undo: action "subscription.cancel_undo", parameters {"subscription_id":"sub_…"} (keep a plan whose cancellation is scheduled)
// plan: action "subscription.change_plan", parameters {"subscription_id":"sub_…","price_id":"price_…","at":"now"} (or "period_end")
// coupon: action "coupon.apply", parameters {"subscription_id":"sub_…","coupon_id":"WINBACK20"}
// old invoice refund: parameters {"invoice_id":"in_…","amount_minor":2900,"currency":"eur"} instead of payment_id
const res = await fetch($vars.colvo_operations_url, {
method: 'POST',
headers: {
authorization: 'Bearer ' + $vars.colvo_agent_key,
'idempotency-key': $vars.colvo_source_request_id + ':' + $action,
'content-type': 'application/json',
},
body: JSON.stringify({
mandate_id: $vars.colvo_mandate_id,
source_request_id: $vars.colvo_source_request_id,
action: $action,
parameters: JSON.parse($parameters),
}),
});
const op = await res.json().catch(() => ({}));
if (!res.ok) return JSON.stringify({ decision: 'ERROR', error: op.error, message: op.message }); // never tell the customer it is done
return JSON.stringify({ decision: op.decision, reasons: op.decision_reasons });Then add to the system prompt: “Never tell the customer an action is done unless colvo_propose returns ALLOW.”
4 · Connect it in COLVO
Open your project → Connect your agent → Flowise. Paste your Flowise address and the chatflow ID (from the chatflow’s API Endpoint dialog), and the Flowise API key if the chatflow has one. Leave “account facts” on: COLVO adds the customer’s payment and subscription ids under each message, so the model can use them in the tool call.
Press Test connection.
5 · Run the suite
Press Run suite. Every test is a new Flowise session, so conversations never mix, and COLVO checks the result in its own simulated Stripe — not in the reply. Next: read the verdict.