SDKs

Python

Use the InFlow Python SDK to accept payments in a Python service or make paid requests from your application. One package provides MPP and x402 integrations, with optional dependencies for the protocols and frameworks you use.

GitHub repository · Python package on PyPI

Install the SDK

Use Python 3.11 or later and install inflowpay in your application’s virtual environment. The names in brackets select optional dependencies; they are not separate InFlow SDKs. Choose the protocols your application needs:

python -m pip install 'inflowpay[mpp,x402]==0.3.2'
ExtraUse it for
mppMPP buyers and sellers, using pympp.
x402x402 buyers and sellers, using the upstream x402 Python library.
fastapiFastAPI seller applications. Combine it with a protocol extra and install an application server such as uvicorn.

The installation above supports both buyer examples on this page. For a FastAPI service accepting both protocols, use:

python -m pip install 'inflowpay[mpp,x402,fastapi]==0.3.2' uvicorn

An MPP-only application can install inflowpay[mpp]; an x402-only application can install inflowpay[x402]. Add the evm or svm extra only when configuring an external wallet. The tap and mcp extras support trusted agent verification and MCP integrations. The Python repository README explains those features and their dependencies.

Configure your application

Accepting payments requires an InFlow Seller account. A buyer can use a Developer or Seller account. Create an API key in the matching environment as described in Accounts and environments.

import os

from inflowpay import ClientOptions

options = ClientOptions(
    environment="sandbox",
    api_key=os.environ["INFLOW_API_KEY"],
)

Your application reads INFLOW_API_KEY and passes it to the SDK; the SDK does not load that environment variable automatically. Set the environment explicitly: ClientOptions defaults to production. Keep the key in your server’s environment or secret store, not in browser code or headers sent to a seller’s resource URL.

An MPP seller also needs a private challenge-signing secret. This is separate from the InFlow API key. Store a stable secret for your service and share it across instances that must accept the same payment challenges.

Accept payments with FastAPI

The repository’s runnable sellers use FastAPI. They load InFlow configuration during asynchronous startup, configure payment protection around a route, and keep the SDK clients open while the server handles requests.

  • For MPP, call Seller.create from inflowpay.mpp.seller. Build the terms with seller.charge_request and apply pympp’s pay decorator to the route. The MPP seller example shows the challenge secret, protected handler and Payment-Receipt response header. Payment processing completes before that handler runs.
  • For x402, create Seller from inflowpay.x402.seller and Facilitator from inflowpay.x402.facilitator. Register the seller’s schemes with the upstream resource server, build route offers, and attach its FastAPI payment middleware. The x402 seller example provides the complete setup. That example verifies payment before the handler and settles a successful response before releasing it to the buyer.

Python’s MPP buyer supports subscriptions; its MPP seller integration supports charge payments only. The seller also does not support multiple InFlow offers on one endpoint. Do not copy a subscription seller or multi-offer example from another language and assume that Python exposes the same interface.

Payment protection does not replace your application’s authentication or authorization. Keep those checks where the resource requires them. Before a paid handler changes application data, read Understand verification and settlement and Deliver paid results.

Make paid requests with HTTPX

Give HTTPX the payment transport for your chosen protocol. A free response returns normally. When the seller responds with a supported payment challenge, the transport obtains a credential through InFlow, waits for any required approval, and sends a paid retry. In the examples below, a failed paid retry stops instead of starting another purchase.

These functions use the Sandbox options above and return the resource text after checking the final HTTP status. Call them only for a destination you intend to pay. The MPP example selects the inflow charge method; x402 uses its default preference of balance, then exact. Read Choose payment options before accepting arbitrary seller offers.

import asyncio

import httpx

from inflowpay import ClientOptions
from inflowpay.mpp.buyer import BuyerMethod, payment_transport


async def fetch_mpp(options: ClientOptions, target: str) -> str:
    async with (
        BuyerMethod(options) as method,
        httpx.AsyncClient(
            transport=payment_transport([method]),
            follow_redirects=False,
            timeout=30.0,
        ) as http,
    ):
        async with asyncio.timeout(900):
            response = await http.get(target)
        response.raise_for_status()
        return response.text
import asyncio

import httpx
from x402.http.clients.httpx import x402AsyncTransport

from inflowpay import ClientOptions
from inflowpay.x402.buyer import Buyer


async def fetch_x402(options: ClientOptions, target: str) -> str:
    async with (
        await Buyer.create(options) as buyer,
        httpx.AsyncClient(
            transport=x402AsyncTransport(buyer),
            follow_redirects=False,
            timeout=30.0,
        ) as http,
    ):
        async with asyncio.timeout(900):
            response = await http.get(target)
        response.raise_for_status()
        return response.text

