Last updated

Voyado

How to get started and work with Voyado

NB: This requires configuration in internal systems in order to work.

If not configured properly, you'll get presented with the following error:

{
  "message": "Internal system responded with status code NotImplemented",
  "extensions": {
    "code": "ExternalCustomerLookupFailed",
    "codes": ["ExternalCustomerLookupFailed"]
  }
}

external customer lookup

For the lookup you'll be using the externalCustomerLookup endpoint with a key argument. The key is configured internally and can be one of the following: email, phone or pid. The action you should be doing differs depending on the response from the endpoint, meaning you are able to end up in five different states, presented below.

Call externalCustomerLookup

NON_EXISTING_CUSTOMER

PREEXISTING_CUSTOMER

ACTIVATION_REQUIRED

COUNTRY_NOT_VALID

ADDITIONAL_USER_DATA_REQUIRED

query ExternalLookup($key: String) {
  externalCustomerLookup(key: $key) {
    status
    customer {
      firstName {
        masked
        encrypted
      }
      externalId
    }
  }
}
{
  "data": {
    "externalCustomerLookup": {
      "status": "NON_EXISTING_CUSTOMER",
      "customer": null
    }
  }
}
{
  "data": {
    "externalCustomerLookup": {
      "status": "ADDITIONAL_USER_DATA_REQUIRED",
      "customer": {
        "firstName": {
          "masked": "Er**",
          "encrypted": "eTZ7FGaVn/RAThBesp3unQ=="
        }
        "email": {
          "masked": "h*j@o**ry.cool",
          "encrypted": "a3k/eW8DeaassJrelr2xuw=="
        },
        "externalId": "af083b2e-1a88-42ae-afbc-ac63008e277d"
      }
    }
  }
}
{
  "data": {
    "externalCustomerLookup": {
      "status": "ACTIVATION_REQUIRED",
      "customer": {
        "firstName": {
          "masked": "Aktivera",
          "encrypted": "Q8XIf+4IC6TMgLPYtFxi3Q=="
        },
        "email": {
          "masked": "h*j@o**ry.cool",
          "encrypted": "a3k/eW8DeaassJrelr2xuw=="
        },
        "externalId": "af083b2e-1a88-42ae-afbc-ac63008e277d"
      }
    }
  }
}
{
  "data": {
    "externalCustomerLookup": {
      "status": "PREEXISTING_CUSTOMER",
      "customer": null
      }
    }
  }
}

Keep in mind here that you're supposed to take action based on the response inside status field. For example, if the status is NON_EXISTING_CUSTOMER then you likely want to present a signup form and so on.

As you may have noticed, we only return the customer data when status is either ACTIVATION_REQUIRED or ADDITIONAL_USER_DATA_REQUIRED. ADDITIONAL_USER_DATA_REQUIRED means there are fields present and required in Norce admin, but the information is missing in Voyado. The customer object returns all needed fields for an actual signup. Each data point inside the customer object is masked or encrypted. The masked data can be presented as information or as a prefilled form. The encrypted values should be sent in as SignupInput in order for our backend to decrypt them.

person lookup

In some cases the client is using a third party to fetch information based on PID. This is done from within Voyado but should be queried from our StoreAPI. In these cases you'd want to use the personLookup endpoint. This is useful when the end user is not registered and you want a prefilled form based on the response. Same logic applies to this action, prefill form with masked data and send the encrypted ones as SignupInput.

query PersonLookup($key: String) {
  personLookup(key: $key) {
    firstName {
      masked
      encrypted
    }
  }
}
{
  "data": {
    "personLookup": {
      "firstName": {
        "masked": "Einár",
        "encrypted": "eTZ7FdwVn/RAThadBesunQ=="
      }
    }
  }
}

activate customer by id

In order for the Norce - Voyado to work the customer must exist in both Voyado and Norce. The status ACTIVATION_REQUIRED is returned when the customer exists in Voyado, but not in Norce. This is where you'd want to use the activateExternalCustomerById endpoint. The only required argument for this endpoint is the returned value in externalId you got from the lookup query.

mutation ActivateByExternalId($input: ActivateExternalCustomerByIdInput) {
  activateExternalCustomerById(
    input: $input
  ) {
    success
    token {
      value
    }
  }
}
{
  "data": {
    "activateExternalCustomerById": {
      "success": true,
      "token": {
        "value": "<your token>"
      }
    }
  }
}

