Purpose
Locate a QuickBooks Online invoice by invoice number and use the invoice page's send or PDF controls to deliver the invoice as a PDF.
When to Use
Use when the caller provides an invoice number and asks to send, email, or obtain that invoice as a PDF.
Workflow
- If an opaque QuickBooks transaction ID is already known, navigate directly to
https://qbo.intuit.com/app/invoice?txnId={txnId}. Otherwise navigate tohttps://qbo.intuit.com/app/homepagewithwaitUntil: "domcontentloaded". - If Intuit redirects to
https://accounts.intuit.com/app/sign-in?..., show the live interactive browser view and let the user complete sign-in, SSO, MFA, consent, or other verification themselves. Do not guess, request, or enter credentials or OTPs. - If authentication was initiated through a transaction deeplink, QuickBooks also supports the form
https://qbo.intuit.com/app/login?pagereq=invoice%3FtxnId%3D{txnId}&deeplinkcompanyid={company-id}. Use this only when both the already-resolved opaque{txnId}and the company ID are available; never derive either value from the human invoice number. - In the authenticated QuickBooks application, use the available invoice/transaction search or invoice list to search for
{invoice-number}. Select the result whose visible invoice number exactly matches{invoice-number}; do not rely on customer name or approximate text alone. - Before opening the result, run this evaluator on the search/list page to capture the opaque transaction identifier and verify the matching invoice link:
(() => {
const wanted = String({ invoiceNumber }).trim();
const links = [...document.querySelectorAll('a[href*="/app/invoice?"]')];
const rows = links.map((a) => {
const container = a.closest('tr,[role="row"],li,[data-testid],div') || a;
const text = (container.innerText || a.innerText || "")
.replace(/\s+/g, " ")
.trim();
const m = a.href.match(/[?&]txnId=([^&#]+)/i);
return { text, href: a.href, txnId: m ? decodeURIComponent(m[1]) : null };
});
const escaped = wanted.replace(/[.*+?^${}()|[\\]\\]/g, "\\\\$&");
const exact = rows.find(
(r) => r.txnId && new RegExp(`(?:^|\\D)${escaped}(?:\\D|$)`).test(r.text),
);
return { invoiceNumber: wanted, match: exact || null, candidates: rows };
})();- If an exact match is returned, navigate directly to
https://qbo.intuit.com/app/invoice?txnId={txnId}using the captured opaque{txnId}. Never guess or derive the transaction ID from the invoice number. - On the invoice page, run this evaluator to identify the invoice and available PDF/send controls:
(() => {
const text = (document.body?.innerText || "").replace(/\s+/g, " ").trim();
const controls = [
...document.querySelectorAll(
'button,a,[role="button"],input[type="button"],input[type="submit"]',
),
]
.map((el) => ({
text: (
el.innerText ||
el.value ||
el.getAttribute("aria-label") ||
el.title ||
""
)
.replace(/\s+/g, " ")
.trim(),
href: el.href || null,
disabled: !!el.disabled || el.getAttribute("aria-disabled") === "true",
}))
.filter((x) => x.text || x.href);
const pdfOrSend = controls.filter((x) =>
/pdf|print|send|email|mail/i.test(`${x.text} ${x.href || ""}`),
);
return {
url: location.href,
title: document.title,
visibleText: text.slice(0, 6000),
controls,
pdfOrSend,
};
})();- Use the clearly labeled invoice-page control to send the PDF. If QuickBooks first opens a send form, confirm that the recipient and attachment/format indicate PDF, then submit only after the caller has supplied or confirmed the recipient. If the caller only wants the file, use the labeled PDF/Print control and return the resulting downloaded PDF or print-to-PDF output.
- Report whether the PDF was sent or downloaded, the invoice number, and any recipient or confirmation shown by QuickBooks.
Site-Specific Gotchas
- The direct invoice route is
https://qbo.intuit.com/app/invoice?txnId={txnId}.txnIdis an opaque QuickBooks transaction identifier and must be captured from a matching invoice result; it must not be fabricated from the human invoice number. - QuickBooks transaction deeplinks may use
https://qbo.intuit.com/app/login?pagereq=invoice%3FtxnId%3D{txnId}&deeplinkcompanyid={company-id}before authentication. This preserves the requested invoice, but both identifiers must come from trusted page state or caller input. - Unauthenticated access commonly redirects to an Intuit Accounts URL such as
https://accounts.intuit.com/app/sign-in?app_group=QBO&asset_alias=Intuit.accounting.core.qbowebapp&app_environment=prod&iux_redirect_reason=UNAUTHENTICATED. - Authentication may require interactive MFA, SSO, consent, or other account verification. Leave these steps to the user; do not automate password or OTP entry.
- Invoice search results can contain multiple transaction types and similarly named records. Require an exact visible invoice-number match before following an
/app/invoice?txnId=...link. - Send, email, PDF, and print controls can vary by account permissions and QuickBooks UI variant; inspect their accessible labels on the already loaded invoice page rather than guessing a secondary URL.
- Do not submit an email/send form without a confirmed recipient and caller authorization.
Expected Output
Confirm the exact invoice matched, the final QuickBooks invoice URL, and whether the invoice PDF was successfully sent or downloaded. Include the recipient or QuickBooks confirmation when available.