App Instance (Client Side)

Note:
There are two types of App Instance, the below info refers to the App Instance that gets returned in the client:

  • In iframe endpoints
  • For external dashboard apps when clicking the "Open App" button 
  • For apps with an external package picker when clicking the "Upgrade App" button.

For the API instance see here, note though that most new apps will use both of these, and while there are many similarities they're not identical.
The Wix platform accesses each of your app endpoints using a URL with a set of query parameters that describes the endpoint context. The most important of these is the instance parameter.

The instance parameter enables you to identify the site and the Wix user, and to verify that the calling party is indeed Wix. The identity of the calling party is verified by a digital signature that's generated using the app secret key, which is generated during the app registration process in the Wix Developers' Center.
The instance parameter is composed of two parts that are separated by a dot:

  1. Signature: HMACSHA-256 signature. Generated using the App Secret Key and the data part of the instance. The signature is Base64 URL encoded.
  2. Data: A Base64 URL encoded JSON object. This JSON includes the instance properties, listed below. You’ll need to decode the data to see these properties.

Example of an instance query parameter:
1
2
// Signature                                Data
vrinSv2HB9tqbnJ6RSwoMgVamAIxpmmsA0I6eAan960.eyJpbnN0YW5jZUlkIjoiYWZmNTAxNmQtMjkxNC00ZDYzLWEzOGMtYTZk...

Instance properties

These properties make up the data part of the Instance parameter. They’re encoded with base64 URL, so you’ll need to decode it.
Field
Description
instanceId
The instance ID of the app within Wix. Read more about the App Instance ID below.

Note for "old" SDK users: To get the instanceId of your app in a given site, use the Wix.Utils.getInstanceId SDK method.
signDate
The date of the payload signature. 
uid
(Optional) The ID of the Wix user or site member who is logged in:
  • In the Wix Editor: The ID of the site owner or one of the site’s contributors.

  • In the live site: The ID of the site member (a site visitor who signed up for the site's "membership zone", or the site owner). If the site visitor is not a member, the value is null.

    Note: To check if the site owner is logged in, compare the uid to the siteOwnerId property. If they are not the site owner, then hide any sensitive data or settings from them (such as payment settings).
permissions
The permission set of the Wix user or site member:
  • In the Wix Editor: The permissions value is “OWNER” if the site owner or a contributor is logged in (based on the uid).

  • In the live site: The permissions value is “OWNER” only if the site owner is logged in. Otherwise, this property is not included in the instance.

Note: To check if the site owner is logged in, compare the uid to the siteOwnerId property.
ipAndPort (deprecated)
The user's current IP address and port number. 
vendorProductId
(Optional, appears if the site owner upgraded the app) The Plan ID of the package the site owner purchased. 
aid
The ID of an anonymous site visitor.  
originInstanceId
(Optional, appears in copied sites) The instance ID of the app in the original website.  
siteOwnerId
The ID of the site owner. When this value is the same as the uid, it means the site owner is logged in.

Note: The siteOwnerId for a given instanceId can change. If a site owner transfers the site to another user, the existing instanceId is now linked to the new site owner. For example - User A transfers the site to User B. The app keeps its instanceId - but is now linked to User B's siteOwnerId.

App Instance ID

The App Instance ID is the unique identifier of the app within the website. Read more about the app instance ID.
Note for "old" SDK users:
To get the instanceId of your app in a given site, use the Wix.Utils.getInstanceId SDK method.
Important:
Consent policy will be passed as a query param in the iframe URL – but it's for internal use and will not necessarily be accurate. Your app should not depend on it at all.

JSON example

1
2
3
4
5
6
7
8
9
10
{
"instanceId":"bf296da1-75ce-48e6-9f72-14b7148d4fa2",
"signDate":"2015-12-10T06:57:37.201Z",
"uid":"da32cbf7-7f8b-4f9b-a97e-e67f3072ce92",
"permissions":"OWNER",
"ipAndPort":"91.199.119.13/35734",
"vendorProductId":null,
"originInstanceId":"c38e4e00-dcc1-433e-9e90-b332def7b342",
"siteOwnerId":"da32cbf7-7f8b-4f9b-a97e-e67f3072ce92"
}

Parsing examples

Node.JS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const CryptoJS = require("crypto-js");
function verifyInstance(instance, secret) {
   // spilt the instance into signature and data
   var pair = instance.split('.');
   var signature = decode(pair[0], 'binary');
   var data = pair[1];
   // sign the data using hmac-sha1-256
   var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, secret);
   hmac.update(data);
   var hash = decode(hmac.finalize().toString(CryptoJS.enc.Base64), 'binary')
   return (signature === hash)
}
function decode(data, encoding) {
  encoding = encoding === undefined ? 'utf8' : encoding
  var buf = Buffer.from(data.replace(/-/g, '+').replace(/_/g, '/'), 'base64')
  return encoding ? buf.toString(encoding) : buf;
}

