skills/airwallex-contract-to-billing/SKILL.md
Use this skill when creating Airwallex invoices or subscriptions from a purchase order, contract, or quote — extract line items and match existing customers, products, and prices.
npx skillsauth add chatandbuild/chatchat-skills Airwallex Contract to BillingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Reads a customer document (PO, contract, quote), extracts line items, and creates a fully populated invoice or subscription in Airwallex Billing. Uses the Airwallex MCP billing tools and operates on live production data — there is no sandbox.
This skill covers Billing-domain operations exposed by this connector: invoices (list, retrieve, create, update, finalize, void, mark-as-paid, list line items, add line items), products (list, create), prices (list, create), customers (list, retrieve, create, update), subscriptions (create, list items), coupons (list, create, update), and meters (list, create, update).
Not exposed by this connector — direct the user to the Airwallex Dashboard for: line-item update/delete (correct by voiding and re-issuing instead), credit notes, subscription cancellation, payment-source listing, and billing-transaction listing.
If the task requires anything outside the Billing 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.CHARGE_ON_CHECKOUT, ask for linked_payment_account_id — without it the invoice has no checkout link and is unusable.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.billing_customer_id; notes go in memo. There is no description field on invoices.invoice_items in the create body is silently ignored. Add items via the dedicated add-line-items operation after the draft exists. (Convenience: this connector also accepts line_items on the invoice create — it creates the draft, attaches the items, and returns the refreshed invoice. If that attach step fails you get the draft back with a warnings entry, so always check the returned total before finalizing.)due_at OR days_until_due — passing both is rejected.+0000 and Z. Tested exception: the invoice listing only accepts +0000 — Z returns a 400. Do NOT pre-encode the offset to %2B0000.line_items. Bare arrays are rejected. Line items only accept ONE_OFF + PER_UNIT/FLAT prices — RECURRING, VOLUME, GRADUATED are rejected. If the contract has tiered pricing, split into separate PER_UNIT line items per band.currency — inherited from the invoice.total_amount > 0) before finalize. A draft with no line items fails to finalize — and invoice_items in the create body is silently dropped, so this state is easy to land in by accident."discounts": [{"type": "COUPON", "coupon": {"id": "..."}}]), not negative amounts. Credit notes are not exposed by this connector — 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.currency, pricing_model, amount, or tiers via update — deactivate the old price and create a new one.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. legal_entity_id may also be required on subscription create in multi-entity accounts.[?] if it is unclear whether prices are tax-inclusive or exclusive, and ask. Do NOT silently compute tax.request_id for create operations — you do not need to supply it.page_size minimum 10 across billing list endpoints. Most billing listings use cursor pagination — pass the returned page_after bookmark into the next call. Repeat until the cursor is absent.Step 1 — Get the document. Accept local files (.pdf .docx .txt .md .png .jpg .webp) or pasted text. If the host cannot read a PDF/image reliably, do not pretend it was read — ask the user to re-upload, paste the text, or provide a readable format before extracting.
Step 2 — Extract billing details. Read the entire document. Distinguish the product catalog (all products/pricing defined in the contract) from the current order (specific items being billed now). Identify: customer (name, address, email), document reference, currency, payment terms, all products and pricing, fees, and subscription terms if applicable.
Step 3 — Build five tables (always structured tables, not prose; show a table marked N/A if a section does not apply):
Step 4 — Validate and confirm. Cross-check against API requirements. List all gaps explicitly. Accept natural-language corrections and loop until the user approves. Do NOT proceed to any create/finalize call until every required field is complete and the user confirms.
Step 5 — Confirm live data. Validate required fields for all planned operations.
Step 6 — Match existing resources. Search customers by email (filter on the customers list). The products list has no name filter — paginate fully and match by name client-side. Search prices by product_id. Present matches and get confirmation. Only match core goods/services. Do NOT match existing products for per-order ad-hoc fees (shipping, handling, setup) — 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 the current order. Price type: N/A (Table 4) → ONE_OFF; has subscription data → RECURRING. Pricing model: FLAT (fixed), PER_UNIT (per-seat), VOLUME/GRADUATED (tiered).
Step 7b — Confirm collection method. Use the method inferred from the document; if ambiguous or silent, ask now. If CHARGE_ON_CHECKOUT, require linked_payment_account_id from the user — do not guess.
Step 8 — Route based on Table 4:
| Table 4 | Action | | --- | --- | | Has subscription data | → Create subscription | | N/A (one-time) | → Create invoice | | Both | → Subscription for recurring + invoice for one-time fees |
Create a subscription with billing_customer_id, currency, collection_method, and items (RECURRING prices). Verify after creation. Receivables note: remind the user this subscription generates recurring invoices (expected money in). Mention the subscription ID, currency, billing interval, and next billing date so they can cross-reference with the airwallex-manage-cashflow skill. (Note: this connector cannot cancel subscriptions — direct cancellation requests to the Airwallex Dashboard.)
Create draft with billing_customer_id, currency, collection_method, optional days_until_due/due_at, and memo.
Add line items with the dedicated add operation after the draft exists. For an existing price: {"price_id": "...", "quantity": N}. For ad-hoc fees, use an inline price: {"price": {"product_id": "...", "pricing_model": "FLAT", "flat_amount": 350.00, "description": "Shipping"}, "quantity": 1}. Do NOT include currency in an inline price. Convert tiered pricing into invoice-compatible PER_UNIT/FLAT line items per band.
Finalize — confirm with the user first. Show a summary: resources created/reused, total, due date, pdf_url, hosted_url. Receivables note: after finalize, remind the user this invoice is now a receivable (expected money in). Mention the invoice ID, amount, currency, and due date. For a batch, also show a one-line aggregate of total outstanding per currency (e.g., "3 invoices totalling 47,200 GBP outstanding") so the cash-position impact is immediately visible.
Must be explicitly requested. After finalize, present:
pdf_url — direct link to the PDF (always available on finalized invoices).hosted_url — online checkout page. Only available when collection_method is CHARGE_ON_CHECKOUT. For OUT_OF_BAND invoices, hosted_url may be absent — share the pdf_url and instruct the customer on bank transfer details.Airwallex Billing has no API to email invoices directly — the agent cannot send on the user's behalf. Offer to draft a payment email the user can copy and send themselves.
| Situation | Action |
| --- | --- |
| Document unreadable | Ask for the content another way and stop |
| Ambiguous extraction | Flag with [?], ask the user, do not guess |
| legal_entity_id required (missed pre-check) | Account has multiple legal entities. Ask which legal_entity_id to use (not discoverable via API), include it in the body, and retry |
| Draft fails to finalize | Verify total_amount > 0 — the draft likely has no line items; add them via the add-line-items operation first |
| User requests external gateway setup | Explain it is outside this skill's scope; continue with Airwallex Billing only if the user still wants that |
| Credit note / line-item edit / subscription cancel requested | Not exposed by this connector — direct the user to the Airwallex Dashboard |
| Auth expired | The connector refreshes tokens automatically; if a tool keeps failing on auth, ask the user to re-authorize the Airwallex connection |
Phase 1: Extract
get document → read → extract → build 5 tables → validate → user confirms
Phase 2: Match & Create
confirm live data → match existing → user confirms → create missing
→ confirm collection method
→ if recurring: subscription → if one-time: invoice → finalize
→ receivables note (cross-ref with airwallex-manage-cashflow)
Phase 3: Share (opt-in)
present URLs (pdf_url + hosted_url) → draft email if requested
Adapted from Airwallex's official AgentOS contract-to-billing skill, licensed under the Apache License 2.0 (see LICENSE.txt). Modified for the ChatChat Airwallex connector: CLI-specific instructions and external URLs removed, supporting reference files inlined, workflow steps aligned to the operations this connector actually exposes, and unsupported operations redirected to the Airwallex Dashboard.
tools
Use only when the user explicitly asks to stage, commit, push, and open a GitHub pull request in one flow using the GitHub CLI (`gh`).
development
Use this skill any time a spreadsheet file is the primary input or output. This means any task where the user wants to: open, read, edit, or fix an existing .xlsx, .xlsm, .csv, or .tsv file (e.g., adding columns, computing formulas, formatting, charting, cleaning messy data); create a new spreadsheet from scratch or from other data sources; or convert between tabular file formats. Trigger especially when the user references a spreadsheet file by name or path — even casually (like "the xlsx in my downloads") — and wants something done to it or produced from it. Also trigger for cleaning or restructuring messy tabular data files (malformed rows, misplaced headers, junk data) into proper spreadsheets. The deliverable must be a spreadsheet file. Do NOT trigger when the primary deliverable is a Word document, HTML report, standalone Python script, database pipeline, or Google Sheets API integration, even if tabular data is involved.
development
Use this skill when turning messy workout information into clear logs, comparing user-provided sessions, surfacing trends or likely PRs, and suggesting realistic next-session steps.
tools
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.