acp

package module
v0.0.0-...-a7b5525 Latest Latest
Warning

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

Go to latest
Published: Apr 6, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

README

Go SDK for the Agentic Commerce Protocol

Go Reference CI Status License

Go SDK for the Agentic Commerce Protocol (ACP). github.com/sumup/acp supports Agentic Checkout, Delegated Payment, and Product Feeds.

Examples

Checkout Sample
go run ./examples/checkout

Once the server is up, try exercising the flow with curl:

# Create a checkout session with two SKUs
curl -sS -X POST http://localhost:8080/checkout_sessions \
  -H 'Content-Type: application/json' \
  -d '{
        "line_items": [
          {"id": "latte"},
          {"id": "mug"}
        ],
        "currency": "EUR",
        "buyer": {
          "first_name": "Ava",
          "last_name": "Agent",
          "email": "ava.agent@example.com"
        }
      }'

# Complete the session once you have the id from the response above
curl -sS -X POST http://localhost:8080/checkout_sessions/<session_id>/complete \
  -H 'Content-Type: application/json' \
  -d '{
        "payment_data": {
          "provider": "sumup",
          "token": "pm_sample_token"
        }
      }'

Feel free to copy this sample into your own project and swap the in-memory store for your real product catalog, fulfillment rules, and payment hooks.

To see webhook delivery end-to-end, export the environment variables below before starting the sample server. The handler will POST an order_created event every time a checkout session completes.

export ACP_WEBHOOK_ENDPOINT="https://webhook.site/your-endpoint"
export ACP_WEBHOOK_HEADER="Merchant_Name-Signature"
export ACP_WEBHOOK_SECRET="super-secret"
go run ./examples/checkout
Delegated Payment Sample
go run ./examples/delegated_payment

Then call it with:

curl -sS -X POST http://localhost:8080/agentic_commerce/delegate_payment \
  -H 'Content-Type: application/json' \
  -d '{
        "payment_method": {
          "type": "card",
          "card_number_type": "fpan",
          "number": "4242424242424242",
          "exp_month": "11",
          "exp_year": "2026",
          "display_last4": "4242",
          "display_card_funding_type": "credit",
          "metadata": {"issuer": "demo-bank"}
        },
        "allowance": {
          "reason": "one_time",
          "max_amount": 2000,
          "currency": "EUR",
          "checkout_session_id": "cs_000001",
          "merchant_id": "demo-merchant",
          "expires_at": "2025-12-31T23:59:59Z"
        },
        "risk_signals": [
          {"type": "card_testing", "action": "manual_review", "score": 10}
        ],
        "metadata": {"source": "sample"}
      }'
Product Feed Sample
go run ./examples/feed

This writes compressed feed exports to examples/feed/output/product_feed.jsonl.gz and examples/feed/output/product_feed.csv.gz.

License

Apache 2.0

Documentation

Overview

Package acp documents the Go SDK for the Agentic Commerce Protocol (ACP). It aggregates the checkout and delegated payment packages under a single module so merchants and PSPs can share common helpers, models, and documentation.

Checkout

Use [NewCheckoutHandler] with your [CheckoutProvider] implementation to expose the ACP checkout contract over `net/http`. Handler options such as [WithSignatureVerifier] and [WithRequireSignedRequests] enforce the canonical JSON signatures and timestamp skew requirements spelled out in the spec.

Delegated Payment

Payment service providers can call [NewDelegatedPaymentHandler] with their own [DelegatedPaymentProvider] to accept delegate payment payloads, validate them, and emit vault tokens scoped to a checkout session. Helpers in the github.com/sumup/acp/acpauth package and [DelegatedPaymentWithSignatureVerifier] keep bearer-token authorization and signed requests in sync with ACP's security requirements.

How it works

  • Buyers check out using their preferred payment method and save it in ChatGPT.
  • The delegated payment payload is sent to the merchant’s PSP or vault directly. The delegated payment is single-use and set with allowances.
  • The PSP or vault returns a payment token scoped to the delegated payment outside of PCI scope.
  • OpenAI forwards the token during the complete-checkout call to enable the merchant to complete the transaction.

Index

Constants

View Source
const APIVersion = "2026-01-30"

APIVersion matches the published Agentic Commerce Protocol API. Emitted via the API-Version header on all HTTP responses returned by the handlers.

Variables

This section is empty.

Functions

func ContextWithRequestContext

func ContextWithRequestContext(ctx context.Context, requestCtx *RequestContext) context.Context

func ContextWithRequestContextFromRequest

func ContextWithRequestContextFromRequest(r *http.Request) (context.Context, error)

func WithInternal

func WithInternal(err error) errorOption

WithInternal sets an internal error that can be retrieved from Error for telemetry purposes.

func WithOffendingParam

func WithOffendingParam(jsonPath string) errorOption

WithOffendingParam sets the JSON path for the field that triggered the error.

func WithRetryAfter

func WithRetryAfter(d time.Duration) errorOption

WithRetryAfter specifies how long clients should wait before retrying.

func WithStatusCode

func WithStatusCode(status int) errorOption

WithStatusCode overrides the HTTP status code returned to the client.

func WithSupportedVersions

func WithSupportedVersions(versions []string) errorOption

WithSupportedVersions sets the supported protocol versions returned to clients.

Types

type Error