If the activation succeded, we'll automatically send an email to the customer, where they are able to set a password for the account. This email is only editable by our product support. You can however use the token to do a soft login. Soft logged in means the customer have access to personal information and discounts, they are able to make a purchase but they are not able to change any information regarding the account.

active customer by token

The second option for account activation is to click a link from within a promotion email sent by Voyado. This time we'll be using the activateExternalCustomerByToken endpoint, the argument is the token appended by Voyado in the promotion email link.

mutation ActivateByToken($input: ActivateExternalCustomerByTokenInput) {
  activateExternalCustomerByToken(
    input: $input
  ) {
    success
    customer {
      firstName {
        masked
        encrypted
      }
      email {
        masked
        encrypted
      }
      externalId
    }
  }
}
{
  "data": {
    "activateExternalCustomerByToken": {
      "success": true,
      "customer": null
    }
  }
}
{
  "errors": [
    {
      "message": "AdditionalUserDataRequired",
      "extensions": {
        "code": "InvalidCustomerActivateInput",
        "codes": [
          "InvalidCustomerActivateInput"
        ]
      }
    }
  ],
  "data": {
    "activateExternalCustomerByToken": {
      "success": false,
      "customer": {
        "firstName": {
          "masked": "Er**",
          "encrypted": "eTZ7FGaVn/RAThBesp3unQ=="
        },
        "email": {
          "masked": "a*d@je***op.se",
          "encrypted": "Iyafl0B5de6zG+++YS9caw=="
        },
        "externalId": "220999da-3f78-45a4-91b3-ac6200e7a416"
      }
    }
  }
}

In this scenario too, the customer may end up in a AdditionalUserDataRequired state where you have an option to either fail the activation and persist the url the customer tried to visit, or to redirect to a signup form. If succeded, keep in mind that this always soft logins the customer.

loyalties

Loyalties can be unique for each customer and can only be queried for when a valid Authorization header is present. All loyalties are added in Voyado.

query Loyalties($includeRedeemed: Boolean!) {
  customerLoyalty {
    bonusChecks {
      name
      redeemed
      value
    }
    pointCards {
      name
      numberOfSlots
      numberOfSlotsRemaining
    }
    discounts(includeRedeemed: $includeRedeemed) {
      name
      description
      isActivatedByDiscountCode
      discountCode
    }
    bonusPoints {
      points
    }
  }
}
{
  "data": {
    "customerLoyalty": {
      "bonusChecks": [
        {
          "name": "Bonusutbetalning 2021-12-02 10:00",
          "redeemed": false,
          "value": 600
        }
      ],
      "pointCards": [],
      "discounts": [
        {
          "name": "Alla glada",
          "description": "",
          "isActivatedByDiscountCode": false
          "discountCode": null
        }
      ],
      "bonusPoints": {
        "points": 0
      }
    }
  }
}

complete lookup flow example

NB: This is an exmpale on how you could present your UI when utilizing all or some of the lookup and activation endpoints.

Calls externalCustomerLookup

NON_EXISTING_CUSTOMER

PREEXISTING_CUSTOMER

ACTIVATION_REQUIRED

COUNTRY_NOT_VALID

ADDITIONAL_USER_DATA_REQUIRED

If configured,
manually/automatically calls personLookup

Yes

No

Manually/automatically calls
activateExternalCustomerById

No

Yes

Manually/automatically login

Customer fills LookupField

Lookup success

Returns no customer data

Can login

Returns masked and
encrypted customer data

Returns countryCode

Returns masked customer data

Customer manually
fills required fields

Customer data found

Prefills signup form
with personLookup response

Success

Present error message / try again

Customer activated
Returns temporary auth token

Soft logged in

Present error message

Populates signup form
with masked data

Customer manually fills in
missing required data

Can create customer

complete softlogin flow example

NB: This is an exmpale on how you could present your UI when utilizing all or some of the activation endpoints.

Automatically
calls loginExternalCustomer

No

Yes

Yes

No

Yes

No

No

Yes

NON_EXISTING_CUSTOMER

ADDITIONAL_USER_DATA_REQUIRED

ACTIVATION_REQUIRED

PREEXISTING_CUSTOMER

Yes

No

Customer clicks campaign link with hash

Was customer logged in?

Is activation on softlogin configured

Continue to campaign destination
with personal discounts

Calls activateExternalCustomerByToken

Is redirect on activation
failure configured

Signup page

Continue to campaign destination
without personal discounts

Customer found?

Checks customer status

Is activation on
softlogin configured