acpwebhook

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 15, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package acpwebhook sends ACP order lifecycle events to agent endpoints.

Sender signs each raw JSON body with HMAC-SHA256 and sets Merchant-Signature to "t=<unix_seconds>,v1=<hex_digest>". The signed payload is "timestamp.raw_body", as required by ACP 2026-04-17.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Address

type Address struct {
	// City City name
	City string `json:"city"`

	// Country ISO 3166-1 alpha-2 country code
	Country string `json:"country"`

	// LineOne Primary street address line
	LineOne string `json:"line_one"`

	// LineTwo Secondary address line (apartment, suite, etc.)
	LineTwo *string `json:"line_two,omitempty"`

	// Name Recipient name for this address
	Name string `json:"name"`

	// PostalCode Postal or ZIP code
	PostalCode string `json:"postal_code"`

	// State State or province code
	State string `json:"state"`
}

Address Physical address for shipping, billing, or pickup locations

type Adjustment

type Adjustment struct {
	// Amount Total amount credited to the buyer in minor currency units, inclusive of any applicable tax
	Amount *int `json:"amount,omitempty"`

	// Currency ISO 4217 currency code
	Currency *string `json:"currency,omitempty"`

	// Description Human-readable reason (e.g., 'Defective item')
	Description *string `json:"description,omitempty"`

	// Id Adjustment identifier
	Id string `json:"id"`

	// LineItems Which line items and quantities are affected (optional for order-level adjustments)
	LineItems *[]LineItemReference `json:"line_items,omitempty"`

	// OccurredAt RFC 3339 timestamp when this adjustment occurred
	OccurredAt time.Time `json:"occurred_at"`

	// Reason Structured reason code
	Reason *string `json:"reason,omitempty"`

	// Status Adjustment status. Implementations MUST accept unrecognized values gracefully. Defined values: 'pending', 'completed', 'failed'.
	Status string `json:"status"`

	// Type Type of adjustment. Implementations MUST accept unrecognized values gracefully. Defined values: 'refund', 'credit', 'return', 'exchange', 'price_adjustment', 'cancellation', 'dispute'. Use 'refund' for both full and partial refunds (distinguish by amount). 'credit' replaces 'store_credit'. 'dispute' covers chargebacks.
	Type string `json:"type"`
}

Adjustment A post-order change such as refund, credit, return, or dispute.

type Error

type Error struct {
	// Code Specific error code for programmatic handling
	Code string `json:"code"`

	// Message Human-readable error message
	Message string `json:"message"`

	// Param JSONPath of the offending field if applicable
	Param *string `json:"param,omitempty"`

	// Type High-level error category
	Type ErrorType `json:"type"`
}

Error defines model for Error.

type ErrorType

type ErrorType string

ErrorType High-level error category

const (
	InvalidRequest     ErrorType = "invalid_request"
	ProcessingError    ErrorType = "processing_error"
	ServiceUnavailable ErrorType = "service_unavailable"
)

Defines values for ErrorType.

func (ErrorType) Valid

func (e ErrorType) Valid() bool

Valid indicates whether the value is a known member of the ErrorType enum.

type EstimatedDelivery

type EstimatedDelivery struct {
	// Earliest RFC 3339 timestamp for earliest expected delivery
	Earliest time.Time `json:"earliest"`

	// Latest RFC 3339 timestamp for latest expected delivery
	Latest time.Time `json:"latest"`
}

EstimatedDelivery Estimated delivery date range for a fulfillment option

type EventDataOrder

