Universal connector: send anything from any tool (beta)
One signed webhook for disputes, orders, refunds, shipments and customer messages from Zapier, Make, n8n or your own code.
Where in VerdikxConnections → Any other tool
The universal connector is for every tool Verdikx has no native connection to. Your workspace gets one webhook URL and a signing secret; anything that can send a signed JSON POST can push records in. Each record type lands where its native connector would: disputes become cases (you submit evidence to the processor yourself, like email and CSV intake), orders join the orders table and are screened, refunds and shipments join the order's evidence, and customer messages join the conversation record. Nothing in a payload is fetched or executed: no URLs are followed and no files are downloaded.
For a one-off file, import a chargeback CSV instead.
Set it up
- Open Connections and scroll to Any other tool.
- Click Set up universal connector. Copy the webhook URL and the signing secret: the secret is shown once. Create new secret rotates it (the old one stops working immediately).
- In your tool, send a POST to the URL with the headers below and a JSON body.
Headers
Content-Type: application/jsonX-Verdikx-Timestamp: the current time in unix seconds.X-Verdikx-Signature:v1=followed by the hex HMAC-SHA256 of<timestamp>.<raw body>, computed with your signing secret.
Requests older than five minutes, larger than 256 KB, unsigned or with more than 50 events are refused. Re-sending the same record is safe: records are keyed on your ids, so a retry updates rather than duplicates.
Body
Send one event, or { "events": [ ... ] } with up to 50. Every event is { "type": "...", "data": { ... } } with one of these types:
- dispute:
case_id(required),processor(one of paypal, braintree, square, adyen, checkout, authorize_net, klarna, afterpay, amazon_pay, shop_pay, bank; anything else is recorded as a bank/issuer notice with the name kept),amount,currency,reason,due_by,order_id,customer_email,payment_reference,outcome(open, won, lost),opened_at. - order:
id,created_at,total,currency(required),number,status,payment_status(paid, pending, refunded, failed),fulfillment_status(fulfilled, partial, unfulfilled),payment_gateway,customer{ id, email },billing_addressandshipping_address{ first_name, last_name, line1, line2, city, region, postal_code, country },line_items[{ id, sku, title, quantity, price }],fulfillments[{ id, carrier, tracking_number, shipped_at }],refunds[{ id, amount, reason, created_at }]. - refund:
id,order_id,amount,created_at(required),currency,reason. - shipment:
order_id,tracking_number(required),carrier,status,shipped_at,delivered_at,checkpoints[{ time, description, location, status }]. - customer_message:
id,body,sent_at(required),thread_id,direction(inbound, outbound, internal),customer_email,sender_email,subject,order_id.
Amounts are major units (89.50), times are ISO 8601. The response lists each event with saved, updated or skipped; a schema problem answers 400 with the event index and the field.
Zapier and Make
- Zapier: use Webhooks by Zapier → Custom Request (POST, JSON body). Add a Code by Zapier step before it to compute the signature:
crypto.createHmac("sha256", secret).update(timestamp + "." + body).digest("hex")with the exact body string you send. - Make: use the HTTP → Make a request module with a Crypto → HMAC step (SHA-256, hex) over
timestamp.body. - n8n and code: any HTTP node or client works; sign the raw body string, not a re-serialized copy.
Full examples for each type are in the developer docs.
Turn it off
Click Turn off on the card. The URL stops accepting requests; records already received stay.