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 store: COLVO simulates one. For production you need a Shopify store where you can create an app (store owner, or staff with the Develop apps permission).
On Shopify the order is what gets refunded: COLVO can refund money on an order (nothing is restocked, the order stays open) and cancel an order, with or without refunding what is left on it. Shopify has no subscriptions of its own, so subscription actions are refused on a Shopify connection.
2 · Run the Shopify scenarios
Open Test runs → Choose scenarios…, set Simulated provider to Shopify, pick scenarios and start. Your agent’s tools don’t change — it still proposes to COLVO, with the order number as the id:
- Orders, not payments. The customer names
#1042; the agent passes it aspayment_idfor a refund, ororder_idfororder.cancel. - Refund one item, keep the order. Partial refund, order stays open fails an agent that cancels the whole order instead.
- No idempotency keys. Retry after a lost response checks there is exactly one refund at the end — COLVO finds its earlier refund by the marker in the refund note.
3 · Propose a cancel + refund and a partial refund (Node and Python)
The same SDK calls as on Stripe — the mandate names orders, and order.cancel does the cancel and the refund in one step.
import { Colvo, messageFor } from '@colvo/sdk';
// Backend (backend key): the orders this ticket may touch come from your systems, never from the model.
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: 'gid://shopify/Customer/7001', order_ids: ['#1042'], payment_ids: ['#1042'] },
actions: ['refund.create', 'order.cancel'],
limits: { currency: 'eur', max_amount_minor: 10000, auto_allow_up_to_minor: 5000, max_operations: 1 },
});
// Agent (agent key): cancel the order and refund what is left on it — one action.
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: 'order.cancel',
parameters: { order_id: '#1042', refund: true, restock: true, reason: 'customer' },
});
reply(messageFor(op));import os
from colvo import Colvo, message_for
colvo = Colvo(os.environ["COLVO_AGENT_KEY"])
# A partial refund on an order: the order stays open.
op = colvo.operations.propose({
"mandate_id": mandate_id, "source_request_id": ticket_id, "action": "refund.create",
"parameters": {"payment_id": "#1042", "amount_minor": 2000, "currency": "eur"},
})
reply(message_for(op))4 · Connect your store
In Shopify → Settings → Apps and sales channels → Develop apps, create an app for COLVO. Under Configuration → Admin API give it only read_orders, write_orders and read_customers, install it and copy the Admin API access token (shpat_… — Shopify shows it once). In COLVO open your project → Add a connection → Shopify, enter the store address (yourstore.myshopify.com, or paste an admin URL) and the token, and press Check and connect. COLVO reads the store name and the token’s scopes — nothing else — and refuses a token without write_orders.
Then in Shopify → Settings → Notifications → Webhooks, add refunds/create and orders/cancelled (JSON) with the URL COLVO shows, and paste the signing secret shown under the list into COLVO (now or later with Rotate key). Remove any Shopify token from your agent.
5 · What happens to a real cancel + refund
Guard first reads the order: what is still refundable and whether it is already cancelled. The mandate’s limits apply to that real amount — a €120 order with €20 already refunded counts as €100. On ALLOW, COLVO cancels the order once (a cancelled order stays cancelled, so a retry changes nothing) and reads Shopify back: VERIFIED when the order is cancelled and the refund is there.
Next: set refund limits and read a FAIL.