type EventDataOrder struct {
	// Adjustments Post-order changes: refunds, credits, returns, disputes
	Adjustments *[]Adjustment `json:"adjustments,omitempty"`

	// CheckoutSessionId ID of the checkout session that created this order
	CheckoutSessionId string `json:"checkout_session_id"`

	// Confirmation Order confirmation details including order number and tracking information
	Confirmation *OrderConfirmation `json:"confirmation,omitempty"`

	// EstimatedDelivery Estimated delivery date range for a fulfillment option
	EstimatedDelivery *EstimatedDelivery `json:"estimated_delivery,omitempty"`

	// Fulfillments How items are being delivered (shipping, pickup, digital)
	Fulfillments *[]Fulfillment `json:"fulfillments,omitempty"`

	// Id Unique identifier for the order
	Id string `json:"id"`

	// LineItems What was ordered, with per-item fulfillment tracking
	LineItems *[]OrderLineItem `json:"line_items,omitempty"`

	// OrderNumber Human-readable order number for customer reference
	OrderNumber *string `json:"order_number,omitempty"`

	// PermalinkUrl Permanent URL where the customer can view order details
	PermalinkUrl string `json:"permalink_url"`

	// Status Order-level status. Implementations MUST accept unrecognized values gracefully. Defined values: 'created', 'confirmed', 'manual_review', 'processing', 'shipped', 'completed', 'canceled'. 'completed' means all items have been delivered/received regardless of fulfillment method. Distinct from LineItem.status 'fulfilled', which indicates the seller has dispatched the item.
	Status string `json:"status"`

	// Support Customer support contact information including email, phone, and URL
	Support *SupportInfo `json:"support,omitempty"`

	// Totals Order-level totals using the same Total schema as checkout. The 'total' entry is always the original charged amount. 'amount_refunded' tracks cumulative refunds.
	Totals *[]Total `json:"totals,omitempty"`

	// Type Discriminator field for webhook payloads. Always 'order' when present.
	Type EventDataOrderType `json:"type"`
}

EventDataOrder Order data included in webhook events. Uses the full Order schema from the checkout spec. The 'type' discriminator field is always 'order'.

type EventDataOrderType

type EventDataOrderType string

EventDataOrderType Discriminator field for webhook payloads. Always 'order' when present.

const (
	EventDataOrderTypeOrder EventDataOrderType = "order"
)

Defines values for EventDataOrderType.

func (EventDataOrderType) Valid

func (e EventDataOrderType) Valid() bool

Valid indicates whether the value is a known member of the EventDataOrderType enum.

type Fulfillment

type Fulfillment struct {
	// Carrier Carrier name (e.g., 'FedEx', 'UPS', 'USPS'). Applies to type: shipping.
	Carrier *string `json:"carrier,omitempty"`

	// Description Human-readable description (e.g., 'Backordered - ships Feb 15')
	Description *string `json:"description,omitempty"`

	// Destination Physical address for shipping, billing, or pickup locations
	Destination *Address `json:"destination,omitempty"`

	// DigitalDelivery Digital delivery details. Applies to type: digital.
	DigitalDelivery *struct {
		// AccessUrl URL to access digital content (download link, streaming page, etc.)
		AccessUrl *string `json:"access_url,omitempty"`

		// ExpiresAt When access expires (RFC 3339 timestamp)
		ExpiresAt *time.Time `json:"expires_at,omitempty"`

		// LicenseKey License or activation key
		LicenseKey *string `json:"license_key,omitempty"`
	} `json:"digital_delivery,omitempty"`

	// EstimatedDelivery Estimated delivery date range for a fulfillment option
	EstimatedDelivery *EstimatedDelivery `json:"estimated_delivery,omitempty"`

	// Events Append-only event log tracking fulfillment progress
	Events *[]FulfillmentEvent `json:"events,omitempty"`

	// Id Fulfillment identifier
	Id string `json:"id"`

	// LineItems Which line items and quantities are in this fulfillment
	LineItems *[]LineItemReference `json:"line_items,omitempty"`

	// Status Current fulfillment status. Implementations MUST accept unrecognized values gracefully. Defined values: 'pending', 'processing', 'shipped', 'in_transit', 'out_for_delivery', 'ready_for_pickup', 'delivered', 'failed', 'canceled'. Not all statuses apply to all types:
	// - shipping: pending, processing, shipped, in_transit, out_for_delivery, delivered, failed, canceled
	// - pickup: pending, processing, ready_for_pickup, delivered, failed, canceled
	// - digital: pending, processing, delivered, failed, canceled
	Status *string `json:"status,omitempty"`

	// TrackingNumber Carrier tracking number. Applies to type: shipping.
	TrackingNumber *string `json:"tracking_number,omitempty"`

	// TrackingUrl URL to track this shipment. Applies to type: shipping.
	TrackingUrl *string `json:"tracking_url,omitempty"`

	// Type Fulfillment method type
	Type FulfillmentType `json:"type"`
}

Fulfillment A fulfillment represents how items are delivered to the buyer (shipping, pickup, digital).

type FulfillmentEvent

type FulfillmentEvent struct {
	// Description Human-readable description (e.g., 'Left at front door')
	Description *string `json:"description,omitempty"`

	// Id Event identifier
	Id string `json:"id"`

	// Location Location where this event occurred (e.g., 'Memphis, TN')
	Location *string `json:"location,omitempty"`

	// OccurredAt RFC 3339 timestamp when this event occurred
	OccurredAt time.Time `json:"occurred_at"`

	// Type Event type. Implementations MUST accept unrecognized values gracefully. Defined values: 'processing', 'shipped', 'in_transit', 'out_for_delivery', 'ready_for_pickup', 'delivered', 'failed_attempt', 'returned_to_sender', 'canceled', 'undeliverable'. 'out_for_delivery' and 'ready_for_pickup' are ACP extensions for richer agent experiences.
	Type string `json:"type"`
}

FulfillmentEvent A point-in-time event in the fulfillment lifecycle.

type FulfillmentType

type FulfillmentType string

FulfillmentType Fulfillment method type

const (
	Digital  FulfillmentType = "digital"
	Pickup   FulfillmentType = "pickup"
	Shipping FulfillmentType = "shipping"
)

Defines values for FulfillmentType.

func (FulfillmentType) Valid

func (e FulfillmentType) Valid() bool

Valid indicates whether the value is a known member of the FulfillmentType enum.

type LineItemReference

type LineItemReference struct {
	// Id Line item ID reference
	Id string `json:"id"`

	// Quantity Quantity in this fulfillment or adjustment
	Quantity int `json:"quantity"`
}

LineItemReference Reference to a line item with quantity, used in fulfillments and adjustments

type Option

type Option func(*Sender)

Option configures a Sender.

func WithHTTPClient

func WithHTTPClient(client *http.Client) Option

WithHTTPClient overrides the HTTP client used to deliver webhook events.

type Order

type Order struct {
	// Adjustments Post-order changes: refunds, credits, returns, disputes
	Adjustments *[]Adjustment `json:"adjustments,omitempty"`

	// CheckoutSessionId ID of the checkout session that created this order
	CheckoutSessionId string `json:"checkout_session_id"`

	// Confirmation Order confirmation details including order number and tracking information
	Confirmation *OrderConfirmation `json:"confirmation,omitempty"`

	// EstimatedDelivery Estimated delivery date range for a fulfillment option
	EstimatedDelivery *EstimatedDelivery `json:"estimated_delivery,omitempty"`

	// Fulfillments How items are being delivered (shipping, pickup, digital)
	Fulfillments *[]Fulfillment `json:"fulfillments,omitempty"`

	// Id Unique identifier for the order
	Id string `json:"id"`

	// LineItems What was ordered, with per-item fulfillment tracking
	LineItems *[]OrderLineItem `json:"line_items,omitempty"`

	// OrderNumber Human-readable order number for customer reference
	OrderNumber *string `json:"order_number,omitempty"`

	// PermalinkUrl Permanent URL where the customer can view order details
	PermalinkUrl string `json:"permalink_url"`

	// Status Order-level status. Implementations MUST accept unrecognized values gracefully. Defined values: 'created', 'confirmed', 'manual_review', 'processing', 'shipped', 'completed', 'canceled'. 'completed' means all items have been delivered/received regardless of fulfillment method. Distinct from LineItem.status 'fulfilled', which indicates the seller has dispatched the item.
	Status *string `json:"status,omitempty"`

	// Support Customer support contact information including email, phone, and URL
	Support *SupportInfo `json:"support,omitempty"`

	// Totals Order-level totals using the same Total schema as checkout. The 'total' entry is always the original charged amount. 'amount_refunded' tracks cumulative refunds.
	Totals *[]Total `json:"totals,omitempty"`

	// Type Discriminator field for webhook payloads. Always 'order' when present.
	Type *OrderType `json:"type,omitempty"`
}

Order Order returned after checkout completion. Contains order details and optional rich post-purchase tracking (line items, fulfillments, adjustments).

type OrderConfirmation

type OrderConfirmation struct {
	// ConfirmationEmailSent Whether a confirmation email has been sent
	ConfirmationEmailSent *bool `json:"confirmation_email_sent,omitempty"`

	// ConfirmationNumber Order confirmation number
	ConfirmationNumber *string `json:"confirmation_number,omitempty"`

	// InvoiceNumber Invoice number if generated
	InvoiceNumber *string `json:"invoice_number,omitempty"`

	// ReceiptUrl URL to the order receipt
	ReceiptUrl *string `json:"receipt_url,omitempty"`
}

OrderConfirmation Order confirmation details including order number and tracking information

type OrderLineItem

type OrderLineItem struct {
	// Description Product description
	Description *string `json:"description,omitempty"`

	// Id Line item identifier, used for references in fulfillments and adjustments
	Id string `json:"id"`

	// ImageUrl Product image URL
	ImageUrl *string `json:"image_url,omitempty"`

	// ProductId Catalog product ID
	ProductId *string `json:"product_id,omitempty"`

	// Quantity Quantity tracking for an order line item. Uses a 3-field model: ordered (original), current (active after cancellations/returns), fulfilled (completed).
	Quantity OrderLineItemQuantity `json:"quantity"`

	// Status Derived from quantity fields. Implementations MUST accept unrecognized values gracefully. Defined values: 'processing', 'partial', 'fulfilled', 'removed'. Rules: 'removed' if current==0, 'fulfilled' if fulfilled==current, 'partial' if 0<fulfilled<current, 'processing' otherwise.
	Status *string `json:"status,omitempty"`

	// Subtotal Line total in minor currency units (quantity.ordered * unit_price)
	Subtotal *int `json:"subtotal,omitempty"`

	// Title Product name
	Title string `json:"title"`

	// Totals Optional line-item level totals breakdown using the same Total schema as checkout. Merchants who can provide richer breakdowns MAY use this alongside or instead of unit_price/subtotal.
	Totals *[]Total `json:"totals,omitempty"`

	// UnitPrice Price per unit in minor currency units (cents)
	UnitPrice *int `json:"unit_price,omitempty"`

	// Url Product page URL
	Url *string `json:"url,omitempty"`
}

OrderLineItem Per-line-item tracking of what was ordered and fulfillment progress.

type OrderLineItemQuantity

type OrderLineItemQuantity struct {
	// Current Current active quantity on the order. May be less than ordered due to cancellations or returns. A value of 0 means the line item has been fully removed.
	Current int `json:"current"`

	// Fulfilled Quantity that has been fulfilled (shipped, picked up, or digitally delivered). Applies to all fulfillment types, not just shipping.
	Fulfilled *int `json:"fulfilled,omitempty"`

	// Ordered Quantity originally ordered by the customer
	Ordered int `json:"ordered"`
}

OrderLineItemQuantity Quantity tracking for an order line item. Uses a 3-field model: ordered (original), current (active after cancellations/returns), fulfilled (completed).

type OrderType

type OrderType string

OrderType Discriminator field for webhook payloads. Always 'order' when present.

const (
	OrderTypeOrder OrderType = "order"
)

Defines values for OrderType.

func (OrderType) Valid

func (e OrderType) Valid() bool

Valid indicates whether the value is a known member of the OrderType enum.

type PostOrderEventsJSONRequestBody

type PostOrderEventsJSONRequestBody = WebhookEvent

PostOrderEventsJSONRequestBody defines body for PostOrderEvents for application/json ContentType.

type PostOrderEventsParams

type PostOrderEventsParams struct {
	// MerchantSignature t=<unix_seconds>,v1=<64_hex>. HMAC-SHA256(timestamp + "." + raw_body, secret). Return 401 if invalid.
	MerchantSignature string `json:"Merchant-Signature"`

	// RequestId Unique identifier for request tracking and debugging
	RequestId *string `json:"Request-Id,omitempty"`

	// Timestamp ISO 8601 timestamp for request timing validation
	Timestamp *time.Time `json:"Timestamp,omitempty"`

	// ContentType Must be application/json
	ContentType string `json:"Content-Type"`
}

PostOrderEventsParams defines parameters for PostOrderEvents.

type Sender

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

Sender delivers signed ACP order webhook events to an agent endpoint.

func NewSender

func NewSender(endpoint string, secret []byte, opts ...Option) (*Sender, error)

NewSender returns a webhook sender for an absolute HTTP(S) endpoint. It copies secret before returning.

Example
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
	"strings"

	"github.com/sumup/acp/acpwebhook"
)

