Prices and offers
A price says what you charge. A payment offer tells the buyer how to pay that price. You can provide several payment options for the same purchase; the buyer chooses one.
Use this page after Accept MPP or Accept x402. Those guides connect payment handling to your endpoint. This page explains how to choose and check the terms you advertise.
Set the price for the result
Define what one payment buys before choosing an amount. For example, 0.01 USDC can buy one report for a selected company and date range.
For a quantity-based purchase, calculate the total before asking for payment. Three reports at 0.01 USDC each cost 0.03 USDC. Validate the quantity and available products in your application.
These are one-time purchases with a known total. They do not bill usage measured after execution. Recurring charges belong to Subscriptions.
Use the right amount format
Keep prices as decimal strings, such as 0.01, or use exact decimal arithmetic when calculating totals. Avoid binary floating-point calculations that can introduce rounding errors.
A payment request may use a decimal currency amount or an integer count of the asset’s smallest units. For a token with six decimal places, 0.01 tokens equals 10000 atomic units. The interface you call determines whether you supply the decimal price or the already-scaled amount.
| Interface | Amount you supply | Amount in the payment request |
|---|---|---|
| InFlow x402 Seller price helpers | 0.01 USDC | An integer amount derived from the configured asset or method precision. For a six-decimal on-chain asset: 10000. |
| MPP inflow charge requests | 0.01 with currency USDC | The decimal string 0.01. Do not convert this amount to token base units. |
| InFlow MPP Stripe Seller helpers | 1.00 USD | The helper converts dollars to cents: 100, with currency usd. |
The Stripe row applies to Go’s StripeOffer, Node.js’s stripe charge method, Python’s stripe_request, and Rust’s Seller::offer with Method::Stripe. It does not describe a manually constructed Stripe request.
Do not reuse one conversion rule for every MPP method. In particular, low-level Tempo requests use token base units. Use the selected method’s documented interface rather than copying an amount from another method.
The x402 price helpers accept up to eight decimal places, but each generated offer must also fit its asset or method precision. For a six-decimal asset, 0.0000001 is too small to represent exactly and causes an error. The helper does not silently round the price.
InFlow linked-card payments require at least 0.50 USD in whole cents. The Stripe Seller helpers accept 0.50 through 999999.99 USD, with at most two decimal places. A 0.01 USDC balance price cannot simply become a 0.01 USD card offer. Choose an eligible card price or offer a larger purchase.
Choose currencies deliberately
Name the currency you intend to accept. 0.01 USDC requests USDC offers, while $0.01 expresses a USD price to the x402 helper. A bare 0.01 needs the helper’s separate currency option.
For balance and blockchain offers, the x402 helpers can expand a USD price into the configured stablecoin currencies. If USDC and USDT are configured, a USD price can produce options for both. The helper keeps the same numeric price; it does not obtain an exchange rate or convert funds.
Fiat USD card payments are a separate choice. For x402, explicitly select the instrument scheme and a USD price. For MPP, select the intended method and, where applicable, the instrument rail within the inflow method.
The MPP stripe method is not the same as an inflow linked-card payment. Read Linked cards or Stripe payments for the account setup each requires.
Keep currency, network, asset, and recipient together as one payment option. The same token name on two networks does not make the payment destinations interchangeable.
Offer payment choices
Build options from your seller’s configuration. For x402, scheme and network filters narrow the generated offers. They do not enable a payment capability that your seller or facilitator lacks.
These functions build balance-only x402 offers for the report. Pass an initialized Seller client from Accept x402. Go and Rust also take the context or cancellation token used by your application.
package pricing
import (
"context"
"github.com/inflowpayai/inflow-go/x402/seller"
xhttp "github.com/x402-foundation/x402/go/v2/http"
)
func ReportOffers(ctx context.Context, client *seller.Client) ([]xhttp.PaymentOption, error) {
return client.Accepts(ctx, seller.AcceptsOptions{
Price: seller.PriceSpec{Amount: "0.01 USDC"},
Schemes: []string{"balance"},
})
}import {
inflowAccepts,
type InflowSellerClient,
} from '@inflowpayai/x402-seller';
export async function reportOffers(seller: InflowSellerClient) {
return inflowAccepts(seller, {
price: '0.01 USDC',
schemes: ['balance'],
});
}from x402.http.types import PaymentOption
from inflowpay.x402.seller import Seller
async def report_offers(seller: Seller) -> list[PaymentOption]:
return await seller.offers("0.01 USDC", schemes=["balance"])use inflow_x402_seller::{
CancellationToken, Error, OfferOptions, PaymentRequirements, Seller,
};
pub async fn report_offers(
seller: &Seller,
cancellation: &CancellationToken,
) -> Result<Vec<PaymentRequirements>, Error> {
let mut options = OfferOptions::new("0.01 USDC");
options.schemes = Some(vec!["balance".into()]);
seller.offers(&options, cancellation).await
}Each function returns offers, not a payment result. Check for an empty list and propagate configuration errors before advertising the paid route. Use the generated offers with the framework setup from Accept x402; these functions alone do not protect an endpoint.
If you offer several options, the buyer selects one compatible option. The options can differ in currency, network, or payment mechanism. They represent alternative ways to buy the result, not amounts the buyer must add together.
MPP describes choices with methods and intents, such as inflow and charge. x402 uses schemes, such as balance and exact. These identifiers are not interchangeable. Use Accept both protocols when exposing both formats.
Advertise only options you intend to accept. For example, offering both a balance payment and a linked-card payment also requires prices valid for both. The buyer’s preference and spending approval do not decide your seller’s price.
Calculate request-dependent prices
When the request selects products, quantities, or options, calculate the price from your application’s data. Treat those selections as input to validate, not as permission for the buyer to choose the total.
- Validate the selected product, quantity, options, and access permissions. Confirm the result is available before requesting payment.
- Look up the unit price in your catalog. Apply your pricing rules and calculate the total with exact arithmetic.
- Create the payment terms for that purchase. Retain enough information to recognize the same purchase when the buyer returns with payment.
- On the paid request, check the purchase details and payment terms before accepting payment or delivering the result.
For example, a payment for three reports should not authorize four reports. Matching the total alone is also insufficient when different products share a price.
Decide how long a quoted price remains valid. Your application can retain the agreed price for that purchase, or require fresh terms when the price changes. Do not silently charge a higher total or start a new payment while an earlier payment’s outcome is uncertain.
Use your existing order or quote record when the purchase must survive a price change or a retry. Creating that record does not automatically bind a payment to it. The seller must check the payment against the stored purchase details.
The SDKs and framework adapters do not all provide the same dynamic-pricing or request-body hooks. Follow the request-validation guidance in Accept MPP or Accept x402 before extending a fixed-price route. A signature over payment terms does not prove that every application parameter was checked.
Check the advertised terms
Inspect the actual unpaid response from your running endpoint. Verify what buyers receive, not just the price string passed to a helper.
- Confirm the amount and its units. Check the currency or asset, payment method or scheme, network where applicable, and recipient.
- Test a price that fits the asset precision and one that does not. Confirm that an unrepresentable price is rejected instead of rounded.
- Test a filter with no matching offers. Keep the endpoint unavailable for payment until it has a usable configuration.
- Test quantity limits and changes to the requested product. Confirm that the paid request still matches the purchase the buyer approved.
- Test a catalog price change between the unpaid and paid requests. Confirm that your chosen quote policy is applied without an unexpected extra charge.
Use the controlled Sandbox payment checks in Accept MPP or Accept x402 to verify the full purchase. Retain your project’s tests for pricing, permissions, payment failures, and delivery.
Continue your integration
Networks and currencies
Check supported assets and networks before expanding your payment options.
Accept both protocols
Offer MPP and x402 without charging twice for the same request.
Deliver paid results
Keep payment, fulfillment, and retries consistent for each purchase.