AlphaHackers: Shopify → Xubio Invoice Automation
Every paid Shopify order becomes an AFIP-compliant Xubio invoice in seconds — with a credential vault that survives rotating tokens.

The gap between Shopify and AFIP used to be a person
AlphaHackers is an Argentine e-commerce business selling cold plunges and saunas. Like every Argentine business, every sale must produce an AFIP-compliant electronic invoice through a certified platform — in their case, Xubio. Like every e-commerce business, their orders land in Shopify. The gap between "order placed in Shopify" and "AFIP-compliant invoice issued in Xubio" used to be a person, manually re-keying every sale.
This case study is the bridge: a fully-automated pipeline that, every time a Shopify order is paid, generates the Xubio invoice, downloads the PDF, files it in a date-organized Google Drive folder, appends a row to a Google Sheet for accounting, and pings Santiago (the founder) on Telegram so he knows the pipeline ran. End-to-end, no human in the loop, no double entry, no missed invoices.
The interesting part — the reason this lives in my portfolio — isn't the integration. It's the credential architecture.
Three constraints shaped the whole project
Rotating tokens that n8n credentials can't track. Shopify Custom App tokens refresh every 24 hours. Xubio OAuth tokens last about an hour. n8n's credential store doesn't gracefully handle either pattern — store a Xubio token in an n8n credential and the workflow starts failing silently 61 minutes later. Refreshing requires editing the credential by hand in the UI (no automation surface) or wrestling with OAuth nodes that don't expose a clean "use this cached refresh token" affordance for non-standard providers.
A shared n8n instance. AlphaHackers' workflows run on the same Railway-hosted n8n as a UGC lead-gen pipeline and my personal finance/shopper agents. Anything that touches the global credential surface — env vars, OAuth redirect URIs, credential names — risks affecting other tenants. The credential architecture has to be per-client, not per-instance.
Operational visibility. Santiago and Mati don't open the n8n panel. They open Telegram. If an invoice fails to issue, they need to know within minutes — not on the next time someone checks the dashboard, which is never.

The cornerstone of the project. Instead of storing Shopify and Xubio tokens in n8n's credential store, I created an Airtable base with a Token_Cache table holding the token value, expiry timestamp, refresh token, last-refresh timestamp, and service name (shopify | xubio).
Every workflow that calls Shopify or Xubio reads Token_Cache first, checks whether the token is expired or inside the refresh window, hits the refresh endpoint if needed, updates the cache, and only then makes the actual API call. A separate refresh workflow runs every 23 hours proactively — so if a workflow happens to execute right as a token is rotating, the cache already has a fresh value. Belt and suspenders.
Two design points worth surfacing. Airtable is a feature here, not a workaround — it gives me a queryable, audit-friendly record of every token rotation, which n8n credentials never could. And the pattern is replicable — when another client needs the same long-running token handling, the base extends with a new row. The infrastructure pays back for years.

Shopify webhook (order_paid) → read & refresh Shopify token → fetch order details → read & refresh Xubio token → POST to Xubio /invoices with mapped line items → fetch invoice PDF → upload to Google Drive (date-organized folder) → append row to Google Sheet → Telegram notification with invoice number and amount. Any failed step branches to a Telegram error notification with the execution ID and offending node name.
A few details worth surfacing. Line item mapping is its own concern — Shopify line items don't translate 1:1 to Xubio's (internal product ID, IVA classification, discount formatting). The mapping lives in a Code node; new SKUs grow the table by one row. PDF filing is deterministic — Drive folders organized by year/month, the Sheet is the authoritative record, no tribal knowledge required. Error notifications include the execution ID — Santiago forwards it to me, I open the execution, see exactly what failed. "Something broke at some point" becomes "here's the line."
Telegram is the client surface — the panel should never need opening
Santiago doesn't open the n8n dashboard. He opens Telegram. The system tells him three things, in his actual workflow:
- Success notifications. Every issued invoice posts via the
Jarvis Telegram Botcredential. Dry tone: "✅ Invoice 0001-00001234 issued for [Customer] — $42,000 ARS." PDF link in the message if he wants to verify. - Error notifications. Any failed step posts the offending node name and the n8n execution ID. He doesn't need to know what to do with the ID — he forwards it.
- Daily summary. End of day, a scheduled workflow counts the day's invoices, totals the day's revenue, posts a one-line summary. The only message he needs to read every day.
The discipline: the client should never have to open a panel. If they're opening a panel, the abstraction has leaked. Every notification format is deliberate — short, scannable, with the next action implicit. The same discipline I apply to agent UX everywhere else.
Defensive patterns that hold the pipeline together. continueOnFail on every external HTTP node (Shopify rate-limits, Xubio has scheduled maintenance, Drive auth hiccups — none of these get to crash the pipeline). Idempotency via Shopify order ID — before issuing an invoice, the workflow checks whether the Sheet already has a row with this order ID. Webhook retries are a fact of life. No invoice without a complete payload — if line-item mapping returns an unknown SKU, the workflow halts before calling Xubio. A half-issued AFIP invoice is worse than no invoice — you can't edit an AFIP invoice without a credit note. Token refresh is itself instrumented — every refresh writes a timestamp and status to Airtable, so I see degradation before any invoice fails.
Outcomes
The brand the pipeline serves


Reflection — infrastructure is a design problem
The lesson I'd most want a future reviewer to take from this work: infrastructure is a design problem, not just an engineering problem. The Airtable credential vault isn't a clever trick — it's a decision about where the system's source of truth for secrets should live, and what affordances that source needs (queryability, audit trail, per-tenant isolation, refresh observability). Choosing Airtable over n8n credentials was a UX decision as much as a technical one. Santiago can open the Airtable base and see the system's state, which he could never do with n8n credentials.
The other lesson is about Telegram-as-UI for non-technical operators. Design the messages first, design the pipeline second. If the messages are right, the pipeline is in service of them. If the messages are an afterthought, you've built a system that requires a panel — and the client is never going to open the panel.
What I'd do differently: I'd build the daily summary first. The per-invoice notifications are useful, but the summary is the only message Santiago reads every day. Building it first would have forced clearer thinking about which aggregate signals actually matter.
What I'm proud of: an unsexy integration — Shopify to invoicing API to PDF to Sheets — done with the discipline of a production system. Rotating credentials handled, errors visible, idempotency enforced, client surface designed. The unsexy work, done with care, is what separates "I built an integration" from "I shipped infrastructure my client trusts."
A follow-on project, alfahuman-dashboard, shipped 2026-04-29 — an employee web portal that extends the same credential and observability patterns to AlphaHackers' internal staff. The patterns ported cleanly. That's the test of an architecture: whether the next project benefits from the previous one.