quote-to-cash

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Resources

资源

FileWhen to use
resources/q2c-essentials.md
Six-field cheat sheet, association directions, portal caveats for invoices/subscriptions/orders/carts.
文件使用场景
resources/q2c-essentials.md
六字段速查表、关联操作指南、发票/订阅/订单/购物车的门户注意事项。

Foundations

基础操作

Read
bulk-operations/SKILL.md
first — JSONL piping, batch read, pagination, and the dry-run/digest/confirm flow for destructive ops live there. Reshape recipes (read → write payload) are in
bulk-operations/resources/json-patterns.md
.
hubspot <command> --help
is the source of truth. Object types are plural (
products
,
line_items
,
quotes
,
invoices
,
subscriptions
). Never hardcode property tables —
hubspot properties list --type <type>
is one call away. Verify any enum value the agent is about to write with
hubspot properties get --type <type> --name <property>
and read
options[].value
.
Portal note:
invoices
,
subscriptions
,
orders
,
carts
show an empty
objectTypeId
in
hubspot objects types
. They work through
objects search
/
list
when the token has the matching scope (
invoices-read
,
subscriptions-read
, etc.) and 403 otherwise. CLI-created quotes are always
DRAFT
; approval routing, share links, PDF generation, and invoice creation usually require the HubSpot UI.
请先阅读
bulk-operations/SKILL.md
——其中包含JSONL管道传输、批量读取、分页,以及破坏性操作的试运行/摘要/确认流程。数据重塑模板(读取→写入负载)位于
bulk-operations/resources/json-patterns.md
中。
hubspot <command> --help
是权威参考来源。对象类型为复数形式(
products
line_items
quotes
invoices
subscriptions
)。切勿硬编码属性表——只需调用
hubspot properties list --type <type>
即可获取。在Agent写入枚举值前,请通过
hubspot properties get --type <type> --name <property>
并读取
options[].value
来验证。
门户注意事项:在
hubspot objects types
中,
invoices
subscriptions
orders
carts
objectTypeId
显示为空。当令牌具备匹配权限(
invoices-read
subscriptions-read
等)时,可通过
objects search
/
list
操作它们,否则会返回403错误。通过CLI创建的报价始终处于
DRAFT
(草稿)状态;审批流程、共享链接、PDF生成和发票创建通常需要使用HubSpot UI。

1. Create a product

1. 创建产品

bash
hubspot objects create --type products \
  --property name="Enterprise License" \
  --property price=12000 \
  --property hs_sku=ENT-001
For a recurring product set
recurringbillingfrequency
; check the API enum values first with
hubspot properties get --type products --name recurringbillingfrequency --format json | jq -r '.options[].value'
. Bulk-import a catalog by piping JSONL of
{"properties":{...}}
to
hubspot objects create --type products --dry-run
.
bash
hubspot objects create --type products \
  --property name="Enterprise License" \
  --property price=12000 \
  --property hs_sku=ENT-001
对于周期性产品,请设置
recurringbillingfrequency
;设置前请先通过
hubspot properties get --type products --name recurringbillingfrequency --format json | jq -r '.options[].value'
查看API枚举值。通过将
{"properties":{...}}
格式的JSONL数据管道传输至
hubspot objects create --type products --dry-run
,可批量导入产品目录。

2. Build a quote: line items → quote → associations

2. 构建报价:订单项 → 报价 → 关联

objects create
emits one result line per stdin line, in input order. That lets you build line items, capture their IDs, and associate them to the new quote in three pipes — no per-record shell loop.
bash
DEAL_ID=12345
objects create
会按输入顺序为每个标准输入行输出一条结果记录。这使您无需逐记录执行shell循环,即可通过三次管道操作创建订单项、捕获其ID并将其关联至新报价。
bash
DEAL_ID=12345

1. Create the line items. items.jsonl holds {"name":..,"qty":..,"price":..,"product_id":..} per line.

1. 创建订单项。items.jsonl每行包含{"name":..,"qty":..,"price":..,"product_id":..}。

