Go SDK

The official Go SDK for Unified Commerce Platform. Built with idiomatic Go patterns, featuring context-aware operations, structured error handling, and comprehensive test coverage.

Version: 1.5.2 | License: MIT | Go: 1.21+ | Module: github.com/unified-commerce/go-sdk

Installation

Install the SDK using Go modules:

# Using go get
go get github.com/unified-commerce/go-sdk

# Or add to go.mod
require github.com/unified-commerce/go-sdk v1.5.2

Requirements

  • Go 1.21 or higher
  • Go modules enabled

Optional Packages

# GraphQL support
go get github.com/unified-commerce/go-sdk/graphql

# Webhook utilities
go get github.com/unified-commerce/go-sdk/webhooks

# Testing utilities
go get github.com/unified-commerce/go-sdk/testing

Quick Start

Basic Setup

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    unifiedcommerce "github.com/unified-commerce/go-sdk"
)

func main() {
    // Initialize the client
    client := unifiedcommerce.NewClient(
        unifiedcommerce.WithAPIKey(os.Getenv("UNIFIED_COMMERCE_API_KEY")),
        unifiedcommerce.WithEnvironment("production"),
    )

    // Create a context
    ctx := context.Background()

    // Query products
    products, err := client.Products.List(ctx, &unifiedcommerce.ProductListParams{
        Category: unifiedcommerce.String("electronics"),
        Limit:    unifiedcommerce.Int64(10),
    })

    if err != nil {
        log.Fatalf("Error fetching products: %v", err)
    }

    for _, product := range products.Data {
        fmt.Printf("%s: $%.2f\n", product.Name, product.Price)
    }
}

Using Context

import (
    "context"
    "time"
)

func fetchProducts() error {
    // Create context with timeout
    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()

    // All SDK methods accept context
    products, err := client.Products.List(ctx, &unifiedcommerce.ProductListParams{
        Limit: unifiedcommerce.Int64(100),
    })

    if err != nil {
        return fmt.Errorf("failed to fetch products: %w", err)
    }

    return nil
}

Configuration

Client Options

import (
    unifiedcommerce "github.com/unified-commerce/go-sdk"
)

// Create client with custom configuration
client := unifiedcommerce.NewClient(
    // Required: API key
    unifiedcommerce.WithAPIKey("uc_live_xxxxxxxxxxxxx"),

    // Environment: production or sandbox
    unifiedcommerce.WithEnvironment("production"),

    // Custom API URL
    unifiedcommerce.WithAPIURL("https://api.custom-domain.com"),

    // Request timeout
    unifiedcommerce.WithTimeout(60 * time.Second),

    // Maximum retry attempts
    unifiedcommerce.WithMaxRetries(5),

    // Custom HTTP client
    unifiedcommerce.WithHTTPClient(&http.Client{
        Timeout: 30 * time.Second,
    }),

    // Enable debug mode
    unifiedcommerce.WithDebug(true),

    // Custom headers
    unifiedcommerce.WithHeaders(map[string]string{
        "X-Custom-Header": "value",
    }),

    // Custom user agent
    unifiedcommerce.WithUserAgent("MyApp/1.0"),
)

Configuration Struct

// Alternative: using configuration struct
config := &unifiedcommerce.Config{
    APIKey:      os.Getenv("UNIFIED_COMMERCE_API_KEY"),
    Environment: "production",
    Timeout:     60 * time.Second,
    MaxRetries:  5,
    Debug:       true,
}

client := unifiedcommerce.NewClientWithConfig(config)

Environment Variables

// Load from environment
client := unifiedcommerce.NewClient(
    unifiedcommerce.WithAPIKey(os.Getenv("UNIFIED_COMMERCE_API_KEY")),
    unifiedcommerce.WithEnvironment(os.Getenv("UNIFIED_COMMERCE_ENV")),
)

// Using .env file
import "github.com/joho/godotenv"

func init() {
    if err := godotenv.Load(); err != nil {
        log.Fatal("Error loading .env file")
    }
}

Authentication

API Key Authentication

import (
    "context"
    unifiedcommerce "github.com/unified-commerce/go-sdk"
)

// Method 1: Via client initialization
client := unifiedcommerce.NewClient(
    unifiedcommerce.WithAPIKey("uc_live_xxxxxxxxxxxxx"),
)

// Method 2: From environment variable
client := unifiedcommerce.NewClient(
    unifiedcommerce.WithAPIKey(os.Getenv("UNIFIED_COMMERCE_API_KEY")),
)