PHP

1
2
3
4
5
6
7
8
9
10
11
12
13
public static function &isWixRequest() {
 
    list( $code, $data ) = explode( '.', $_GET[ 'instance' ] );
 
    if ( base64_decode( strtr( $code, "-_", "+/" ) ) != hash_hmac( "sha256", $data, '[APP_SECRET]', TRUE ) ) {
        die();  // Report error
    }
 
    if ( ( $json = json_decode( base64_decode( $data ) ) ) === null ) {
        die();  // Report error
    }
    return $json;
}

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
----------------------------------------------------------------------
The following example uses the apache commons-codec library for Base64 encoding and Jackson for JSON parsing.
 
The Maven dependencies of those libraries are:
 
    commons-codec
    commons-codec
    1.6
 
    com.fasterxml.jackson.core
    jackson-databind
    2.0.4        
 
-----------------------------------------------------------------------
 
import java.util.Arrays;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
 
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
 
import org.apache.commons.codec.binary.Base64;
 
public class WixSignatureDecoder {
 
 public final static JsonNode decodeSignature(final String signedInstance, final String secretKey) throws Exception {
  // initialization
  final SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "HMACSHA256");
  final Mac mac = Mac.getInstance("HMACSHA256");
  mac.init(secretKeySpec);
 
  // split the signed-instance
  Base64 base64 = new Base64(256, null, true);
  int idx = signedInstance.indexOf(".");
  String signature = signedInstance.substring(0, idx);
  String encodedJson = signedInstance.substring(idx+1);
 
  byte[] sig = base64.decode(signature.getBytes());
  byte[] mySig = mac.doFinal(encodedJson.getBytes());
  if (!Arrays.equals(mySig, sig))  {
      throw new Exception("signatures do not match");
  } 
 
     // objectMapper is jackson interface for reading JSON - one JSON serialization library in java
     return objectMapper.readTree(new String(base64.decode(encodedJson)));
 }
}

Ruby

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def parse_instance_data(signed_instance)
    APP_SECRET = 'YOUR_APP_SECRET_GOES_HERE'
    signature, encoded_json = signed_instance.split('.', 2)
 
    # Need to add Base64 padding to make base64 decode work in Ruby. (ref: http://stackoverflow.com/questions/4987772/decoding-facebooks-signed-request-in-ruby-sinatra)
 
    encoded_json_hack = encoded_json + ('=' * (4 - encoded_json.length.modulo(4)))
 
    json_str = Base64.decode64(encoded_json_hack)
 
    hmac = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, APP_SECRET, encoded_json)
 
    # bug in ruby. why are there '=' chars on urlsafe_encode ?!
 
    my_signature = Base64.urlsafe_encode64(hmac).gsub('=','')
 
    raise "the signatures do not match" if (signature != my_signature)
 
    JSON.parse(json_str)
 
end

Padding

The Base64 spec indicates that for URL-Safe Base64, the padding characters at the end of the encoded character (=) are optional. Wix encoding does not add the padding character.

In Ruby or Python, you should add the padding to the Base64 encoded values that you get from Wix.