func main() {
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		var event acpwebhook.WebhookEvent
		if err := json.NewDecoder(r.Body).Decode(&event); err != nil {
			panic(err)
		}
		fmt.Println(event.Type, strings.HasPrefix(r.Header.Get("Merchant-Signature"), "t="))
		w.WriteHeader(http.StatusNoContent)
	}))
	defer server.Close()

	sender, err := acpwebhook.NewSender(server.URL, []byte("webhook-secret"))
	if err != nil {
		panic(err)
	}
	err = sender.Send(context.Background(), acpwebhook.WebhookEvent{
		Type: "order_create",
		Data: acpwebhook.EventDataOrder{
			Type:              acpwebhook.EventDataOrderTypeOrder,
			Id:                "ord_123",
			CheckoutSessionId: "cs_123",
			PermalinkUrl:      "https://merchant.example/orders/ord_123",
		},
	})
	if err != nil {
		panic(err)
	}

}
Output:
order_create true

func (*Sender) Send

func (s *Sender) Send(ctx context.Context, event WebhookEvent) error

Send posts event using the ACP Merchant-Signature format. It returns an error for transport failures and non-2xx responses.

type SupportInfo

type SupportInfo struct {
	// Email Support contact email
	Email *openapi_types.Email `json:"email,omitempty"`

	// HelpCenterUrl URL to merchant's help center
	HelpCenterUrl *string `json:"help_center_url,omitempty"`

	// Hours Support hours of operation
	Hours *string `json:"hours,omitempty"`

	// Phone Support contact phone number
	Phone *string `json:"phone,omitempty"`
}

SupportInfo Customer support contact information including email, phone, and URL

type TaxBreakdownItem

type TaxBreakdownItem struct {
	// Amount Tax amount in minor currency units (e.g. 100 cents for $1.00 or 100 for ¥100)
	Amount int `json:"amount"`

	// Jurisdiction Tax jurisdiction name (e.g., 'California State Tax', 'City of San Francisco')
	Jurisdiction string `json:"jurisdiction"`

	// Rate Tax rate as a decimal (e.g., 0.0875 for 8.75%)
	Rate float32 `json:"rate"`
}

TaxBreakdownItem Breakdown of tax amounts by type, jurisdiction, or rate

type Total

type Total struct {
	// Amount Amount in minor currency units (e.g. 100 cents for $1.00 or 100 for ¥100)
	Amount int `json:"amount"`

	// Breakdown Detailed breakdown for tax totals
	Breakdown *[]TaxBreakdownItem `json:"breakdown,omitempty"`

	// Description Additional descriptive text for this total
	Description *string `json:"description,omitempty"`

	// DisplayText Localized display text for this total
	DisplayText string `json:"display_text"`

	// PresentmentAmount Amount in presentment currency minor units if different from settlement currency
	PresentmentAmount *int `json:"presentment_amount,omitempty"`

	// Type Type of total line item
	Type TotalType `json:"type"`
}

Total Total amounts for the checkout including subtotal, discounts, tax, shipping, and final total

type TotalType

type TotalType string

TotalType Type of total line item

const (
	TotalTypeAmountRefunded  TotalType = "amount_refunded"
	TotalTypeDiscount        TotalType = "discount"
	TotalTypeFee             TotalType = "fee"
	TotalTypeFulfillment     TotalType = "fulfillment"
	TotalTypeGiftWrap        TotalType = "gift_wrap"
	TotalTypeItemsBaseAmount TotalType = "items_base_amount"
	TotalTypeItemsDiscount   TotalType = "items_discount"
	TotalTypeStoreCredit     TotalType = "store_credit"
	TotalTypeSubtotal        TotalType = "subtotal"
	TotalTypeTax             TotalType = "tax"
	TotalTypeTip             TotalType = "tip"
	TotalTypeTotal           TotalType = "total"
)

Defines values for TotalType.

func (TotalType) Valid

func (e TotalType) Valid() bool

Valid indicates whether the value is a known member of the TotalType enum.

type WebhookEvent

type WebhookEvent struct {
	// Data The order object associated with this event
	Data EventDataOrder `json:"data"`

	// Type Event type. Implementations MUST accept unrecognized values gracefully. Defined values: 'order_create', 'order_update'. order_create for new orders, order_update for changes to existing orders.
	Type string `json:"type"`
}

WebhookEvent defines model for WebhookEvent.

Jump to

Keyboard shortcuts

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