# Digital Goods MCP > A remote MCP server that lets any AI agent sell software, online courses and digital products through a MERCHANT OF RECORD (Paddle Billing, Lemon Squeezy, Polar, Whop, Creem, Dodo Payments, FastSpring, 2Checkout/Verifone) that handles global sales tax / VAT. One set of tools switches provider with the provider argument or x-mor-provider header. Stateless, bring-your-own API key, never stores anything. Complements the local-payments family (where the merchant is their own seller of record). - MCP endpoint (Streamable HTTP): https://mor.wishpool.app/mcp - Provider header: x-mor-provider = paddle | lemonsqueezy | polar | whop | creem | dodo | fastspring | twocheckout (or the provider argument). REQUIRED. - Credential header: x-mor-key = that platform's API key (Paddle pdl_..., Lemon Squeezy API key, Polar polar_oat_..., Whop key, Creem creem_test_..., Dodo key, FastSpring "username:password" for HTTP Basic, 2Checkout "MERCHANT_CODE:SECRET_KEY"). REQUIRED, forwarded per-request, never stored. - Env header: x-mor-env = sandbox/test (default, no real money) | prod/live (real money & real tax). Paddle & Polar have dedicated sandbox hosts; Creem & Dodo have dual test/live hosts; Lemon Squeezy uses a test key + test_mode; Whop & FastSpring have no separate sandbox host (test with a test/dev company or Test storefront); 2Checkout uses a DEMO account as its built-in sandbox (same host). - Design: this server forwards the platform API calls and never holds funds. Money flows buyer -> merchant of record -> merchant. The merchant of record is the legal seller and remits global sales tax / VAT on the merchant's behalf. ## Tools - create_checkout: Create a hosted checkout link for a catalog item — { provider, item, store_id? (Lemon Squeezy store; FastSpring storefront), quantity?, amount? (major unit; Lemon Squeezy custom price + owner policy gate), customer_email? (required by Dodo), country? (Dodo billing country), success_url? } in, checkout_url + reference_id + capabilities out. - query_order: Unified order/transaction status — { provider, order_id } in, status (PAID | PENDING | FAILED | REFUNDED | PARTIALLY_REFUNDED | CANCELED | PAST_DUE | UNKNOWN) + raw_status + raw passthrough out. - issue_refund: Refund an order — { provider, order_id, amount? (Lemon Squeezy partial / Polar required / Paddle+Dodo+FastSpring must omit / 2Checkout partial-or-full), reason? } in. Paddle = full-only (pending approval on production); Lemon Squeezy = partial or full; Polar = amount + reason enum required; Dodo = full-only; FastSpring = full-only; 2Checkout = partial (pass amount) or full (omit); Whop & Creem = NOT supported via API (dashboard-only, honestly reported). - query_subscription: Unified subscription status — { provider, subscription_id } in, status (ACTIVE | TRIALING | PAST_DUE | PAUSED | CANCELED | EXPIRED | UNKNOWN) + raw out. - cancel_subscription: Cancel a subscription — { provider, subscription_id, immediately? (Paddle only) } in. Paddle = now or period-end; Lemon Squeezy = period-end only; Polar = immediate (revoke). - Owner policy guardrails: x-agentpay-max-amount (hard cap), x-agentpay-approval-above (returns a draft for human review), x-agentpay-allowed-tools (tool allow-list) — set by the human owner in the MCP client config; the agent cannot relax them. Applied to the amount on create_checkout / issue_refund when supplied. ## Provider capabilities & honest gaps - Paddle Billing: sandbox-api.paddle.com / api.paddle.com; Bearer pdl_ key; sell a catalog price_id; refunds full-only via /adjustments (pending_approval on production). PRODUCTION requires a Paddle-verified seller account (Paddle's gate). checkout.url needs an approved domain / default payment link. - Lemon Squeezy: api.lemonsqueezy.com; Bearer key; JSON:API media type; sell a variant_id with a store_id; custom price + partial refunds supported. Acquired by Stripe (2024) — may steer to Stripe Managed Payments long-term. - Polar: api.polar.sh / sandbox-api.polar.sh; Bearer polar_oat_ token; sell a product_id; refunds require amount + reason enum. Production payout/KYC onboarding NOT yet verified end-to-end (NEEDS-DEEPER). - Whop: api.whop.com (v2 REST); Bearer key; sell a plan_id (POST /v2/checkout-sessions -> purchase_url). Order = payment/receipt (GET /v2/payments/{id}); subscription = MEMBERSHIP (GET /v2/memberships/{id}, cancel POST .../cancel at period-end). No sandbox host (production API only). issue_refund NOT supported via API (dashboard-only). - Creem: api.creem.io/v1 (prod) / test-api.creem.io/v1 (test); x-api-key header; test keys prefixed creem_test_. Sell a product_id (POST /v1/checkouts -> checkout_url). Order = checkout (GET /v1/checkouts?checkout_id); subscription GET /v1/subscriptions?subscription_id, cancel POST /v1/subscriptions/{id}/cancel (mode=scheduled = period-end). issue_refund NOT supported (no public refund endpoint; /v1/refunds 404s). - Dodo Payments: test.dodopayments.com / live.dodopayments.com; Bearer key; sell a product_id (POST /payments with payment_link:true -> payment_link; requires customer email + billing country). Order GET /payments/{id}; refund POST /refunds { payment_id } (full-only); subscription GET /subscriptions/{id}, cancel PATCH /subscriptions/{id} (immediate or cancel_at_next_billing_date). PRODUCTION requires KYC / business verification (24-72h, Dodo's gate). - FastSpring: api.fastspring.com; HTTP Basic auth (x-mor-key = "username:password"); sell a product path (POST /sessions -> build hosted URL https://{storefront}.onfastspring.com/session/{id}, needs store_id = storefront). Order GET /orders/{id} (order.completed = paid); refund POST /orders/{id}/refunds (full-only); subscription GET /subscriptions/{id}, cancel DELETE /subscriptions/{id} (period-end only). No separate sandbox host (Test storefront / test mode). - 2Checkout (Verifone): api.2checkout.com/rest/6.0; CUSTOM HMAC-SHA256 auth header X-Avangate-Authentication (code + UTC date + hash over strlen(code)+code+strlen(date)+date, keyed by the Secret Key); x-mor-key = "MERCHANT_CODE:SECRET_KEY". Sell a catalog product code via a locally-built ConvertPlus buy-link https://secure.2checkout.com/checkout/buy/?merchant={code}&prod={product}&qty={n} (zero API call; unsigned for a plain catalog link — signed buy-links / dynamic pricing need the separate Buy-Link Secret Word, out of scope). Order GET /orders/{RefNo}/; refund POST /orders/{RefNo}/refund/ (partial or full); subscription GET /subscriptions/{ref}/, cancel DELETE /subscriptions/{ref}/ (stops auto-renewal at period-end). New accounts are in DEMO mode (sandbox) instantly; LIVE selling requires Verifone to activate the account (their gate). - Gumroad: intentionally NOT included — API capability-limited and docs block automated access (NEEDS-DEEPER). ## Safety Stateless translation layer. The API key travels per-request in a header and is never stored; this server never stores credentials, orders, or customer data. Money flows buyer -> merchant of record -> merchant. Privacy policy: https://mor.wishpool.app/privacy ## Sister servers Local payments in 81 countries: https://mcp.wishpool.app/llms.txt. E-invoicing: Malaysia MyInvois https://inv-my.wishpool.app/mcp, Saudi ZATCA https://inv-sa.wishpool.app/mcp, Poland KSeF https://inv-pl.wishpool.app/mcp, Mexico CFDI https://inv-mx.wishpool.app/mcp, Chile DTE https://inv-cl.wishpool.app/mcp, Brazil NF-e https://inv-br.wishpool.app/mcp, Peru CPE https://inv-pe.wishpool.app/mcp, India GST https://inv-in.wishpool.app/mcp. Shipping & logistics: https://logi.wishpool.app. Same stateless BYO pattern. ## Trust & security No database: keys travel in a request header, are used once, never stored. We never hold funds and never take a cut. On rails requiring cryptographic signing the merchant signs and we relay - the private key never leaves the merchant. MIT-licensed and self-hostable. Threat model, credential map and known limits: https://mcp.wishpool.app/trust