// Method 3: Via context
ctx := unifiedcommerce.WithAPIKey(context.Background(), "different_api_key")
products, err := client.Products.List(ctx, params)

Request Signing

// Enable request signing for enhanced security
client := unifiedcommerce.NewClient(
    unifiedcommerce.WithAPIKey(os.Getenv("UNIFIED_COMMERCE_API_KEY")),
    unifiedcommerce.WithRequestSigning(true),
    unifiedcommerce.WithSigningSecret(os.Getenv("SIGNING_SECRET")),
)

Core Concepts

Products

import (
    "context"
    unifiedcommerce "github.com/unified-commerce/go-sdk"
)

func manageProducts(client *unifiedcommerce.Client) error {
    ctx := context.Background()

    // List products with filters
    products, err := client.Products.List(ctx, &unifiedcommerce.ProductListParams{
        Category:  unifiedcommerce.String("electronics"),
        MinPrice:  unifiedcommerce.Float64(100),
        MaxPrice:  unifiedcommerce.Float64(1000),
        InStock:   unifiedcommerce.Bool(true),
        Limit:     unifiedcommerce.Int64(20),
        Offset:    unifiedcommerce.Int64(0),
        SortBy:    unifiedcommerce.String("price"),
        SortOrder: unifiedcommerce.String("asc"),
    })
    if err != nil {
        return fmt.Errorf("list products: %w", err)
    }

    // Get a single product
    product, err := client.Products.Get(ctx, "product-123")
    if err != nil {
        return fmt.Errorf("get product: %w", err)
    }

    // Create a product
    newProduct, err := client.Products.Create(ctx, &unifiedcommerce.ProductCreateParams{
        Name:        unifiedcommerce.String("Wireless Headphones"),
        Description: unifiedcommerce.String("Premium noise-cancelling headphones"),
        Price:       unifiedcommerce.Float64(299.99),
        Category:    unifiedcommerce.String("electronics"),
        SKU:         unifiedcommerce.String("WH-1000XM5"),
        Inventory: &unifiedcommerce.InventoryParams{
            Quantity:       unifiedcommerce.Int64(100),
            TrackInventory: unifiedcommerce.Bool(true),
        },
    })
    if err != nil {
        return fmt.Errorf("create product: %w", err)
    }

    // Update a product
    updated, err := client.Products.Update(ctx, "product-123", &unifiedcommerce.ProductUpdateParams{
        Price: unifiedcommerce.Float64(279.99),
        Inventory: &unifiedcommerce.InventoryParams{
            Quantity: unifiedcommerce.Int64(150),
        },
    })
    if err != nil {
        return fmt.Errorf("update product: %w", err)
    }

    // Delete a product
    err = client.Products.Delete(ctx, "product-123")
    if err != nil {
        return fmt.Errorf("delete product: %w", err)
    }

    return nil
}

Orders

func manageOrders(client *unifiedcommerce.Client) error {
    ctx := context.Background()

    // Create an order
    order, err := client.Orders.Create(ctx, &unifiedcommerce.OrderCreateParams{
        Items: []*unifiedcommerce.OrderItemParams{
            {
                ProductID: unifiedcommerce.String("product-123"),
                Quantity:  unifiedcommerce.Int64(2),
                Price:     unifiedcommerce.Float64(299.99),
            },
            {
                ProductID: unifiedcommerce.String("product-456"),
                Quantity:  unifiedcommerce.Int64(1),
                Price:     unifiedcommerce.Float64(149.99),
            },
        },
        Customer: &unifiedcommerce.CustomerParams{
            ID:    unifiedcommerce.String("customer-789"),
            Email: unifiedcommerce.String("customer@example.com"),
            Name:  unifiedcommerce.String("John Doe"),
        },
        ShippingAddress: &unifiedcommerce.AddressParams{
            Street:     unifiedcommerce.String("123 Main St"),
            City:       unifiedcommerce.String("San Francisco"),
            State:      unifiedcommerce.String("CA"),
            PostalCode: unifiedcommerce.String("94105"),
            Country:    unifiedcommerce.String("US"),
        },
        PaymentMethod: &unifiedcommerce.PaymentMethodParams{
            Type:  unifiedcommerce.String("card"),
            Token: unifiedcommerce.String("pm_xxxxxxxxxxxxx"),
        },
    })
    if err != nil {
        return fmt.Errorf("create order: %w", err)
    }

    // List orders
    orders, err := client.Orders.List(ctx, &unifiedcommerce.OrderListParams{
        CustomerID: unifiedcommerce.String("customer-789"),
        Status:     unifiedcommerce.String("pending"),
        Limit:      unifiedcommerce.Int64(20),
    })
    if err != nil {
        return fmt.Errorf("list orders: %w", err)
    }

    // Get order details
    orderDetails, err := client.Orders.Get(ctx, "order-123")
    if err != nil {
        return fmt.Errorf("get order: %w", err)
    }

    // Update order status
    err = client.Orders.Update(ctx, "order-123", &unifiedcommerce.OrderUpdateParams{
        Status: unifiedcommerce.String("shipped"),
        Tracking: &unifiedcommerce.TrackingParams{
            Carrier:        unifiedcommerce.String("UPS"),
            TrackingNumber: unifiedcommerce.String("1Z999AA10123456784"),
        },
    })
    if err != nil {
        return fmt.Errorf("update order: %w", err)
    }

    // Cancel an order
    err = client.Orders.Cancel(ctx, "order-123", &unifiedcommerce.OrderCancelParams{
        Reason: unifiedcommerce.String("Customer requested cancellation"),
    })
    if err != nil {
        return fmt.Errorf("cancel order: %w", err)
    }

    return nil
}

