### Install go-shopify
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Use go get to install the latest version of the library.
```bash
go get github.com/bold-commerce/go-shopify/v4
```
--------------------------------
### Install go-shopify v3
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Use 'go get' to install version 3 of the go-shopify library.
```console
$ go get github.com/bold-commerce/go-shopify/v3
```
--------------------------------
### Install go-shopify v4
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Use 'go get' to install version 4 of the go-shopify library.
```console
$ go get github.com/bold-commerce/go-shopify/v4
```
--------------------------------
### Install go-shopify v2
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Use 'go get' to install version 2 of the go-shopify library.
```console
$ go get github.com/bold-commerce/go-shopify
```
--------------------------------
### Import go-shopify v3
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Import the goshopify package after installing v3.
```go
import "github.com/bold-commerce/go-shopify/v3"
```
--------------------------------
### Import go-shopify v4
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Import the goshopify package after installing v4.
```go
import "github.com/bold-commerce/go-shopify/v4"
```
--------------------------------
### Import go-shopify v2
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Import the goshopify package after installing v2.
```go
import "github.com/bold-commerce/go-shopify"
```
--------------------------------
### Fetch Product Count with Standard Options
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Use standard CountOptions to filter API results. This example fetches the number of products created after a specific date.
```go
// Create standard CountOptions
date := time.Date(2016, time.January, 1, 0, 0, 0, 0, time.UTC)
options := goshopify.CountOptions{createdAtMin: date}
// Use the options when calling the API.
numProducts, err := client.Product.Count(options)
```
--------------------------------
### Shopify Client with API Version Option
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Example of creating a Shopify API client with a specific API version specified using the `WithVersion` option. This ensures compatibility with a particular Shopify API release.
```go
client, err := goshopify.NewClient(app, "shopname", "", goshopify.WithVersion("2019-04"))
```
--------------------------------
### Shopify API Calls with Access Token
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Example of making API calls to Shopify using a permanent access token obtained via OAuth. This demonstrates creating a client and fetching the product count.
```go
// Create an app somewhere.
app := goshopify.App{
ApiKey: "abcd",
ApiSecret: "efgh",
RedirectUrl: "https://example.com/shopify/callback",
Scope: "read_products",
}
// Create a new API client
client, err := goshopify.NewClient(app, "shopname", "token")
// Fetch the number of products.
numProducts, err := client.Product.Count(nil)
```
--------------------------------
### Fetch Order Count with Custom Query Options
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Utilize custom structs with `url` tags to define query parameters for API requests. This example fetches order counts based on a 'status' field.
```go
// Create custom options for the orders.
// Notice the `url:"status"` tag
options := struct {
Status string `url:"status"`
}{"any"}
// Fetch the order count for orders with status="any"
orderCount, err := client.Order.Count(options)
```
--------------------------------
### Shopify OAuth Flow - Callback Handler
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Example of handling the callback from Shopify after OAuth authorization. This function verifies the callback signature and exchanges the authorization code for a permanent access token.
```go
// Fetch a permanent access token in the callback
func MyCallbackHandler(w http.ResponseWriter, r *http.Request) {
// Check that the callback signature is valid
if ok, _ := app.VerifyAuthorizationURL(r.URL); !ok {
http.Error(w, "Invalid Signature", http.StatusUnauthorized)
return
}
query := r.URL.Query()
shopName := query.Get("shop")
code := query.Get("code")
ctx := context.TODO() // adds context which will be used in GetAccessToken below
token, err := app.GetAccessToken(ctx, shopName, code)
// Do something with the token, like store it in a DB.
}
```
--------------------------------
### Shopify Private App Authentication
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Example of authenticating with Shopify using a private app's API key and password. This method bypasses the OAuth flow and is suitable for server-to-server integrations.
```go
// Create an app somewhere.
app := goshopify.App{
ApiKey: "apikey",
Password: "apipassword",
}
// Create a new API client (notice the token parameter is the empty string)
client, err := goshopify.NewClient(app, "shopname", "")
// Fetch the number of products.
numProducts, err := client.Product.Count(nil)
```
--------------------------------
### List and Manage Shopify Orders
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Fetch orders with various filters like status, financial status, and fulfillment status. Also demonstrates getting a single order, cancelling an order with a reason, and counting all orders.
```go
ctx := context.Background()
// Fetch all unfulfilled, paid orders updated after a date
opts := goshopify.OrderListOptions{
Status: goshopify.OrderStatusOpen,
FinancialStatus: goshopify.OrderFinancialStatusPaid,
FulfillmentStatus: goshopify.OrderFulfillmentStatusUnfulfilled,
ListOptions: goshopify.ListOptions{Limit: 250},
}
orders, err := client.Order.ListAll(ctx, opts)
if err != nil {
log.Fatal(err)
}
for _, o := range orders {
fmt.Printf("Order #%d total=%s items=%d\n",
o.OrderNumber, o.TotalPrice, len(o.LineItems))
}
// Get a single order
order, _ := client.Order.Get(ctx, 123456789, nil)
fmt.Println("Customer:", order.Customer.Email)
// Cancel an order with a reason
cancelOpts := goshopify.OrderCancelOptions{
Reason: string(goshopify.OrderCancelReasonCustomer),
Email: true,
}
cancelled, _ := client.Order.Cancel(ctx, order.Id, cancelOpts)
fmt.Println("Cancelled at:", cancelled.CancelledAt)
// Count all orders regardless of status
total, _ := client.Order.Count(ctx, struct {
Status string `url:"status"`
}{"any"})
fmt.Println("Total orders:", total)
```
--------------------------------
### Shopify OAuth Flow - Authorize URL
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Example of creating an OAuth authorization URL for a Shopify app. This is typically done within an HTTP request handler to redirect the user to Shopify for authorization.
```go
// Create an app somewhere.
app := goshopify.App{
ApiKey: "abcd",
ApiSecret: "efgh",
RedirectUrl: "https://example.com/shopify/callback",
Scope: "read_products,read_orders",
}
// Create an oauth-authorize url for the app and redirect to it.
// In some request handler, you probably want something like this:
func MyHandler(w http.ResponseWriter, r *http.Request) {
shopName := r.URL.Query().Get("shop")
state := "nonce"
authUrl := app.AuthorizeUrl(shopName, state)
http.Redirect(w, r, authUrl, http.StatusFound)
}
```
--------------------------------
### Build and Test with Make
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Use the provided Makefile for simplified development and testing. Commands include building the Docker image, running tests, cleaning up, and generating coverage reports.
```shell
make && make test
```
--------------------------------
### Configure go-shopify Client with Options
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Initialize the go-shopify client using `NewClient` and pass variadic `Option` functions to customize its behavior, such as API version, retry logic, logging, and HTTP client settings.
```go
import (
"log"
"net/http"
"time"
goshopify "github.com/bold-commerce/go-shopify/v4"
)
app := goshopify.App{ApiKey: "key", ApiSecret: "secret"}
client, err := goshopify.NewClient(app, "mystore", "shpat_token",
// Pin to a specific Shopify API release
goshopify.WithVersion("2024-01"),
// Retry up to 5 times on 429 (rate limit) or 503 (service unavailable)
goshopify.WithRetry(5),
// Use a custom logger at Debug level
goshopify.WithLogger(&goshopify.LeveledLogger{Level: goshopify.LevelDebug}),
// Use an http.Client with a custom timeout and transport
goshopify.WithHTTPClient(&http.Client{
Timeout: 45 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 10,
IdleConnTimeout: 30 * time.Second,
},
}),
)
if err != nil {
log.Fatal(err)
}
// After the first request, the negotiated API version is stored
ctx := context.Background()
_, _ = client.Shop.Get(ctx, nil)
log.Printf("Negotiated API version: %s", client.RateLimits.RequestCount) // access rate limit info too
```
--------------------------------
### Create and Manage Price Rules and Discount Codes
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Illustrates creating a percentage-off price rule with a minimum subtotal prerequisite and then creating a discount code associated with that rule. Ensure correct value types and date handling.
```go
ctx := context.Background()
// Create a 10% off discount rule for all products
value := decimal.NewFromFloat(-10.0)
rule, err := client.PriceRule.Create(ctx, goshopify.PriceRule{
Title: "10PERCENT",
ValueType: "percentage",
Value: &value,
CustomerSelection: "all",
TargetType: "line_item",
TargetSelection: "all",
AllocationMethod: "across",
UsageLimit: 100,
OncePerCustomer: true,
StartsAt: func() *time.Time { t := time.Now(); return &t }(),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("PriceRule ID: %d\n", rule.Id)
// Set prerequisite: cart subtotal >= $50
minSubtotal := "50.00"
if err := rule.SetPrerequisiteSubtotalRange(&minSubtotal); err != nil {
log.Fatal(err)
}
updated, _ := client.PriceRule.Update(ctx, *rule)
fmt.Println("Updated rule:", updated.Id)
// Create a discount code under this price rule
code, _ := client.DiscountCode.Create(ctx, rule.Id, goshopify.DiscountCode{Code: "SAVE10"})
fmt.Println("Discount code:", code.Code)
```
--------------------------------
### Create, List, and Update Shop Metafields
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Demonstrates how to create, list, and update shop-level metafields using JSON values. Ensure the correct MetafieldType is specified.
```go
ctx := context.Background()
// Create a shop-level metafield
mf, err := client.Metafield.Create(ctx, goshopify.Metafield{
Namespace: "app_settings",
Key: "feature_flags",
Value: `{"beta_checkout": true}`,
Type: goshopify.MetafieldTypeJSON,
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created metafield: %s.%s = %v\n", mf.Namespace, mf.Key, mf.Value)
// List all shop metafields
mfs, _ := client.Metafield.List(ctx, nil)
for _, m := range mfs {
fmt.Printf(" %s.%s [%s]\n", m.Namespace, m.Key, m.Type)
}
// Update value
mf.Value = `{"beta_checkout": false}`
updated, _ := client.Metafield.Update(ctx, *mf)
fmt.Println("Updated value:", updated.Value)
```
--------------------------------
### Execute Shopify GraphQL Queries
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Demonstrates executing a GraphQL query to fetch product data and inspecting the GraphQL cost. Handles rate limiting errors by checking for `goshopify.RateLimitError`.
```go
ctx := context.Background()
type ProductNode struct {
Id string `json:"id"`
Title string `json:"title"`
}
type ProductEdge struct {
Node ProductNode `json:"node"`
}
type ProductsConn struct {
Edges []ProductEdge `json:"edges"`
}
type QueryResp struct {
Products ProductsConn `json:"products"`
}
q := `
query getProducts($first: Int!) {
products(first: $first) {
edges {
node {
id
title
}
}
}
}
`
vars := map[string]interface{}{"first": 5}
var resp QueryResp
if err := client.GraphQL.Query(ctx, q, vars, &resp); err != nil {
// RateLimitError is returned if retries are exhausted
if rlErr, ok := err.(goshopify.RateLimitError); ok {
fmt.Printf("Rate limited, retry after %d seconds\n", rlErr.RetryAfter)
return
}
log.Fatal(err)
}
for _, edge := range resp.Products.Edges {
fmt.Printf("Product: %s (%s)\n", edge.Node.Title, edge.Node.Id)
}
// Inspect GraphQL cost
fmt.Printf("Query cost: %d / available: %.0f\n",
client.RateLimits.GraphQLCost.RequestedQueryCost,
client.RateLimits.GraphQLCost.ThrottleStatus.CurrentlyAvailable)
```
--------------------------------
### API Calls with Token
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Demonstrates how to make API calls after obtaining an access token.
```APIDOC
## API Calls with Token
### Description
With a permanent access token, you can make API calls like this.
### Usage
1. **Create an App Configuration**:
Define your application's details.
```go
app := goshopify.App{
ApiKey: "abcd",
ApiSecret: "efgh",
RedirectUrl: "https://example.com/shopify/callback",
Scope: "read_products",
}
```
2. **Create a New API Client**:
Instantiate the client using your app details, shop name, and the obtained token.
```go
client, err := goshopify.NewClient(app, "shopname", "token")
```
3. **Make API Calls**:
Use the client to interact with Shopify resources, for example, fetching the product count.
```go
// Fetch the number of products.
numProducts, err := client.Product.Count(nil)
```
```
--------------------------------
### Import go-shopify
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Import the library with a custom alias for convenience.
```go
import goshopify "github.com/bold-commerce/go-shopify/v4"
```
--------------------------------
### Client Options - WithVersion
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Details how to specify a Shopify API version when creating the client.
```APIDOC
### Client Options - WithVersion
#### Description
When creating a client, there are configuration options you can pass to `NewClient`. The `WithVersion` option allows you to specify a particular version of the Shopify API.
Read more details on the [Shopify API Versioning](https://shopify.dev/concepts/about-apis/versioning) to understand the format and release schedules.
#### Usage
```go
client, err := goshopify.NewClient(app, "shopname", "", goshopify.WithVersion("2019-04"))
```
```
--------------------------------
### client.Shop.Get
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Retrieves metadata about the authenticated store, including its name, domain, currency, timezone, and plan details.
```APIDOC
## client.Shop.Get — retrieve store information
Fetch metadata about the authenticated store: name, domain, currency, timezone, plan, and more.
### Usage
```go
ctx := context.Background()
shop, err := client.Shop.Get(ctx, nil)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Name: %s\nCurrency: %s\nTimezone: %s\nPlan: %s\n",
shop.Name, shop.Currency, shop.IanaTimezone, shop.PlanName)
// Output:
// Name: My Shopify Store
// Currency: USD
// Timezone: America/New_York
// Plan: basic
```
```
--------------------------------
### Client Options
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Configure the Shopify client using variadic Option functions such as WithVersion, WithRetry, WithLogger, and WithHTTPClient when creating a new client instance.
```APIDOC
## Client Options — WithVersion, WithRetry, WithLogger, WithHTTPClient
All client options are passed as variadic `Option` functions to `NewClient`.
```go
import (
"log"
"net/http"
"time"
goshopify "github.com/bold-commerce/go-shopify/v4"
)
app := goshopify.App{ApiKey: "key", ApiSecret: "secret"}
client, err := goshopify.NewClient(app, "mystore", "shpat_token",
// Pin to a specific Shopify API release
goshopify.WithVersion("2024-01"),
// Retry up to 5 times on 429 (rate limit) or 503 (service unavailable)
goshopify.WithRetry(5),
// Use a custom logger at Debug level
goshopify.WithLogger(&goshopify.LeveledLogger{Level: goshopify.LevelDebug}),
// Use an http.Client with a custom timeout and transport
goshopify.WithHTTPClient(&http.Client{
Timeout: 45 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 10,
IdleConnTimeout: 30 * time.Second,
},
}),
)
if err != nil {
log.Fatal(err)
}
// After the first request, the negotiated API version is stored
ctx := context.Background()
_, _ = client.Shop.Get(ctx, nil)
log.Printf("Negotiated API version: %s", client.RateLimits.RequestCount) // access rate limit info too
```
```
--------------------------------
### Fetch Webhooks Using Custom Models
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Implement custom models for data structures not yet supported by the library. Use `client.Get` to fetch resources and populate your custom models.
```go
// Declare a model for the webhook
type Webhook struct {
Id int `json:"id"`
Address string `json:"address"`
}
// Declare a model for the resource root.
type WebhooksResource struct {
Webhooks []Webhook `json:"webhooks"`
}
func FetchWebhooks() ([]Webhook, error) {
path := "admin/webhooks.json"
resource := new(WebhooksResource)
client, _ := goshopify.NewClient(app, "shopname", "token")
// resource gets modified when calling Get
err := client.Get(path, resource, nil)
return resource.Webhooks, err
}
```
--------------------------------
### Manage Inventory Levels
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Shows how to set absolute inventory levels, adjust stock counts by a relative delta, and list inventory levels for specific items across locations. Requires valid inventory and location IDs.
```go
ctx := context.Background()
inventoryItemId := uint64(11111)
locationId := uint64(22222)
// Set absolute inventory at a location
level, err := client.InventoryLevel.Set(ctx, goshopify.InventoryLevel{
InventoryItemId: inventoryItemId,
LocationId: locationId,
Available: 100,
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Available at location %d: %d\n", level.LocationId, level.Available)
// Adjust (relative delta) – add 10 units
adjusted, _ := client.InventoryLevel.Adjust(ctx, goshopify.InventoryLevelAdjustOptions{
InventoryItemId: inventoryItemId,
LocationId: locationId,
Adjust: 10,
})
fmt.Printf("New available: %d\n", adjusted.Available)
// List inventory levels across locations for specific items
levels, _ := client.InventoryLevel.List(ctx, goshopify.InventoryLevelListOptions{
InventoryItemIds: []uint64{inventoryItemId},
LocationIds: []uint64{locationId},
})
fmt.Printf("Found %d inventory levels\n", len(levels))
```
--------------------------------
### Generate Coverage Report with Docker Compose
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Create a coverage profile and generate an HTML report for Go tests using Docker Compose.
```shell
docker-compose run --rm dev sh -c 'go test -coverprofile=coverage.out ./... && go tool cover -html coverage.out -o coverage.html'
```
--------------------------------
### Build Test Image with Docker Compose
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Manually build the `go-shopify:latest` Docker image required for running tests using Docker Compose.
```shell
docker-compose build test
```
--------------------------------
### Create Authenticated API Client
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Construct a client for a specific store using OAuth or private app credentials. Functional options can configure API version, retries, logging, and the HTTP client.
```go
package main
import (
"context"
"fmt"
"log"
"net/http"
"time"
goshopify "github.com/bold-commerce/go-shopify/v4"
)
func main() {
app := goshopify.App{
ApiKey: "your-api-key",
ApiSecret: "your-api-secret",
}
// OAuth app client
client, err := goshopify.NewClient(
app,
"mystore", // resolves to mystore.myshopify.com
"shpat_accesstoken",
goshopify.WithVersion("2024-01"), // pin API version
goshopify.WithRetry(3), // retry on 429 / 503
goshopify.WithLogger(&goshopify.LeveledLogger{Level: goshopify.LevelInfo}),
goshopify.WithHTTPClient(&http.Client{Timeout: 30 * time.Second}),
)
if err != nil {
log.Fatal(err)
}
// Private app (Basic Auth) – omit access token
privateApp := goshopify.App{ApiKey: "apikey", Password: "apipassword"}
privateClient, _ := goshopify.NewClient(privateApp, "mystore", "")
shop, _ := client.Shop.Get(context.Background(), nil)
fmt.Printf("Connected to: %s (%s)\n", shop.Name, shop.MyshopifyDomain)
_ = privateClient
}
```
--------------------------------
### NewClient - Create an Authenticated API Client
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Constructs a *Client bound to a single store. Supports OAuth and private-app authentication. Functional options configure API version, retry behavior, logging, and the underlying http.Client.
```APIDOC
## NewClient — create an authenticated API client
`NewClient` (or `MustNewClient`) constructs a `*Client` bound to a single store. Pass an `App` for credentials, the shop name, and a permanent access token. Functional options configure API version, retry behaviour, logging, and the underlying `http.Client`.
```go
package main
import (
"context"
"fmt"
"log"
"net/http"
"time"
goshopify "github.com/bold-commerce/go-shopify/v4"
)
func main() {
app := goshopify.App{
ApiKey: "your-api-key",
ApiSecret: "your-api-secret",
}
// OAuth app client
client, err := goshopify.NewClient(
app,
"mystore", // resolves to mystore.myshopify.com
"shpat_accesstoken",
goshopify.WithVersion("2024-01"), // pin API version
goshopify.WithRetry(3), // retry on 429 / 503
goshopify.WithLogger(&goshopify.LeveledLogger{Level: goshopify.LevelInfo}),
goshopify.WithHTTPClient(&http.Client{Timeout: 30 * time.Second}),
)
if err != nil {
log.Fatal(err)
}
// Private app (Basic Auth) – omit access token
privateApp := goshopify.App{ApiKey: "apikey", Password: "apipassword"}
privateClient, _ := goshopify.NewClient(privateApp, "mystore", "")
shop, _ := client.Shop.Get(context.Background(), nil)
fmt.Printf("Connected to: %s (%s)\n", shop.Name, shop.MyshopifyDomain)
_ = privateClient
}
```
```
--------------------------------
### Initialize Client with Retry Option
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Configure the Shopify client to automatically retry requests that fail due to rate limiting or HTTP 503 errors. Specify the number of retry attempts.
```go
client, err := goshopify.NewClient(app, "shopname", "", goshopify.WithRetry(3))
```
--------------------------------
### client.PriceRule
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Creates and manages Shopify discount rules, including percentage off, fixed amount, and free shipping, with support for prerequisite conditions.
```APIDOC
## client.PriceRule — create and manage discount rules
`PriceRuleService` creates Shopify discount rules (percentage off, fixed amount, free shipping) that power discount codes. Supports prerequisite conditions on subtotal, quantity, and shipping price.
### Create a 10% off discount rule for all products
```go
ctx := context.Background()
value := decimal.NewFromFloat(-10.0)
rule, err := client.PriceRule.Create(ctx, goshopify.PriceRule{
Title: "10PERCENT",
ValueType: "percentage",
Value: &value,
CustomerSelection: "all",
TargetType: "line_item",
TargetSelection: "all",
AllocationMethod: "across",
UsageLimit: 100,
OncePerCustomer: true,
StartsAt: func() *time.Time { t := time.Now(); return &t }()
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("PriceRule ID: %d\n", rule.Id)
```
### Set prerequisite: cart subtotal >= $50
```go
ctx := context.Background()
# Assuming rule is an existing PriceRule object
minSubtotal := "50.00"
if err := rule.SetPrerequisiteSubtotalRange(&minSubtotal); err != nil {
log.Fatal(err)
}
updated, _ := client.PriceRule.Update(ctx, *rule)
fmt.Println("Updated rule:", updated.Id)
```
### Create a discount code under this price rule
```go
ctx := context.Background()
# Assuming rule is an existing PriceRule object
code, _ := client.DiscountCode.Create(ctx, rule.Id, goshopify.DiscountCode{Code: "SAVE10"})
fmt.Println("Discount code:", code.Code)
```
```
--------------------------------
### Retrieve Authenticated Store Information
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Fetches metadata about the authenticated store, including its name, domain, currency, timezone, and plan. Requires a background context.
```go
ctx := context.Background()
shop, err := client.Shop.Get(ctx, nil)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Name: %s\nCurrency: %s\nTimezone: %s\nPlan: %s\n",
shop.Name, shop.Currency, shop.IanaTimezone, shop.PlanName)
// Output:
// Name: My Shopify Store
// Currency: USD
// Timezone: America/New_York
// Plan: basic
```
--------------------------------
### Shopify Product CRUD and Metafields
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Demonstrates full CRUD operations for products, including listing, counting, creating, updating, deleting, and managing metafields. Supports pagination for large product lists.
```go
ctx := context.Background()
// Count active products
count, _ := client.Product.Count(ctx, goshopify.ProductListOptions{
Status: []goshopify.ProductStatus{goshopify.ProductStatusActive},
})
fmt.Println("Active products:", count)
// Page through all products (cursor-based)
opts := &goshopify.ProductListOptions{
ListOptions: goshopify.ListOptions{Limit: 50},
Status: []goshopify.ProductStatus{goshopify.ProductStatusActive},
}
for {
products, pagination, err := client.Product.ListWithPagination(ctx, opts)
if err != nil {
log.Fatal(err)
}
for _, p := range products {
fmt.Printf(" [%d] %s (%s)\n", p.Id, p.Title, p.Status)
}
if pagination.NextPageOptions == nil {
break
}
opts = pagination.NextPageOptions
}
// Create a product
newProduct := goshopify.Product{
Title: "Premium Widget",
BodyHTML: "Best widget ever.",
Vendor: "Acme Corp",
ProductType: "Widget",
Status: goshopify.ProductStatusActive,
Tags: "widget, premium",
}
created, err := client.Product.Create(ctx, newProduct)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created product ID: %d\n", created.Id)
// Add a metafield to the product
mf, _ := client.Product.CreateMetafield(ctx, created.Id, goshopify.Metafield{
Namespace: "custom",
Key: "material",
Value: "aluminum",
Type: goshopify.MetafieldTypeSingleLineTextField,
})
fmt.Printf("Metafield ID: %d\n", mf.Id)
// Update title
created.Title = "Premium Widget v2"
updated, _ := client.Product.Update(ctx, *created)
fmt.Println("Updated title:", updated.Title)
// Delete
_ = client.Product.Delete(ctx, created.Id)
```
--------------------------------
### Private App Authentication
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Explains how to authenticate using private app credentials.
```APIDOC
## Private App Auth
### Description
Private Shopify apps use basic authentication and do not require going through the OAuth flow. Here is an example:
### Usage
1. **Create an App Configuration**:
Use your private app's API key and password.
```go
app := goshopify.App{
ApiKey: "apikey",
Password: "apipassword",
}
```
2. **Create a New API Client**:
Instantiate the client. Note that the token parameter is an empty string for private apps.
```go
// Create a new API client (notice the token parameter is the empty string)
client, err := goshopify.NewClient(app, "shopname", "")
```
3. **Make API Calls**:
Use the client to interact with Shopify resources.
```go
// Fetch the number of products.
numProducts, err := client.Product.Count(nil)
```
```
--------------------------------
### Fetch and POST using Custom Models with client.Get/Post
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Use client.Get and client.Post with custom struct models for Shopify endpoints not directly supported by the library. Ensure your structs match the JSON structure of the Shopify API.
```go
ctx := context.Background()
// Fetch webhooks using custom models
type MyWebhook struct {
Id int `json:"id"`
Topic string `json:"topic"`
Address string `json:"address"`
}
type MyWebhooksResource struct {
Webhooks []MyWebhook `json:"webhooks"`
}
resource := new(MyWebhooksResource)
if err := client.Get(ctx, "webhooks.json", resource, nil); err != nil {
log.Fatal(err)
}
for _, wh := range resource.Webhooks {
fmt.Printf("[%d] %s → %s\n", wh.Id, wh.Topic, wh.Address)
}
// POST using custom data
type ScriptTagPayload struct {
ScriptTag struct {
Event string `json:"event"`
Src string `json:"src"`
} `json:"script_tag"`
}
type ScriptTagResult struct {
ScriptTag struct {
Id int `json:"id"`
Src string `json:"src"`
} `json:"script_tag"`
}
payload := ScriptTagPayload{}
payload.ScriptTag.Event = "onload"
payload.ScriptTag.Src = "https://example.com/script.js"
result := new(ScriptTagResult)
_ = client.Post(ctx, "script_tags.json", payload, result)
fmt.Println("Created script tag ID:", result.ScriptTag.Id)
```
--------------------------------
### Create, Search, and Manage Shopify Customers
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Search for customers by email, create new customers with details and tags, list all orders for a specific customer, and retrieve all unique customer tags in the store.
```go
ctx := context.Background()
// Search customers by email
results, _ := client.Customer.Search(ctx, goshopify.CustomerSearchOptions{
Query: "email:jane@example.com",
Limit: 10,
})
for _, c := range results {
fmt.Printf("Customer: %s %s (%s)\n", c.FirstName, c.LastName, c.Email)
}
// Create a customer
newCust := goshopify.Customer{
FirstName: "Jane",
LastName: "Doe",
Email: "jane@example.com",
Tags: "vip, wholesale",
}
cust, err := client.Customer.Create(ctx, newCust)
if err != nil {
log.Fatal(err)
}
// Get all orders for a customer
orders, _ := client.Customer.ListOrders(ctx, cust.Id, nil)
fmt.Printf("Customer %d has %d orders\n", cust.Id, len(orders))
// Get all unique customer tags in the store
tags, _ := client.Customer.ListTags(ctx, nil)
fmt.Println("Tags:", tags)
```
--------------------------------
### Custom Models with client.Get / client.Post
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Use the low-level client.Get, client.Post, client.Put, and client.Delete methods for Shopify endpoints not yet wrapped by a dedicated service, allowing you to use your own struct models for requests and responses.
```APIDOC
## Custom Models with client.Get / client.Post
For any Shopify endpoint not yet wrapped by a dedicated service, use the low-level `client.Get`, `client.Post`, `client.Put`, and `client.Delete` methods with your own struct models.
```go
ctx := context.Background()
// Fetch webhooks using custom models
type MyWebhook struct {
Id int `json:"id"`
Topic string `json:"topic"`
Address string `json:"address"`
}
type MyWebhooksResource struct {
Webhooks []MyWebhook `json:"webhooks"`
}
resource := new(MyWebhooksResource)
if err := client.Get(ctx, "webhooks.json", resource, nil); err != nil {
log.Fatal(err)
}
for _, wh := range resource.Webhooks {
fmt.Printf("[%d] %s → %s\n", wh.Id, wh.Topic, wh.Address)
}
// POST using custom data
type ScriptTagPayload struct {
ScriptTag struct {
Event string `json:"event"`
Src string `json:"src"`
} `json:"script_tag"`
}
type ScriptTagResult struct {
ScriptTag struct {
Id int `json:"id"`
Src string `json:"src"`
} `json:"script_tag"`
}
payload := ScriptTagPayload{}
payload.ScriptTag.Event = "onload"
payload.ScriptTag.Src = "https://example.com/script.js"
result := new(ScriptTagResult)
_ = client.Post(ctx, "script_tags.json", payload, result)
fmt.Println("Created script tag ID:", result.ScriptTag.Id)
```
```
--------------------------------
### client.Product
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Provides comprehensive CRUD operations for products, including listing, retrieving, creating, updating, deleting, and managing metafields.
```APIDOC
## client.Product — full CRUD + pagination + metafields
`ProductService` provides `List`, `ListAll`, `ListWithPagination`, `Count`, `Get`, `Create`, `Update`, `Delete`, and full metafield sub-resource methods.
### Usage
```go
ctx := context.Background()
// Count active products
count, _ := client.Product.Count(ctx, goshopify.ProductListOptions{
Status: []goshopify.ProductStatus{goshopify.ProductStatusActive},
})
fmt.Println("Active products:", count)
// Page through all products (cursor-based)
opts := &goshopify.ProductListOptions{
ListOptions: goshopify.ListOptions{Limit: 50},
Status: []goshopify.ProductStatus{goshopify.ProductStatusActive},
}
for {
products, pagination, err := client.Product.ListWithPagination(ctx, opts)
if err != nil {
log.Fatal(err)
}
for _, p := range products {
fmt.Printf(" [%d] %s (%s)\n", p.Id, p.Title, p.Status)
}
if pagination.NextPageOptions == nil {
break
}
opts = pagination.NextPageOptions
}
// Create a product
newProduct := goshopify.Product{
Title: "Premium Widget",
BodyHTML: "Best widget ever.",
Vendor: "Acme Corp",
ProductType: "Widget",
Status: goshopify.ProductStatusActive,
Tags: "widget, premium",
}
created, err := client.Product.Create(ctx, newProduct)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created product ID: %d\n", created.Id)
// Add a metafield to the product
mf, _ := client.Product.CreateMetafield(ctx, created.Id, goshopify.Metafield{
Namespace: "custom",
Key: "material",
Value: "aluminum",
Type: goshopify.MetafieldTypeSingleLineTextField,
})
fmt.Printf("Metafield ID: %d\n", mf.Id)
// Update title
created.Title = "Premium Widget v2"
updated, _ := client.Product.Update(ctx, *created)
fmt.Println("Updated title:", updated.Title)
// Delete
_ = client.Product.Delete(ctx, created.Id)
```
```
--------------------------------
### Create, Complete, and List Shopify Fulfillments
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Create a new fulfillment for an order, including tracking information and notification settings. Also demonstrates completing a fulfillment and listing all fulfillments associated with an order.
```go
ctx := context.Background()
orderId := uint64(987654321)
// Create a fulfillment with tracking info
fulfillment := goshopify.Fulfillment{
TrackingInfo: goshopify.FulfillmentTrackingInfo{
Company: "FedEx",
Number: "1234567890",
Url: "https://www.fedex.com/tracking?id=1234567890",
},
NotifyCustomer: true,
LineItemsByFulfillmentOrder: []goshopify.LineItemByFulfillmentOrder{
{FulfillmentOrderId: 111222333},
},
}
created, err := client.Fulfillment.Create(ctx, fulfillment)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Fulfillment %d status: %s\n", created.Id, created.Status)
// Complete a fulfillment
completed, _ := client.Fulfillment.Complete(ctx, created.Id)
fmt.Println("Completed:", completed.Status)
// List fulfillments for an order via the order service
list, _ := client.Order.ListFulfillments(ctx, orderId, nil)
fmt.Printf("Order has %d fulfillments\n", len(list))
```
--------------------------------
### client.Webhook
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Enables subscription to Shopify events and verification of incoming webhook requests.
```APIDOC
## client.Webhook — subscribe and verify
Manage webhook subscriptions and verify incoming requests from Shopify.
### Create Webhook
Subscribes to a specific Shopify event topic.
#### Parameters
- `ctx` (context.Context) - The context for the request.
- `webhook` (goshopify.Webhook) - The webhook subscription details, including topic, address, format, and fields.
### List Webhooks
Retrieves a list of existing webhook subscriptions, optionally filtered by topic.
#### Parameters
- `ctx` (context.Context) - The context for the request.
- `options` (goshopify.WebhookOptions) - Options for filtering the webhook list, such as by topic.
### Update Webhook
Updates an existing webhook subscription.
#### Parameters
- `ctx` (context.Context) - The context for the request.
- `webhook` (goshopify.Webhook) - The updated webhook object, including its ID.
### Delete Webhook
Deletes a webhook subscription.
#### Parameters
- `ctx` (context.Context) - The context for the request.
- `webhookID` (uint64) - The ID of the webhook to delete.
```
--------------------------------
### Run Tests with Docker Compose
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Execute the test suite within the Docker environment using Docker Compose.
```shell
docker-compose run --rm tests
```
--------------------------------
### Remove Docker Image
Source: https://github.com/bold-commerce/go-shopify/blob/master/README.md
Clean up by removing the `go-shopify:latest` Docker image after testing.
```shell
docker image rm go-shopify:latest
```
--------------------------------
### client.Order
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Provides full CRUD operations for orders, including filtering, canceling, closing, and opening orders. The ListAll method automatically handles pagination to retrieve all matching orders.
```APIDOC
## client.Order — orders with filtering, cancel, close, open
`OrderService` provides full CRUD plus `Cancel`, `Close`, and `Open` actions. `ListAll` automatically follows pagination to return every matching order.
### ListAll Orders
Fetches all orders matching the specified options, automatically handling pagination.
#### Parameters
- `ctx` (context.Context) - The context for the request.
- `opts` (goshopify.OrderListOptions) - Options for filtering and pagination.
### Get Order
Retrieves a single order by its ID.
#### Parameters
- `ctx` (context.Context) - The context for the request.
- `orderID` (uint64) - The ID of the order to retrieve.
- `options` (*goshopify.OrderGetOptions) - Optional parameters for retrieving the order.
### Cancel Order
Cancels an order with an optional reason and notification flag.
#### Parameters
- `ctx` (context.Context) - The context for the request.
- `orderID` (uint64) - The ID of the order to cancel.
- `options` (goshopify.OrderCancelOptions) - Options for cancellation, including reason and email notification.
### Count Orders
Counts all orders in the store, regardless of their status.
#### Parameters
- `ctx` (context.Context) - The context for the request.
- `options` (struct{ Status string `url:"status"` }) - Options for counting orders. Use `{"status": "any"}` to count all orders.
```
--------------------------------
### client.GraphQL.Query
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Executes GraphQL queries against the Shopify API, automatically handling rate limiting and unmarshalling responses.
```APIDOC
## client.GraphQL.Query — execute GraphQL queries
`GraphQLService.Query` POSTs to Shopify's `graphql.json` endpoint and unmarshals the `data` portion of the response into the supplied struct. It automatically handles GraphQL-level rate limiting with the configured `WithRetry` option.
### Execute a GraphQL query to get products
```go
ctx := context.Background()
type ProductNode struct {
Id string `json:"id"`
Title string `json:"title"`
}
type ProductEdge struct {
Node ProductNode `json:"node"`
}
type ProductsConn struct {
Edges []ProductEdge `json:"edges"`
}
type QueryResp struct {
Products ProductsConn `json:"products"`
}
q := `
query getProducts($first: Int!) {
products(first: $first) {
edges {
node {
id
title
}
}
}
}
`
vars := map[string]interface{}{"first": 5}
var resp QueryResp
if err := client.GraphQL.Query(ctx, q, vars, &resp); err != nil {
// RateLimitError is returned if retries are exhausted
if rlErr, ok := err.(goshopify.RateLimitError); ok {
fmt.Printf("Rate limited, retry after %d seconds\n", rlErr.RetryAfter)
return
}
log.Fatal(err)
}
for _, edge := range resp.Products.Edges {
fmt.Printf("Product: %s (%s)\n", edge.Node.Title, edge.Node.Id)
}
# Inspect GraphQL cost
fmt.Printf("Query cost: %d / available: %.0f\n",
client.RateLimits.GraphQLCost.RequestedQueryCost,
client.RateLimits.GraphQLCost.ThrottleStatus.CurrentlyAvailable)
```
```
--------------------------------
### Shopify OAuth Flow
Source: https://context7.com/bold-commerce/go-shopify/llms.txt
Handles the OAuth process: redirecting merchants to Shopify, verifying the callback signature, and exchanging the authorization code for an access token. Ensure the App struct is configured with API key, secret, redirect URL, and scopes.
```go
package main
import (
"context"
"fmt"
"net/http"
goshopify "github.com/bold-commerce/go-shopify/v4"
)
var app = goshopify.App{
ApiKey: "abcd",
ApiSecret: "efgh",
RedirectUrl: "https://example.com/shopify/callback",
Scope: "read_products,write_orders",
}
// Step 1: redirect merchant to Shopify
func InstallHandler(w http.ResponseWriter, r *http.Request) {
shopName := r.URL.Query().Get("shop") // e.g. "mystore.myshopify.com"
state := "random-nonce-1234"
authURL, err := app.AuthorizeUrl(shopName, state)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
http.Redirect(w, r, authURL, http.StatusFound)
}
// Step 2: handle callback, verify signature, exchange code for token
func CallbackHandler(w http.ResponseWriter, r *http.Request) {
if ok, err := app.VerifyAuthorizationURL(r.URL); !ok {
http.Error(w, "invalid signature: "+err.Error(), http.StatusUnauthorized)
return
}
shopName := r.URL.Query().Get("shop")
code := r.URL.Query().Get("code")
token, err := app.GetAccessToken(context.Background(), shopName, code)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
// persist token, then redirect
fmt.Fprintf(w, "Token acquired: %s\n", token)
}
```