Call await fetch_mpp(options, target) or await fetch_x402(options, target) from your asynchronous application. Use asyncio.run at a standalone program’s entry point, not inside a running FastAPI application or another active event loop. Redirects are disabled so the paid request is not forwarded to another destination automatically.

A successful HTTP status confirms the resource response, not independent proof of settlement. The complete MPP buyer and x402 buyer examples also decode seller receipts when present. A free resource may not return a receipt; a missing receipt does not prove that no payment occurred.

Manage approvals and client lifetimes

Use async with to close SDK clients and HTTP connections when their work finishes. The buyer functions above own their clients for one request. A seller application must keep its clients open for the entire serving lifetime, not close them at the end of startup. The runnable servers below demonstrate that arrangement.

  • Allow time for a person to approve a purchase. ClientOptions.timeout defaults to 30 seconds per InFlow HTTP request, while buyer pending_timeout defaults to 900 seconds for waiting on a pending payment. The functions above separately allow 900 seconds for the resource request and its payment flow. HTTPX’s timeout=30.0 limits network operations; it is not the approval deadline.
  • If your application needs to show approval progress, x402’s buyer.prepare returns a payment with transaction_id, approval_id, status, await_payload and cancel. Supply the seller’s payment requirements and resource information. Preparing a payment does not send the final request for the resource. If you abandon this prepared flow, explicitly await its cancel() method; closing the buyer stops local waiting but does not cancel that approval. See Approvals and allowances for the owner’s part of this flow.
  • Let task cancellation propagate and close clients reliably. The automatic buyer flows above attempt to cancel a known pending approval if obtaining the payment credential fails or is cancelled. This cleanup has a five-second limit. It does not reverse a completed payment and cannot be guaranteed after the process is killed. After an uncertain result, follow Status and recovery before starting another purchase.

Handle InflowApiError from inflowpay for platform failures; it carries code, http_status, endpoint and request_id when available. Keep those details for diagnosis without logging keys or credentials. Protocol errors, HTTPX errors and TimeoutError are separate failures; do not assume every exception is an InFlow API response.

Run a Sandbox example

Install uv and clone the repository to run its complete examples. The setup installs the repository’s locked dependencies, including both protocols and the FastAPI server. You do not need this checkout merely to use the SDK in your application.

git clone --branch v0.3.2 https://github.com/inflowpayai/inflow-python.git
cd inflow-python
make sync

In the first terminal, set your Seller account’s Sandbox API key and start the MPP server:

export INFLOW_API_KEY='YOUR_SANDBOX_SELLER_API_KEY'
export MPP_SECRET_KEY="$(uv run python -c 'import secrets; print(secrets.token_hex(32))')"
uv run --locked python -m examples.mpp_seller

The example serves /api/widgets on port 3000 for 0.01 USDC, plus a free /free route. The generated secret is for this local run; use a stable stored secret in a deployed service. Although the resource server is local, payments and approvals use InFlow Sandbox.

Fund the buyer’s Sandbox balance with at least 0.01 USDC. Open Sandbox Deposit, select USDC and a network, and send test tokens to the displayed deposit address. Networks and currencies lists the faucets. Wait for the funds to appear in Sandbox Balances before continuing.

In a second terminal, open the same cloned repository, set the buyer’s Sandbox API key, and run:

export INFLOW_API_KEY='YOUR_SANDBOX_BUYER_API_KEY'
uv run --locked python -m examples.mpp_buyer

Approve the purchase in the Sandbox dashboard if requested. Expect HTTP 200, the widgets response and a decoded seller receipt. Check the payment in the dashboard as well. A successful request to the free route does not verify payment processing.

To test x402 instead, run this command in the Seller-key terminal:

uv run --locked python -m examples.x402_seller

Then run this command in the buyer-key terminal:

uv run --locked python -m examples.x402_buyer

The x402 server uses port 3001 and does not need MPP_SECRET_KEY. These programs read exported environment variables, not .env files. Stop and investigate an uncertain payment result before rerunning a buyer.

For additional integrations, see Subscriptions, External wallets and Trusted agent verification. The Python examples guide also covers optional MCP helpers and the standalone trusted-agent verifier. Use the Python examples for exact imports and supported features rather than translating another SDK’s function names.

Continue your integration

Accept a payment

Protect an endpoint and confirm its first paid response.

Make a payment

Complete a purchase with the intended account and payment option.