jq -c '{properties:{ name:.name, quantity:(.qty|tostring), price:(.price|tostring), hs_product_id:.product_id, hs_line_item_currency_code:"USD" }}' items.jsonl
| hubspot objects create --type line_items > /tmp/lineitems.jsonl
jq -c '{properties:{ name:.name, quantity:(.qty|tostring), price:(.price|tostring), hs_product_id:.product_id, hs_line_item_currency_code:"USD" }}' items.jsonl
| hubspot objects create --type line_items > /tmp/lineitems.jsonl

2. Create the quote.

2. 创建报价。

QUOTE_ID=$(hubspot objects create --type quotes
--property hs_title="Acme Corp - 2026"
--property hs_expiration_date=2026-06-30
--property hs_currency=USD
--format json | jq -r '.data.id // .id')
QUOTE_ID=$(hubspot objects create --type quotes
--property hs_title="Acme Corp - 2026"
--property hs_expiration_date=2026-06-30
--property hs_currency=USD
--format json | jq -r '.data.id // .id')

3. Associate every new line item to the quote in one pipe.

3. 通过一次管道操作将所有新订单项关联至报价。

jq -r '.id' /tmp/lineitems.jsonl
| jq -cR --arg q "$QUOTE_ID" '{from:("quotes:" + $q), to:("line_items:" + .)}'
| hubspot associations create
jq -r '.id' /tmp/lineitems.jsonl
| jq -cR --arg q "$QUOTE_ID" '{from:("quotes:" + $q), to:("line_items:" + .)}'
| hubspot associations create

4. Link the quote to the deal.

4. 将报价关联至交易。

hubspot associations create --from "deals:$DEAL_ID" --to "quotes:$QUOTE_ID"

Discount handling — `discount` is the writable percentage (`10` = 10% off). `hs_total_discount` is HubSpot-computed; do not set it. Verify with `hubspot properties get --type line_items --name hs_total_discount` (look for `modificationMetadata.readOnlyValue:true`) before relying on this in a portal you don't own.

Promote a quote out of `DRAFT` when ready to share:

```bash
hubspot objects update --type quotes <quote_id> --property hs_status=APPROVAL_NOT_NEEDED
Verify
hs_status
enum values for your portal:
hubspot properties get --type quotes --name hs_status --format json | jq -r '.options[].value'
.
hubspot associations create --from "deals:$DEAL_ID" --to "quotes:$QUOTE_ID"

折扣处理——`discount`为可设置的百分比(`10`即打9折)。`hs_total_discount`由HubSpot计算生成;请勿手动设置。在非您所有的门户中使用此属性前,请通过`hubspot properties get --type line_items --name hs_total_discount`验证(查看`modificationMetadata.readOnlyValue:true`)。

准备好分享报价时,将其从`DRAFT`状态升级:

```bash
hubspot objects update --type quotes <quote_id> --property hs_status=APPROVAL_NOT_NEEDED
请验证您门户的
hs_status
枚举值:
hubspot properties get --type quotes --name hs_status --format json | jq -r '.options[].value'

3. Track invoices

3. 跟踪发票

The CLI reads invoice data and updates status; creation usually needs HubSpot Commerce + UI. Filter by
hs_invoice_status
and date.
bash
undefined
CLI可读取发票数据并更新状态;发票创建通常需要HubSpot Commerce + UI支持。可按
hs_invoice_status
和日期进行筛选。
bash
undefined

All outstanding invoices

所有未结清发票

hubspot objects search --type invoices
--filter "hs_invoice_status=OUTSTANDING"
--properties hs_number,hs_amount_billed,hs_balance,hs_due_date
hubspot objects search --type invoices
--filter "hs_invoice_status=OUTSTANDING"
--properties hs_number,hs_amount_billed,hs_balance,hs_due_date

Past-due (overdue) invoices, dynamic date

逾期发票,动态日期