Customers

func manageCustomers(client *unifiedcommerce.Client) error {
    ctx := context.Background()

    // Create a customer
    customer, err := client.Customers.Create(ctx, &unifiedcommerce.CustomerCreateParams{
        Email: unifiedcommerce.String("customer@example.com"),
        Name:  unifiedcommerce.String("John Doe"),
        Phone: unifiedcommerce.String("+1234567890"),
        Addresses: []*unifiedcommerce.AddressParams{
            {
                Type:       unifiedcommerce.String("shipping"),
                Street:     unifiedcommerce.String("123 Main St"),
                City:       unifiedcommerce.String("San Francisco"),
                State:      unifiedcommerce.String("CA"),
                PostalCode: unifiedcommerce.String("94105"),
                Country:    unifiedcommerce.String("US"),
            },
        },
    })
    if err != nil {
        return fmt.Errorf("create customer: %w", err)
    }

    // List customers
    customers, err := client.Customers.List(ctx, &unifiedcommerce.CustomerListParams{
        Search: unifiedcommerce.String("john"),
        Limit:  unifiedcommerce.Int64(20),
    })
    if err != nil {
        return fmt.Errorf("list customers: %w", err)
    }

    // Update customer
    err = client.Customers.Update(ctx, "customer-123", &unifiedcommerce.CustomerUpdateParams{
        Phone: unifiedcommerce.String("+9876543210"),
    })
    if err != nil {
        return fmt.Errorf("update customer: %w", err)
    }

    return nil
}

Inventory

func manageInventory(client *unifiedcommerce.Client) error {
    ctx := context.Background()

    // Get inventory for a product
    inventory, err := client.Inventory.Get(ctx, "product-123")
    if err != nil {
        return fmt.Errorf("get inventory: %w", err)
    }

    // Update inventory
    err = client.Inventory.Update(ctx, "product-123", &unifiedcommerce.InventoryUpdateParams{
        Quantity:         unifiedcommerce.Int64(100),
        Location:         unifiedcommerce.String("warehouse-1"),
        ReservedQuantity: unifiedcommerce.Int64(5),
    })
    if err != nil {
        return fmt.Errorf("update inventory: %w", err)
    }

    // Bulk update
    err = client.Inventory.BulkUpdate(ctx, []*unifiedcommerce.InventoryBulkUpdateParams{
        {ProductID: unifiedcommerce.String("product-123"), Quantity: unifiedcommerce.Int64(100)},
        {ProductID: unifiedcommerce.String("product-456"), Quantity: unifiedcommerce.Int64(50)},
    })
    if err != nil {
        return fmt.Errorf("bulk update inventory: %w", err)
    }

    // Track inventory movements
    movements, err := client.Inventory.Movements(ctx, "product-123", &unifiedcommerce.InventoryMovementsParams{
        StartDate: unifiedcommerce.String("2024-01-01"),
        EndDate:   unifiedcommerce.String("2024-01-31"),
    })
    if err != nil {
        return fmt.Errorf("get movements: %w", err)
    }

    return nil
}

Error Handling

Error Types

