server

package
v0.0.0-...-ae40238 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 16, 2026 License: MIT, Apache-2.0, MIT Imports: 8 Imported by: 0

Documentation

Overview

Package server provides the generic challenge-or-verify flow for Payment authentication on the server side.

Examples import this package by its bare name. The Tempo charge package uses the alias `charge`, so there is no conflict.

Package server provides the server-side MPP payment handler.

It implements the HTTP 402 challenge/credential flow: when a request arrives without payment credentials, it returns a 402 with a WWW-Authenticate challenge. When valid credentials are provided, it verifies them and returns a receipt.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ChargeMiddleware

func ChargeMiddleware(m *Mpp, params ChargeParams) func(http.Handler) http.Handler

ChargeMiddleware creates an http.Handler middleware for the charge intent.

It calls Mpp.Charge with the provided ChargeParams, injects the incoming Authorization header automatically, returns a 402 challenge when payment is required, and stores the verified Credential and Receipt in the request context on success.

func CredentialFromContext

func CredentialFromContext(ctx context.Context) *mpp.Credential

CredentialFromContext extracts the Credential from the request context.

func DetectRealm

func DetectRealm() string

DetectRealm auto-detects the server realm from environment variables. It checks MPP_REALM, FLY_APP_NAME, HEROKU_APP_NAME, RAILWAY_PUBLIC_DOMAIN, RENDER_EXTERNAL_HOSTNAME, VERCEL_URL, WEBSITE_HOSTNAME, HOST, and HOSTNAME in that order. Returns "MPP Payment" if none are set.

func DetectSecretKey

func DetectSecretKey() (string, error)

DetectSecretKey reads the MPP_SECRET_KEY environment variable. Returns an error if it is not set.

func ReceiptFromContext

func ReceiptFromContext(ctx context.Context) *mpp.Receipt

ReceiptFromContext extracts the Receipt from the request context.

Types

type ChargeParams

type ChargeParams struct {
	// Authorization is the incoming Authorization header value.
	Authorization string
	// Amount is the human-readable charge amount.
	Amount string
	// Currency overrides the method's default currency.
	Currency string
	// Recipient overrides the method's default recipient.
	Recipient string
	// ExternalID is copied into the request and echoed back in the Receipt.
	ExternalID string
	// Expires overrides the default Challenge expiry.
	Expires string
	// Description is exposed in the server-generated Challenge.
	Description string
	// Memo sets a Tempo transfer memo when the method supports it.
	Memo string
	// Splits adds Tempo split-payment transfers under methodDetails.splits.
	Splits []tempo.SplitParams
	// FeePayer requests the sponsored Tempo flow when the method supports it.
	FeePayer bool
	// FeePayerURL points at a remote fee-payer signer.
	FeePayerURL string
	// SupportedModes advertises the Tempo submission modes allowed for this challenge.
	SupportedModes []tempo.ChargeMode
	// ChainID overrides the method's default Tempo chain ID.
	ChainID int
	// Meta stores opaque Challenge metadata.
	Meta map[string]string
}

ChargeParams contains the parameters for a charge operation.

type ChargeRequestBuilder

type ChargeRequestBuilder interface {
	BuildChargeRequest(params ChargeParams) (map[string]any, error)
}

ChargeRequestBuilder lets a method provide a canonical request shape for the generic charge helper. Tempo uses this to normalize human amounts and nest method-specific fields under methodDetails.

type ChargeResult

type ChargeResult struct {
	// Challenge is returned when the client still needs to satisfy the payment.
	Challenge *mpp.Challenge
	// Credential is the verified client credential on success.
	Credential *mpp.Credential
	// Receipt acknowledges a successfully verified payment.
	Receipt *mpp.Receipt
}

ChargeResult is either a Challenge or a verified (Credential, Receipt) pair.

func (*ChargeResult) IsChallenge

func (r *ChargeResult) IsChallenge() bool

IsChallenge returns true if the result is a 402 challenge.

type Intent

type Intent interface {
	Name() string
	Verify(ctx context.Context, credential *mpp.Credential, request map[string]any) (*mpp.Receipt, error)
}

Intent is the interface for payment intents (server-side verification).

type Method

type Method interface {
	Name() string
	Intents() map[string]Intent
}

Method is the interface for server-side payment methods.

type Mpp

type Mpp struct {
	// contains filtered or unexported fields
}

Mpp is the server-side payment handler.

func New

func New(method Method, realm, secretKey string) *Mpp

New creates an Mpp instance.

func (*Mpp) Charge

func (m *Mpp) Charge(ctx context.Context, params ChargeParams) (*ChargeResult, error)

Charge handles a charge intent with human-readable amounts.

type VerifyParams

type VerifyParams struct {
	// Authorization is the incoming Authorization header value.
	Authorization string
	// Intent verifies Credentials for this request.
	Intent Intent
	// Request is the canonical request shape the Challenge binds to.
	Request map[string]any
	// Realm is the expected server realm.
	Realm string
	// SecretKey signs and verifies Challenge IDs.
	SecretKey string
	// Method is the payment method token, for example "tempo".
	Method string
	// Description is copied into a newly issued Challenge.
	Description string
	// Meta stores opaque Challenge metadata.
	Meta map[string]string
	// Expires overrides the default Challenge expiry.
	Expires string
}

VerifyParams contains the parameters for VerifyOrChallenge.

type VerifyResult

type VerifyResult struct {
	// Challenge is returned when the server needs the client to pay first.
	Challenge *mpp.Challenge
	// Credential is the parsed client credential on success.
	Credential *mpp.Credential
	// Receipt acknowledges successful verification.
	Receipt *mpp.Receipt
}

VerifyResult is either a Challenge or a verified (Credential, Receipt) pair.

func VerifyOrChallenge

func VerifyOrChallenge(ctx context.Context, params VerifyParams) (*VerifyResult, error)

VerifyOrChallenge checks for a valid payment credential or generates a new challenge. Returns a Challenge if payment is required, or (Credential, Receipt) if verified.

Logic:

  1. If no authorization header, create new challenge
  2. Extract "Payment" scheme from Authorization header
  3. Parse credential
  4. Recompute expected challenge ID from echoed parameters via HMAC
  5. Constant-time compare IDs
  6. Verify echoed fields match (realm, method, intent name, request)
  7. Check expiry
  8. Call intent.Verify
  9. Return result

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL