Skip to content
Go client for the Shopify API
Branch: master
Clone or download
Pull request Compare This branch is 41 commits ahead, 1 commit behind getconversio:master.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
fixtures Shopify API versioning support (#48) Apr 25, 2019
.gitignore Adding debug webhook verify method (#18) Sep 28, 2018
.travis.yml Updating package names (#11) Sep 10, 2018
Dockerfile Updating package names (#11) Sep 10, 2018
LICENSE Update repo name, improve test coverage (#19) Apr 4, 2017
README.md Fix typo (#55) Jun 13, 2019
applicationcharge.go Shopify API versioning support (#48) Apr 25, 2019
applicationcharge_test.go Shopify API versioning support (#48) Apr 25, 2019
asset.go Shopify API versioning support (#48) Apr 25, 2019
asset_test.go Shopify API versioning support (#48) Apr 25, 2019
blog.go Shopify API versioning support (#48) Apr 25, 2019
blog_test.go Shopify API versioning support (#48) Apr 25, 2019
collect.go Shopify API versioning support (#48) Apr 25, 2019
collect_test.go Shopify API versioning support (#48) Apr 25, 2019
customcollection.go
customcollection_test.go Shopify API versioning support (#48) Apr 25, 2019
customer.go
customer_address.go Shopify API versioning support (#48) Apr 25, 2019
customer_address_test.go Shopify API versioning support (#48) Apr 25, 2019
customer_test.go Shopify API versioning support (#48) Apr 25, 2019
discount_code.go Shopify API versioning support (#48) Apr 25, 2019
discount_code_test.go Shopify API versioning support (#48) Apr 25, 2019
docker-compose.yml Updating package names (#11) Sep 10, 2018
draft_order.go Fix tag for DraftOrder (#49) May 3, 2019
draft_order_test.go Shopify API versioning support (#48) Apr 25, 2019
fulfillment.go Remove omit_empty from json tag for Fulfillment.NotifyCustomer (#56) Jun 20, 2019
fulfillment_test.go Shopify API versioning support (#48) Apr 25, 2019
goshopify.go Fixed Bug with backwards compatibility and api version (#53) May 16, 2019
goshopify_test.go Added test for when the `WithVersion` option is omitted (#54) May 21, 2019
image.go Shopify API versioning support (#48) Apr 25, 2019
image_test.go
inventory_item.go Shopify API versioning support (#48) Apr 25, 2019
inventory_item_test.go Shopify API versioning support (#48) Apr 25, 2019
location.go Shopify API versioning support (#48) Apr 25, 2019
location_test.go Shopify API versioning support (#48) Apr 25, 2019
metafield.go int to int64 type conversion for ID fields (#46) Mar 28, 2019
metafield_test.go Shopify API versioning support (#48) Apr 25, 2019
oauth.go Adding debug webhook verify method (#18) Sep 28, 2018
oauth_test.go Adding debug webhook verify method (#18) Sep 28, 2018
order.go Add AppliedDiscount to LineItem (#50) May 14, 2019
order_test.go Shopify API versioning support (#48) Apr 25, 2019
page.go Shopify API versioning support (#48) Apr 25, 2019
page_test.go Shopify API versioning support (#48) Apr 25, 2019
product.go Shopify API versioning support (#48) Apr 25, 2019
product_test.go Shopify API versioning support (#48) Apr 25, 2019
recurringapplicationcharge.go Shopify API versioning support (#48) Apr 25, 2019
recurringapplicationcharge_test.go Shopify API versioning support (#48) Apr 25, 2019
redirect.go Shopify API versioning support (#48) Apr 25, 2019
redirect_test.go Shopify API versioning support (#48) Apr 25, 2019
scripttag.go Shopify API versioning support (#48) Apr 25, 2019
scripttag_test.go Shopify API versioning support (#48) Apr 25, 2019
shop.go Shopify API versioning support (#48) Apr 25, 2019
shop_test.go Shopify API versioning support (#48) Apr 25, 2019
smartcollection.go Shopify API versioning support (#48) Apr 25, 2019
smartcollection_test.go Shopify API versioning support (#48) Apr 25, 2019
storefrontaccesstoken.go Shopify API versioning support (#48) Apr 25, 2019
storefrontaccesstoken_test.go Shopify API versioning support (#48) Apr 25, 2019
theme.go Shopify API versioning support (#48) Apr 25, 2019
theme_test.go Shopify API versioning support (#48) Apr 25, 2019
transaction.go Shopify API versioning support (#48) Apr 25, 2019
transaction_test.go Shopify API versioning support (#48) Apr 25, 2019
usagecharge.go Shopify API versioning support (#48) Apr 25, 2019
usagecharge_test.go Shopify API versioning support (#48) Apr 25, 2019
util.go Shopify API versioning support (#48) Apr 25, 2019
util_test.go Shopify API versioning support (#48) Apr 25, 2019
variant.go Shopify API versioning support (#48) Apr 25, 2019
variant_test.go Shopify API versioning support (#48) Apr 25, 2019
webhook.go Shopify API versioning support (#48) Apr 25, 2019
webhook_test.go Shopify API versioning support (#48) Apr 25, 2019

README.md

go-shopify

The new home of Conversio's Shopify Go library.

Note: The library does not have implementations of all Shopify resources, but it is being used in production and should be stable for usage. PRs for new resources and endpoints are welcome, or you can simply implement some yourself as-you-go. See the section "Using your own models" for more info.

Build Status codecov Join the chat at https://gitter.im/bold-commerce/go-shopify

Install

$ go get github.com/bold-commerce/go-shopify

Use

import "github.com/bold-commerce/go-shopify"

This gives you access to the goshopify package.

Oauth

If you don't have an access token yet, you can obtain one with the oauth flow. Something like this will work:

// 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")
    authUrl := app.AuthorizeURL(shopName)
    http.Redirect(w, r, authUrl, http.StatusFound)
}

// 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")
    token, err := app.GetAccessToken(shopName, code)

    // Do something with the token, like store it in a DB.
}

Api calls with a token

With a permanent access token, you can make API calls like this:

// 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 := goshopify.NewClient(app, "shopname", "token")

// Fetch the number of products.
numProducts, err := client.Product.Count(nil)

Private App Auth

Private Shopify apps use basic authentication and do not require going through the OAuth flow. Here is an example:

// 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 := goshopify.NewClient(app, "shopname", "")

// Fetch the number of products.
numProducts, err := client.Product.Count(nil)

Query options

Most API functions take an options interface{} as parameter. You can use one from the library or create your own. For example, to fetch the number of products created after January 1, 2016, you can do:

// 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)

The options are parsed with Google's go-querystring library so you can use custom options like this:

// 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)

Using your own models

Not all endpoints are implemented right now. In those case, feel free to implement them and make a PR, or you can create your own struct for the data and use NewRequest with the API client. This is how the existing endpoints are implemented.

For example, let's say you want to fetch webhooks. There's a helper function Get specifically for fetching stuff so this will work:

// 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
}

Webhooks verification

In order to be sure that a webhook is sent from ShopifyApi you could easily verify it with the VerifyWebhookRequest method.

For example:

func ValidateWebhook(httpRequest *http.Request) (bool) {
    shopifyApp := goshopify.App{ApiSecret: "ratz"}
    return shopifyApp.VerifyWebhookRequest(httpRequest)
}

Develop and test

There's nothing special to note about the tests except that if you have Docker and Compose installed, you can test like this:

$ docker-compose build dev
$ docker-compose run --rm dev

Testing the package is the default command for the dev container. To create a coverage profile:

$ docker-compose run --rm dev bash -c 'go test -coverprofile=coverage.out ./... && go tool cover -html coverage.out -o coverage.html'
You can’t perform that action at this time.