import (
    "errors"
    unifiedcommerce "github.com/unified-commerce/go-sdk"
)

func handleErrors(client *unifiedcommerce.Client) error {
    ctx := context.Background()

    product, err := client.Products.Get(ctx, "invalid-id")
    if err != nil {
        // Type assertion for specific errors
        var notFoundErr *unifiedcommerce.NotFoundError
        var authErr *unifiedcommerce.AuthenticationError
        var rateLimitErr *unifiedcommerce.RateLimitError
        var validationErr *unifiedcommerce.ValidationError

        switch {
        case errors.As(err, &notFoundErr):
            log.Printf("Product not found: %s", notFoundErr.Message)
            return err

        case errors.As(err, &authErr):
            log.Printf("Authentication failed: %s", authErr.Message)
            return err

        case errors.As(err, &rateLimitErr):
            log.Printf("Rate limit exceeded. Retry after: %v", rateLimitErr.RetryAfter)
            time.Sleep(rateLimitErr.RetryAfter)
            // Retry the request
            return nil

        case errors.As(err, &validationErr):
            log.Printf("Validation errors:")
            for field, errs := range validationErr.Errors {
                log.Printf("  %s: %v", field, errs)
            }
            return err

        default:
            log.Printf("Unexpected error: %v", err)
            return err
        }
    }

    return nil
}

Automatic Retries

// Enable automatic retries with exponential backoff
client := unifiedcommerce.NewClient(
    unifiedcommerce.WithAPIKey(os.Getenv("UNIFIED_COMMERCE_API_KEY")),
    unifiedcommerce.WithMaxRetries(5),
    unifiedcommerce.WithRetryBackoff(2*time.Second),
)

// The SDK automatically retries on:
// - Network errors
// - 5xx server errors
// - Rate limit errors (with retry-after header)

Custom Retry Logic

import "github.com/unified-commerce/go-sdk/retry"

// Create custom retry policy
retryPolicy := retry.NewExponentialBackoff(
    retry.WithMaxRetries(5),
    retry.WithInitialDelay(1*time.Second),
    retry.WithMaxDelay(30*time.Second),
    retry.WithMultiplier(2),
)

client := unifiedcommerce.NewClient(
    unifiedcommerce.WithAPIKey(os.Getenv("UNIFIED_COMMERCE_API_KEY")),
    unifiedcommerce.WithRetryPolicy(retryPolicy),
)

Concurrency

Goroutines

import (
    "sync"
    "context"
)

func fetchProductsConcurrently(client *unifiedcommerce.Client, categories []string) ([]*unifiedcommerce.Product, error) {
    ctx := context.Background()
    var (
        mu       sync.Mutex
        wg       sync.WaitGroup
        products []*unifiedcommerce.Product
        errs     []error
    )

    for _, category := range categories {
        wg.Add(1)
        go func(cat string) {
            defer wg.Done()

            result, err := client.Products.List(ctx, &unifiedcommerce.ProductListParams{
                Category: unifiedcommerce.String(cat),
                Limit:    unifiedcommerce.Int64(100),
            })

            mu.Lock()
            defer mu.Unlock()

            if err != nil {
                errs = append(errs, err)
                return
            }

            products = append(products, result.Data...)
        }(category)
    }

    wg.Wait()

    if len(errs) > 0 {
        return nil, fmt.Errorf("errors occurred: %v", errs)
    }

    return products, nil
}

Worker Pool

func processProductsWithWorkerPool(client *unifiedcommerce.Client, productIDs []string) error {
    ctx := context.Background()
    numWorkers := 10

    jobs := make(chan string, len(productIDs))
    results := make(chan error, len(productIDs))

    // Start workers
    for w := 0; w < numWorkers; w++ {
        go func() {
            for productID := range jobs {
                product, err := client.Products.Get(ctx, productID)
                if err != nil {
                    results <- err
                    continue
                }

                // Process product
                if err := processProduct(product); err != nil {
                    results <- err
                    continue
                }

                results <- nil
            }
        }()
    }

    // Send jobs
    for _, id := range productIDs {
        jobs <- id
    }
    close(jobs)

    // Collect results
    for range productIDs {
        if err := <-results; err != nil {
            log.Printf("Error processing product: %v", err)
        }
    }

    return nil
}

Context Cancellation

func fetchWithCancellation(client *unifiedcommerce.Client) error {
    // Create cancelable context
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    // Start fetching in goroutine
    done := make(chan error)
    go func() {
        products, err := client.Products.List(ctx, &unifiedcommerce.ProductListParams{
            Limit: unifiedcommerce.Int64(1000),
        })
        if err != nil {
            done <- err
            return
        }

        // Process products
        for _, p := range products.Data {
            select {
            case <-ctx.Done():
                done <- ctx.Err()
                return
            default:
                processProduct(p)
            }
        }

        done <- nil
    }()

    // Wait for completion or timeout
    select {
    case err := <-done:
        return err
    case <-time.After(30 * time.Second):
        cancel() // Cancel the context
        return errors.New("operation timed out")
    }
}

Webhooks

Webhook Verification

import (
    "net/http"
    "io"
    "github.com/unified-commerce/go-sdk/webhooks"
)

func handleWebhook(w http.ResponseWriter, r *http.Request) {
    // Read request body
    body, err := io.ReadAll(r.Body)
    if err != nil {
        http.Error(w, "Error reading body", http.StatusBadRequest)
        return
    }

    // Get signature from header
    signature := r.Header.Get("X-Unified-Commerce-Signature")

    // Verify webhook
    event, err := webhooks.Verify(body, signature, os.Getenv("WEBHOOK_SECRET"))
    if err != nil {
        http.Error(w, "Invalid signature", http.StatusUnauthorized)
        return
    }

    // Handle event based on type
    switch event.Type {
    case webhooks.OrderCreated:
        order := event.Data.(*unifiedcommerce.Order)
        handleOrderCreated(order)

    case webhooks.OrderUpdated:
        order := event.Data.(*unifiedcommerce.Order)
        handleOrderUpdated(order)

    case webhooks.InventoryLow:
        inventory := event.Data.(*unifiedcommerce.Inventory)
        handleLowInventory(inventory)

    default:
        log.Printf("Unhandled webhook type: %s", event.Type)
    }

    w.WriteHeader(http.StatusOK)
    w.Write([]byte(`{"received": true}`))
}

Webhook Handler

import "github.com/unified-commerce/go-sdk/webhooks"

func setupWebhookHandler() http.Handler {
    handler := webhooks.NewHandler(os.Getenv("WEBHOOK_SECRET"))

    // Register event handlers
    handler.On(webhooks.OrderCreated, func(event *webhooks.Event) error {
        order := event.Data.(*unifiedcommerce.Order)
        log.Printf("Order created: %s", order.ID)
        return sendConfirmationEmail(order)
    })

    handler.On(webhooks.PaymentFailed, func(event *webhooks.Event) error {
        payment := event.Data.(*unifiedcommerce.Payment)
        log.Printf("Payment failed: %s", payment.ID)
        return notifyCustomer(payment)
    })

    handler.On(webhooks.InventoryLow, func(event *webhooks.Event) error {
        inventory := event.Data.(*unifiedcommerce.Inventory)
        log.Printf("Low inventory: %s", inventory.ProductID)
        return reorderStock(inventory)
    })

    return handler
}

Advanced Features

GraphQL Queries

import "github.com/unified-commerce/go-sdk/graphql"

func customGraphQLQuery(client *unifiedcommerce.Client) error {
    ctx := context.Background()

    query := `
        query GetProductsWithReviews($category: String!) {
            products(category: $category) {
                id
                name
                price
                reviews {
                    id
                    rating
                    comment
                    author {
                        name
                    }
                }
            }
        }
    `

    var result struct {
        Products []struct {
            ID      string
            Name    string
            Price   float64
            Reviews []struct {
                ID      string
                Rating  int
                Comment string
                Author  struct {
                    Name string
                }
            }
        }
    }

    err := client.GraphQL.Query(ctx, query, map[string]interface{}{
        "category": "electronics",
    }, &result)

    if err != nil {
        return fmt.Errorf("graphql query: %w", err)
    }

    return nil
}

Batch Operations

func batchOperations(client *unifiedcommerce.Client) error {
    ctx := context.Background()

    // Batch create products
    products, err := client.Products.BatchCreate(ctx, []*unifiedcommerce.ProductCreateParams{
        {Name: unifiedcommerce.String("Product 1"), Price: unifiedcommerce.Float64(99.99)},
        {Name: unifiedcommerce.String("Product 2"), Price: unifiedcommerce.Float64(149.99)},
        {Name: unifiedcommerce.String("Product 3"), Price: unifiedcommerce.Float64(199.99)},
    })
    if err != nil {
        return fmt.Errorf("batch create: %w", err)
    }

    // Batch update
    err = client.Products.BatchUpdate(ctx, []*unifiedcommerce.ProductBatchUpdateParams{
        {ID: unifiedcommerce.String("product-1"), Price: unifiedcommerce.Float64(89.99)},
        {ID: unifiedcommerce.String("product-2"), Price: unifiedcommerce.Float64(139.99)},
    })
    if err != nil {
        return fmt.Errorf("batch update: %w", err)
    }

    return nil
}

