Node.js
Use the InFlow Node.js SDKs to accept payments in your service or make paid requests from a JavaScript or TypeScript application. Choose the buyer or seller package for MPP, x402, or both.
The InFlow Node.js repository on GitHub contains the SDK packages and runnable examples. Each package has its own npm release and README. The links below take you to those packages.
Choose and install packages
Use Node.js 22 or later. A seller accepts payments for a resource; a buyer requests and pays for that resource. Install only the packages for your application’s role and protocols. An application can use both buyer and seller packages.
| npm package | Use it to |
|---|---|
| @inflowpayai/mpp-buyer | Respond to MPP challenges and obtain payment credentials through InFlow. |
| @inflowpayai/mpp-seller | Offer MPP payments and process submitted credentials before delivering a resource. |
| @inflowpayai/x402-buyer | Create x402 payment payloads with InFlow-managed funds or a configured external wallet. |
| @inflowpayai/x402-seller | Build payment offers and connect x402 middleware to InFlow’s facilitator. |
Run the command for your role and protocol in your application directory. The MPP packages use mppx; the x402 packages use @x402/core. These protocol libraries are shared dependencies, so the commands install them explicitly. InFlow’s own core packages are installed automatically.
For an MPP buyer:
npm install @inflowpayai/mpp-buyer@0.8.1 mppx@0.8.17
For an x402 buyer:
npm install @inflowpayai/x402-buyer@0.11.2 @x402/core@2.27.0
For an MPP seller using Express:
npm install @inflowpayai/mpp-seller@0.11.0 mppx@0.8.17 express
For an x402 seller using Express:
npm install @inflowpayai/x402-seller@0.10.0 @x402/core@2.27.0 \ @x402/extensions@2.27.0 @x402/express@2.27.0 express
The seller commands use Express as one example. Choose the adapter for your framework below. External-wallet and MCP integrations have additional dependencies; install those when you add the corresponding feature. You do not need to clone the repository to use a published package.
Configure your application
Create an API key as described in Accounts and environments. Accepting payments requires a Seller account. A buyer-only application can use a Developer account; an existing Seller account can also make payments.
Read INFLOW_API_KEY from your application’s environment or secret store and pass it as apiKey. Set environment: 'sandbox' while testing, with a Sandbox key. Use 'production' and a production key for live payments. Keep keys in server-side code, not browser bundles or logs.
The TypeScript request examples below accept the key as a function argument. They do not read environment variables automatically. The runnable buyer and seller examples linked below load their local .env files with dotenv.
An MPP seller also supplies secretKey to Mppx.create. This private secret signs the service’s payment challenges; it is not the InFlow API key. Store a stable value shared by your service instances. For a local example, generate one with openssl rand -hex 32.
Initialize x402 clients before accepting work. Both createInflowClient and createInflowSellerClient are asynchronous because they load InFlow configuration. Await their results and handle startup failures; a constructed JavaScript object alone does not establish that the account is ready.
Accept payments with your framework
Keep your resource handler in your existing web framework. Add payment protection to the routes you charge for, with an explicit price and payment options. InFlow supplies the payment methods and facilitator connection; the protocol adapters connect them to HTTP requests and responses.
- For MPP, create an InFlow seller method and pass it to Mppx.create with your challenge secret and paymentHttpTransport(). Apply the adapter’s charge middleware to the paid route. The Express example and Hono example show the full setup. The InFlow transport returns server failures without attaching a fresh payment challenge, so a processing error does not invite another payment.
- For x402, use createInflowSellerClient to load seller configuration and inflowAccepts to build the route’s offers. Supply createInflowFacilitator and inflowSchemeRegistrations to the upstream middleware. Complete examples cover Express, Hono, Fastify and Next.js.
Start with Accept MPP or Accept x402 for route code and settlement behavior. Deliver paid results explains when handlers run and how to handle application side effects. Payment processing does not replace your application’s authentication or access checks.
One endpoint can offer MPP and x402 as alternatives. Follow Accept both protocols for the combined route and separate-route examples. Separate routes are useful when the combined payment headers exceed your server or proxy limits.
Make paid requests
The MPP client below uses its own payment-aware fetch. Setting polyfill: false leaves global fetch unchanged. The registered inflow method handles InFlow charge challenges; it does not automatically register every MPP payment method.
Call this function only for a resource you intend to pay for. It permits one paid retry and uses the method’s default offer selection. Read Choose payment options to constrain the options your application accepts.
import { Mppx, Receipt, inflow } from '@inflowpayai/mpp-buyer';
export async function fetchMpp(apiKey: string, target: string) {
const method = inflow({ apiKey, environment: 'sandbox' });
const client = Mppx.create({
methods: [method],
polyfill: false,
maxPaymentRetries: 1,
});
try {
const response = await client.fetch(target, { redirect: 'error' });
const body = await response.text();
if (!response.ok) {
throw new Error(`Resource returned HTTP ${response.status}`);
}
const receipt = response.headers.has('Payment-Receipt')
? Receipt.fromResponse(response)
: undefined;
return { body, receipt };
} finally {
method.cleanup();
}
}A free response returns without buying anything. The receipt is decoded only when the response contains one. A missing receipt is not proof of payment; an unsuccessful response is not returned as a paid result. The function owns its method instance, so cleanup cannot interrupt other callers.
Send an x402 request
For x402, connect createInflowClient to x402HTTPClient. Your application makes the initial request, decodes a 402 challenge, creates a payment payload, and sends one request with the payment header. The HTTP helper encodes and decodes protocol headers; it does not make the fetch calls for you.
import { createInflowClient } from '@inflowpayai/x402-buyer';
import { x402HTTPClient } from '@x402/core/client';
export async function fetchX402(apiKey: string, target: string) {
const client = await createInflowClient({ apiKey, environment: 'sandbox' });
const http = new x402HTTPClient(client);
let response = await fetch(target, { redirect: 'error' });
if (response.status === 402) {
const challengeBody: unknown = response.headers.has('PAYMENT-REQUIRED')
? undefined
: await response.json();
const required = http.getPaymentRequiredResponse(
(name) => response.headers.get(name), challengeBody,
);
if (!response.bodyUsed) await response.body?.cancel();
const payload = await http.createPaymentPayload(required);
response = await fetch(target, {
redirect: 'error',
headers: http.encodePaymentSignatureHeader(payload),
});
}
const body = await response.text();
if (!response.ok) {
throw new Error(`Resource returned HTTP ${response.status}`);
}
const receipt = response.headers.has('PAYMENT-RESPONSE')
? http.getPaymentSettleResponse((name) => response.headers.get(name))
: undefined;
if (receipt && !receipt.success) throw new Error('Settlement failed');
return { body, receipt };
}Both functions return the resource body as text and any decoded receipt. The x402 function also rejects a receipt that reports settlement failure. Keep the resource result and settlement result distinct when displaying them to a user. See Pay with x402 for the complete payment flow.
These are GET examples with redirects disabled. For POST requests, preserve the method, replayable body and application headers on the paid request. MPP uses Authorization for its payment credential, so an application bearer token needs a separate agreed header or cookie. Pay with MPP covers that integration.
Manage approvals and failures
The buyer helpers wait when InFlow requires owner approval. Keep the dashboard available during a test; waiting does not approve a purchase. Approvals and allowances explains what the owner must do.
- For explicit x402 approval handling, call prepareInflowPayment with a selected InFlow-supported offer and its payment context. Retain the returned transaction and approval identifiers. awaitPayload waits for the payload. cancel stops local waiting and requests approval cancellation, but suppresses cancellation errors. Its completion does not confirm that the server cancelled the approval. Receiving a payload is not settlement: your application still submits it to the seller.
- For MPP, cleanup() aborts active approval polling for that method instance. Call it when the instance’s owner finishes or shuts down. If you share one method across requests, do not clean it up after each request: that can cancel another caller’s wait. An ordinary fetch abort signal does not stop the InFlow method’s approval polling; manage that method’s lifetime separately.
- Catch typed errors such as MppPaymentTimeoutError or X402ApprovalFailedError when your application needs a specific response. Preserve available transaction identifiers and the original error. Network failures and malformed responses can throw other errors, so do not assume every exception has an approval identifier.
The high-level MPP fetch helper does not return a durable payment handle. Use the MPP core client when you need to store transaction state before delivery and resume explicitly. x402’s prepared-payment handle provides that control for InFlow-managed offers; it is not the external-wallet signing interface.
A cancelled wait does not refund a payment, and a network timeout does not establish that no money moved. After an uncertain result, follow Status and recovery before creating another payment. Do not retry the entire purchase function blindly.
Run an example
The repository pairs local HTTP sellers with buyers that use InFlow Sandbox. Clone it, use the pnpm version specified by its packageManager field, then install and build the workspace packages:
git clone https://github.com/inflowpayai/inflow-node.git cd inflow-node pnpm install --frozen-lockfile pnpm build cp examples/mpp-seller-express/.env.example examples/mpp-seller-express/.env cp examples/mpp-buyer-manual/.env.example examples/mpp-buyer-manual/.env
In the seller example’s .env, set INFLOW_API_KEY to your Seller Sandbox key. Set MPP_SECRET_KEY to the output of openssl rand -hex 32. Leave INFLOW_BASE_URL empty to use Sandbox. From the repository root, start the seller:
pnpm --filter @inflowpayai/example-mpp-seller-express start
The seller listens on port 3000. Its /api/widgets route requires 0.01 USDC; /free does not require payment. Use a second terminal for the buyer. In its .env, set INFLOW_API_KEY to the buyer’s Sandbox key and keep the default widgets URL. Leave INFLOW_BASE_URL and INSTRUMENT_ID empty for this balance-funded test.
Fund the buyer’s Sandbox balance with at least 0.01 USDC. Open Sandbox Deposit and follow its deposit instructions using a test-token faucet. Wait for the deposit to appear in Sandbox Balances, then run this command from the repository root:
pnpm --filter @inflowpayai/example-mpp-buyer-manual start
Approve the payment in Sandbox if requested. The buyer prints the HTTP status, resource body and receipt. Check the widgets response and the payment in the dashboard. Stop and investigate an uncertain result before running the buyer again. For an x402 pair, follow the seller example and fetch buyer example.
Add the features your application needs
- Subscriptions covers recurring InFlow MPP offers, purchases and access using an existing subscription. Choose that flow deliberately; the widgets example above makes a one-time purchase.
- External wallets covers x402 signing from your application’s wallet. Trusted agent verification covers the separate seller-side verifier package.
- The optional MPP-over-MCP buyer integration uses @inflowpayai/mpp-buyer/mcp and the MCP SDK. The AEP seller example shows AEP authentication alongside MPP payment protection.
Continue your integration
Accept a payment
Configure a paid endpoint and check the seller’s first payment flow.
Make a payment
Prepare the buyer account and complete a request to a paid resource.