Go
Use the InFlow Go SDK to accept payments in your HTTP service or make paid requests from your application. The SDK provides buyer and seller packages for MPP and x402 in one Go module.
Install the SDK
Use Go 1.26 or later. Run this command in your application’s Go module:
go get github.com/inflowpayai/inflow-go@v0.3.2
All InFlow Go packages share one module version. Import only the packages your application needs; you do not need to clone the repository to use the SDK. Clone it when you want to run or adapt the complete examples below.
Choose your packages
A seller accepts payment for a resource. A buyer requests and pays for that resource. Choose packages for your application’s role and payment protocol; an application can use both roles.
| Package | Use it to |
|---|---|
| mpp/buyer | Make MPP requests and obtain payment credentials through InFlow. |
| mpp/seller | Offer MPP payments and protect HTTP handlers. |
| x402/buyer | Make x402 requests with InFlow-managed payments or a configured external wallet. |
| x402/seller | Build seller offers and connect x402 middleware to InFlow’s facilitator. |
Each path above follows github.com/inflowpayai/inflow-go/. The root package contains shared configuration and API error types. The mpp and x402 packages contain protocol types and helpers. Use import aliases such as mppbuyer and x402buyer to distinguish packages named buyer.
Configure your application
Create your account and API key as described in Accounts and environments. Accepting payments requires a Seller account. A buyer can use a Developer or Seller account. Use a key from the same environment as the client.
Read INFLOW_API_KEY from your application’s environment or secret store and pass it to the constructor. The SDK does not load that variable automatically. These functions create separate Sandbox buyers; use whichever protocol your application needs.
package payments
import (
inflow "github.com/inflowpayai/inflow-go"
mppbuyer "github.com/inflowpayai/inflow-go/mpp/buyer"
x402buyer "github.com/inflowpayai/inflow-go/x402/buyer"
)
func NewMPPBuyer(apiKey string) (*mppbuyer.Client, error) {
return mppbuyer.New(mppbuyer.Options{Options: inflow.Options{
APIKey: apiKey, Environment: inflow.Sandbox,
}})
}
func NewX402Buyer(apiKey string) (*x402buyer.Client, error) {
return x402buyer.New(x402buyer.Options{Options: inflow.Options{
APIKey: apiKey, Environment: inflow.Sandbox,
}})
}Seller constructors also receive inflow.Options. Set Environment explicitly: the default is production. Constructors do not contact InFlow; network operations happen when you load configuration or use the client. Keep API keys on your server, not in browser code or logs.
An MPP seller also needs a private challenge-signing secret. This secret binds payment challenges to your service; it is separate from the InFlow API key. Keep it consistent across your service instances so they can accept each other’s challenges.
Accept payments in a Go service
Both seller integrations work with net/http. Keep your business logic in an HTTP handler and configure payment protection around the paid route. Load seller configuration before accepting traffic so a rejected key or unavailable payment option fails during startup.
- For MPP, create the seller client and call Load. Define the route’s offers and challenge settings, then pass the route and handler to Protect. Payment processing completes before the protected handler runs. The MPP seller example shows startup checks, distinct route bindings and a free endpoint.
- For x402, build offers and scheme registrations from the seller client. Connect NewFacilitator to the upstream x402 HTTP server, initialize it, and wrap your handler with its net/http middleware. The x402 seller example supplies the complete wiring. That example verifies before the handler and settles a successful response before releasing it.
Payment protection and application authentication have separate jobs. Keep your existing access checks where the service needs them. A payment does not establish the caller’s account or make application changes reversible. Read Understand verification and settlement and Deliver paid results before adding handlers with side effects.
Make payments from Go
Use the buyer’s Do method to request an HTTP resource and respond to a supported payment challenge. The buyer waits for approval when required, then sends one paid retry. A free response returns without a payment. A second 402 returns to your application rather than starting another purchase.
This function uses the MPP client configured above. Call it only for a destination you intend to pay, with a context that allows time for any required approval. It uses the helper’s default offer selection; see Choose payment options when your application needs tighter selection rules.
package payments
import (
"context"
"fmt"
"io"
"net/http"
mppbuyer "github.com/inflowpayai/inflow-go/mpp/buyer"
)
func FetchMPP(ctx context.Context, client *mppbuyer.Client,
target string, output io.Writer) error {
request, err := http.NewRequestWithContext(ctx, http.MethodGet, target, nil)
if err != nil {
return err
}
response, err := client.Do(request, mppbuyer.PaymentOptions{})
if err != nil {
return err
}
defer response.Body.Close()
if response.StatusCode < 200 || response.StatusCode >= 300 {
return fmt.Errorf("resource returned HTTP %d; check the payment before retrying",
response.StatusCode)
}
_, err = io.Copy(output, response.Body)
return err
}The function checks the final HTTP status and copies the resource body to the supplied writer. That establishes delivery, not independent proof of settlement. The complete buyer examples also decode seller receipts. For x402, call its buyer’s Do with x402buyer.SignOptions{}; see the x402 buyer example.
Use Prepare and the returned payment’s Wait when your application needs to retain the transaction and approval identifiers. This lets you display approval progress and manage waiting explicitly. These methods operate on the seller’s payment challenge or requirements; they do not replace the final HTTP request. Approvals and allowances explains the owner’s role.
Handle requests and errors
Pass a context through each operation and close each returned response body. The shared Timeout defaults to 30 seconds for an HTTP attempt. Buyer WaitTimeout defaults to 15 minutes for approval waiting. An earlier caller deadline can stop either operation; a short request deadline can also prevent a person from completing approval.
- For POST requests, provide a replayable body through Request.GetBody. Go sets it when http.NewRequestWithContext receives a *strings.Reader, *bytes.Reader or *bytes.Buffer. Both buyers check replayability before starting payment. They return ErrBodyNotReplayable if the body cannot be sent again.
- The buyer HTTP helpers do not follow redirects. MPP uses the Authorization header for payment, so its helper rejects an existing application authorization header. Use a separate application header or cookie, as described in Pay with MPP.
- Use errors.As to inspect *inflow.APIError or the protocol buyer’s *Error type. API errors carry a code, HTTP status and request identifier when available. Keep those identifiers for diagnosis, but do not log API keys or payment credentials. Not every error is an API error; preserve other errors rather than assuming a type assertion will succeed.
Cancellation behavior differs between the prepared payment flows. An MPP wait failure ends that payment handle and attempts to cancel its approval. An x402 prepared wait can resume on the same handle after a timeout; call Cancel if you want to abandon it. The one-shot x402 Sign path used by Do attempts approval cleanup after a failed wait instead. None of these operations refunds a completed payment.
After a network failure, retain the transaction identifier and check Status and recovery before creating another payment. A timeout tells you that the call did not complete as expected; it does not establish that no money moved.
Run an example
The InFlow Go examples include separate MPP and x402 buyers and sellers, plus a trusted agent verifier. Payment examples run the seller locally but use InFlow Sandbox for configuration, approvals and payment processing. They are not a simulated payment platform.
git clone --branch v0.3.2 https://github.com/inflowpayai/inflow-go.git cd inflow-go go mod download
For an MPP test, use two terminals in the cloned repository. In the first, set the Seller account’s Sandbox key and start the seller:
export INFLOW_API_KEY='YOUR_SANDBOX_SELLER_API_KEY' export MPP_SECRET_KEY="$(openssl rand -hex 32)" go run ./examples/mpp-seller
This generates a signing secret for the local example. In a deployed service, store a stable secret instead. The seller listens on port 3000. An unpaid request to /api/widgets returns a 402 challenge for 0.01 USDC.
Fund the buyer’s Sandbox balance with at least 0.01 USDC before continuing. Open Sandbox Deposit, select USDC and a network, and send test assets to the displayed deposit address. The Networks and currencies page links to test-token faucets. Wait for the funds to appear in Sandbox Balances. In the second terminal, set the buyer’s key and run:
export INFLOW_API_KEY='YOUR_SANDBOX_BUYER_API_KEY' go run ./examples/mpp-buyer
Keep the Sandbox dashboard available to approve the payment if requested. The buyer prints the HTTP status, resource body and decoded seller receipt when supplied. Check the resource and the payment in your dashboard. A successful unpaid response alone does not test payment processing.
To test x402, use the x402 seller commands and x402 buyer commands. That seller uses port 3001. The examples read exported shell variables, not .env files. Stop and investigate an uncertain payment result before rerunning a buyer.
Add the features your application needs
- Subscriptions: Go supports InFlow MPP subscription offers, purchases and authorization under an existing subscription. The MPP examples include a separate subscription endpoint; choosing it starts a recurring purchase, not the 0.01 USDC widgets charge.
- External wallets: configure an x402 signer when your application pays from its own blockchain wallet. This is separate from spending an InFlow-managed balance.
- Trusted agent verification: the optional tap/seller package verifies signed requests independently of payment. The verifier example does not require an InFlow API key.
Go’s MPP integration supports HTTP requests, not MPP-over-MCP. Check the Go SDK reference when adapting an example from another language; helper APIs and optional integrations differ.
Continue your integration
Accept a payment
Protect an endpoint and confirm its first paid response.
Make a payment
Complete a purchase from a buyer application with the intended account and payment option.