From airwallex-agentos
Extract billing details from purchase orders, contracts, or quotes, then set up Airwallex Billing by creating invoices and/or subscriptions — matching existing customers, products, and prices to avoid duplicates. Use when the user says "create invoice from this PO", "set up billing from this contract", "create a subscription from this agreement", "invoice this quote", "bill this customer", or attaches a document and asks to set up one-time, recurring, or mixed billing. Do NOT use for paying suppliers, provisioning cards, or checking FX rates.
How this skill is triggered — by the user, by Claude, or both
Slash command
/airwallex-agentos:contract-to-billingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Reads a customer document (PO, contract, quote), extracts line items with AI, and creates a fully populated invoice in Airwallex Billing.
Reads a customer document (PO, contract, quote), extracts line items with AI, and creates a fully populated invoice in Airwallex Billing.
This skill only covers Billing-domain operations — invoices (list, create, retrieve, finalize, void, mark-as-paid, plus line-item add / update / delete / list), products (list, create), prices (list, create), customers (list, retrieve, create, update), subscriptions (create, list items), coupons (list, create, update), meters (list, create, update), payment sources (list), and billing transactions (list, retrieve). Credit notes follow create → line-items add → finalize — if the operation is not exposed on the current surface, direct the user to the Airwallex Dashboard.
If the task requires capabilities outside this domain, stop — this is the wrong skill. Redirect the user:
collection_method mapping from document language:| Document says | API value |
|---|---|
| "send invoice", "bank transfer", "wire transfer", "offline payment", "pay by bank" | OUT_OF_BAND |
| "online payment", "checkout", "payment link", "pay online" | CHARGE_ON_CHECKOUT |
| "auto-debit", "direct debit", "auto-charge" | AUTO_CHARGE |
Never use SEND_INVOICE, MANUAL, AUTOMATIC, or any value not in the exact list: AUTO_CHARGE, CHARGE_ON_CHECKOUT, OUT_OF_BAND. Always ask the user if the document language is ambiguous.
[?] — never guess currencies, quantities, or amounts.OUT_OF_BAND, "online payment" → CHARGE_ON_CHECKOUT), use it and note the choice in the extraction summary. Ask the user when the document language is genuinely ambiguous or absent. If the inferred method is CHARGE_ON_CHECKOUT, ask for linked_payment_account_id — without it the invoice has no checkout link and is unusable.invoices finalize, invoices void, invoices delete, invoices mark-as-paid) need the same confirmation as create/update — they are not free passes.legal_entity_id — Before creating any invoice or subscription, ask the user: "Does your account have multiple legal entities? If so, please provide the legal_entity_id (available in the Airwallex Dashboard)." If the account has multiple legal entities and this field is omitted, the API rejects with "Need to specify the legal_entity_id in the request". This ID is not discoverable via API. If the user confirms only one legal entity, omit the field.collection_method MUST be set BEFORE finalize — set at create time or via the invoice update operation. See Terminology above for exact valid values.billing_customer_id; notes go in memo. There is no description field on invoices.invoice_items in the create body is silently ignored. Use the dedicated line-items operation after the draft exists.due_at OR days_until_due — passing both is rejected.+0000 and Z. Tested exception: the billing-invoice listing only accepts +0000 — Z returns a 400. Both surfaces URL-encode for you — do NOT pre-encode the offset to %2B0000.line_items; delete uses line_item_ids. Bare arrays are rejected.currency — inherited from invoice.total_amount > 0) before finalize. A draft with no line items will fail to finalize — and invoice_items in the invoice create body is silently dropped, so this state is easy to land in by accident."discounts": [{"type": "COUPON", "coupon": {"id": "..."}}]), not negative flat_amount. Credit notes: lifecycle is create → line-items add → finalize; if the operation is not exposed on the current surface, direct the user to the Airwallex Dashboard.percentage_off (0–100), no currency/amount_off. FLAT → amount_off + currency, no percentage_off. duration_type: CUSTOM needs a duration object with both period and period_unit.metadata replaces entirely on update — omit to keep existing.upper_bound (not up_to); the last tier omits upper_bound entirely.starts_at (subscriptions) must be strictly future. Compute dynamically — never hardcode. Omit to default to "now".items[*].price_id must reference RECURRING prices — ONE_OFF rejected.AUTO_CHARGE requires payment_source_id — ask the user.[?] if it is unclear whether document prices are tax-inclusive or exclusive, and ask the user. Do NOT silently compute tax.dunning.enabled, dunning.reminders, days_after_due, etc.).page_size minimum 10 across billing list endpoints. Most billing listings use cursor pagination — pass page_after back into the next call. The payment-links list endpoint is an exception (numeric page_num, 0-based). Repeat until cursor absent.Step 1 — Get the document. Accept local files (.pdf .docx .txt .md .png .jpg .webp), folder paths, or pasted text. If shell access is available, you can also fetch download URLs.
Reading strategy: PDF → Read tool (fall back to pdfplumber). DOCX → python-docx. Image → Read tool. TXT/MD → Read tool.
If the host/model cannot read a PDF, image, or other attachment reliably, do not pretend the document was read. Ask the user to re-upload, paste the relevant text, or provide a readable format before extracting billing details.
Step 2 — Extract billing details. Read the entire document. Distinguish between:
Identify: customer (name, address, email), document reference, currency, payment terms, all products and pricing, fees, subscription terms if applicable.
Step 3 — Build five tables:
Always use structured tables, not prose summaries. If a section does not apply, still show the table and mark it N/A.
Step 4 — Validate and confirm. Cross-check against API requirements. List all gaps explicitly. Accept natural-language corrections and loop until user approves. Do NOT proceed to any create/finalize call until every required field is complete and the user confirms.
Step 5 — Confirm environment. State sandbox vs production to the user (sandbox default; production only on explicit confirmation). Validate required fields for all planned operations. Include request_id (UUIDv4) on every write that accepts it.
Step 6 — Match existing resources. Search for customers by email (filter parameter email on the billing-customers list). For products, the billing-products list has no name filter — paginate fully and match by name client-side. Search prices by product (parameter product_id on the billing-prices list). Present matches and get confirmation.
Only match core goods/services (e.g., "Widget Alpha"). Do NOT match existing products for per-order ad-hoc fees (shipping, handling, setup charges) — always create fresh products for these and use inline prices in line items.
Step 7 — Create missing resources. Create ALL missing products and needed prices from the contract (full catalog), not just current order.
Price type depends on Table 4: N/A → ONE_OFF. Has subscription data → RECURRING.
Pricing model depends on contract: FLAT (fixed amount), PER_UNIT (per-seat), VOLUME/GRADUATED (tiered).
Step 7b — Confirm collection method. Use the method inferred from the document (see operational rules). If the document was ambiguous or silent, ask the user now. If CHARGE_ON_CHECKOUT, require linked_payment_account_id from the user or Airwallex Dashboard context — do not guess or invent one.
Step 8 — Route based on Table 4:
The path comes from the extracted document terms, not from user preference. Requests for external payment gateways or custom dunning do not change the billing route. Create the Airwallex invoice/subscription that is supported, then clearly state any unsupported extra was not configured.
| Table 4 | Action |
|---|---|
| Has subscription data | → Create subscription |
| N/A (one-time) | → Create invoice |
| Both | → Subscription for recurring + invoice for one-time fees |
Create subscription with billing_customer_id, currency, collection_method, items (RECURRING prices). Verify after creation.
Receivables note — after creation, remind the user that this subscription will generate recurring invoices (expected money in). If they use the manage-cashflow skill, upcoming subscription invoices will appear in their receivables picture. Mention the subscription ID, currency, billing interval, and next billing date so they can cross-reference.
Create draft with billing_customer_id, currency, collection_method, optional days_until_due/due_at, memo.
Add line items. Use the dedicated line-items operation after the draft exists. Body shape for an existing price: {"price_id": "...", "quantity": N}. For ad-hoc fees, use inline price: {"price": {"product_id": "...", "pricing_model": "FLAT", "flat_amount": 350.00, "description": "Shipping"}, "quantity": 1}. Do NOT include currency in inline price. If the contract uses tiered pricing, convert the billed tiers into invoice-compatible PER_UNIT/FLAT line items per band — do not attach VOLUME/GRADUATED price_ids to invoice line items.
Finalize — confirm with user first. Show summary: resources created/reused, total, due date, pdf_url, hosted_url.
Receivables note — after finalize, remind the user that this invoice is now a receivable (expected money in). If they use the manage-cashflow skill, this finalized invoice will appear in their receivables/obligations picture. Mention the invoice ID, amount, currency, and due date so they can cross-reference. When multiple invoices are created in a batch, also show a one-line aggregate: total outstanding amount per currency (e.g., "3 invoices totalling 47,200 GBP in outstanding receivables") so the user can immediately see the cash-position impact without switching to manage-cashflow.
Must be explicitly requested. After finalize, present:
pdf_url — direct link to the PDF version of the invoice (always available on finalized invoices).hosted_url — online checkout page for the customer to pay. Only available when collection_method is CHARGE_ON_CHECKOUT. For OUT_OF_BAND invoices, hosted_url may be absent — share the pdf_url instead and instruct the customer on bank transfer details.Airwallex Billing has no API to email invoices directly — the agent cannot send on behalf of the user. Offer to draft a payment email the user can copy and send themselves (e.g., via their email client or Slack).
Generic patterns (401/auth, API validation, duplicates, partial writes, missing required fields) — see awx-best-practices Error handling and api_traps.md.
Domain-specific:
| Situation | Action |
|---|---|
| Document unreadable | Ask for content another way and stop |
| Ambiguous extraction | Flag with [?], ask user, do not guess |
legal_entity_id required (missed pre-check) | Account has multiple legal entities. Ask the user which legal_entity_id to use — not discoverable via API. Include in the request body and retry. |
| User requests external gateway setup | Explain that external gateway configuration is outside this skill's scope. Continue with Airwallex Billing setup only if the user still wants that. |
| User requests custom dunning cadence not confirmed by docs | Do not invent fields. Say the reminder customization is unsupported or handled separately, and continue with the supported invoice/subscription setup only. |
Phase 1: Extract
get document → read → extract → build 5 tables → validate → user confirms
Phase 2: Match & Create
environment / account + auth → match existing → user confirms
→ create missing → confirm collection method
→ if recurring: subscription → if one-time: invoice → finalize
→ receivables note (cross-ref with manage-cashflow)
Phase 3: Share (opt-in)
present URLs (pdf_url + hosted_url) → draft email if requested
Offers UI/UX design guidance for web and mobile with 50+ styles, 161 color palettes, 57 font pairings, and 99 UX guidelines across 10 stacks. Use for designing pages, components, color systems, or reviewing UI code.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
npx claudepluginhub anthropics/claude-plugins-official --plugin airwallex-agentos