> ## Documentation Index
> Fetch the complete documentation index at: https://developer.voyado.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Field definitions

## The datetime format

Engage expects dates and times to be formatted according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) with Time Zone Designators. For example:

```
2021-11-12T10:14:00+01:00
```

This represents 10:14 on the 12th of November, 2021, in a time zone one hour ahead of [UTC](https://en.wikipedia.org/wiki/Coordinated_Universal_Time).

<Warning>
  Use local time with an offset, like in the example shown, instead of converting to UTC time.
</Warning>

## Transactions

<ResponseField name="contact.matchKey" type="string" required>
  A value to match against the specified `customerKeyType` and `contactType`.
</ResponseField>

<ResponseField name="contact.matchKeyType" type="string" required>
  What the `matchKeyType` value represents. Options are: contactId, memberNumber, socialSecurityNumber, mobilePhone, externalId, email.
</ResponseField>

<ResponseField name="contact.contactType" type="string" required>
  If used, matching will only be done for this contactType. If NOT used the default value will be "Member".
</ResponseField>

<ResponseField name="uniqueReceiptId" type="string" required>
  If a transaction already exists with this `uniqueReceiptId` the new transaction with the same value will be seen as a duplicate and ignored.
</ResponseField>

<ResponseField name="createdDate" type="datetime" required>
  Datetime when order was first created formatted according to ISO 8601. Example: 2017-09-06T15:55:54+01:00.
</ResponseField>

<ResponseField name="storeExternalId" type="string" required>
  The external id for the store (usually a numerical code).
</ResponseField>

<ResponseField name="currency" type="currency" required>
  The currency code according to ISO 4217 for the currency that the customer paid in (local currency). Example: NOK, SEK, EUR.
</ResponseField>

<ResponseField name="totalGrossPrice" type="decimal" required>
  The total price paid by the customer including VAT. A decimal point (.) is always used as decimal separator. If the transaction is of type RETURN then `totalGrossPrice` should be negative.
</ResponseField>

<ResponseField name="paymentMethods" type="rows" required>
  All payment methods used in this transaction.
</ResponseField>

<ResponseField name="items" type="rows" required>
  One row per line item in the transaction.
</ResponseField>

<ResponseField name="receiptNumber" type="string" required>
  The transaction number, does not need to be unique.
</ResponseField>

<ResponseField name="exchangeRateToGroupCurrency" type="decimal">
  Currency values for a transaction should be in the local currency. This multiplier is used to convert those to a group currency when storing them for segmentation and reporting. Omitting this will cause problems.
</ResponseField>

<ResponseField name="usedRewardVouchers" type="rows">
  One row per used reward voucher.
</ResponseField>

<ResponseField name="usedPromotions" type="rows">
  One row per used promotion.
</ResponseField>

While `exchangeRateToGroupCurrency` is not mandatory, it's recommended in order to ensure that currency conversions are correct. If no exchange rate is sent, Engage will use the fallback conversion set up in the back-end.

If `contact.matchKeyType` is set to `contactId`, then `contact.contactType` is not a required field. In this case, if the value is not given, Engage will just use whatever your default contact type is.

## paymentMethods\[row]

<ResponseField name="type" type="string" required>
  Predefined values can be set: “card”, “cash”, “creditcard”, “swish”, “klarna”.\
  If your value does not match one of the above, it will be categorized as custom: “custom:\[value]” (max 245 characters).
</ResponseField>

<ResponseField name="value" type="decimal" required>
  Amount as a decimal. This can't be empty.
</ResponseField>

<ResponseField name="description" type="string">
  Descriptive text (max 255 characters).
</ResponseField>

<ResponseField name="extraData" type="array">
  Additional data regarding the specific payment method.
</ResponseField>

## items\[row]

<ResponseField name="type" type="string" required>
  A line item can either be a PURCHASE or a RETURN.
</ResponseField>

<ResponseField name="sku" type="string" required>
  Stock keeping unit.
</ResponseField>

<ResponseField name="articleNumber" type="string" required>
  Can be the same as the SKU.
</ResponseField>

<ResponseField name="articleName" type="string" required>
  The name.
</ResponseField>

<ResponseField name="quantity" type="integer" required>
  Number of units sold in this line item. Must be negative for a return.
</ResponseField>

<ResponseField name="grossPaidPrice" type="decimal" required>
  The paid price including VAT for this line item. Note: always withdraw discount values for the item itself or the distributed discount value for a total discount. Read more under Discounts.
</ResponseField>

<ResponseField name="taxAmount" type="decimal" required>
  The VAT paid for this line item.
</ResponseField>

<ResponseField name="taxPercent" type="decimal" required>
  The VAT (moms) percentage for this line item.
</ResponseField>

<ResponseField name="articleGroup" type="string">
  The group.
</ResponseField>

<ResponseField name="marginPercent" type="decimal">
  The margin in percent on this order line. Can't be empty or negative. Note that your Engage instance needs to be activated for searching on margins. Please contact your Voyado team for configuration requests.
</ResponseField>

<ResponseField name="awardsPoints" type="bool">
  Flag that controls if the line item should award points or not when generating reward points. Values are "true" or "false". If not specified, this will default to "true".
</ResponseField>

<ResponseField name="extraData" type="array">
  Key/value pairs for additional data regarding the transactional line item apart from the article meta-data.
</ResponseField>

<ResponseField name="discounts" type="rows">
  Could be several sources of discounts for the total discount. One row per discount type.
</ResponseField>

<Tip>
  The `grossPaidPrice` value sent to Engage always reflects the total price paid for a specific item or multiples of that item. So if `quantity` for an item is greater than 1 (or less than -1) then `grossPaidPrice` is the total price of all those items. Or to put it another way, the calculation of (quantity \* item price) is already done. Of course, if `quantity` is 1, then `grossPaidPrice` is just the single item price.
</Tip>

<Tip>
  For returns, `quantity` is always negative but `grossPaidPrice` is still positive.
</Tip>

## Discounts - items\[row].discounts\[row]

Engage requires discounts to be taken care of before the data is sent. The `grossPaidPrice` should always describe the amount the contact has paid for the item, meaning that the discount values withdrawn with the following patterns:

* Full discounts (*e.g. 20% off the whole purchase*) should always be applied for every line item, equally distributed.
* Specific transaction item discounts should be withdrawn for the specific line item only.

Regardless of the nature of a discount, `item.discount` can be used to tell Engage what discounts have been used. If a line item is exposed to both a full discount, for instance 20% on a whole purchase, and a 100 SEK off for that article, these are combined to make the total value withdrawn from the original price. These aggregated row values are stored as a parameter for searching in Engage.

<Frame caption="Aggregated row values as search parameter">
  <img src="https://mintcdn.com/voyado/1UQKz-_fA36SqHpz/images/field-definitions-01.png?fit=max&auto=format&n=1UQKz-_fA36SqHpz&q=85&s=f347efaa52056c82042b467a4ba6dc32" alt="Screenshot of Engage showing how the aggregated row values can be used as a search parameter" width="729" height="379" data-path="images/field-definitions-01.png" />
</Frame>

In Engage the search locates every transaction connected to a particular contact that contains one or more items that have been exposed to discounts greater/less/equal to a total value or total percentage of the original price.

<Tip>
  Searching using discounts needs to be activated in your set-up. Please contact your Voyado team about this.
</Tip>

<ResponseField name="value" type="decimal" required>
  Discount value in the local currency. Should always be negative. Searching for discounts in Engage is possible.
</ResponseField>

<ResponseField name="type" type="string" required>
  Type of discount.
</ResponseField>

<ResponseField name="description" type="string">
  A description.
</ResponseField>

<ResponseField name="extraData" type="array">
  Key/value pairs for additional data regarding the discount.
</ResponseField>

## usedBonusCheck\[row]

<ResponseField name="voucherNumber" type="string" required>
  The unique ID number of the reward voucher to be redeemed when saving the transaction.
</ResponseField>

## usedPromotion\[row]

<ResponseField name="promotionId" type="string" required>
  The ID for the main promotion. Can be used to link the purchase to a promotion.
</ResponseField>

<ResponseField name="couponId" type="string" required>
  The ID for the "instance" of the promotion assigned to a contact.\
  Don't confuse the `couponId` (for an individual contact) with the `promotionId` (the "template" used).\
  Voyado recommends you use `couponId` over `promotionId` if possible, to avoid ambiguity in matching.
</ResponseField>

## Validations

* `discounts.value` should always be negative
* A return should have `item.type` "RETURN" and the `quantity` should be negative
* A purchase should have `item.type` "PURCHASE" and the `quantity` should be positive
* A `quantity` should never be 0
* Sum of all `paymentMethods` should equal `totalGrossPrice`
* Sum of all `grossPaidPrice` should equal `totalGrossPrice`
* The `taxAmount` should equal `grossPaidPrice` - `grossPaidPrice` / (1 + `taxPercent` / 100). The rounding error precision of this validation is by default 0.01. This value can be configured in the Engage backend to other values, or also turned off completely.

You can download the XSD schema [on the example files page](/docs/file-based-transfer/example-files).
