Documentation
¶
Overview ¶
Package webhooks provides webhook handling for QuickBooks Online.
This package supports parsing webhook payloads, verifying webhook signatures, and querying for changes using Change Data Capture (CDC).
Features ¶
- Webhook payload parsing
- HMAC-SHA256 signature verification
- Change Data Capture (CDC) queries
- Entity change tracking
Webhook Parsing ¶
payload, err := webhooks.Parse(requestBody)
if err != nil {
log.Fatal(err)
}
for _, change := range payload.AllChanges() {
fmt.Printf("%s %s was %s\n",
change.Name, change.ID, change.Operation)
}
Signature Verification ¶
Always verify webhook signatures before processing:
verifier := webhooks.NewVerifier(verifierToken)
payload, err := verifier.VerifyAndParse(requestBody, signature)
if err != nil {
// Invalid signature - reject the webhook
log.Fatal(err)
}
Change Data Capture ¶
Query for entity changes since a specific time:
cdcService := webhooks.NewCDCService(client)
response, err := cdcService.Query(ctx,
[]string{"Customer", "Invoice"},
time.Now().Add(-24*time.Hour),
)
var customers []entities.Customer
response.GetEntities("Customer", &customers)
Signature Header ¶
The webhook signature is sent in the "intuit-signature" HTTP header. Use SignatureHeader for the header name.
Package webhooks provides webhook parsing and verification for QuickBooks Online.
Index ¶
- Constants
- func ComputeSignatureBase64(payload []byte, verifierToken string) string
- func VerifySignature(payload []byte, signature, verifierToken string) error
- type CDCEntity
- type CDCQueryResponse
- type CDCResponse
- type CDCService
- type DataChangeEvent
- type EntityChange
- type EventNotification
- type Operation
- type Payload
- type Verifier
Constants ¶
const SignatureHeader = "intuit-signature"
SignatureHeader is the HTTP header name containing the webhook signature.
Variables ¶
This section is empty.
Functions ¶
func ComputeSignatureBase64 ¶
ComputeSignatureBase64 computes and returns the base64-encoded signature. This is useful for testing webhook endpoints.
func VerifySignature ¶
VerifySignature verifies the HMAC-SHA256 signature of a webhook payload. payload is the raw webhook request body. signature is the base64-encoded signature from the intuit-signature header. verifierToken is your webhook verifier token from Intuit Developer portal.
Types ¶
type CDCEntity ¶
type CDCEntity struct {
// ID is the entity ID.
ID string `json:"Id"`
// SyncToken is the sync token.
SyncToken string `json:"SyncToken"`
// Status is "Deleted" for deleted entities, otherwise empty.
Status string `json:"status,omitempty"`
// Domain indicates the entity type.
Domain string `json:"domain,omitempty"`
// RawData contains the full entity JSON.
RawData json.RawMessage `json:"-"`
}
CDCEntity represents an entity in a CDC response with deletion status.
type CDCQueryResponse ¶
type CDCQueryResponse struct {
// QueryResponse contains the actual entity data.
QueryResponse []json.RawMessage `json:"QueryResponse"`
}
CDCQueryResponse contains the query response for a single entity type.
type CDCResponse ¶
type CDCResponse struct {
// CDCResponse contains the query responses per entity type.
CDCResponse []CDCQueryResponse `json:"CDCResponse"`
// Time is when the response was generated.
Time string `json:"time,omitempty"`
}
CDCResponse represents the response from a CDC query.
func (*CDCResponse) GetDeletedIDs ¶
func (r *CDCResponse) GetDeletedIDs(entityType string) ([]string, error)
GetDeletedIDs returns the IDs of deleted entities of a specific type.
func (*CDCResponse) GetEntities ¶
func (r *CDCResponse) GetEntities(entityType string, result interface{}) error
GetEntities extracts entities of a specific type from the CDC response. entityType should match the entity name (e.g., "Customer"). The result slice should be a pointer to a slice of the entity type.
type CDCService ¶
type CDCService struct {
// contains filtered or unexported fields
}
CDCService provides Change Data Capture queries for QuickBooks Online.
func NewCDCService ¶
func NewCDCService(c *client.Client) *CDCService
NewCDCService creates a new CDC service.
func (*CDCService) Query ¶
func (s *CDCService) Query(ctx context.Context, entities []string, changedSince time.Time) (*CDCResponse, error)
Query queries for changes to the specified entities since the given time. entities should be a list of entity type names (e.g., "Customer", "Invoice"). changedSince should be the time to query changes from.
func (*CDCService) QuerySince ¶
func (s *CDCService) QuerySince(ctx context.Context, entities []string, since time.Duration) (*CDCResponse, error)
QuerySince queries for changes since a duration ago. This is a convenience method for Query.
type DataChangeEvent ¶
type DataChangeEvent struct {
// Entities is the list of changed entities.
Entities []EntityChange `json:"entities"`
}
DataChangeEvent contains information about changed entities.
type EntityChange ¶
type EntityChange struct {
// Name is the entity type name (e.g., "Customer", "Invoice").
Name string `json:"name"`
// ID is the entity ID.
ID string `json:"id"`
// Operation is the type of change (Create, Update, Delete, Merge, Void).
Operation Operation `json:"operation"`
// LastUpdated is when the entity was last updated (RFC3339 format).
LastUpdated string `json:"lastUpdated"`
// DeletedID is set for Merge operations, containing the ID of the deleted entity.
DeletedID string `json:"deletedId,omitempty"`
}
EntityChange represents a single entity change event.
func (*EntityChange) IsCreate ¶
func (e *EntityChange) IsCreate() bool
IsCreate returns true if this is a create operation.
func (*EntityChange) IsDelete ¶
func (e *EntityChange) IsDelete() bool
IsDelete returns true if this is a delete operation.
func (*EntityChange) IsMerge ¶
func (e *EntityChange) IsMerge() bool
IsMerge returns true if this is a merge operation.
func (*EntityChange) IsUpdate ¶
func (e *EntityChange) IsUpdate() bool
IsUpdate returns true if this is an update operation.
func (*EntityChange) IsVoid ¶
func (e *EntityChange) IsVoid() bool
IsVoid returns true if this is a void operation.
func (*EntityChange) LastUpdatedTime ¶
func (e *EntityChange) LastUpdatedTime() (time.Time, error)
LastUpdatedTime parses the LastUpdated string into a time.Time.
type EventNotification ¶
type EventNotification struct {
// RealmID is the company ID (realm) that generated the event.
RealmID string `json:"realmId"`
// DataChangeEvent contains the entity change details.
DataChangeEvent DataChangeEvent `json:"dataChangeEvent"`
}
EventNotification represents a single notification in a webhook payload.
type Operation ¶
type Operation string
Operation represents the type of entity change.
const ( // OpCreated indicates an entity was created. OpCreated Operation = "Create" // OpUpdated indicates an entity was updated. OpUpdated Operation = "Update" // OpDeleted indicates an entity was deleted. OpDeleted Operation = "Delete" // OpMerged indicates entities were merged. OpMerged Operation = "Merge" // OpVoided indicates a transaction was voided. OpVoided Operation = "Void" )
type Payload ¶
type Payload struct {
// EventNotifications contains the list of event notifications.
EventNotifications []EventNotification `json:"eventNotifications"`
}
Payload represents a QuickBooks Online webhook payload.
func (*Payload) AllChanges ¶
func (p *Payload) AllChanges() []EntityChange
AllChanges returns all entity changes from all notifications.
func (*Payload) GetChangesByEntity ¶
func (p *Payload) GetChangesByEntity() map[string][]EntityChange
GetChangesByEntity returns all changes grouped by entity type.
func (*Payload) GetChangesByOperation ¶
func (p *Payload) GetChangesByOperation() map[Operation][]EntityChange
GetChangesByOperation returns all changes grouped by operation type.
func (*Payload) GetChangesForRealm ¶
func (p *Payload) GetChangesForRealm(realmID string) []EntityChange
GetChangesForRealm returns all entity changes for a specific realm.
type Verifier ¶
type Verifier struct {
// contains filtered or unexported fields
}
Verifier provides webhook signature verification with a configured token.
func NewVerifier ¶
NewVerifier creates a new webhook verifier with the given token.