Giter Site home page Giter Site logo

exshopify's Introduction

ExShopify

Elixir client for the Shopify REST API.

Documentation

Installation

def deps do
  [
    {:exshopify, "~> 0.9"},
    {:hackney, "~> 1.15"},
    {:jason, "~> 1.1"},
    # only required when rate limiting
    {:gen_stage, "~> 0.14"}
  ]
end

ExShopify allows you to use the HTTP client and JSON codec of your choice. However, we support hackney and jason out of the box. If you would like to use a different HTTP client or JSON codec please see (link to something here).

Making Requests

Making requests to the API is done using the Shopify.request/3 function. It's arguments are an operation, a session (more on sessions below) and an optional config.

An operation is a struct that describes the HTTP request to be executed. You can create an operation manually but typically you would use one of the resource modules to create one for you.

Example

Shopify.Customer.list() |> Shopify.request(session)

You can see which resource modules have been implemented under Supported Endpoints. If we have not added support for an endpoint you need you can still make a request by constructing an operation manually.

Example

%Shopify.Operation{http_method: :get, path: "/customers.json"} |> Shopify.request(session)

Opening issues and PR's for unsupported endpoints is always appreciated.

Configuration

When making a request you can pass an optional map as the third argument to provide config per request.

Example

config = %{http_client: MyHttpClient}

Shopify.Customer.list() |> Shopify.request(session, config)

Configuration Options

  • :host - HTTP host to make requests to. Defaults to myshopify.com.
  • :http_client - the HTTP client used to make requests. Takes a module that implements the Shopify.Client behaviour. Defaults to Shopify.Client.Hackney.
  • :http_client_opts - options to be passed to the configured :http_client
  • :json_codec - the JSON encoder and decoder. Defaults to Jason.
  • :port - the HTTP port used when making requests
  • :scheme - the HTTP scheme used when making requests. Defaults to https.

Authentication

Shopify provides two authentication strategies when making API requests: public and private.

Public apps allow you to interact with the Shopify API on behalf of multiple stores. Private apps, on the other handle, allow you to make requests on behalf of only a single store.

ExShopify handles this distinction using something we call "sessions". A session contains all the information necessary to make requests to the Shopify API as either a public app or a private app.

Mutipass sessions are a special use case: they are used to create a token that is used to support a single-sign-on (SSO) operation that lets your app authenticate a user and then redirect them to the Shopify store.

Additional Reading

Private Sessions

You can make API requests as a private app using a private session. A private session can be created using the Shopify.new_private_session/3 function. This function takes shop name, api key and password as arguments.

Example

session = Shopify.new_private_session("johns-apparel", "4478eb7ac138a136852babd861956c19", "3e5a6edec71eab039422c6444d02659d")

Public Sessions

You can make API requests as a public app using a public session. Public sessions are also used when obtaining an OAuth access token. You can create a public sessions using the Shopify.new_public_sessions/2 function. This function takes a shop name and an optional access token as arguments.

Example

session = Shopify.new_public_session("johns-apparel", "f85632530bf277ec9ac6f649fc327f17")

OAuth

For a detailed explanation of the Shopify OAuth authorization process please see the Shopify OAuth documentation.

You can obtain an access token using the Shopify.OAuth.get_access_token/1 function.

Example

session = Shopify.new_public_session("johns-apparel")

%{client_id: "43f41262ce65cd5d4e8a4081649208e3", client_secret: "2240ab28b61f42e6c8bfc0adcbfc5ac2", code: "18djf91ufv0vkr938z7b69v810v710v7"}
|> Shopify.OAuth.get_access_token()
|> Shopify.request(session)

Multipass

Multipass allows your website to be the single source of truth for authentication; you can pass your customer data to Shopify via an encrypted token and Shopify will use that information to log in to your Shopify store.

Note: the Multipass feature is only available to Shopify Plus plans.