type Error struct {
	Type              ErrorType `json:"type"`
	Code              ErrorCode `json:"code"`
	Message           string    `json:"message"`
	Param             *string   `json:"param,omitempty"`
	SupportedVersions []string  `json:"supported_versions,omitempty"`

	Internal error `json:"-"`
	// contains filtered or unexported fields
}

Error represents a structured ACP error payload.

func NewHTTPError

func NewHTTPError(status int, typ ErrorType, code ErrorCode, message string, opts ...errorOption) *Error

NewHTTPError allows callers to control the status code explicitly.

func NewInvalidRequestError

func NewInvalidRequestError(message string, opts ...errorOption) *Error

NewInvalidRequestError builds a Bad Request ACP error payload.

func NewProcessingError

func NewProcessingError(message string, opts ...errorOption) *Error

NewProcessingError builds an Internal Server Error ACP error payload.

func NewRateLimitExceededError

func NewRateLimitExceededError(message string, opts ...errorOption) *Error

NewRateLimitExceededError builds a Too Many Requests ACP error payload.

func NewServiceUnavailableError

func NewServiceUnavailableError(message string, opts ...errorOption) *Error

NewServiceUnavailableError builds a Service Unavailable ACP error payload.

func (*Error) Error

func (e *Error) Error() string

Error makes *Error satisfy the stdlib error interface.

func (*Error) RetryAfter

func (e *Error) RetryAfter() time.Duration

RetryAfter returns the duration clients should wait before retrying.

func (*Error) StatusCode

func (e *Error) StatusCode() int

StatusCode returns the HTTP status associated with the error.

type ErrorCode

type ErrorCode string

ErrorCode is a machine-readable identifier for the specific failure.

const (
	DuplicateRequest       ErrorCode = "duplicate_request"        // Safe duplicate with the same idempotency key.
	IdempotencyConflict    ErrorCode = "idempotency_conflict"     // Same idempotency key but different parameters.
	IdempotencyKeyRequired ErrorCode = "idempotency_key_required" // Idempotency-Key header is missing.
	IdempotencyInFlight    ErrorCode = "idempotency_in_flight"    // Request with same idempotency key is still processing.
	InvalidCard            ErrorCode = "invalid_card"             // Credential failed basic validation (such as length or expiry).
	InvalidSignature       ErrorCode = "invalid_signature"        // Signature is missing or does not match the payload.
	SignatureRequired      ErrorCode = "signature_required"       // Signed requests are required but headers were missing.
	StaleTimestamp         ErrorCode = "stale_timestamp"          // Timestamp skew exceeded the allowed window.
	MissingAuthorization   ErrorCode = "missing_authorization"    // Authorization header missing.
	InvalidAuthorization   ErrorCode = "invalid_authorization"    // Authorization header malformed or API key invalid.
	RequestNotIdempotent   ErrorCode = "request_not_idempotent"
	TooManyRequests        ErrorCode = "too_many_requests"
)

type ErrorType

type ErrorType string

ErrorType mirrors the ACP error.type field.

const (
	InvalidRequest ErrorType = "invalid_request" // Missing or malformed field.
	// Deprecated: use invalid_request + code idempotency_conflict/idempotency_key_required/idempotency_in_flight.
	RequestNotIdempotentType ErrorType = "request_not_idempotent" // Idempotency violation.
	ProcessingError          ErrorType = "processing_error"       // Downstream gateway or network failure.
	RateLimitExceeded        ErrorType = "rate_limit_exceeded"    // Too many requests.
	ServiceUnavailable       ErrorType = "service_unavailable"    // Temporary outage or maintenance.
)

type RequestContext

type RequestContext struct {
	// API Key used to make requests.
	//
	// Example: Bearer api_key_123
	Authorization string
	// The preferred locale for content like messages and errors.
	//
	// Example: en-US
	AcceptLanguage string
	// Information about the client making this request.
	//
	// Example: ChatGPT/2.0 (Mac OS X 15.0.1; arm64; build 0)
	UserAgent string
	// Key used to ensure requests are idempotent.
	//
	// Example: idempotency_key_123
	IdempotencyKey string
	// Unique key for each request for tracing purposes.
	//
	// Example: request_id_123
	RequestID string
	// Base64 encoded signature of the request body.
	//
	// Example: eyJtZX...
	Signature string
	// Formatted as an RFC 3339 string.
	//
	// Example: 2025-09-25T10:30:00Z
	Timestamp string
	// API version.
	//
	// Example: 2026-01-30
	APIVersion string
}

RequestContext carries the standard ACP headers.

func RequestContextFromContext

func RequestContextFromContext(ctx context.Context) *RequestContext

RequestContextFromContext extracts the HTTP request metadata previously stored in the context.

func RequestContextFromRequest

func RequestContextFromRequest(r *http.Request) (*RequestContext, error)

Directories

Path Synopsis
Package acpcheckout provides primitives to interact with the openapi HTTP API.
Package acpcheckout provides primitives to interact with the openapi HTTP API.
Package acppayment provides primitives to interact with the openapi HTTP API.
Package acppayment provides primitives to interact with the openapi HTTP API.
examples
checkout command
feed command
Package feed provides types and helpers for exporting [ACP product feeds].
Package feed provides types and helpers for exporting [ACP product feeds].
internal
srv

Jump to

Keyboard shortcuts

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