OAuth for 3rd Party Integrations

The following page details the technical flow of allowing users of your integration to authorize it to access their Foxy user and/or store through an OAuth client. For details on approaching this for a whitelabeled integration where you want to obscure Foxy from view of your users - see the OAuth for Whitelabeled Integrations page.

Register your OAuth Client

Check out the Creating an OAuth Client page for information on setting up a client for your integration

Forward the User to the Foxy Authorization Server

To allow your application to access a Foxy user or store, a user with access to that resource needs to grant that access. Within your application you can include a link or form to send the user to the Foxy Authorization server where they will be asked to log in and authorize your application.

Your application should forward users to the following URL

https://my.foxycart.com/authorize

The following values should be passed as GET parameters:

  • response_type - (required) should be set to “code”
  • client_id - (required) as returned when creating your applications OAuth Client
  • scope - (required) permissions you require. This can be either store_full_access if you need access to a users store, or user_full_access if you need access to their user account.
  • state - (required) a unique randomly generated string for this request which will be returned to your redirect_uri upon completion of the authorization request. This is used to assist with preventing cross-site request forgery.
https://my.foxycart.com/authorize?response_type=code&client_id=client_N9a5EgHjIQ95hsd0sD27&scope=store_full_access&state=abc123

Handling the Foxy Authorization Server response

If the user approves the request to access their store, they’ll be redirected to the endpoint set as your redirect_uri when creating your OAuth Client. The endpoint will be passed two GET parameters: code will be a single-use code that you can use to request the tokens necessary to interact with the API, and state will be the unique string you passed when sending the user to the Foxy Authorization server. If the state value received does not match what you passed in the previous request, you should abort the authorization process.

https://www.example.com/oauth?code=6fb99ac7815241d4b32d06de72e07ea4db59020e&state=abc123

The initial authorization response includes a code rather than the tokens because the response is sent in the clear as a URL parameter. As that isn’t a secure way to communicate sensitive details like access tokens that provide access to the user or store details - a single use code is sent instead. The code is only valid for 30 seconds, and can only be used once.

Error responses

If the user denied the request, or if there was some other error (for example, required fields weren’t passed) the user will be redirected back to your endpoint with the GET parameters of state and error, providing a short code describing the error. If available, an additional error_description parameter will provide a longer form description of the error as well. Your application should handle an error response appropriately.

https://www.example.com/oauth?state=abc123&error=access_denied&error_message=The+user+denied+access+to+your+application

Possible error responses

Error Message Action Required
access_denied The user denied access to your application Your application can display a message to the user that the operation is not possible without access.
invalid_client No client id supplied Supply a valid client id
invalid_client The client id supplied is invalid Confirm the client_id supplied is valid
invalid_client This application requires you specify a scope parameter Supply a valid scope
invalid_request Invalid or missing response type Ensure you’re passing code as the response type
invalid_request The state parameter is required Supply a state parameter
invalid_scope An unsupported scope was requested Confirm the scope you are requesting is valid

Request Access Tokens

After receiving a success response from the Foxy Authorization server, your application should immediately attempt to exchange the code you received for an access and refresh token to use when communicating with the API.

To do that, you POST to the Hypermedia API’s fx:token endpoint, accessible from the API home page.

➔ curl -H "FOXY-API-VERSION: 1" https://api.foxycart.com

{
    "_links": {
        ...
        "fx:token": {
            "href": "https://api.foxycart.com/token",
            "title": "The OAuth endpoint for obtaining a new access_token using an existing refresh_token. Post www-form-url-encoded data as follows: grant_type=refresh_token&refresh_token={refresh_token}&client_id={client_id}&client_secret={client_secret}",
            "type": "application/json"
        }
    }
}

The following values need to be POSTed to the token endpoint:

  • grant_type - (required) set to authorization_code
  • code - (required) set to the code received from the Foxy Authorization server
  • redirect_uri - (required) must match the original URI set when creating the client exactly.

The call also needs to be authenticated to the respective OAuth Client. If possible, passing those details as a header using HTTP Basic Authentication is recommended. To create the header value, base64 encode a combination of the client_id and the client_secret, joined with a :, for example in PHP:

$basic_auth_header = base64_encode($client_id . ":" . $client_secret);

You then pass the encoded value as a header with your request like this:

Authorization: Basic Y2xpZW50X045YTVFZ0hqSVE5NWhzZDBzRDI3OlZzejI2dWUzOFFkU0lnSVFTazRyRGg5YkRCbVRRNE5WU3BoQ1JQbUw=

If HTTP Basic Authentication is not possible, you can instead POST the values separately:

  • client_id - as returned when creating your applications OAuth Client
  • client_secret - as returned when creating your applications OAuth Client

If successful, in response your application will receive an access_token, refresh_token and access_token_expires. The access_token and refresh_token should be securely stored within your application as detailed on this page. The access_token_expires value notes in seconds how long until the returned access token will expire, and you can optionally store that to keep a record of when the access token will need to be refreshed.

➔ curl -H "FOXY-API-VERSION: 1" -H "Authorization: Basic Y2xpZW50X045YTVFZ0hqSVE5NWhzZDBzRDI3OlZzejI2dWUzOFFkU0lnSVFTazRyRGg5YkRCbVRRNE5WU3BoQ1JQbUw=" https://api.foxycart.com/token -d "grant_type=authorization_code&code=6fb99ac7815241d4b32d06de72e07ea4db59020e&redirect_uri=https://www.example.com/oauth"

{
    "access_token":"76e9237hHosdp4890sjjafu38U78HJSund7295a9",
    "expires_in":7200,
    "token_type":"Bearer",
    "scope":"store_full_access store_id_3200",
    "refresh_token":"812j49yns9HS46HJ4Djdn38s4HujSHB40S08dd33"
}

Authenticating API Calls

With the Access token in hand, your application can begin interacting with the Foxy API. Requests to the API need to include the access_token in the Authorization header for the protected resource you're wanting to work with, along with the version of the API you’re connecting to:

FOXY-API-VERSION: 1
Authorization: Bearer 76e9237hHosdp4890sjjafu38U78HJSund7295a9

For more details on working with the API, see the API Reference.

Refreshing the Access Token

As the Access Token expires after 2 hours, if your integration needs to access the protected resource beyond that point, you’ll need to use the corresponding refresh_token and the fx:token endpoint of the API to request a new access_token. Review the Refreshing the Access Token page for details on doing that.