Pagination

func paginateProducts(client *unifiedcommerce.Client) ([]*unifiedcommerce.Product, error) {
    ctx := context.Background()
    var allProducts []*unifiedcommerce.Product

    // Method 1: Cursor-based pagination
    cursor := ""
    for {
        result, err := client.Products.List(ctx, &unifiedcommerce.ProductListParams{
            Limit:  unifiedcommerce.Int64(100),
            Cursor: unifiedcommerce.String(cursor),
        })
        if err != nil {
            return nil, err
        }

        allProducts = append(allProducts, result.Data...)

        if result.NextCursor == "" {
            break
        }
        cursor = result.NextCursor
    }

    // Method 2: Using iterator
    iter := client.Products.Iterate(ctx, &unifiedcommerce.ProductListParams{
        Category: unifiedcommerce.String("electronics"),
    })

    for iter.Next() {
        product := iter.Product()
        allProducts = append(allProducts, product)
    }

    if err := iter.Err(); err != nil {
        return nil, err
    }

    return allProducts, nil
}

File Uploads

import "os"

func uploadProductImage(client *unifiedcommerce.Client) error {
    ctx := context.Background()

    // Open file
    file, err := os.Open("product-image.jpg")
    if err != nil {
        return err
    }
    defer file.Close()

    // Upload image
    image, err := client.Products.UploadImage(ctx, "product-123", &unifiedcommerce.ImageUploadParams{
        File:     file,
        Alt:      unifiedcommerce.String("Product image"),
        Position: unifiedcommerce.Int64(0),
    })
    if err != nil {
        return err
    }

    log.Printf("Image uploaded: %s", image.URL)
    return nil
}

Testing

Mock Client

import (
    "testing"
    "github.com/unified-commerce/go-sdk/testing"
)

func TestFetchProducts(t *testing.T) {
    // Create mock client
    mockClient := testing.NewMockClient()

    // Setup mock response
    mockClient.Products.On("List", mock.Anything, mock.Anything).Return(
        &unifiedcommerce.ProductList{
            Data: []*unifiedcommerce.Product{
                {ID: "1", Name: "Test Product", Price: 99.99},
            },
            Total: 1,
        },
        nil,
    )

    // Use in test
    products, err := mockClient.Products.List(context.Background(), &unifiedcommerce.ProductListParams{
        Limit: unifiedcommerce.Int64(10),
    })

    if err != nil {
        t.Fatalf("unexpected error: %v", err)
    }

    if len(products.Data) != 1 {
        t.Errorf("expected 1 product, got %d", len(products.Data))
    }

    mockClient.Products.AssertExpectations(t)
}

Test Utilities

import "github.com/unified-commerce/go-sdk/testing"

func TestOrderCreation(t *testing.T) {
    // Create test fixtures
    testProduct := testing.MockProduct(t, testing.ProductOptions{
        Name:  "Test Product",
        Price: 99.99,
    })

    testOrder := testing.MockOrder(t, testing.OrderOptions{
        Items: []*unifiedcommerce.OrderItem{
            {Product: testProduct, Quantity: 2},
        },
    })

    // Use in tests
    if testOrder.Total != 199.98 {
        t.Errorf("expected total 199.98, got %f", testOrder.Total)
    }
}

Changelog

Version 1.5.2 (Latest)

  • Added Go 1.22 support
  • Improved context cancellation handling
  • New webhook verification utilities
  • Performance optimizations in HTTP client
  • Fixed memory leak in long-running operations

Version 1.5.0

  • Breaking: Minimum Go version is now 1.21
  • Added generics support for type-safe operations
  • New GraphQL client with query builder
  • Improved error types with structured errors
  • Added batch operations support

Version 1.4.0

  • Added worker pool utilities
  • New file upload support
  • Improved pagination with iterators
  • Added request signing
  • Performance improvements

View full changelog →

Resources

Support

Need help? We're here for you:

Was this page helpful?