@flexpay/sdk
v0.1.15
Published
Umbrella package for **FlexPay**: headless core (`@flexpay/core`), React checkout UI (`@flexpay/react`), and server-side Jupiter proxies (`@flexpay/server`). Install once and import the surface you need.
Readme
@flexpay/sdk
Umbrella package for FlexPay: headless core (@flexpay/core), React checkout UI (@flexpay/react), and server-side Jupiter proxies (@flexpay/server). Install once and import the surface you need.
Install
npm i @flexpay/sdk
# or
pnpm add @flexpay/sdkPeer expectations for the React entry:
reactandreact-dom(18.3+ or 19+)- A Solana wallet context from
@solana/wallet-adapter-react(e.g.ConnectionProvider+WalletProvider).
Entry points
| Import | Package | Use when |
|--------|---------|----------|
| @flexpay/sdk | Re-exports @flexpay/core | Same as import { … } from "@flexpay/core" |
| @flexpay/sdk/core | @flexpay/core | Headless FlexPayClient, types, errors |
| @flexpay/sdk/react | @flexpay/react | FlexPayWidget, useFlexPay, styles |
| @flexpay/sdk/server | @flexpay/server | proxyQuote, flexPayRouter, etc. |
import { FlexPayClient } from "@flexpay/sdk/core";
import { FlexPayWidget } from "@flexpay/sdk/react";
import { proxyQuote } from "@flexpay/server";React widget: required styles
Import the widget stylesheet once (e.g. in your app layout):
import "@flexpay/react/styles.css";(When using the umbrella package, the CSS is still published from @flexpay/react; the import path above is the supported one.)
API base URLs (important)
FlexPayClient and FlexPayWidget need Jupiter proxy base URLs for quote, swap, and (optionally) token metadata. The core client appends route segments such as order and execute to these bases—do not include /order in the base.
Supported forms:
| Form | Example | Notes |
|------|---------|--------|
| Absolute HTTPS | https://your-api.example/flexpay/quote | Works everywhere (SSR, iframes, native embeds). |
| Root-relative | /api/flexpay/quote | Common in Next.js; resolved against the page origin in the browser. |
| App-relative | api/flexpay/quote or ./api/flexpay/quote | Normalized to /api/flexpay/quote before use. |
Avoid bare strings such as quote-api or hostnames without https://—they are rejected with INVALID_CONFIG.
Default widget bases (if you omit props) mirror the demo app:
- Quote:
/api/flexpay/quote - Swap:
/api/flexpay/swap - Tokens:
/api/flexpay/tokens
Minimal Next.js App Router example
1. Environment — set Jupiter endpoints your server routes will call (names may vary; align with your deployment):
FLEXPAY_JUPITER_QUOTE_API=https://quote-api.jup.ag/v6
# plus swap API host as used by your proxy helpers2. API route (sketch—mirror your Jupiter version; see @flexpay/server helpers):
app/api/flexpay/quote/route.ts proxies quote requests; app/api/flexpay/quote/order/route.ts (or equivalent) should serve Swap API order calls used by the client when building quotes.
Your bases passed to the widget should match the routes you implement, e.g.:
<FlexPayWidget
merchantWallet={merchant}
amount={29.99}
rpcEndpoint={process.env.NEXT_PUBLIC_SOLANA_RPC!}
quoteApiUrl="/api/flexpay/quote"
swapApiUrl="/api/flexpay/swap"
tokensApiUrl="/api/flexpay/tokens"
/>3. Wallet + styles in app/layout.tsx:
import "@flexpay/react/styles.css";
// Wrap children with ConnectionProvider + WalletProvider …FlexPayWidget props (reference)
| Prop | Required | Description |
|------|----------|-------------|
| merchantWallet | Yes | Merchant USDC ATA or wallet receiving settlement. |
| amount | Yes | Fiat/UI amount to settle (exact-out flow). |
| rpcEndpoint | Yes | Solana HTTP RPC (cluster must match Jupiter APIs you use). |
| jupiterApiKey | No | Passed as x-api-key to Jupiter if your routes/proxy require it. |
| slippageBps | No | Slippage in basis points. |
| quoteApiUrl | No | Quote base URL (see above). |
| swapApiUrl | No | Swap base URL. |
| tokensApiUrl | No | Token list / metadata proxy base. |
For full typings, see @flexpay/react and @flexpay/core type exports.
Headless usage
import { FlexPayClient } from "@flexpay/sdk/core";
const client = new FlexPayClient({
merchantWallet: "…",
rpcEndpoint: "https://api.mainnet-beta.solana.com",
quoteApiUrl: "https://…/flexpay/quote",
swapApiUrl: "https://…/flexpay/swap",
tokensApiUrl: "https://…/flexpay/tokens"
});Troubleshooting
Failed to construct 'URL': Invalid URL (browser)
Usually means a relative API base could not be turned into an absolute URL, or a base string was not a valid URL.
Checklist:
- Prefer absolute
https://…bases for production if you embed the widget in iframes or non-standard origins. - For root-relative paths (
/api/...), ensure the app runs in a normal browser context with a validlocation.origin(not a brokenfile:URL). - Use
api/...or./api/...only when you intend a path under the site root; do not pass bare words (quoteApi) or partial hosts (api.example.comwithouthttps://). - Ensure RPC cluster matches Jupiter (mainnet Jupiter APIs require a mainnet RPC).
Same message, but only after “pick a token” (often Next.js / Vercel)
The browser calls your /api/flexpay/quote/order proxy. On the server, new URL(...) runs when building the upstream Jupiter URL. If FLEXPAY_JUPITER_QUOTE_API (or your deployment’s equivalent) is missing the https:// scheme or is otherwise malformed, Node throws the same Failed to construct 'URL' text; it surfaces as an HTTP error from your API route, not as a client-side stack trace.
Fix: set FLEXPAY_JUPITER_QUOTE_API=https://api.jup.ag/swap/v2 (or your Jupiter v2 base), fully qualified. Check Vercel → Project → Settings → Environment Variables.
On localhost, compare .env.local with production: a bad FLEXPAY_JUPITER_* line often exists only on your machine. Prefer omitting the variable so the demo defaults apply, or copy from apps/demo-store/.env.example in this repo.
Use the browser Network tab: open the failing quote/order request and read the JSON message body.
The React package records every widget error in both console.error and console.warn (search for [FlexPay]) and, more reliably, on globalThis.__FLEXPAY_LAST__ and globalThis.__FLEXPAY_LOG__. In the browser console, run globalThis.__FLEXPAY_LAST__ if your build or DevTools filters hide console output. These are client-side (not the Vercel/Node server log stream).
The React hook maps URL-style failures to FlexPayError code INVALID_CONFIG when the message matches; server configuration errors may appear as INVALID_RESPONSE with the same text in error.message—read the Technical details block on the error screen.
No routes / 404 on quote or swap
Confirm your server implements the same path layout the client expects: bases at /api/flexpay/quote and /api/flexpay/swap with order and execute segments appended by the SDK (buildApiUrl).
Wallet errors
Connect a wallet that supports signing before confirming payment. The adapter context must wrap the widget.
Related packages
@flexpay/core—FlexPayClient, URL helpers, errors@flexpay/react— UI components@flexpay/server— Express-style routers and proxies