To use this feature, you will need your Multipass secret (a 32 character value that gets created when you enable Multipass within your store's checkout settings).

At a minimum, you must provide the customer's email and a created_at datetime in ISO8601 format. The time must be current: the tokens generated for Multipass logins are valid for only a short period of time.

Examples

Given the following customer data and multipass secret:

# From your Shopify Checkout Settings:
multipass_secret = "1234567890abcdef1234567890abcdef"

customer_data = %{
  email: "[email protected]",
  created_at: DateTime.to_iso8601(Timex.now())
}

Get the Sign-in Url

url = Shopify.Multipass.get_url("myteststore", customer_data, multipass_secret)

# Redirect to:
# "https://johnsapparel.myshopify.com/account/login/multipass/f88EnlbFeWADw...8hlT6vevRH0Dtk="

Use a fully custom domain

If your Shopify shop is hosted on a custom domain, provide a map specifying the host: key and the TLD:

url = Shopify.Multipass.get_url("johnsapparel", customer_data, multipass_secret, %{host: "com"})

# Redirect to
# "https://johnsapparel.com/account/login/multipass/f88EnlbFeWADw...8hlT6vevRH0Dtk="

Get the Token

If desired, you can grab only the token and assemble the URL yourself:

token = Shopify.Multipass.get_token(customer_data, multipass_secret)

# Assemble your own login URL, e.g.
"https://johns-apparel.myshopify.com/account/login/multipass/#{token}"

Rate Limiting

You can throttle your requests to the Shopify REST API by using the Shopify.Client.RateLimit HTTP client. This client will throttle the requests it sends to Shopify in order to stay below the maximum call limit.

Shopify.Client.RateLimit acts as a pass through. It only implements the rate limiting logic and hands off the responsibility of making an actual HTTP request to the HTTP client of your choice.

To use Shopify.Client.RateLimit you will need to add gen_stage as a dependency. You will also need to add Shopify.RateLimiter to your supervision tree.

When making API requests you will need to specify Shopify.Client.RateLimit in the request config as :http_client. You will then need to specify the pass through HTTP client in the :http_client_opts config option.

Example

config =
  %Shopify.Config{
    http_client: Shopify.Client.RateLimit,
    http_client_opts: [
      http_client: Shopify.Client.Hackney,
      http_client_opts: [] # optional
    ]
  }

Shopify.Product.list() |> Shopify.request(session, config)

Supported Endpoints

  • Shopify Payments
    • Balance
    • Payouts
    • Transactions
  • Access
    • AccessScope
    • StorefrontAccessToken
  • Analytics
    • Report
  • Billing
    • ApplicationCharge
    • ApplicationCredit
    • RecurringApplicationCharge
    • UsageCharge
  • Customers
    • Customer
    • CustomerAddress
    • CustomerSavedSearch
  • Discounts
    • DiscountCode
    • PriceRule
  • Events
    • Event
    • Webhook
  • Inventory
    • InventoryItem
    • InventoryLevel
    • Location
  • MarketingEvent
  • Metafield
    • Article
    • Blog
    • CustomCollection and SmartCollection
    • Customer
    • Draft Order
    • Order
    • Page
    • Product
    • Product Variant
    • Product Image
    • Shop
  • Online Store
    • Asset
    • Blog
    • BlogArticle
    • Comment
    • Page
    • Redirect
    • ScriptTag
    • Theme
  • Orders
    • AbandonedCheckout
    • DraftOrder
    • Order
    • OrderRisk
    • Refund
    • Transaction
  • Plus
    • GiftCard
    • Multipass
    • User
  • Products
    • Collect
    • CustomCollection
    • Product
    • ProductImage
    • ProductVariant
    • SmartCollection
  • Sales Channel
    • Checkout
    • CollectionListing
    • Payment
    • ProductListing
    • ResourceFeedback
  • Shipping and Fulfillment
    • CarrierService
    • Fulfillment
    • FulfillmentEvent
    • FulfillmentService
  • Store Properties
    • Country
    • Currency
    • Policy
    • Province
    • ShippingZone
    • Shop
  • TenderTransaction

Contributors

A special thanks to all of our contributors!

exshopify's People

Contributors

anthonator avatar kernelmadness avatar oohnoitz avatar pjungwir avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

exshopify's Issues

README instructions a bit out of date

The installation instructions in the readme should be bumped to reference the most current version of the exshopify app and its dependencies, e.g.

{:exshopify, "~> 0.8.0"},
{:hackney, "~> 1.15"},
{:jason, "~> 1.1"}

Feature: Support Metafields for customers

It would be nice if the functions allowed us to explicitly deal with Metafields. Functionality would have to be added to each resource type that supports metafields.

Newbie question: Functions in top Shopify module not available

Hi, my apologies as I am sure I am missing something obvious, but:

When I am trying to call Shopify.request() I'm getting:

Shopify.new_public_session/2 is undefined or private

In the iex session, I am able to tab into the other sub-modules etc though.

Only the functions defined at the top module (Shopify) seem to be not available.

Any clue on what I might be missing?

I tried both with import Shopify and alias Shopify in my own module which is named ShopifyAPI.Asset

Calls using Private Session fail with 401

Private sessions do not seem to be properly creating a URL.

Example:

store_name = "teststore"
api_key = "xxxxxxx"
password = "yyyyyy"
session = Shopify.new_private_session(store_name, api_key, password)

Shopify.Customer.list() |> Shopify.request(session)

Expected: results similar to those returned by the sample URL that Shopify lists when you create your private app, e.g. https://xxxxxxxxxxxxxx:[email protected]/admin/customers.json

Actual: 401 status code.

To consider: what if our store uses a custom domain name and is not a subdomain of myshopify? Can the host config option be changed to get a result for that scenario? The build_url/3 function may not handle a completely custom domain with this line: host: "#{session.shop_name}.#{config.host}"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.