hubspot objects search --type invoices
--filter "hs_due_date<$(date +%Y-%m-%d) AND hs_invoice_status!=PAID"
--properties hs_number,hs_due_date,hs_balance
hubspot objects search --type invoices
--filter "hs_due_date<$(date +%Y-%m-%d) AND hs_invoice_status!=PAID"
--properties hs_number,hs_due_date,hs_balance

Invoices billed in the last 30 days

过去30天内开具的发票

hubspot objects search --type invoices
--filter "hs_invoice_date>=$(date -v-30d +%Y-%m-%d 2>/dev/null || date -d '30 days ago' +%Y-%m-%d)"
--properties hs_number,hs_amount_billed,hs_invoice_date

Verify the status enum the same way: `hubspot properties get --type invoices --name hs_invoice_status --format json | jq -r '.options[].value'`.
hubspot objects search --type invoices
--filter "hs_invoice_date>=$(date -v-30d +%Y-%m-%d 2>/dev/null || date -d '30 days ago' +%Y-%m-%d)"
--properties hs_number,hs_amount_billed,hs_invoice_date

同样请验证状态枚举值:`hubspot properties get --type invoices --name hs_invoice_status --format json | jq -r '.options[].value'`。

4. Track subscriptions

4. 跟踪订阅

Same shape, filter on
hs_subscription_status
. Verify the enum values before writing the filter — do not hardcode
ACTIVE
/
CANCELLED
/
PAST_DUE
:
bash
hubspot properties get --type subscriptions --name hs_subscription_status --format json \
  | jq -r '.options[].value'
操作方式类似,按
hs_subscription_status
筛选。设置筛选条件前请先验证枚举值——请勿硬编码
ACTIVE
/
CANCELLED
/
PAST_DUE
bash
hubspot properties get --type subscriptions --name hs_subscription_status --format json \
  | jq -r '.options[].value'

Then filter (case matters)

然后进行筛选(区分大小写)

hubspot objects search --type subscriptions
--filter "hs_subscription_status=<value-from-above>"
--properties hs_mrr,hs_arr,hs_subscription_status
hubspot objects search --type subscriptions
--filter "hs_subscription_status=<value-from-above>"
--properties hs_mrr,hs_arr,hs_subscription_status

Sum MRR across active subs

计算所有活跃订阅的MRR总和

hubspot objects search --type subscriptions
--filter "hs_subscription_status=<active-value>" --format json
| jq '[.data[].properties.hs_mrr | select(. != null) | tonumber] | add'
undefined
hubspot objects search --type subscriptions
--filter "hs_subscription_status=<active-value>" --format json
| jq '[.data[].properties.hs_mrr | select(. != null) | tonumber] | add'
undefined

Known constraints

已知限制

  • invoices
    ,
    subscriptions
    ,
    orders
    ,
    carts
    need the matching read scope on the active token; 403 means the user OAuth login or private-app token is missing the scope.
  • Destructive ops (
    objects delete
    on products/quotes/line_items) often need a private-app token:
    export HUBSPOT_ACCESS_TOKEN=<token>
    . See
    bulk-operations/SKILL.md
    for the dry-run → digest → confirm flow before bulk-deleting catalog records.
  • Quote share links, PDF generation, approval routing, and from-scratch invoice creation are UI-only — the CLI updates records but cannot send a quote to a customer.
  • hs_total_discount
    on line items is read-only — set
    discount
    (percentage) instead.
  • invoices
    ,
    subscriptions
    ,
    orders
    ,
    carts
    需要活跃令牌具备匹配的读取权限;返回403错误意味着用户OAuth登录或私有应用令牌缺少相应权限。
  • 破坏性操作(
    objects delete
    on products/quotes/line_items)通常需要私有应用令牌:
    export HUBSPOT_ACCESS_TOKEN=<token>
    。批量删除目录记录前,请查看
    bulk-operations/SKILL.md
    中的试运行→摘要→确认流程。
  • 报价共享链接、PDF生成、审批流程和从零创建发票仅支持UI操作——CLI可更新记录,但无法向客户发送报价。
  • hs_total_discount
    on line items为只读属性——请改用
    discount
    (百分比)设置折扣。