For shopping agents and developers
Every Shopfront seller is Store-Sync-ready
Each shop answers PayPal's Cart API v1, the merchant contract behind PayPal Store Sync, and our MCP server. An agent builds a cart, gets validation issues it can resolve, and the buyer approves in PayPal. Prices, totals and every PayPal call come from deterministic code, never from the agent.
PayPal Cart API v1
Built to PayPal's published schema (@paypal/agentic-commerce-spec). One base URL per store:
https://shopfront-agent.onrender.com/api/paypal/v1/stores/{store}MCP server
Every seller behind one endpoint: search_products, get_product, create_checkout, get_checkout_status, request_refund. Tools take ids and quantities only.
https://shopfront-agent.onrender.com/mcpllms.txt for crawler agentsEndpoints
POST/merchant-cartCreate a cart. 201 with PayPal's payment token and approval_url when it's valid; 200 with validation_issues when it isn't.
GET/merchant-cart/{id}The cart's current state: READY once the buyer approved in PayPal.
PUT/merchant-cart/{id}Replace the whole cart (the spec's rule). A changed cart gets a fresh PayPal order.
POST/merchant-cart/{id}/checkoutFinish after approval, with the token and payer_id PayPal returned. The payment is authorized and charged when the shop ships.
Auth and payment
One token, one store
Bearer JWT, EdDSA. The audience is the store in the URL: a token for one shop gets 403 at another, and a cart is visible only to the agent that built it. Public key: /.well-known/jwks.json
Charged when it ships
Checkout authorizes the PayPal order; adding tracking captures it. Cancel before shipping and the hold is released. Works for shops paid to the platform and shops paid straight to their own PayPal.
Reconciled with PayPal
Every capture and every open hold is checked against PayPal on start-up and daily, and shown on the seller's dashboard.
Validation issues the shop returns
Computed from the database for every POST and PUT, with PayPal's issue codes and resolution actions, so an agent can fix the cart without a human.
| specific_issue | resolution_options | When |
|---|---|---|
| ITEM_NOT_FOUND | REMOVE_ITEM | A variant this store doesn't sell (other stores' listings included) |
| ITEM_OUT_OF_STOCK · INSUFFICIENT_INVENTORY | SUGGEST_ALTERNATIVE · MODIFY_CART | Live stock; alternatives come from the same shop |
| PRICE_MISMATCH | ACCEPT_NEW_PRICE | The agent sent a price. The shop's price stands; the agent's is never used |
| MISSING_SHIPPING_ADDRESS | UPDATE_ADDRESS | REQUIRES_ADDITIONAL_INFORMATION until the agent sends one |
| INTERNATIONAL_SHIPPING_RESTRICTED | UPDATE_ADDRESS | The store's ship-to countries |
| MAXIMUM_QUANTITY_EXCEEDED | MODIFY_CART | 1 to 10 per item |
| DISCOUNT_CUSTOMER_INELIGIBLE | REMOVE_COUPON | No coupon codes: discounts can't be talked into existence |
| MERCHANT_ACCOUNT_ISSUE | CONTACT_SUPPORT | A shop whose PayPal isn't verified can't take payments |
Try it now
Or run PayPal's own Cart API client as a shopping agent: pnpm --filter web cart-agent -- --store juniper_clay --query mug from the repo
Honest scope: PayPal routes Store Sync traffic to merchants it has onboarded, and issues their tokens, through a request-access program. Shopfront implements the merchant side of the contract and issues its own store-bound tokens until then; the verifier is the one PayPal's tokens would pass through. Sandbox only: no real money moves.