Changelog

RevWhenWhatWho
8.518/AUG/2023Extensions for "Refund" CUWOsWolfgang Knebel
8.413/JUL/2022Extensions for parent/child CUWOsWolfgang Knebel
8.401/JUL/2022Update BarcodeScanned (new result incl. parsed data)Wolfgang Knebel
8.322/JUN/2022Document "getCUWOContextInformation" method in CUWO callback APIWolfgang Knebel
8.226/NOV/2021Pass tip into "Authorize or Capture Payment"-CUWOWolfgang Knebel
8.108/NOV/2021Extensions for "External Invoicing"Wolfgang Knebel
8.005/OCT/2021Extensions for "External Payment Methods"
Rework to use mdbook
Wolfgang Knebel
7.423/MAY/2021“barcodeCode” is plain text stringWolfgang Knebel
7.318/MAY/2021Add “barcodeCode” field to BarcodeScannedWolfgang Knebel
7.205/NOV/2020Add “PrintBusinessDocument” messageWolfgang Knebel
7.130/OCT/2020Add “StatusNotification” messageWolfgang Knebel
7.023/OCT/2020Add “Checkout Basket” & “Evaluate Basket” operationsWolfgang Knebel
6.125/SEP/2020Adapt to refactored LineItem structures; Add CaptureImage operationWolfgang Knebel
6.012/AUG/2020Update “Configure Line Item”-CUWO-API to new versionWolfgang Knebel
5.211/APR/2019Provide barcode as “base64” encoded stringWolfgang Knebel
5.118/FEB/2019Provide barcode value as plain text
Fix operation name for BarcodeScanned structure definition
Wolfgang Knebel
5.025/JAN/2019Add continuous “Scan Barcodes” operation.
Specify what “base64” encoding to use.
Wolfgang Knebel
4.428/SEP/2018Add NFON examples for workflow resultsWolfgang Knebel
4.320/SEP/2018Add API for accessing OrganizationInfo, SalesChannelInfo and RegisterInfo from custom workflowsWolfgang Knebel
4.217/SEP/2018Operation “UpdateLineItemStatus” and flags for “explicit require of cancel/refund flows”Wolfgang Knebel
4.113/SEP/2018Extend LineItemInfo with totalPriceNet/GrossWolfgang Knebel
4.004/SEP/2018Removal of “CUWO proxy” component. Update custom workflow related APIs.Wolfgang Knebel
3.024/AUG/2018Update usage of custom workflows. Removal of “Line item management”Wolfgang Knebel
2.017/AUG/2018Removal of CUWO Controller and related changesWolfgang Knebel
1.018/JUL/2018Initial versionWolfgang Knebel

Introduction

This document describes the CUWO architecture provided by the enfore platform environment to allow integrators to enhance the platform-inherent functionality for custom, integration-specific use cases.

General Architecture

The general architecture for CUWOs consists of a combination of client- and server-side components that are part of the enfore platform and two external components that are provided by the external integrator:

Components

The following sections provide a high-level overview of the relevant components of the architecture.

Relevant components - enfore

The enfore platform allows external parties to implement custom workflows. Each instance of such a workflow is called a “custom workflow instance” or “CUWO instance” and is running inside a specialized container component that sandboxes it and separates the custom UI and logic from the regular enfore application UI/logic.

That container component is called “custom workflow container” or “CUWO container” and is implemented using a WebView component that is capable of rendering HTML/CSS and executing JavaScript code.

Additionally, the “Certificate Service” is a component in the enfore backend responsible for providing the client certificates needed by the custom workflow container to access the external integrators “CUWO provider”. Certificates are issued by enfore and must be trusted by the “CUWO Provider”. To allow the provider to determine what device the request comes from, the certificates contain the serial number of the device as well as the ID of the organization that device belongs to.

Relevant components - external integrator

The “CUWO Provider” is a server backend that provides the custom workflows with their application code as well as all necessary backend APIs.

APIs

This section provides a high-level overview of the various APIs that are part of the architecture

The “CUWO Callback” API is a JavaScript API injected into the JavaScript engine that is part of the CUWO container to allow the workflow running in the container to communicate with the container (e.g., notify termination of workflow).

The “CUWO Messages” API is an API provided by the CUWO container to allow the workflow running in the container to trigger operations (e.g. printing of documents) in the enfore client environment.

The “CUWO Cert” API provided by the Certificate Service is used by the CUWO container to acquire the client certificate necessary to execute custom workflows from the external CUWO provider backend.

Custom workflows and workflow instances

The core functionality of the architecture is to allow external integrators to implement custom workflows (custom UI and logic). Every time the user starts a new custom workflow, a new custom workflow instance (aka “CUWO instance”) is created. Each such instance has a unique identifier (the “CUWO instance ID”), runs inside a CUWO container component, and is sandboxed from the normal client environment. The device (e.g., Dasher) that the workflow instance is running on is called the “CUWO instance host”.

The “CUWO container” is implemented using a webview (e.g., Android WebView) and thus the user interface and logic running inside the container must be implemented using HTML, CSS, and JavaScript. The CUWO instance host will provide the workflow logic with the “CUWO callback” and the “CUWO message” APIs that will allow the workflow to communicate with the surrounding host (e.g. to close the container on completion or to trigger the printing of a document).

The workflow instance is invoked by a “start URL” that is preconfigured in the master data (for example the product in case of a “configure line item” CUWO). The workflow can load additional resources (e.g., CSS or image files) and perform page navigation.

Workflow lifecycle

Each client device has its own CUWO container and is not aware of any workflows running on other devices. The generation of the CUWO instance ID takes this into account and generates a unique identifier based on its client ID (the internal structure of the instance ID is an implementation detail though).

Setup and teardown

From a high-level view, the general setup of a workflow starts with the user triggering the start of a custom workflow. The enfore client will determine the start URL, initialize the container (which in turn checks the necessary client certificate and fetches it as necessary) and initiate the workflow by causing the container to load the start URL. Once the custom workflow is finished (either successfully or not), the workflow must notify the container via the CUWO Callback. The container will then notify the enfore client which will clean up the container and workflow and handle the workflow’s results.

alt_text

Aborting workflows

To guard against workflow instances that are created and then do not complete, the UI window provided by the CUWO container will have some UI elements for aborting the flow.

When the user uses those elements to abort the flow, the workflow will be notified via an TerminationRequested message. The container will then display confirmation query to the user, the message of which the workflow can control if it replies to the TerminationRequested message within 200 ms with an TerminationConfirmationMessage message. If the user confirms that the workflow should be terminated, the container will notify the workflow with a TerminationNotification message and terminate the workflow after another 200ms.

The following diagram shows the possible sequence of events:

alt_text

If the workflow needs to be terminated due to technical reasons (e.g. Android memory warning), the workflow will be notified by a KillNotification message. The system will try to give the workflow some time to persist its state, but due to technical constraints, that is not guaranteed. In exceptional cases, the workflow may also be killed directly without the use of a KillNotifiation message. This happens, for example, if the power connection of the device is cut.

The workflow running inside the container is essentially a web page and thus can invoke page navigation using the usual HTML or JavaScript constructs. Note though that the CUWO container does not provide any UI that would allow the user to navigate the browse history. As such, the workflow should rather be implemented as a single-page application. On the technical level, the target of any navigation link must always be _self. Links to other targets are not supported.

The workflow may also load additional resources such as stylesheets or script files and perform XHR requests using the usual constructs.

Workflow UI

The user interface of the workflow is implemented using plain HTML, CSS, and JavaScript. Enfore provides a collection of React/Redux-based UI components implemented in N4JS, that should be/are to be used to implement a user interface in the same style as the enfore OnlinePresence (OPR).

Workflow interaction with hardware devices

The custom workflow may need to interact with hardware devices such as printers, barcode scanners, or a signature part. As the client-side logic is running inside WebView, it does not have direct access to those devices. Instead, the workflow can trigger device interaction via the “CUWO Messages API”.

Workflow extension points and workflow types

A custom workflow replaces or enriches a processing step in the regular enfore platform behavior. Therefore, the regular platform behavior must define "extension points" where custom workflows can be attached. Each extension point defines what the specific workflow's purpose is, what parameters is receives and what result data is expected of it.

Extension points - sales orders

We want to enable custom workflows to be injected into the regular order processing flows. For this, it is not sufficient to have a single extension point as the lifecycle of a line item contains various state transitions that should be customizable.

The following diagram shows a simplified line item lifecycle with the extension points for custom workflows:

alt_text

The above diagram shows the four possible extension points for custom workflows:

  1. Creation of line item(s) - ConfigureLineItem
  2. Custom assembly for a line item - AssembleProduct
  3. Canceling an unpaid line item - CancelLineItem
  4. Refunding a paid line item - RefundLineItem

ConfigureLineItem

Whenever the user triggers the creation of a new line item by tapping a sales item on the register grid/list, it should be possible to invoke a custom workflow instead of using the default enfore functionality. The workflow will be triggered if the activated sales item has a custom workflow configured for the ConfigureLineItem extension point.

The workflow receives information about the selected sales item and is expected to return one or more fully configured line items. The returned items may all be “root level” items but may also include “sub/depending” items to allow for configuration of BTO products within the CUWO.

Additionally, the returned items may include discounts that will be respected by the enfore pricing engine. Note that the pricing engine may add additional discounts based on the configured promotions/price lists.

If the workflow completes successfully, the line items will be added to the basket/order. If the workflow fails, an error is shown and the basket/order is not modified.

Workflow parameters

The ConfigureLineItem-CUWO does not yet receive a dedicated WorkflowParameters structure.

Success result

On success, the ConfigureLineItem-CUWO is expected to pass a ConfigureLineItemWorkflowResult structure to terminateSuccess.

Attention/Note:

As of CUWO-API v6.0, the expected result structure of EP1 is an instance of n4.cuwo.workflows.configurelineitem.ConfigureLineItemWorkflowResult. For the time being, the enfore runtime will also accept instances of the old n4.cuwo.ConfigureLineItemWorkflowResult type. This support will be removed in a future version of the CUWO-API.

The n4.cuwo.workflows.configurelineitem.ConfigureLineItemWorkflowResult structure is defined as:

/**
 * The result value for a "configure line item" workflow.
 */
class ConfigureLineItemWorkflowResult extends WorkflowResult {
    readonly "@type" : string = "n4.cuwo.workflows.configurelineitem.ConfigureLineItemWorkflowResult";

    /**
     * The line items that have been configured and are to be
     * added to the basket.
     */
    public lineItems : DataList<LineItem>;
}

The n4.cuwo.ConfigureLineItemWorkflowResult structure is defined as:

/**
 * The result value for a "configure line item" workflow.
 */
@Deprecated
class ConfigureLineItemWorkflowResult extends WorkflowResult {
    readonly "@type" : string = "n4.cuwo.ConfigureLineItemWorkflowResult";

    /**
     * The line items that have been configured and are to be
     * added to the basket.
     */
    public lineItems : DataList<LineItemInfo>;
}

Failure result

The ConfigureLineItem-CUWO does not yet have a dedicated WorkflowFailure structure to pass into terminateFailure.

Cancelation result

The ConfigureLineItem workflow does not support cancelation.

AssembleProduct

Whenever a line item has been paid for, it should be possible to invoke a custom workflow for “assembly/production of the product” instead of using the default enfore functionality. The custom workflow will be triggered if the sales item referenced by the line item has a custom workflow configured for the AssembleProduct extension point.

The workflow receives information about the line item. If the workflow completes successfully, no return value is expected and the line item will be considered to have been “assembled”. If the workflow fails, an error is shown and the line item status is left at “paid”.

Workflow parameters

The AssembleProduct-CUWO does not yet receive a dedicated WorkflowParameters structure.

Success result

On success, the AssembleProduct-CUWO is expected to pass a AssemblyProductWorkflowResult structure to terminateSuccess.

The structure is defined as:

/**
 * The result value for a "assemble product" workflow.
 */
class AssemblyProductWorkflowResult extends WorkflowResult {
    readonly "@type" : string = "n4.cuwo.AssemblyProductWorkflowResult";

    /**
     * The new external data to attach to the line item. If not provided,
     * the existing external data of the line item will not be changed.
     */
    public updatedExternalData? : string;
}

Failure result

The AssembleProduct-CUWO does not yet have a dedicated WorkflowFailure structure to pass into terminateFailure.

Cancelation result

The AssembleProduct workflow does not support cancelation.

CancelLineItem

Whenever the user tries to cancel a line item before payment, it should be possible to invoke a custom workflow instead of using the default enfore functionality. The workflow will be triggered if the line item’s requiresCustomCancelFlow is set and the sales item referenced by the line item has a custom workflow configured for the CancelLineItem extension point.

The workflow receives information about the line item to be canceled. If the workflow completes successfully, it must return the reason for the cancelation (a value from the LineItemCancelationReason enum) and the item will be removed from the basket/order. If the workflow fails, an error is shown and the basket/order is not modified.

Workflow parameters

The CancelLineItem-CUWO does not yet receive a dedicated WorkflowParameters structure.

Success result

On success, the CancelLineItem-CUWO is expected to pass a CancelLineItemWorkflowResult structure to terminateSuccess.

The structure is defined as:

/**
 * The result value for a "cancel line item" workflow.
 */
class CancelLineItemWorkflowResult extends WorkflowResult {
    readonly "@type" : string = "n4.cuwo.CancelLineItemWorkflowResult";

    /**
     * The reason for the cancelation of the line item.
     */
    public reason : LineItemCancelationReason;

    /**
     * The new external data to attach to the line item. If not provided,
     * the existing external data of the line item will not be changed.
     */
    public updatedExternalData? : string;
}

Failure result

The CancelLineItem-CUWO does not yet have a dedicated WorkflowFailure structure to pass into terminateFailure.

Cancelation result

The CancelLineItem workflow does not support cancelation.

RefundLineItem

Whenever the user tries to refund an already paid line item a line item, it should be possible to invoke a custom workflow instead of using the default enfore functionality. The workflow will be triggered if the line item’s requiresCustomRefundFlow is set and the sales item referenced by the line item has a custom workflow configured for the RefundLineItem extension point.

The workflow receives information about the line item to be refunded. If the workflow completes successfully, it must return the reason for the refund (a value from the LineItemCancelationReason enum) and the item will be refunded. If the workflow fails, an error is shown and the item is not refunded.

Workflow parameters

The RefundLineItem-CUWO does not yet receive a dedicated WorkflowParameters structure.

Success result

On success, the RefundLineItem-CUWO is expected to pass a RefundLineItemWorkflowResult structure to terminateSuccess.

The structure is defined as:

/**
 * The result value for a "refund line item" workflow.
 */
class RefundLineItemWorkflowResult extends WorkflowResult {
    readonly "@type" : string = "n4.cuwo.RefundLineItemWorkflowResult";

    /**
     * The reason for the refunding of the line item.
     */
    public reason : LineItemCancelationReason;

    /**
     * The new external data to attach to the line item. If not provided,
     * the existing external data of the line item will not be changed.
     */
    public updatedExternalData? : string;
}

Failure result

The RefundLineItem-CUWO does not yet have a dedicated WorkflowFailure structure to pass into terminateFailure.

Cancelation result

The RefundLineItem workflow does not support cancelation.

Extension points - External Payment Methods

While the enfore platform has built-in handling for various payment methods such as cash, card payments via Donner/ZVT, enfore sales vouchers, enfore customer accounts, etc., the number of payment methods available in the world is essentially unlimited since every day, new methods can be added. Also, many payment methods are also only used by a small set of businesses/customers. Therefore, it is not feasible for enfore to provide built-in support for every existing or upcoming payment method. Instead, we aim to provide a framework that allows businesses/integrators to integrate additional payment methods on their own.

The choice of CUWOs for that integration stems from the fact that most, if not all, payment methods require some kind of user interface. For example, the customer will surely need to enter/provide some credentials to authorize a payment. A CUWO has the additional benefit that the enfore platform does not "see" the information (e.g., credentials) entered by the user. The platform provides the CUWO with a runtime environment but is not involved in the actual user/UI interaction.

In general, the enfore platform processes payments as a "payment request" that goes through the following steps:

  • Started - newly create PR, payment amount has not been reserved or moved yet
  • Authorized - payment amount has been reserved/approved (e.g., by a payment provider)
  • Captured - payment amount has been granted/transferred to the merchant
  • Booked - payment amount has been booked into the merchant's accounting system

Additionally, payment requests can "Fail" or become "Canceled".

Also note that not every payment method supports the distinction between "Authorized" and "Captured". For example, a basic cash payment does not have a "Authorization" stage but is immediately "Captured" when the customer has handed over the money.

Note that transitions from "Authorized" or "Captured" to "Canceled" only occur after a previous authorization/capture of money has been released/reverted. And that transitions from "Authorized" or "Captured" to "Failed" only occur after that release/reversal failed.

For the built-in payment methods, the enfore platform contains the logic to perform the operations necessary to transition the states of the payment/payout requests. For CUWO-based external payment methods, that logic must be provided by the CUWOs. Thus, we will define the following new CUWO extension points for the enfore platform:

  • for payments
    • AuthorizeOrCapturePayment
    • CapturePayment
    • CancelPayment
    • RevertPayment
  • for payouts
    • GrantPayout
    • CancelPayout

For payments, the possible activity flow looks like this:

For payouts, the flow is similar:

About abortion of CUWOs

A CUWO normally ends itself by invoking the terminateSuccess or terminateFailure methods of the CUWOCallback API that is injected into the browser instance by enforePOS.

For cases where the CUWO does not end itself, e.g. when the CUWO application could not be loaded or has bugs, the enforePOS UI wrapper around the CUWO window provides a way to cancel/abort a CUWO. There is a process in place how that UI and the CUWO interact to provide the CUWO with a way to gracefully terminate itself but also ensure that an unresponsive CUWO does not block the enforePOS runtime. See the Aborting Workflows in the CUWO documentation about more details.

When any of the payment/payout-related CUWOs becomes unresponsive and needs to be terminated by the enforePOS runtime, that CUWO will be treated as "failed" as the status of the payment/payout is unknown to the enfore platform.

For example, when an AuthorizeOrCapturePayment CUWO needed to be terminated, the enforePOS runtime will invoke a CancelPayment CUWO as must assume that the AuthorizeOrCapturePayment CUWO has already authorized or captured something. Independent of the result status of the CancelPayment CUWO, the payment request will be marked as failed. The enfore runtime will keep track of which CUWO was invoked and how it terminated (success, failure, cancel) to support investiation of failed payments.

AuthorizeOrCapturePayment

The AuthorizeOrCapturePayment-CUWO is responsible for authorizing or capturing the amount for a payment request.

This is the first CUWO that is executed for a new payment request. It is expected, that the CUWO collects any information that is needed (e.g., user credentials) and then authorizes the payment. If the payment method does not perform separate authorization/capture, the CUWO is allowed to directly capture the amount. This must be reflected in the return status.

The CUWO received a "requested amount". This is the amount to be paid and may already include tip. The amount of tip included in the requested amount is available via the includedTipAmount parameter.

Depending on configuration (via the EPM), the CUWO may authorize/capture an amount different from the requested amount. An authorized/captured amount less than the requested amount means that the customer wants to reduce tip and/or make a partial payment. An authorized/captured amount greater than the requested amount means that the customer has given a (additional) tip (i.e., any excess amount is treated as tip).

For the CUWO to end as "canceled", it must not have any authorized or captured amount. If the CUWO has already authorized/captured the amount and cannot release it, it must not end with "canceled" but with "failed".

If the CUWO fails, it should try to release any amount is may have already authorized/captured. As that cannot be guaranteed, the enfore platform will execute the CancelPayment-CUWO to ensure the release of any authorization. Therefore, the AuthorizeOrCapturePayment-CUWO must ensure that the CancelPayment-CUWO has enough information to work on. Either by storing the PaymentRequest-ID on the external side or by providing the information via the "payment processing data".

Note: As CUWO can fail unexpectedly (e.g., power loss), the AuthorizeOrCapturePayment-CUWO should provide "payment processing data" as soon as possible while it is still running and not just as return value. Then, in case of an unexpected termination, the enfore platform can provide that data to the CancelPayment-CUWO.

Workflow parameters

The AuthorizeOrCapturePayment-CUWO will receive an AuthorizeOrCapturePaymentWorkflowParameters structure as input.

The structure is defined as:

/**
 * The parameter/input structure for an "authorize or capture payment" workflow.
 */
class AuthorizeOrCapturePaymentWorkflowParameters extends WorkflowParameters {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.authorizeorcapturepayment.AuthorizeOrCapturePaymentWorkflowParameters";

    /**
     * The ID of the payment request for which the payment is to be authorized/captured.
     */
    public paymentRequestID : string;

    /**
     * The amount requested for the payment.
     *
     * Note that, depending on settings, the CUWO may process an amount that differs
     * from the requested one.
     */
    public requestedAmount : Money;

    /**
     * The amount of tip that is included in the requested amount.
     */
    public includedTipAmount : Money;

    /**
     * Information about the invoices/credit memos that the payment is to be made for.
     * 
     * Note that the enfore platform currently only supports payments for single invoices/
     * credit memos. The list is used as that functionality is planned to be extended in
     * the future.
     */
    public invoiceOrCreditMemoInformation : DataList<InvoiceOrCreditMemoInformation>

    /**
     * Information about the customer that is to pay the requested amount.
     */
    public customerInformation : CustomerInformation;

    /**
     * Identifiers available for identification of the customer that
     * uses the external payment method.
     */
    public customerIdentifiers : DataList<CustomerIdentifier>;

    /**
     * Information about the context in which the CUWO is executed.
     */
    public cuwoContextInformation : CUWOContextInformation;

    /**
     * Holds a reference to and configuration of the external payment method that the CUWO
     * belongs to. 
     */
    public paymentMethodConfiguration : PaymentMethodConfiguration
}

Success result

On success, the AuthorizeOrCapturePayment-CUWO is expected to pass an AuthorizeOrCapturePaymentWorkflowResult structure to terminateSuccess.

The structure is defined as:

/**
 * The result/output structure for a successful "authorize or capture payment" workflow.
 */
class AuthorizeOrCapturePaymentWorkflowResult extends WorkflowResult {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.authorizeorcapturepayment.AuthorizeOrCapturePaymentWorkflowResult";

    /**
     * The status of the payment.
     * 
     * Must be CAPTURED, if the money has been captured/collected or AUTHROIZED,
     * if the money has only been authorized.
     */
    public status : AuthorizeOrCapturePaymentWorkflowResultStatus;

    /**
     * The amount that has been captured or authorized.
     * 
     * Note that, depending on settings, the external payment processor and user choices, that
     * amount may differ from the amount that was requested to be authorized/captured.
     * 
     * If the processed amount is more than the requested amount, the excess amount
     * is treated as (additional) tip.
     * 
     * If the processed amount is less than the requested amount, the reduction is applied
     * to the tip first. Any reduction beyond the tip causes the payment request to become
     * a partial payment. This then usually leads to a second payment request being created
     * to pay for the remaining amount. This second payment request usually uses a different
     * payment method then though.
     */
    public processedAmount : Money;

    /**
     * A human-readable reference identifying the payment.
     * 
     * This is an "external identifier" for the enfore platform, so it will only be stored,
     * shown in the payment/sales UI of the enforePOS client and passed to subsequent CUWOs
     * such as CapturePayment or CancelPayment.
     * 
     * The reason for requiring this reference is that even when all subsequent processing
     * including CUWOs does not work, there is a way for the merchant/customer to look up
     * the payment in the external system or call the external systems support hotline and
     * be able to provide some kind if reference.
     */
    public paymentReference : string;

    /**
     * Optional payment processing data of the payment.
     * 
     * This data will be stored with the payment request and passed to subsequent CUWOs
     * such as CapturePayment or CancelPayment.
     * 
     * Same as the paymentReference, this data is not interpreted by the enfore platform
     * in any way. But other than the paymentReference, this data is not shown in any
     * kind of user interface.
     */
    public paymentProcessingData? : string;

    /**
     * Additional information to be stored with/printed on the payment
     * receipt/invoice for the payment.
     */
    public customReceiptDocumentInformation? : DataList<CustomDocumentInformation>
}

Failure result

On failure, the AuthorizeOrCapturePayment-CUWO is expected to pass an AuthorizeOrCapturePaymentWorkflowFailure structure to terminateFailure.

The structure is defined as:

/**
 * The result/output structure for a failed "authorize or capture payment" workflow.
 */
class AuthorizeOrCapturePaymentWorkflowFailure extends WorkflowFailure {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.authorizeorcapturepayment.AuthorizeOrCapturePaymentWorkflowFailure";

    /**
     * The reason for the failure.
     */
    public failureReason : AuthorizeOrCapturePaymentWorkflowFailureReason;

    /**
     * A failure code specific to the payment method.
     * 
     * The enfore platform simply stores that code and displays it to the user but does
     * not understand it or base any processing on it.
     * 
     * This enables storing a short error identifier from an external system in a way
     * that allows it to be shown in the enforePOS sales/payment history UI.
     */
    public failureCode? : string;

    /**
     * Optional update for the payment processing data of the payment.
     *
     * When provided, replaces the previously stored payment processing
     * data. When not provided, a previously stored payment processing
     * data stays unchanged.
     */
    public paymentProcessingData? : string;
}

Cancelation result

On cancelation, the AuthorizeOrCapturePayment-CUWO is expected to pass an AuthorizeOrCapturePaymentWorkflowCancelation structure to terminateCanceled.

The structure is defined as:

/**
 * The result/output structure for a canceled "authorize or capture payment" workflow.
 */
class AuthorizeOrCapturePaymentWorkflowCancelation extends WorkflowCancelation {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.authorizeorcapturepayment.AuthorizeOrCapturePaymentWorkflowCancelation";

    /**
     * The reason for the cancelation.
     */
    public cancelationReason : AuthorizeOrCapturePaymentWorkflowCancelationReason;
}

CapturePayment

The CapturePayment-CUWO is responsible for capturing a previously authorized amount for a payment request. This type of CUWO will only be used, when an AuthorizeOrCapturePayment-CUWO returns with state AUTHORIZED, as only then a separate capture step is needed.

If the CUWO fails, it is unclear whether the amount was captured or not. Thus, the enfore platform will execute the CancelPayment-CUWO to try to release the authorization/revert the capture.

Workflow parameters

The CapturePayment-CUWO will receive a CapturePaymentWorkflowParameters structure as input.

The structure is defined as:

/**
 * The parameter/input structure for a "capture payment" workflow.
 */
class CapturePaymentWorkflowParameters extends WorkflowParameters {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.capturepayment.CapturePaymentWorkflowParameters";

    /**
     * The ID of the payment request whose payment is to be captured.
     */
    public paymentRequestID : string;

    /**
     * The payment reference of the payment to capture as provided
     * by the AuthorizeOrCapturePayment workflow.
     */
    public paymentReference? : string;

    /**
     * The payment processing data of the payment to capture as
     * provided by the AuthorizeOrCapturePayment workflow.
     */
    public paymentProcessingData? : string;
}

Success result

On success, the CapturePayment-CUWO is expected to pass a CapturePaymentWorkflowResult structure to terminateSuccess.

The structure is defined as:

/**
 * The result/output structure for a successful "capture payment" workflow.
 */
class CapturePaymentWorkflowResult extends WorkflowResult {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.capturepayment.CapturePaymentWorkflowResult";

    /**
     * Optional update for the payment processing data of the payment.
     * 
     * When provided, replaces the previously stored payment processing
     * data. When not provided, a previously stored payment processing
     * data stays unchanged.
     */
    public paymentProcessingData? : string;

    /**
     * Additional information to be stored with/printed on the payment
     * receipt/invoice for the payment.
     */
    public customReceiptDocumentInformation? : DataList<CustomDocumentInformation>
}

Failure result

On failure, the CapturePayment-CUWO is expected to pass a CapturePaymentWorkflowFailure structure to terminateFailure.

The structure is defined as:

/**
 * The result/output structure for a failed "capture payment" workflow.
 */
class CapturePaymentWorkflowFailure extends WorkflowFailure {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.capturepayment.CapturePaymentWorkflowFailure";

    /**
     * The reason for the failure.
     */
    public failureReason : CapturePaymentWorkflowFailureReason;

    /**
     * A failure code specific to the payment method.
     * 
     * The enfore platform simply stores that code and displays it to the user but does
     * not understand it or base any processing on it.
     * 
     * This enables storing a short error identifier from an external system in a way
     * that allows it to be shown in the enforePOS sales/payment history UI.
     */
    public failureCode? : string;

    /**
     * Optional update for the payment processing data of the payment.
     *
     * When provided, replaces the previously stored payment processing
     * data. When not provided, a previously stored payment processing
     * data stays unchanged.
     */
    public paymentProcessingData? : string;
}

Cancelation result

The CapturePayment workflow does not support cancelation.

CancelPayment

The CancelPayment-CUWO is responsible for reverting any authorization or capture a AuthorizeOrCapturePayment- or CapturePayment-CUWO may have performed before failing (or on failure on the enforePOS side after successful CUWO execution).

As it cannot be guaranteed that the cancelation can be performed, the CUWO may return payment processing data as part of a failure result. That data will be stored as part of the payment request (which will be marked as failed) on the enfore side, so that the payment request on the enfore side and the transaction on the external side can be manually reconciled.

This type of CUWO is invoked when:

  • An AuthorizeOrCapturePayment-CUWO failed (to ensure that the potentially authorized/captured amount is released/reverted)
  • A CapturePayment-CUWO failed (to ensure that the authorized and potentially captured amount is released/reverted)
  • An AuthorizeOrCapturePayment-CUWO returned with "success" but the subsequent processing of the payment request was canceled or failed on the enforePOS side.

Workflow parameters

The CancelPayment-CUWO will receive a CancelPaymentWorkflowParameters structure as input.

The structure is defined as:

/**
 * The parameter/input structure for a "cancel payment" workflow.
 */
class CancelPaymentWorkflowParameters extends WorkflowParameters {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.cancelpayment.CancelPaymentWorkflowParameters";

    /**
     * The ID of the payment request whose payment is to be canceled.
     */
    public paymentRequestID : string;

    /**
     * The payment reference of the payment to cancel as provided
     * by the AuthorizeOrCapturePayment workflow.
     */
    public paymentReference? : string;

    /**
     * The payment processing data of the payment to cancel as
     * provided by the AuthorizeOrCapturePayment workflow.
     */
    public paymentProcessingData? : string;
}

Success result

On success, the CancelPayment-CUWO is expected to pass a CancelPaymentWorkflowResult structure to terminateSuccess.

The structure is defined as:

/**
 * The result/output structure for a successful "cancel payment" workflow.
 */
class CancelPaymentWorkflowResult extends WorkflowResult {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.cancelpayment.CancelPaymentWorkflowResult";

    /**
     * Optional update for the payment processing data of the payment.
     * 
     * When provided, replaces the previously stored payment processing
     * data. When not provided, a previously stored payment processing
     * data stays unchanged.
     */
    public paymentProcessingData? : string;
}

Failure result

On failure, the CancelPayment-CUWO is expected to pass a CancelPaymentWorkflowFailure structure to terminateFailure.

The structure is defined as:

/**
 * The result/output structure for a failed "cancel payment" workflow.
 */
class CancelPaymentWorkflowFailure extends WorkflowFailure {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.cancelpayment.CancelPaymentWorkflowFailure";

    /**
     * The reason for the failure.
     */
    public failureReason : CancelPaymentWorkflowFailureReason;

    /**
     * A failure code specific to the payment method.
     * 
     * The enfore platform simply stores that code and displays it to the user but does
     * not understand it or base any processing on it.
     * 
     * This enables storing a short error identifier from an external system in a way
     * that allows it to be shown in the enforePOS sales/payment history UI.
     */
    public failureCode? : string;

    /**
     * Optional update for the payment processing data of the payment.
     *
     * When provided, replaces the previously stored payment processing
     * data. When not provided, a previously stored payment processing
     * data stays unchanged.
     */
    public paymentProcessingData? : string;
}

Cancelation result

The CancelPayment workflow does not support cancelation.

RevertPayment

The RevertPayment-CUWO is used to revert a previously performed payment. This is not done as part of a payment request but as part of a payout request, when a user later decides to "revert/refund this payment" in the sales history. The CUWO receives the information about the payment to revert as part of its input parameters.

Note that an EPM is not required to support reversion of payments. If an EPM does not support it, the client UI in enforePOS will not present the option to revert payments made via that payment method.

Even if the EPM is configured to support reversion of payments, it may not be possible to revert a specific payment. For example, because the payment was made a long time ago and reversion is only allowed within a short time window after making the payment. In those cases, the enforePOS UI will present the option to revert the payment and it is the responsibility of te CUWO to check whether the reversion is possible or not and to communicate that to the user.

For the CUWO to return as "success", it must have reverted the payment.

When the CUWO fails, the enfore platform will invoke the CancelPayout workflow on the payout request and then mark it as failed. Note that the payment request is not changed (except by potentially updating the payment processing data), so the user may trigger the reversal again, which will create a new payout request and invoke the RevertPayment CUWO again. The CUWO must be able to deal with the fact that a previous invocation may have already changed something in the external system.

Workflow parameters

The RevertPayment-CUWO will receive a RevertPaymentWorkflowParameters structure as input.

The structure is defined as:

/**
 * The parameter/input structure for a "revert payment" workflow.
 */
class RevertPaymentWorkflowParameters extends WorkflowParameters {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.revertpayment.RevertPaymentWorkflowParameters";

    /**
     * The ID of the payout request for which the payment is to be reverted.
     */
    public payoutRequestID : string;

    /**
     * The ID of the payment request whose payment is to be reverted.
     */
    public paymentRequestID : string;

    /**
     * The payment reference of the payment to revert as provided
     * by the AuthorizeOrCapturePayment workflow.
     */
    public paymentReference? : string;

    /**
     * The payment processing data of the payment to revert as
     * provided by the AuthorizeOrCapturePayment workflow.
     */
    public paymentProcessingData? : string;
}

Success result

On success, the RevertPayment-CUWO is expected to pass a RevertPaymentWorkflowResult structure to terminateSuccess.

The structure is defined as:

/**
 * The result/output structure for a successful "revert payment" workflow.
 */
class RevertPaymentWorkflowResult extends WorkflowResult {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.revertpayment.RevertPaymentWorkflowResult";

    /**
     * A human-readable reference identifying the payout.
     * 
     * This is an "external identifier" for the enfore platform, so it will only be stored,
     * shown in the payment/sales UI of the enforePOS client and passed to subsequent CUWOs
     * such as CancelPayout.
     * 
     * The reason for requiring this reference is that even when all subsequent processing
     * including CUWOs does not work, there is a way for the merchant/customer to look up
     * the payout in the external system or call the external systems support hotline and
     * be able to provide some kind if reference.
     */
    public payoutReference : string;

    /**
     * Optional payout processing data of the payout.
     * 
     * This data will be stored with the payout request and passed to subsequent CUWOs
     * such as CancelPayout.
     * 
     * Same as the payoutReference, this data is not interpreted by the enfore platform
     * in any way. But other than the payoutReference, this data is not shown in any
     * kind of user interface.
     */
    public payoutProcessingData? : string;

    /**
     * Optional update for the payment processing data of the payment
     * that was reverted.
     * 
     * When provided, replaces the previously stored payment processing
     * data. When not provided, a previously stored payment processing
     * data stays unchanged.
     */
    public paymentProcessingData? : string;

    /**
     * Additional information to be stored with/printed on the payout
     * receipt/credit memo for the payout.
     */
    public customReceiptDocumentInformation? : DataList<CustomDocumentInformation>;
}

Failure result

On failure, the RevertPayment-CUWO is expected to pass a RevertPaymentWorkflowFailure structure to terminateFailure.

The structure is defined as:

/**
 * The result/output structure for a failed "revert payment" workflow.
 */
class RevertPaymentWorkflowFailure extends WorkflowFailure {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.revertpayment.RevertPaymentWorkflowFailure";

    /**
     * The reason for the failure.
     */
    public failureReason : RevertPaymentWorkflowFailureReason;

    /**
     * A failure code specific to the payment method.
     * 
     * The enfore platform simply stores that code and displays it to the user but does
     * not understand it or base any processing on it.
     * 
     * This enables storing a short error identifier from an external system in a way
     * that allows it to be shown in the enforePOS sales/payment history UI.
     */
    public failureCode? : string;

    /**
     * Optional update for the payout processing data of the payout.
     * 
     * When provided, replaces the previously stored payout processing
     * data. When not provided, a previously stored payout processing
     * data stays unchanged.
     */
    public payoutProcessingData? : string;

    /**
     * Optional update for the payment processing data of the payment.
     *
     * When provided, replaces the previously stored payment processing
     * data. When not provided, a previously stored payment processing
     * data stays unchanged.
     */
    public paymentProcessingData? : string;
}

Cancelation result

The RevertPayment workflow does not support cancelation.

GrantPayout

The GrantPayout-CUWO is responsible for granting a payout. There is no distinction between "authorizing" and "capturing" for payouts, so only a single "grant" operation is used.

It is expected, that the CUWO collects any information that is needed (e.g., user credentials) and then performs the payout.

For the CUWO to end as "canceled", it must not have performed the payout. If the CUWO has already performed it and cannot revert it, it must not end with "canceled" but with "failed".

If the CUWO fails, it should try to revert any payout amount it may have granted. As that cannot be guaranteed, the enfore platform will execute the CancelPayout-CUWO to ensure the reversal. Therefore, the GrantPayout-CUWO must ensure that the CancelPayout-CUWO has enough information to work on. Either by storing the PayoutRequest-ID on the external side or by providing the information via the "payout processing data".

Workflow parameters

The GrantPayout-CUWO will receive an GrantPayoutWorkflowParameters structure as input.

The structure is defined as:

/**
 * The parameter/input structure for an "grant payout" workflow.
 */
class GrantPayoutWorkflowParameters extends WorkflowParameters {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.grantpayout.GrantPayoutWorkflowParameters";

    /**
     * The ID of the payout request for which the payout is to be granted.
     */
    public payoutRequestID : string;

    /**
     * The amount requested for the payout.
     *
     * Note that, for now, the CUWO must process exactly that amount. Partial payouts
     * or "over payout" are not supported.
     */
    public requestedAmount : Money;

    /**
     * Information about the invoices/credit memos that the payout is to be made for.
     * 
     * Note that the enfore platform currently only supports payouts for single invoices/
     * credit memos. The list is used as that functionality is planned to be extended in
     * the future.
     */
    public invoiceOrCreditMemoInformation : DataList<InvoiceOrCreditMemoInformation>

    /**
     * Information about the customer that is to receive the requested amount.
     */
    public customerInformation : CustomerInformation;

    /**
     * Identifiers available for identification of the customer that
     * uses the external payment method.
     */
    public customerIdentifiers : DataList<CustomerIdentifier>;

    /**
     * Information about the context in which the CUWO is executed.
     */
    public cuwoContextInformation : CUWOContextInformation;

    /**
     * Holds a reference to and configuration of the external payment method that the CUWO
     * belongs to. 
     */
    public paymentMethodConfiguration : PaymentMethodConfiguration
}

Success result

On success, the GrantPayout-CUWO is expected to pass an GrantPayoutWorkflowResult structure to terminateSuccess.

The structure is defined as:

/**
 * The result/output structure for a successful "grant payout" workflow.
 */
class GrantPayoutWorkflowResult extends WorkflowResult {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.grantpayout.GrantPayoutWorkflowResult";

    /**
     * The amount that has been granted.
     * 
     * Note that, for now, this must be equal to the requested amount.
     */
    public processedAmount : Money;

    /**
     * A human-readable reference identifying the payout.
     * 
     * This is an "external identifier" for the enfore platform, so it will only be stored,
     * shown in the payment/sales UI of the enforePOS client and passed to subsequent CUWOs
     * such as CancelPayout.
     * 
     * The reason for requiring this reference is that even when all subsequent processing
     * including CUWOs does not work, there is a way for the merchant/customer to look up
     * the payout in the external system or call the external systems support hotline and
     * be able to provide some kind if reference.
     */
    public payoutReference : string;

    /**
     * Optional payout processing data of the payout.
     * 
     * This data will be stored with the payout request and passed to subsequent CUWOs
     * such as CancelPayout.
     * 
     * Same as the payoutReference, this data is not interpreted by the enfore platform
     * in any way. But other than the payoutReference, this data is not shown in any
     * kind of user interface.
     */
    public payoutProcessingData? : string;

    /**
     * Additional information to be stored with/printed on the payout
     * receipt/credit memo for the payout.
     */
    public customReceiptDocumentInformation? : DataList<CustomDocumentInformation>
}

Failure result

On failure, the GrantPayout-CUWO is expected to pass an GrantPayoutWorkflowFailure structure to terminateFailure.

The structure is defined as:

/**
 * The result/output structure for a failed "grant payout" workflow.
 */
class GrantPayoutWorkflowFailure extends WorkflowFailure {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.grantpayout.GrantPayoutWorkflowFailure";

    /**
     * The reason for the failure.
     */
    public failureReason : GrantPayoutWorkflowFailureReason;

    /**
     * A failure code specific to the payment method.
     * 
     * The enfore platform simply stores that code and displays it to the user but does
     * not understand it or base any processing on it.
     * 
     * This enables storing a short error identifier from an external system in a way
     * that allows it to be shown in the enforePOS sales/payment history UI.
     */
    public failureCode? : string;

    /**
     * Optional payout processing data of the payout.
     * 
     * This data will be stored with the payout request and passed to subsequent CUWOs
     * such as CancelPayout.
     * 
     * Same as the payoutReference, this data is not interpreted by the enfore platform
     * in any way. But other than the payoutReference, this data is not shown in any
     * kind of user interface.
     */
    public payoutProcessingData? : string;
}

Cancelation result

On cancelation, the GrantPayout-CUWO is expected to pass an GrantPayoutWorkflowCancelation structure to terminateCanceled.

The structure is defined as:

/**
 * The result/output structure for a canceled "grant payout" workflow.
 */
class GrantPayoutWorkflowCancelation extends WorkflowCancelation {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.grantpayout.GrantPayoutWorkflowCancelation";

    /**
     * The reason for the cancelation.
     */
    public cancelationReason : GrantPayoutWorkflowCancelationReason;
}

CancelPayout

The CancelPayout-CUWO is responsible for reverting any grant a GrantPayout-CUWO may have performed before failing (or on failure on the enforePOS side after successful CUWO execution).

As it cannot be guaranteed that the cancelation can be performed, the CUWO may return payout processing data as part of a failure result. That data will be stored as part of the payout request (which will be marked as failed) on the enfore side, so that the payout request on the enfore side and the transaction on the external side can be manually reconciled.

This type of CUWO is invoked when:

  • A GrantPayout-CUWO failed (to ensure that the potentially granted amount is reverted)
  • A GrantPayout-CUWO returned with "success" but the subsequent processing of the payout request was canceled or failed on the enforePOS side.

Workflow parameters

The CancelPayout-CUWO will receive a CancelPayoutWorkflowParameters structure as input.

The structure is defined as:

/**
 * The parameter/input structure for a "cancel payout" workflow.
 */
class CancelPayoutWorkflowParameters extends WorkflowParameters {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.cancelpayout.CancelPayoutWorkflowParameters";

    /**
     * The ID of the payout request whose payout is to be canceled.
     */
    public payoutRequestID : string;

    /**
     * The payout reference of the payout to cancel as provided
     * by the GrantPayout/RevertPayment workflow.
     */
    public payoutReference? : string;

    /**
     * The payout processing data of the payout to cancel as
     * provided by the GrantPayout/RevertPayment workflow.
     */
    public payoutProcessingData? : string;
}

Success result

On success, the CancelPayout-CUWO is expected to pass a CancelPayoutWorkflowResult structure to terminateSuccess.

The structure is defined as:

/**
 * The result/output structure for a successful "cancel payout" workflow.
 */
class CancelPayoutWorkflowResult extends WorkflowResult {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.cancelpayout.CancelPayoutWorkflowResult";

    /**
     * Optional update for the payout processing data of the payout.
     * 
     * When provided, replaces the previously stored payout processing
     * data. When not provided, a previously stored payout processing
     * data stays unchanged.
     */
    public payoutProcessingData? : string;
}

Failure result

On failure, the CancelPayout-CUWO is expected to pass a CancelPayoutWorkflowFailure structure to terminateFailure.

The structure is defined as:

/**
 * The result/output structure for a failed "cancel payout" workflow.
 */
class CancelPayoutWorkflowFailure extends WorkflowFailure {
    readonly "@type" : string = "n4.cuwo.workflows.paymentsandpayouts.cancelpayout.CancelPayoutWorkflowFailure";

    /**
     * The reason for the failure.
     */
    public failureReason : CancelPayoutWorkflowFailureReason;

    /**
     * A failure code specific to the payment method.
     * 
     * The enfore platform simply stores that code and displays it to the user but does
     * not understand it or base any processing on it.
     * 
     * This enables storing a short error identifier from an external system in a way
     * that allows it to be shown in the enforePOS sales/payment history UI.
     */
    public failureCode? : string;

    /**
     * Optional update for the payout processing data of the payout.
     * 
     * When provided, replaces the previously stored payout processing
     * data. When not provided, a previously stored payout processing
     * data stays unchanged.
     */
    public payoutProcessingData? : string;
}

Cancelation result

The CancelPayout workflow does not support cancelation.

Extension points - External Invoicing Methods

Whenever a sale occurs, an invoice must be generated. That is usually done by the enfore platform itself by creating an invoice for the sales order (or order split or settlement). There are cases though, where a sale made via an enforePOS register shall not be invoiced by the enfore platform but shall be invoiced by an external system. For example a hotel restaurant may used enforePOS but still want to all customers to have their meals "billed to my room" via the hotel's PMS.

For such cases, the enfore platform supports "external invoicing". That is, the enforePOS system can be used to take and process an order (incl. productions and goods outs) and that order can then be marked as "invoiced externally". The order can then be considered "complete" from the point of view of the enfore platform as the actual creation of the invoice and collection of payment happens "outside".

Checkout

The usual sequence of actions for checking out an order in enforePOS is:

Instead of selecting a payment method, the user shall be able to select an "external invoicing method" which will invoke an InvoiceSalesOrder CUWO. If that CUWO returns with success, the order is marked as (externally) invoiced and the payment UI is done.

If the CUWO returns with a failure or cancelation, the order is not marked as invoiced and the payment UI allows selection of another external invoicing method or selection of a payment method.

Sales History

For an order that has been "externally invoiced", no invoice object exists in the enfore system. For the "Sales History" UI, such orders are shown together with the invoices created by regular invoicing via the enfore platform.

When the user activates such an order in the "Sales History" UI, the enfore platform will present a view similar to the regular "Invoice Details" but lacking all information that is not available (such as payments or the invoice documents). Instead, the enfore platform will provide an action that can invoke the ViewExternalInvoice CUWO to present invoicing information form the external system.

InvoiceSalesOrder

The InvoiceSalesOrder-CUWO is responsible for invoicing a sales order outside of the enfore platform.

The CUWO receives the sales order as well as context information and is expected to return a confirmation that the order has been or will be externally invoiced. When it has already been invoiced, the CUWO should also immediately return the invoice number and invoicing data so it can be directly persisted when storing the order. When the external system creates the invoice only later (e.g., as a combined settlement when the customer checks out of the hotel), that invoice number cannot be provided as CUWO-result but must then be later set via backend API.

If the sales order cannot be invoiced via the external system, the CUWO shall return as "canceled" with reason UNABLE_TO_INVOICE after informing the user about the reason for this.

When the CUWO returns as "canceled", it is assumed that the user actively decided to cancel and/or was informed about the cancelation and thus no message must be shown by the enfore runtime. The CUWO will simply be closed and the user will be back in the payment UI.

When the CUWO returns as "failed", the enfore runtime will display the failure to the customer and return the user to the payment UI.

Workflow parameters

The InvoiceSalesOrder-CUWO will receive an InvoiceSalesOrderWorkflowParameters structure as input.

The structure is defined as:

/**
 * The parameter/input structure for an "invoice sales order" workflow.
 */
class InvoiceSalesOrderWorkflowParameters extends WorkflowParameters {
    readonly "@type" : string = "n4.cuwo.workflows.externalinvoicing.invoicesalesorder.InvoiceSalesOrderWorkflowParameters";

    /**
     * Information about the order to be invoiced.
     *
     * Includes the orer number, items of the order, information
     * about the customer etc.
     *
     * Note that pricing information is provided via the separate
     * "pricingData" structure.
     */
    public orderData : SalesOrderData;

    /**
     * Information about the pricing calculation for the order and
     * its items.
     *
     * Consists of information about the order itself as well as
     * item- and subitem-level information.
     */
    public pricingData : SalesOrderPricingData;

    /**
     * Holds a reference to and configuration of the external
     * invoicing method that the CUWO belongs to. 
     */
    public invoicingMethodConfiguration : InvoicingMethodConfiguration;
}

Success result

On success, the InvoiceSalesOrder-CUWO is expected to pass an InvoiceSalesOrderWorkflowResult structure to terminateSuccess.

The structure is defined as:

/**
 * The result/output structure for a successful "invoice sales order" workflow.
 */
class InvoiceSalesOrderWorkflowResult extends WorkflowResult {
    readonly "@type" : string = "n4.cuwo.workflows.externalinvoicing.invoicesalesorder.InvoiceSalesOrderWorkflowResult";

    /**
     * A human-readable reference identifying the order/invoice in the external invoicing system.
     *
     * This is an "external identifier" for the enfore platform, so it has no semantic meaning
     * but will only be stored, shown in the sales history UI of the enforePOS client and passed
     * to subsequent CUWOs such as ViewExternalInvoice.
     *
     * The reason for requiring this reference is that with this, there is a way for the
     * merchant/customer to look up the order/invoice in the external system or call the
     * external systems support hotline and be able to provide some kind if reference.
     */
    public externalReference : string;

    /**
     * An optional note that will be stored as part of the "externally
     * invoiced" information at the order.
     *
     * This will be shown in the "Sales History UI".
     */
    public note? : string;

    /**
     * The number of the externally created invoice.
     *
     * When not available yet, this can be left empty. The invoice
     * number must then be set later via backend APIs.
     */
    public invoiceNumber? : string;

    /**
     * The date of the externally created invoice.
     *
     * When not available yet, this can be left empty. The invoice
     * date must then be set later via backend APIs.
     */
    public invoiceDate? : Date;
}

Failure result

On failure, the InvoiceSalesOrder-CUWO is expected to pass an InvoiceSalesOrderWorkflowFailure structure to terminateFailure.

The structure is defined as:

/**
 * The result/output structure for a failed "invoice sales order" workflow.
 */
class InvoiceSalesOrderWorkflowFailure extends WorkflowFailure {
    readonly "@type" : string = "n4.cuwo.workflows.externalinvoicing.invoicesalesorder.InvoiceSalesOrderWorkflowFailure";

    /**
     * The reason for the failure.
     */
    public failureReason : InvoiceSalesOrderWorkflowFailureReason;

    /**
     * A failure message that can be shown to in the UI.
     * When not provided, a generic message will be shown instead.
     */
    public failureMessage? : string;
}

Cancelation result

On cancelation, the InvoiceSalesOrder-CUWO is expected to pass an InvoiceSalesOrderWorkflowCancelation structure to terminateCanceled.

The structure is defined as:

/**
 * The result/output structure for a canceled "invoice sales order" workflow.
 */
class InvoiceSalesOrderWorkflowCancelation extends WorkflowCancelation {
    readonly "@type" : string = "n4.cuwo.workflows.externalinvoicing.invoicesalesorder.InvoiceSalesOrderWorkflowCancelation";

    /**
     * The reason for the cancelation.
     */
    public cancelationReason : InvoiceSalesOrderWorkflowCancelationReason;
}

ViewExternalInvoice

The ViewExternalInvoice-CUWO is responsible for displaying information about an external invoice. Or, more generally, an external invoicing operation - as the actual invoice may not yet exist.

The CUWO is called from the enforePOS's "Sales History" UI for objects (e.g., orders) that have been invoiced via an External Invoicing Methos (when enabled via the configuration of the EIM). It receives the "external reference" provided by the CUWO that handled the external invoicing (e.g., InvoiceSalesOrder).

The CUWO does not have any actual success or failure result as it doesn't perform any business operation from the point of view of the enfore platform. It simply is a "window into the external invoicing system" that the user can choose to invoke.

Workflow parameters

The ViewExternalInvoice-CUWO will receive an ViewExternalInvoiceWorkflowParameters structure as input.

The structure is defined as:

/**
 * The parameter/input structure for an "invoice sales order" workflow.
 */
class ViewExternalInvoiceWorkflowParameters extends WorkflowParameters {
    readonly "@type" : string = "n4.cuwo.workflows.externalinvoicing.viewexternalinvoice.ViewExternalInvoiceWorkflowParameters";

    /**
     * The reference that was provided by the invoicing CUWO (e.g., InvoiceSalesOrder).
     */
    public externalReference : string;

    /**
     * The (optional) note that was provided by the invoicing CUWO (e.g., InvoiceSalesOrder).
     */
    public note? : string;

    /**
     * The number of the externally created invoice, when available.
     */
    public invoiceNumber? : string;

    /**
     * The date of the externally created invoice, when available.
     */
    public invoiceDate? : Date;
}

Success result

On success, the ViewExternalInvoice-CUWO is expected to pass a GenericWorkflowResult structure to terminateSuccess.

Failure result

On failure, the ViewExternalInvoice-CUWO is expected to pass a GenericWorkflowFailure structure to terminateFailure.

Cancelation result

On cancelation, the ViewExternalInvoice-CUWO is expected to pass a GenericWorkflowCancelation structure to terminateCanceled.

Extension points - kiosk

The enfore platform provides the ability to fully replace the enforePOS application UI with a single CUWO. That allows the CUWO to provide a fully customized user experience on top of the enfore runtime functionality.

Child CUWOs

Sometimes a CUWO running on a device A needs to spawn a CUWO on device B. For example, a CUWO running on a merchant-controlled device may require UI interaction with a customer. In those cases, it is usually not feasible for the merchant to hand over the device to the customer as it may be physically impossible and is also problematic as it may give the customer access to merchant-only information/operations.

Therefore, the enfore platform provides CUWOs with ways to spawn child CUWOs on other devices.

Specifically, a CUWO can spawn "customer-level UI" CUWOs on devices that are configured as customer-level devices. The setup usually consists of pairs of merchant-controlled devices (e.g., an enforeDasher or enforeComet or Mac/Windows/Linux device) and customer-level devices (e.g., enforeDonner or enforeComet) that are bound via configuration. Nevertheless, a customer-level device may be used for more than one merchant-controlled device but then is still limited to serve one customer-level CUWO at a time. It is also possible that no customer-level device is paired to a specific merchant-controlled device, in which case the merchant will be presented with a list of suitable devices (at the current service location) to chose on which device the customer-level CUWO shall be started.

Spawning a child CUWO

Child CUWOs are spawned by special operations such as the SpawnCustomerLevelUIChildCUWOOperation operation. Such an operation causes the specified CUWO to be spawned on the target device. As operation result, the parent CUWO receives a handle of the spawned child CUWO. And the child CUWO receives a handle of the spawning parent CUWO as part of its workflow parameters.

Terminating a child CUWO

A child CUWO may terminate itself at any time, in which case the parent CUWO will receive the result data via a ChildCUWOTerminated message.

The parent CUWO may also trigger the termination of the child CUWO via a TerminateChildCUWOOperation operation. This will result in the child CUWO receiving a TerminationRequested message and then being terminated. Note that the parent CUWO will receive both a ChildCUWOTerminated and an OperationFinished message once the child CUWO has been terminated:

As usual, the child CUWO may respond to the TerminationRequested with a TerminationConfirmationMessage message. This message will be shown to the user on the device that runs the parent CUWO as that is the person that requested the termination. Depending on the user's decision, the child CUWO may either be terminated or not. In case of the termination being aborted, the child CUWO is not terminated and the TerminateChildCUWOOperation is resolved with an OperationFinished with status CANCELED_BY_USER. Otherwise, the spawned CUWO is terminated and the TerminateChildCUWOOperation is resolved with an OperationFinished with status COMPLETED.

Sending messages

The parent and child CUWOs have "cuwo handles" of each other that can be used to send messages between them via the PassMessageToCUWOOperation operation.

Note that the data sent via PassMessageToCUWOOperation is processed by the enfore platform as it needs to be transported from one device to another. Therefore, it must not contain confidential information such as user credentials. If such data must be exchanged between the CUWOs, this should ideally be done via an external shared infrastructure controlled by the CUWO provider

If shared infrastructure is not an option, the critical data must at least be encrypted before sending it via PassMessageToCUWOOperation.

CustomerLevelUI

The CustomerLevelUI-CUWO is a child CUWO that was spawned specifically to have a UI interaction with an end customer.

CUWOs of this type are created from other CUWOs via the SpawnCustomerLevelUIChildCUWOOperation operation.

Workflow parameters

The CustomerLevelUI-CUWO will receive a CustomerLevelUIWorkflowParameters structure as input.

The structure is defined as:

/**
 * The parameter/input structure for a "customer-level UI" workflow.
 */
class CustomerLevelUIWorkflowParameters extends WorkflowParameters {
    readonly "@type" : string = "n4.cuwo.workflows.childcuwos.customerlevelui.CustomerLevelUIWorkflowParameters";

    /**
     * The handle of the CUWO that spawned the "customer-level UI" workflow.
     */
    public parentCUWOHandle : string;

    /**
     * Optional parameter data provided by the parent CUWO.
     */
    public parameterData? : string;
}

Success result

On success, the CustomerLevelUI-CUWO is expected to pass a CustomerLevelUIWorkflowResult structure to terminateSuccess.

The structure is defined as:

/**
 * The result/output structure for a successful "customer-level UI" workflow.
 */
class CustomerLevelUIWorkflowResult extends WorkflowResult {
    readonly "@type" : string = "n4.cuwo.workflows.childcuwos.customerlevelui.CustomerLevelUIWorkflowResult";

    /**
     * Optional result data that the customer-level UI CUWO wants
     * to pass to its parent CUWO.
     */
    public resultData? : string;
}

Failure result

On failure, the CustomerLevelUI-CUWO is expected to pass a CustomerLevelUIWorkflowFailure structure to terminateFailure.

The structure is defined as:

/**
 * The result/output structure for a failed "customer-level UI" workflow.
 */
class CustomerLevelUIWorkflowFailure extends WorkflowFailure {
    readonly "@type" : string = "n4.cuwo.workflows.childcuwos.customerlevelui.CustomerLevelUIWorkflowFailure";

    /**
     * Optional failure-related information that the customer-level UI
     * CUWO wants to pass to its parent CUWO.
     */
    public failureInformation? : string;
}

Cancelation result

The CustomerLevelUI workflow does not support cancelation.

Extension points - Refunds

While the enfore platform has built-in handling for refunding of sales performed via the enfore platform, sometimes refunds must be granted for sales performed outside of the enfore platform. Or for sales performed by other organizations.

For this, the enfore platform provides CUWOs that allow each organization to implement whathever refund logic is suitable for them and integrated them as seamlessly as possible into the regular enforePOS UI.

The choice of CUWOs for that integration stems from the fact that most, if not all, refunds processes require some kind of user interface. For example, the customer will surely need to choose what to refund. A CUWO has the additional benefit that the enfore platform does not "see" any information (e.g., full sales history of a customer including sales done outside the enfore system) that it should not have access to. The platform provides the CUWO with a runtime environment but is not involved in the actual user/UI interaction.

In general, the enfore platform processes refunds as a "refund process" that goes through the following steps:

  • Started - newly created RP, refund hat not been authorized yet
  • Authorized - refund has been authorized and refund amount has been defined
  • Processed - refund has been processed

Additionally, refund processes can "Fail" or become "Canceled".

Note that transitions from "Authorized" to "Canceled" only occur after a previous authorization has been released/reverted. And that transitions from "Authorized" to "Failed" only occur after that release/reversal failed.

CUWO extension points

For the built-in refund functionality, the enfore platform contains the logic to perform the operations necessary to transition the states of the refund processes. For CUWO-based refunds, that logic must be provided by the CUWOs. Thus, we will define the following new CUWO extension points for the enfore platform:

  • AuthorizeRefund
  • ProcessRefund
  • CancelRefund

For refunds, the possible activity flow looks like this:

About abortion of CUWOs

A CUWO normally ends itself by invoking the terminateSuccess or terminateFailure methods of the CUWOCallback API that is injected into the browser instance by enforePOS.

For cases where the CUWO does not end itself, e.g. when the CUWO application could not be loaded or has bugs, the enforePOS UI wrapper around the CUWO window provides a way to cancel/abort a CUWO. There is a process in place how that UI and the CUWO interact to provide the CUWO with a way to gracefully terminate itself but also ensure that an unresponsive CUWO does not block the enforePOS runtime. See the Aborting Workflows in the CUWO documentation about more details.

When any of the refund-related CUWOs becomes unresponsive and needs to be terminated by the enforePOS runtime, that CUWO will be treated as "failed" as the status of the refund/payout is unknown to the enfore platform.

For example, when an AuthorizeRefund CUWO needed to be terminated, the enforePOS runtime will invoke a CancelRefund CUWO as it must assume that the AuthorizeRefund CUWO has already authorized something. Independent of the result status of the CancelRefund CUWO, the refund process will be marked as failed. The enfore runtime will keep track of which CUWO was invoked and how it terminated (success, failure, cancel) to support investigation of failed refunds.

AuthorizeRefund

The AuthorizeRefund-CUWO is responsible for authorizing a refund.

This is the first CUWO that is executed for a new refund. It is expected, that the CUWO collects any information that is needed (e.g., original invoice, what to refund) and then authorizes the refund.

The CUWO may receive an "invoice identifier". This is an identifier provided by the customer that requests the refund and that is to identify the original invoice/sales. The CUWO may be invoked without such an identifier. This means that the user chose to directly invoke the CUWO without entering an identifier. The CUWO must then ask the user for the identifier or use other means to determine "what to refund".

If the CUWO fails, it should try to release any authorization that has already been acquired. As that cannot be guaranteed, the enfore platform will execute the CancelRefund-CUWO to ensure the release of any authorization. Therefore, the AuthorizeRefund-CUWO must ensure that the CancelRefund-CUWO has enough information to work on. Either by storing the RefundRequest-ID on the external side or by providing the information via the "refund processing data".

Note: As CUWO can fail unexpectedly (e.g., power loss), the AuthorizeRefund-CUWO should provide "refund processing data" as soon as possible while it is still running and not just as return value. Then, in case of an unexpected termination, the enfore platform can provide that data to the CancelRefund-CUWO.

Workflow parameters

The AuthorizeRefund-CUWO will receive an AuthorizeRefundWorkflowParameters structure as input.

The structure is defined as:

/**
 * The parameter/input structure for an "authorize refund" workflow.
 */
class AuthorizeRefundWorkflowParameters extends WorkflowParameters {
    readonly "@type" : string = "n4.cuwo.workflows.refunds.authorizerefund.AuthorizeRefundWorkflowParameters";

    /**
     * The ID of the refund process.
     */
    public refundProcessID : string;

    /**
     * The identifier of the invoice that is to be (partially) refunded.
     *
     * This is the identifier provided by the customer that asks for the refund.
     * The enfore system has checked and determined that it does not know the
     * identifier (in the current organization) and thus invoked the CUWO to
     * allow it to check additional sources (old invoices not available to
     * enfore, invoices from different organizations, etc.).
     *
     * The CUWO may be invoked without such an identifier. This means that
     * the user chose to directly invoke the CUWO.
     */
    public invoiceIdentifier : String;

    /**
     * Information about the context in which the CUWO is executed.
     */
    public cuwoContextInformation : CUWOContextInformation;
}

Success result

On success, the AuthorizeRefund-CUWO is expected to pass an AuthorizeRefundWorkflowResult structure to terminateSuccess.

The structure is defined as:

/**
 * The result/output structure for a successful "authorize refund" workflow.
 */
class AuthorizeRefundWorkflowResult extends WorkflowResult {
    readonly "@type" : string = "n4.cuwo.workflows.refunds.authorizerefund.AuthorizeRefundWorkflowResult";

    /**
     * The amount that has been authorized to be refunded.
     */
    public refundAmount : Money;

    /**
     * A human-readable reference identifying the refund that will be shown/printed as
     * part of the payout UI/receipt.
     *
     * This is an "external identifier" for the enfore platform, so it will only be stored,
     * shown in the refund/sales UI of the enforePOS client and passed to subsequent CUWOs
     * such as ProcessRefund or CancelRefund.
     *
     * The reason for requiring this reference is that even when all subsequent processing
     * including CUWOs does not work, there is a way for the merchant/customer to look up
     * the refund in the external system or call the external systems support hotline and
     * be able to provide some kind if reference.
     */
    public refundReference : string;

    /**
     * An optional date for the refund reference that will be shown/printed as part of the
     * payout UI/receipt.
     */
    public refundReferenceDate : Date?;

    /**
     * The issuer of the authorized refund.
     * 
     * The the OrganizationReference stucture can either is can either be a
     * "CurrentOrganizationReference" or an "OtherOrganizationReference".
     * When using "OtherOrganizationReference", the enfore platform will
     * check if the current organization already has an organization contact
     * with the specified ID. If one exists, it is used and the specified
     * name is ignored. If no such contact exists, a new one is created using
     * the specified name.
     */
    public refundIssuer : OrganizationReference;

    /**
     * Optional processing data of the refund.
     *
     * This data will be stored with the refund process and passed to subsequent CUWOs
     * such as ProcessRefund or CancelRefund.
     *
     * Same as the refundReference, this data is not interpreted by the enfore platform
     * in any way. But other than the refundReference, this data is not shown in any
     * kind of user interface.
     */
    public refundProcessingData? : string;

    /**
     * Additional information to be stored with/printed on the refund
     * receipt document.
     */
    public customReceiptDocumentInformation? : DataList<CustomDocumentInformation>
}

Failure result

On failure, the AuthorizeRefund-CUWO is expected to pass an AuthorizeRefundWorkflowFailure structure to terminateFailure.

The structure is defined as:

/**
 * The result/output structure for a failed "authorize refund" workflow.
 */
class AuthorizeRefundWorkflowFailure extends WorkflowFailure {
    readonly "@type" : string = "n4.cuwo.workflows.refunds.authorizerefund.AuthorizeRefundWorkflowFailure";

    /**
     * The reason for the failure.
     */
    public failureReason : AuthorizeRefundWorkflowFailureReason;

    /**
     * A failure code specific to the CUWO.
     *
     * The enfore platform simply stores that code and displays it to the user but does
     * not understand it or base any processing on it.
     *
     * This enables storing a short error identifier from an external system in a way
     * that allows it to be shown in the enforePOS UI.
     */
    public failureCode? : string;

    /**
     * Optional update for the processing data of the refund.
     *
     * When provided, replaces the previously stored refund processing
     * data. When not provided, a previously stored refund processing
     * data stays unchanged.
     */
    public refundProcessingData? : string;
}

Cancelation result

On cancelation, the AuthorizeRefund-CUWO is expected to pass an AuthorizeRefundWorkflowCancelation structure to terminateCanceled.

The structure is defined as:

/**
 * The result/output structure for a canceled "authorize refund" workflow.
 */
class AuthorizeRefundWorkflowCancelation extends WorkflowCancelation {
    readonly "@type" : string = "n4.cuwo.workflows.refunds.authorizerefund.AuthorizeRefundWorkflowCancelation";

    /**
     * The reason for the cancelation.
     */
    public cancelationReason : AuthorizeRefundWorkflowCancelationReason;
}

ProcessRefund

The ProcessRefund-CUWO is responsible for processing a previously authorized refund. This type of CUWO will only be used, when an AuthorizeRefund-CUWO successfully authorized a refund and the user did not cancel it.

If the CUWO fails, it is unclear whether the refund was processd or not. Thus, the enfore platform will execute the CancelRefund-CUWO to try to release the authorization/revert the process.

Workflow parameters

The ProcessRefund-CUWO will receive a ProcessRefundWorkflowParameters structure as input.

The structure is defined as:

/**
 * The parameter/input structure for a "process refund" workflow.
 */
class ProcessRefundWorkflowParameters extends WorkflowParameters {
    readonly "@type" : string = "n4.cuwo.workflows.refunds.processrefund.ProcessRefundWorkflowParameters";

    /**
     * The ID of the refund that is to be processd.
     */
    public refundProcessID : string;

    /**
     * The reference of the refund to process as provided
     * by the AuthorizeRefund workflow.
     */
    public refundReference? : string;

    /**
     * The processing data of the refund to process as
     * provided by the AuthorizeRefund workflow.
     */
    public refundProcessingData? : string;
}

Success result

On success, the ProcessRefund-CUWO is expected to pass a ProcessRefundWorkflowResult structure to terminateSuccess.

The structure is defined as:

/**
 * The result/output structure for a successful "process refund" workflow.
 */
class ProcessRefundWorkflowResult extends WorkflowResult {
    readonly "@type" : string = "n4.cuwo.workflows.refunds.processrefund.ProcessRefundWorkflowResult";

    /**
     * Optional update for the processing data of the refund.
     * 
     * When provided, replaces the previously stored refund processing
     * data. When not provided, a previously stored refund processing
     * data stays unchanged.
     */
    public refundProcessingData? : string;

    /**
     * Additional information to be stored with/printed on the refund
     * receipt document.
     */
    public customReceiptDocumentInformation? : DataList<CustomDocumentInformation>
}

Failure result

On failure, the ProcessRefund-CUWO is expected to pass a ProcessRefundWorkflowFailure structure to terminateFailure.

The structure is defined as:

/**
 * The result/output structure for a failed "process refund" workflow.
 */
class ProcessRefundWorkflowFailure extends WorkflowFailure {
    readonly "@type" : string = "n4.cuwo.workflows.refunds.processrefund.ProcessRefundWorkflowFailure";

    /**
     * The reason for the failure.
     */
    public failureReason : ProcessRefundWorkflowFailureReason;

    /**
     * A failure code specific to the CUWO.
     * 
     * The enfore platform simply stores that code and displays it to the user but does
     * not understand it or base any processing on it.
     * 
     * This enables storing a short error identifier from an external system in a way
     * that allows it to be shown in the enforePOS UI.
     */
    public failureCode? : string;

    /**
     * Optional update for the processing data of the refund.
     *
     * When provided, replaces the previously stored refund processing
     * data. When not provided, a previously stored refund processing
     * data stays unchanged.
     */
    public refundProcessingData? : string;
}

Cancelation result

The ProcessRefund workflow does not support cancelation.

CancelRefund

The CancelRefund-CUWO is responsible for reverting any authorization or processing a AuthorizeRefund- or ProcessRefund-CUWO may have performed before failing (or on user cancellation or failure on the enforePOS side after successful CUWO execution).

As it cannot be guaranteed that the cancelation can be performed, the CUWO may return refund processing data as part of a failure result. That data will be stored as part of the refund (which will be marked as failed) on the enfore side, so that the refund on the enfore side and the transaction on the external side can be manually reconciled.

This type of CUWO is invoked when:

  • An AuthorizeRefund-CUWO failed (to ensure that the potentially authorized refund is released/reverted)
  • A ProcessRefund-CUWO failed (to ensure that the authorized and potentially processed refund is released/reverted)
  • An AuthorizeRefund-CUWO returned with "success" but the subsequent processing of the refund was canceled or failed on the enforePOS side.

Workflow parameters

The CancelRefund-CUWO will receive a CancelRefundWorkflowParameters structure as input.

The structure is defined as:

/**
 * The parameter/input structure for a "cancel refund" workflow.
 */
class CancelRefundWorkflowParameters extends WorkflowParameters {
    readonly "@type" : string = "n4.cuwo.workflows.refunds.cancelrefund.CancelRefundWorkflowParameters";

    /**
     * The ID of the refund that is to be canceled.
     */
    public refundProcessID : string;

    /**
     * The reference of the refund to cancel as provided
     * by the AuthorizeRefund workflow.
     */
    public refundReference? : string;

    /**
     * The processing data of the refund to cancel as
     * provided by the AuthorizeRefund workflow.
     */
    public refundProcessingData? : string;
}

Success result

On success, the CancelRefund-CUWO is expected to pass a CancelRefundWorkflowResult structure to terminateSuccess.

The structure is defined as:

/**
 * The result/output structure for a successful "cancel refund" workflow.
 */
class CancelRefundWorkflowResult extends WorkflowResult {
    readonly "@type" : string = "n4.cuwo.workflows.refunds.cancelrefund.CancelRefundWorkflowResult";

    /**
     * Optional update for the processing data of the refund.
     * 
     * When provided, replaces the previously stored refund processing
     * data. When not provided, a previously stored refund processing
     * data stays unchanged.
     */
    public refundProcessingData? : string;
}

Failure result

On failure, the CancelRefund-CUWO is expected to pass a CancelRefundWorkflowFailure structure to terminateFailure.

The structure is defined as:

/**
 * The result/output structure for a failed "cancel refund" workflow.
 */
class CancelRefundWorkflowFailure extends WorkflowFailure {
    readonly "@type" : string = "n4.cuwo.workflows.refunds.cancelrefund.CancelRefundWorkflowFailure";

    /**
     * The reason for the failure.
     */
    public failureReason : CancelRefundWorkflowFailureReason;

    /**
     * A failure code specific to the CUWO.
     * 
     * The enfore platform simply stores that code and displays it to the user but does
     * not understand it or base any processing on it.
     * 
     * This enables storing a short error identifier from an external system in a way
     * that allows it to be shown in the enforePOS UI.
     */
    public failureCode? : string;

    /**
     * Optional update for the processing data of the refund.
     *
     * When provided, replaces the previously stored refund processing
     * data. When not provided, a previously stored refund processing
     * data stays unchanged.
     */
    public refundProcessingData? : string;
}

Cancelation result

The CancelRefund workflow does not support cancelation.

API specifications

The following sections contain specifications for the APIs being used by the system. As those APIs do not exist yet and the specifications have not yet been reviewed and approved, all content of these sections should be considered to be in proposal/draft state.

All client/server APIs designed by enfore will be designed using the N4-IDL, an internal tooling to define strongly typed command/query APIs. At the moment, there is no usable specification available that can be provided to third parties, so the following section documents the N4-IDL as necessary to understand and implement the following APIs

NFON

NFON (eNFore Object Notation) is the standard internal data transport and exchange format of the enfore platform. As the CUWO Container is part of the enfore client, its APIs also use NFON to allow reuse of existing client frameworks.

NFON is an extension to JSON and thus any valid NFON must also be valid JSON. In pure JSON, objects are serialized as a list of key/value pairs enclosed in curly brackets. NFON adds a special key (@type) to all objects. The value of the @type key is a string containing the type name of the serialized type.

Pure JSON object: NFON object:
JSON object structure NFON object structure
{
    "firstName": "John",
    "lastName": "Doe",
    "isMarried": false,
    "numberOfChildren": 3
}
{
    "@type": "n4.sample.Contact",
    "firstName": "John",
    "lastName": "Doe",
    "isMarried": false,
    "numberOfChildren": 3
}

This means that any valid NFON document is also a valid JSON document, but a valid JSON document is only considered valid NFON if any JSON object has an @type meta attribute that identifies its type on the enfore platform.

CUWO messages API

The CUWO messages API is based on the HTML5 Channel Messaging API and provides the controller and workflow with the means to communicate with each other.

There are different types of messages being passed between the controller and workflow. They can be roughly split into lifecycle messages, operation messages, and generic messages.

Note that due to technical limitations, the channel only support communication via plain strings. Thus, the sending side must JSON-stringify any of the message objects before posting them and the receiving side must JSON-parse them on receipt and before handling them further.

Generic messages

n4.cuwo.messages.Error

In the case that the CUWO container or the workflow receive a message it does not understand, they will reply by sending an Error message.

The message has the following structure:

{
  "@type": "n4.cuwo.messages.Error",
  "id": "...",
  "originalMessage": "...",
  "errorMessage": "..."
}

The various member provide the information necessary for the operation:

  • id - The ID of the message that was not understood. If the container could not parse the message or the message did not contain an ID, this field has the value “null”.
  • originalMessage - The original message that was not understood.
  • errorMessage - An optional error message for helping to debug the error.

n4.cuwo.messages.generic.StatusNotification

In the case that the CUWO container detects a state or state change for the system configuration, network or attached peripherals, it will send a StatusNotification message to the CUWO.

Since there are a multitude of different kinds of status values that need to be communicated, the enfore platform uses a three-level structure consisting of categories > groups > codes for organizing them. Additionally, each status may have some “data” object whose structure and content are specific to the status code. For example, a “Peripherals > Printers > ...” status has a DeviceReference identifying the relevant printer.

CategoryTypeCodes
ConnectivityGeneralINTERNET_DOWN
INTERNET_UP
PeripheralsPrintersOK
WARN_PAPER_NEAR_END
ERROR_MEMORY
ERROR_COVER
ERROR_NO_PAPER
ERROR_HEAD_TEMPERATURE
ERROR_HEAD
ERROR_VOLTAGE
ERROR_CUTTER
ERROR_PAPER_FEED
ERROR_UNKOWN
UNKOWN
PeripheralsPayment DevicesUNKNOWN
SUCCESS
DISCOVERY_FAILED
CONFIGURATION_FAILED
IN_PROGRESS
CANCELED
SIGNATURE_REQUIRED
INVALID_TRANSACION_ID
DEVICE_NOT_FOUND
TRANSACTION_CONFIRMATION_REQUIRED
ACTION_REQUIRED
CONCURRENT_OPERATION
REVERSAL_NOT_POSSIBLE
ALREADY_REVERSED

The message has the following structure:

{
  "@type": "n4.cuwo.messages.generic.StatusNotification",
  "id": "...",
  "status": {
    "@type": "n4.n4.apis.status.StatusInformation",
    "category": {...},
    "group": {...},
    "code": {...},
    "data": {...},
    "message": "..."
  }
}

Operation members:

  • id - The ID of the notification
  • status - Information about the status
    • category - The category of the status
    • group - The category-specific type of the status
    • code - The group-specific code of the status
    • data - The code-specific data of the status
    • message - An optional message for helping to debug the error.

Note that the n4.cuwo.messages.StatusInformation structure may also be part of an OperationFinished message if the operation failed due to a problem indicated by the status.

Lifecycle messages

Lifecycle messages are used to control the lifecycle of a workflow.

n4.cuwo.messages.TerminationRequested

In case the user asks for termination of the custom workflow, the container will send a TerminationRequested message to the workflow.

The message has the following structure:

{
  "@type": "n4.cuwo.messages.TerminationRequested",
  "id": "..."
}

The various member provide the information necessary for the operation:

  • id - The ID of the request.

n4.cuwo.messages.TerminationConfirmationMessage

If the custom workflow receives a TerminationRequested message, it can choose to reply with a TerminationConfirmationMessage to control the text of the info message shown to the user for confirmation of the termination.

The message has the following structure:

{
  "@type": "n4.cuwo.messages.TerminationConfirmationMessage",
  "id": "...",
  "message": "..."
}

The various member provide the information necessary for the operation:

  • id - The ID of the TerminationRequested message that is being answered.
  • message - The message to be shown to the user for asking whether the workflow should really be terminated or not.

n4.cuwo.messages.TerminationNotification

In case the user asked for termination of the workflow and then confirmed it, the container will send a TerminationNotification message to the workflow. The workflow then has 1000ms time to terminate itself or it will be destroyed by the container.

The message has the following structure:

{
  "@type": "n4.cuwo.messages.TerminationNotification",
  "id": "..."
}

The various member provide the information necessary for the operation:

  • id - The ID of the notification.

n4.cuwo.messages.KillNotification

In case the custom workflow must be terminated from the outside (e.g. on shutdown of the enforePOS application), the container will send a KillNotification message to the workflow.

The message has the following structure:

{
  "@type": "n4.cuwo.messages.KillNotification",
  "id": "..."
}

The various member provide the information necessary for the operation:

  • id - The ID of the notification.

Operation messages

Operation messages are used to allow the workflow to send an operation request to the container and for the container to provide the workflow with the result of that operation.

The general pattern is that the workflow sends an operation request to the container via the message channel. If the container understands the request and determines that it should be fulfillable, it acknowledges the request, and will then perform the necessary steps of the operation. Once the operation is completed (or has failed for any reason not foreseen before sending the ACK), the container will send an operation result message back to the workflow.

alt_text

Some operations are long running and do not provide a single result. For those, the flow is more complicated. Such operations have separate start, stop and result messages. The CUWO must first send the startXXX-message, which will be replied to by either an error or acknowledgement. If acknowledged, the system then starts sending result messages. If the CUWO does not need any more results, it must send the stopXXX-message, which will also be replied to by either an error or an acknowledgement. If acknowledged, the system will not send any further results.

The following diagram shows the “happy path” assuming there are no errors:

alt_text

n4.cuwo.messages.OperationAcknowledged

Whenever the CUWO container receives a message that it knows how to handle, it will acknowledge it via an OperationAcknowledged message.

The message has the following structure:

{
  "@type": "n4.cuwo.messages.OperationAcknowledged",
  "id": "..."
}

The various member provide the information necessary for the operation:

  • id - The ID of the operation that is being acknowledged.

n4.cuwo.messages.OperationFinished

Whenever an operation completes (successfully or not), the CUWO container will notify the workflow via an OperationFinished message.

The message has the following structure:

{
  "@type": "n4.cuwo.messages.OperationFinished",
  "id": "...",
  "status": {
    "@type": "n4.cuwo.OperationStatus",
    "value": "..."
  },
  "result": "...",
  "errorMessage": "...",
  "statusInformations": [...]
}

The various member provide the information necessary for the operation:

  • id - The ID of the operation that was finished.
  • status.value - The status of the operation.
  • result - The actual operation result value. May be available for status value "COMPLETED" and "FAILED".
  • errorMessage - An optional error message. May be available if status is other than "COMPLETED".
  • statusInformations - Optional list of instances of n4.apis.status.StatusInformation. May be available for status value "FAILED".

The status.value of the command is a string with the possible values:

  • "COMPLETED" - The operation was completed successfully
  • "CANCELLED_BY_USER" - The operation was cancelled by the user
  • "FAILED" - The operation failed

The result depends on the type of operation that was completed.

n4.cuwo.messages.printbusinessdocument.PrintBusinessDocumentOperation

The PrintBusinessDocumentOperation message is used to trigger the printing of a business document by referencing the business entity the document belongs to and the document type.

The message has the following structure:

{
  "@type": "n4.cuwo.messages.printbusinessdocument.PrintBusinessDocumentOperation",
  "id": "...",
  "businessEntity": { ... },
  "documentType": { ... },
  "printerType": { ... }
}

The various member provide the information necessary for the operation:

  • id - The ID of the operation. Will be used as part of the acknowledgement and result messages
  • businessEntity - A BusinessEntityReference specifying the business entity whose document to print
  • documentType - The type of document to print. Available types are specific to each type of business entity.
  • printerType - The type of printer to print the document on.

n4.cuwo.messages.PrintDocumentOperation

The PrintDocumentOperation message is used to trigger the printing of a document.

The message has the following structure:

{
  "@type": "n4.cuwo.messages.PrintDocumentOperation",
  "id": "...",
  "documentDownloadURL": "...",
  "documentData": "...",
  "printerType": {
    "@type": "n4.cuwo.messages.PrinterType",
    "value": "..."
  }
}

The various member provide the information necessary for the operation:

  • id - The ID of the operation. Will be used as part of the acknowledgement and result messages
  • documentDownloadURL - The URL from which the document binary can be downloaded. Must be using https:// protocol
  • documentData - The base64 encoded data of the document to print as a string. The string must use the “base64” encoding defined in RFC 4648 Section 4.
  • printerType.value - The type of printer to print the document on. One of "RECEIPT", "LABEL", or "DOCUMENT"

Note that the “documentData” is available for the POC/MVP only and will be removed later. For now, only one of “documentDownloadURL” and “documentData” must be present. If both are present, the container will not be able to parse the message.

n4.cuwo.messages.ScanBarcodesStartOperation

The ScanBarcodesStartOperation message is used to enable barcode scanning on the client.

The message has the following structure:

{
  "@type": "n4.cuwo.messages.ScanBarcodesStartOperation",
  "id": "...",
  "barcodeTypes": [
    { "@type": "n4.cuwo.messages.BarcodeType", "value": "..." },
    { "@type": "n4.cuwo.messages.BarcodeType", "value": "..." },
    ...
  ],
  "infoMessage": "..."
}

The various member provide the information necessary for the operation:

  • id - The ID of the operation. Will be used as part of the acknowledgement and result messages
  • barcodeTypes - An array of n4.cuwo.messages.BarcodeType values listing the types of barcodes that are allowed to be scanned. The array must always be present. When non-empty, a barcode is only accepted if it is one of the listed types. If empty, any type of barcode generally supported by the system is accepted. One of EAN13, EAN8, EAN5, EAN2, UPCE, QRCODE, CODE128, CODE39, CODE93, CODABAR, DATAMATRIX, ITF, PDF417, DATABAR, DATABAR_EXPANDED
  • infoMessage - The message that will be shown by the user when they enable the native UI for manually entering the barcode.

Once barcode scanning has been enabled, the CUWO will start to receive BarcodeScanned-messages whenever the user scans a code or manually enters one (via a special native UI). To stop receiving codes, the CUWO must invoke the ScanBarcodesStopOperation operation.

Sending multiple ScanBarcodesStartOperation messages without intermediate ScanBarcodesStopOperation’s will update the allowed barcode types and the info message but a single ScanBarcodesStopOperation will still be enough to stop the barcode scanning functionality.

n4.cuwo.messages.ScanBarcodesStopOperation

The ScanBarcodesStopOperation message is used to end barcode scanning on the client.

The message has the following structure:

{
  "@type": "n4.cuwo.messages.ScanBarcodesStopOperation",
  "id": "..."
}

The various member provide the information necessary for the operation:

  • id - The ID of the operation. Will be used as part of the acknowledgement and result messages

Once the ScanBarcodesStopOperation message is acknowledged, the CUWO will not receive further BarcodeScanned-messages. If the user has invoked the native UI for manually entering barcodes and a ScanBarcodesStopOperation message is received by the system, the native UI will be closed automatically as well.

n4.cuwo.messages.BarcodeScanned

When barcode scanning is enabled, a BarcodeScanned message is sent to the CUWO every time the user scans a barcode (or manually enters one via the native UI).

The message has the following structure:

{
  "@type": "n4.cuwo.messages.BarcodeScanned",
  "id": "...",

  "barcode": {
    "@type": "n4.data.barcodes.Barcode",
    "barcodeFormat": {
      "@type": "n4.data.barcodes.BarcodeFormat",
      "value": "..."
    },
    "rawValue": "...",
    "codeValue": "...",
    "parsedData": {
      ...
    },
  },

  // deprecated fields
  "barcodeType": {
    "@type": "n4.cuwo.messages.BarcodeType",
    "value": "..."
  },
  "barcodeValue": "...",
  "barcodeCode": "..."
}

The various member provide the information necessary for the operation:

  • id - The ID of the message
  • barcode - The barcode that was scanned.
  • Deprecated fields:
    • barcodeType - The type of barcode that was scanned. One of EAN13, EAN8, EAN5, EAN2, UPCE, QRCODE, CODE128, CODE39, CODE93, CODABAR, DATAMATRIX, ITF, PDF417, DATABAR, DATABAR_EXPANDED
    • barcodeValue - The barcode value as a base64 encoded string. The string must use the “base64” encoding defined in RFC 4648 Section 4. Note that the scanned value may consist of not just the code but also some additional data such as a prefix indicating the code type or type-variant.
    • barcodeCode - The code part of the barcode that was scanned as a plain-text string. The enfore platform tries to clean up the scanned value as much as possible but there may be cases where some additional data is not detected and thus left in the code.

The Barcode structure is defined as:

/**
 * Data structure holding information about a barcode.
 */
class Barcode {
    readonly "@type" : string = "n4.data.barcodes.Barcode";

    /**
     * The format/symbology of the barcode.
     */
    public barcodeFormat : BarcodeFormat;

    /**
     * The full barcode value that was scanned as a base64
     * encoded string.
     * 
     * The string must use the “base64” encoding defined in
     * RFC 4648 Section 4.
     * 
     * Note that the scanned value may consist of not just the code
     * but also some additional data such as a prefix indicating the
     * code type or type-variant.
     */
    public rawValue : string;

    /**
     * The code part of the barcode that was scanned.
     * 
     * The enfore platform tries to clean up the scanned value as
     * much as possible but there may be cases where some additional
     * data is not detected and thus left in the code.
     */
    public codeValue : string;

    /**
     * A barcode may contain data that is understood by the enfore
     * platform and can thus be parsed into structured data.
     * 
     * For example, a barcode may contain a GTIN encoding "Variable
     * Measure Retail Item" information (mainly a combination of a
     * product identifier/PLU and a price or a weight/pieces
     * quantity value).
     * 
     * If such data is detected within the code, the enfore platform
     * will make it available via this field.
     */
    public parsedData? : BarcodeData;
}

Barcode data

The enfore platform provides additional support for some commonly used standards of data being encoded in barcodes.

GS1

Variable measure RCNs

The enfore platform provides parsed data for GS1 RCNs within the prefix range 20 to 29 for variable measure trade items that contain money or quantity information.

GS1VariableMeasurePrice

/**
 * Data structure holding the information parsed from a GS1 RCN
 * (Restricted Circulation Number) holding price information for
 * a variable measure trade item.
 * 
 * See https://www.gs1.org/docs/barcodes/SummaryOfGS1MOPrefixes20-29.pdf for more information
 */
class GS1VariableMeasurePrice extends BarcodeData {
    readonly "@type" : string = "n4.data.barcodes.data.gs1.GS1VariableMeasurePrice";

    /**
     * The country used to parse the code.
     * 
     * This information is important as the GS1 prefix range 20-29
     * is controlled by each GS1 member organization and the specficiations
     * differ between countries. For example, 23 is used to encode
     * the price for both Austria and Germany but is not used (reserved)
     * for Switzerland.
     * 
     * Note that the enfore platform does not try to parse a code
     * for all possible countries. Rather, it uses a single country
     * that is either explicitly specified for the scan or derived
     * from the context information (organization country).
     * 
     * Therefore, if a CUWO or application knows that the code must
     * be interpreted using logic for country AAA but this data
     * states that is was created using logic for country BBB, the
     * CUWO/application knows that this data is invalid an must
     * be ignored.
     */
    public country : Country;

    /**
     * The prefix part of the RCN code.
     */
    public prefix : String;

    /**
     * The (product) identifier contained in the code.
     */
    public identifier : String;

    /**
     * The price contained in the code.
     */
    public price : Money;
}

GS1VariableMeasurePieces

/**
 * Data structure holding the information parsed from a GS1 RCN
 * (Restricted Circulation Number) holding pieces information for
 * a variable measure trade item.
 * 
 * See https://www.gs1.org/docs/barcodes/SummaryOfGS1MOPrefixes20-29.pdf for more information
 */
class GS1VariableMeasurePieces extends BarcodeData {
    readonly "@type" : string = "n4.data.barcodes.data.gs1.GS1VariableMeasurePieces";

    /**
     * The country used to parse the code.
     * 
     * This information is important as the GS1 prefix range 20-29
     * is controlled by each GS1 member organization and the specficiations
     * differ between countries. For example, Germany uses prefixes 25
     * and 26 for encoding pieces whereas Austria uses 28.
     * 
     * Note that the enfore platform does not try to parse a code
     * for all possible countries. Rather, it uses a single country
     * that is either explicitly specified for the scan or derived
     * from the context information (organization country).
     * 
     * Therefore, if a CUWO or application knows that the code must
     * be interpreted using logic for country AAA but this data
     * states that is was created using logic for country BBB, the
     * CUWO/application knows that this data is invalid an must
     * be ignored.
     */
    public country : Country;

    /**
     * The prefix part of the RCN code.
     */
    public prefix : String;

    /**
     * The (product) identifier contained in the code.
     */
    public identifier : String;

    /**
     * The pieces contained in the code.
     */
    public pieces : Quantity<UnitOfQuantity>;
}

GS1VariableMeasureWeight

/**
 * Data structure holding the information parsed from a GS1 RCN
 * (Restricted Circulation Number) holding weight information for
 * a variable measure trade item.
 * 
 * See https://www.gs1.org/docs/barcodes/SummaryOfGS1MOPrefixes20-29.pdf for more information
 * 
 * Note that the "weight" here technically is "mass" but "weight" is
 * used as that is the term used by GS1 and in all related documentation.
 */
class GS1VariableMeasureWeight extends BarcodeData {
    readonly "@type" : string = "n4.data.barcodes.data.gs1.GS1VariableMeasureWeight";

    /**
     * The country used to parse the code.
     * 
     * This information is important as the GS1 prefix range 20-29
     * is controlled by each GS1 member organization and the specficiations
     * differ between countries. For example, Germany uses prefixes 28
     * and 29 for encoding weight whereas Austria uses 21 and 27.
     * 
     * Note that the enfore platform does not try to parse a code
     * for all possible countries. Rather, it uses a single country
     * that is either explicitly specified for the scan or derived
     * from the context information (organization country).
     * 
     * Therefore, if a CUWO or application knows that the code must
     * be interpreted using logic for country AAA but this data
     * states that is was created using logic for country BBB, the
     * CUWO/application knows that this data is invalid an must
     * be ignored.
     */
    public country : Country;

    /**
     * The prefix part of the RCN code.
     */
    public prefix : String;

    /**
     * The (product) identifier contained in the code.
     */
    public identifier : String;

    /**
     * The weight contained in the code.
     */
    public weight : Quantity<UnitOfMass>;
}

n4.cuwo.messages.imagecapture.CaptureImageOperation

The CaptureImageOperation message is used to trigger the capture of an image.

The message has the following structure:

{
  "@type": "n4.cuwo.messages.imagecapture.CaptureImageOperation",
  "id": "...",
}

The various member provide the information necessary for the operation:

  • id - The ID of the operation. Will be used as part of the acknowledgement and result messages

If the operation is successful, an instance of CaptureImageResult is returned as part of the OperationFinished message.

CaptureImageResult has the following structure:

{
  "@type": "n4.cuwo.messages.imagecapture.CaptureImageResult",
  "image": "...",
  "mimetype": "..."
}

The various member provide the result information for the operation:

  • image - The image data value as a base64 encoded string. The string must use the “base64” encoding defined in RFC 4648 Section 4.
  • mimetype - The Mime-Type of the image as a string

n4.cuwo.messages.checkoutbasket.CheckoutBasketOperation

The CheckoutBasketOperation message is used to trigger the checkout of a basket.

This operation is only available to KIOSK CUWOs!

The message has the following structure:

{
  "@type": "n4.cuwo.messages.checkoutbasket.CheckoutBasketOperation",
  "id": "...",
  "basket": {...},
  "customerInformation": {...},
  "preconfiguredPayments": [...],
  "preconfiguredPayouts": [...]
}

The various member provide the information necessary for the operation:

  • id - The ID of the operation. Will be used as part of the acknowledgement and result messages
  • basket - The basket to check out. Consists of items and may hold discounts.
  • customerInformation - Information about the customer.
  • preconfiguredPayments - Optional preconfigured payments
  • preconfiguredPayouts - Optional preconfigured payouts

If the operation is successful, an instance of CheckoutBasketResult is returned as part of the OperationFinished message.

CheckoutBasketResult has the following structure:

{
  "@type": "n4.cuwo.messages.checkoutbasket.CheckoutBasketResult",
  "invoiceNumber": "...",
  "invoiceData": {...}
}

The various member provide the result information for the operation:

  • invoiceNumber - The invoice number as a string.
  • invoiceData - The invoice data (amounts, taxes, security information, etc.) as an InvoiceData structure

n4.cuwo.messages.evaluatebasket.EvaluateBasketOperation

The EvaluateBasketOperation message is used to trigger the evaluation of a basket.

This operation is only available to KIOSK CUWOs!

The message has the following structure:

{
  "@type": "n4.cuwo.messages.evaluatebasket.EvaluateBasketOperation",
  "id": "...",
  "basket": {...},
  "customerInformation": {...}
}

The various member provide the information necessary for the operation:

  • id - The ID of the operation. Will be used as part of the acknowledgement and result messages
  • basket - The basket to evaluate. Consists of items and may hold discounts.
  • customerInformation - Information about the customer.

If the operation is successful, an instance of EvaluateBasketResult is returned as part of the OperationFinished message.

EvaluateBasketResult has the following structure:

{
  "@type": "n4.cuwo.messages.evaluatebasket.EvaluateBasketResult",
  "evaluationResult": {...}
}

The various member provide the result information for the operation:

  • evaluationResult - The evaluation result (amounts, taxes, etc.) as a BasketEvaluationData structure

Parent/child CUWO-related messages

For dealing with parent and child CUWOs, the enfore platform provides the following operations/messages:

  • SpawnCustomerLevelUIChildCUWOOperation
  • TerminateChildCUWOOperation
  • ChildCUWOTerminated
  • PassMessageToCUWOOperation
  • MessageReceived

SpawnCustomerLevelUIChildCUWOOperation

SpawnCustomerLevelUIChildCUWOOperation is an operation of the "parent/child CUWOs" API and allows a CUWO to spawn a customer-level UI CUWO.

This operation can only be used from a limited set of CUWOs:

  • ConfigureLineItem
  • AuthorizeOrCapturePayment
  • GrantPayout

The device the CUWO is spawned on is either configured for the current device or must be selected by the merchant (a platform UI will be shown with a list of suitable devices at the current service location).

The message is defined as follows:

/**
 * Operation of the "parent/child CUWOs" API that spawns a customer-level UI CUWO
 * on another device.
 */
class SpawnCustomerLevelUIChildCUWOOperation extends AbstractMessage {
    readonly "@type" : string = "n4.cuwo.messages.parentchild.SpawnCustomerLevelUIChildCUWOOperation";

    /**
     * The ID of the operation message.
     */
    public id : string;

    /**
     * The start URL of the CUWO to spawn.
     */
    public cuwoStartURL : string;

    /**
     * Optional data to be passed to the spawned CUWO.
     */
    public parameterData? : string;
}

Here's an example NFON:

{
  "@type": "n4.cuwo.messages.parentchild.SpawnCustomerLevelUIChildCUWOOperation",
  "id": "0e5e526c-35a2-11ec-8d3d-0242ac130003",
  "cuwoStartURL": "https://cuwo.example.com/mycuwo",
  "parameterData": "S6TLybt2e/BUlV6dqVwuWA=="
}

Success result

On success, the OperationFinished message will contain a SpawnChildCUWOSuccess result holding the handle of the spawned CUWO. That handle can then be used for other operations (e.g., PassMessageToCUWOOperation) to address the spawned CUWO.

The structure is defined as follows:

/**
 * Data structure returned by a "spawn ... cuwo" operation of the
 * "parent/child CUWOs" API on success.
 * 
 * Holds the handle of the spawned CUWO.
 */
class SpawnChildCUWOSuccess {
    readonly "@type" : string = "n4.cuwo.messages.parentchild.results.SpawnChildCUWOSuccess";

    /**
     * The handle of the spawned CUWO.
     */
    public childCUWOHandle : string;
}

Failure result

On failure, the OperationFinished message will contain a SpawnChildCUWOFailure result holding an error code and a debug message.

The structure is defined as follows:

/**
 * Data structure returned by a "spawn ... CUWO" operation of the
 * "parent/child CUWOs" API on failure.
 * 
 * Holds the failure code and an optional debug message.
 */
class SpawnChildCUWOFailure {
    readonly "@type" : string = "n4.cuwo.messages.parentchild.results.SpawnChildCUWOFailure";

    /**
     * A code indicating the reason for the failure.
     */
    public failureCode : FailureCode;

    /**
     * A debug message providing more information about the failure.
     */
    public debugMessage? : string;
}

TerminateChildCUWOOperation

TerminateChildCUWOOperation is an operation of the "parent/child CUWOs" API and allows a parent CUWO to terminate one of its child CUWOs.

The message is defined as follows:

/**
 * Operation of the "parent/child CUWOs" API that terminates
 * a CUWO spawned via a "spawn ... CUWO" opepration.
 */
class TerminateChildCUWOOperation extends AbstractMessage {
    readonly "@type" : string = "n4.cuwo.messages.parentchild.TerminateChildCUWOOperation";

    /**
     * The ID of the operation message.
     */
    public id : string;

    /**
     * The handle of the CUWO to terminate.
     */
    public cuwoHandle : string;

Here's an example NFON:

{
  "@type": "n4.cuwo.messages.parentchild.TerminateChildCUWOOperation",
  "id": "0e5e526c-35a2-11ec-8d3d-0242ac130003",
  "cuwoHandle": "pgPdiUF11JL7xaBWbHeV"
}

Success result

On success, the OperationFinished message will contain a TerminateChildCUWOSuccess result. This result holds the result data of the terminated CUWO when available.

The structure is defined as follows:

/**
 * Data structure returned by the "terminate child CUWO" operation of the
 * "parent/child CUWOs" API on success.
 */
class TerminateChildCUWOSuccess {
    readonly "@type" : string = "n4.cuwo.messages.parentchild.results.TerminateCUWOSuccess";

    /**
     * Result data that the terminated CUWO provided.
     */
    public resultData? : string;
}

Failure result

On failure, the OperationFinished message will contain a TerminateChildCUWOFailure result holding an error code and a debug message.

The structure is defined as follows:

/**
 * Data structure returned by the "terminate child CUWO" operation of the
 * "parent/child CUWOs" API on failure.
 * 
 * Holds the failure code and an optional debug message.
 */
class TerminateChildCUWOFailure {
    readonly "@type" : string = "n4.cuwo.messages.parentchild.results.TerminateChildCUWOFailure";

    /**
     * A code indicating the reason for the failure.
     */
    public failureCode : FailureCode;

    /**
     * A debug message providing more information about the failure.
     */
    public debugMessage? : string;
}

ChildCUWOTerminated

When a child CUWO either terminates itself or is terminated due to a TerminateChildCUWOOperation operation, the parent CUWO will be notified via a ChildCUWOTerminated message.

The message is defined as follows:

/**
 * Message of the "parent/child CUWOs" API that informs a parent CUWO about the
 * termination of one of its child CUWOs.
 */
class ChildCUWOTerminated extends AbstractMessage {
    readonly "@type" : string = "n4.cuwo.messages.parentchild.ChildCUWOTerminated";

    /**
     * The ID of the message.
     */
    public id : string;

    /**
     * The handle of the terminated child CUWO.
     */
    public cuwoHandle : string;

    /**
     * Result data that the terminated child CUWO provided.
     */
    public resultData? : string;
}

PassMessageToCUWOOperation

PassMessageToCUWOOperation is an operation of the "parent/child CUWOs" API and allows a CUWO to send a message to another CUWO.

The message is defined as follows:

/**
 * Operation of the "parent/child CUWOs" API that sends a message to another CUWO.
 */
class PassMessageToCUWOOperation extends AbstractMessage {
    readonly "@type" : string = "n4.cuwo.messages.parentchild.PassMessageToCUWOOperation";

    /**
     * The ID of the operation message.
     */
    public id : string;

    /**
     * The handle of the CUWO to send the message to.
     */
    public cuwoHandle : string;

    /**
     * The message to send to the CUWO.
     */
    public message : string;
}

Here's an example NFON:

{
  "@type": "n4.cuwo.messages.parentchild.PassMessageToCUWOOperation",
  "id": "0e5e526c-35a2-11ec-8d3d-0242ac130003",
  "cuwoHandle": "CDwTJK6R5y0CMFglvt78",
  "message": "1234"
}

Success result

On success, the OperationFinished message will contain a PassMessageToCUWOSuccess result.

The structure is defined as follows:

/**
 * Data structure returned by the "pass message to cuwo" operation of the
 * "parent/child CUWOs" API on success.
 */
class PassMessageToCUWOSuccess {
    readonly "@type" : string = "n4.cuwo.messages.parentchild.results.PassMessageToCUWOSuccess";
}

Failure result

On failure, the OperationFinished message will contain a PassMessageToCUWOFailure result holding an error code and a debug message.

The structure is defined as follows:

/**
 * Data structure returned by the "pass message to cuwo" operation of the
 * "parent/child CUWOs" API on failure.
 * 
 * Holds the failure code and an optional debug message.
 */
class PassMessageToCUWOFailure {
    readonly "@type" : string = "n4.cuwo.messages.parentchild.results.PassMessageToCUWOFailure";

    /**
     * A code indicating the reason for the failure.
     */
    public failureCode : FailureCode;

    /**
     * A debug message providing more information about the failure.
     */
    public debugMessage? : string;
}

MessageReceived

When a CUWO receives a message from another CUWO (sent via PassMessageToCUWOOperation), it will receive a MessageReceived message.

The message is defined as follows:

/**
 * Message of the "parent/child CUWOs" API that informs a CUWO
 * that about a message that was sent to it via the "pass message
 * to CUWO" operation.
 */
class MessageReceived extends AbstractMessage {
    readonly "@type" : string = "n4.cuwo.messages.parentchild.MessageReceived";

    /**
     * The ID of the message.
     */
    public id : string;

    /**
     * The handle of the CUWO that sent the message.
     */
    public cuwoHandle : string;

    /**
     * The message that was sent.
     */
    public message : string;
}

n4.cuwo.messages.UpdateLineItemStatus

An UpdateLineItemStatus message is used to trigger an update of the custom workflow status of a line item.

The message has the following structure:

{
  "@type": "n4.cuwo.messages.UpdateLineItemStatus",
  "id": "...",
  "lineItemID": "...",
  "externalData": "...",
  "requiresCustomRefundFlow": true | false
}

The various member provide the information necessary for the operation:

  • id - The ID of the message. Will be used as part of the acknowledgement and result messages
  • lineItemID - The enfore identifier of the line item whose status is to be updated
  • externalData - Updated external data for the line item. When not set, existing external data will not be modified
  • requiresCustomRefundFlow - Whether or not the line item requires a custom workflow to be called when it is to be refunded. When not set, the existing value of the flag is not changed.

UpdatePaymentProcessingDataOperation

UpdatePaymentProcessingDataOperation is an operation for the "payment & payout" CUWOs to update the processing data of a payment request.

This operation can only be used for CUWOs that are part of or related to a payment request. For now, this means:

  • AuthorizeOrCapturePayment
  • CapturePayment
  • CancelPayment
  • RevertPayment

The message is defined as follows:

/**
 * Operation for the payment & payout CUWOs to update the processing
 * data of a payment request.
 */
class UpdatePaymentProcessingDataOperation extends AbstractMessage {
    readonly "@type" : string = "n4.cuwo.messages.paymentpayoutprocessingdata.UpdatePaymentProcessingDataOperation";

    /**
     * The ID of the operation message.
     */
    public id : string;

    /**
     * The ID of the payment request whose processing data to update.
     * 
     * This must be the ID that was passed into the CUWO, otherwise
     * the operation will fail.
     */
    public paymentRequestID : string;

    /**
     * The updated payment processing data to store for the payment.
     */
    public paymentProcessingData : string;

Here's an example NFON:

{
  "@type": "n4.cuwo.messages.paymentpayoutprocessingdata.UpdatePaymentProcessingDataOperation",
  "id": "44b00404-2838-11ec-9621-0242ac130002",
  "paymentRequestID": "616041c899256dee7c84e346",
  "paymentProcessingData": "AtOEhvtUvOMSQge5igfjSvffROkcn4fjrr6ihN2xQm9OhpmJ26kkW07sA1AP",
}

UpdatePayoutProcessingDataOperation

UpdatePayoutProcessingDataOperation is an operation for the "payment & payout" CUWOs to update the processing data of a payout request.

This operation can only be used for CUWOs that are part of or related to a payout request. For now, this means:

  • GrantPayout
  • CancelPayout
  • RevertPayment

The message is defined as follows:

/**
 * Operation for the payment & payout CUWOs to update the processing
 * data of a payout request.
 */
class UpdatePayoutProcessingDataOperation extends AbstractMessage {
    readonly "@type" : string = "n4.cuwo.messages.paymentpayoutprocessingdata.UpdatePayoutProcessingDataOperation";

    /**
     * The ID of the operation message.
     */
    public id : string;

    /**
     * The ID of the payout request whose processing data to update.
     * 
     * This must be the ID that was passed into the CUWO, otherwise
     * the operation will fail.
     */
    public payoutRequestID : string;

    /**
     * The updated payout processing data to store for the payout.
     */
    public payoutProcessingData : string;

Here's an example NFON:

{
  "@type": "n4.cuwo.messages.paymentpayoutprocessingdata.UpdatePayoutProcessingDataOperation",
  "id": "44b00404-2838-11ec-9621-0242ac130002",
  "payoutRequestID": "616041c899256dee7c84e346",
  "payoutProcessingData": "AtOEhvtUvOMSQge5igfjSvffROkcn4fjrr6ihN2xQm9OhpmJ26kkW07sA1AP",
}

UpdateRefundProcessingDataOperation

UpdateRefundProcessingDataOperation is an operation for the "refund" CUWOs to update the processing data of a refund process.

This operation can only be used for CUWOs that are part of or related to a refund process. For now, this means:

  • AuthorizeRefund
  • ProcessRefund
  • CancelRefund

The message is defined as follows:

/**
 * Operation for the refund CUWOs to update the processing
 * data of a refund process.
 */
class UpdateRefundProcessingDataOperation extends AbstractMessage {
    readonly "@type" : string = "n4.cuwo.messages.refundprocessingdata.UpdateRefundProcessingDataOperation";

    /**
     * The ID of the operation message.
     */
    public id : string;

    /**
     * The ID of the refund process whose processing data to update.
     * 
     * This must be the ID that was passed into the CUWO, otherwise
     * the operation will fail.
     */
    public refundProcessID : string;

    /**
     * The updated refund processing data to store for the refund.
     */
    public refundProcessingData : string;

Here's an example NFON:

{
  "@type": "n4.cuwo.messages.refundprocessingdata.UpdateRefundProcessingDataOperation",
  "id": "44b00404-2838-11ec-9621-0242ac130002",
  "refundProcessID": "616041c899256dee7c84e346",
  "refundProcessingData": "AtOEhvtUvOMSQge5igfjSvffROkcn4fjrr6ihN2xQm9OhpmJ26kkW07sA1AP",
}

CUWO callback API

The CUWO callback API is a JavaScript API that the CUWO container injects into the global JavaScript namespace of each workflow instance. That API is to be used by the workflow instance to receive extended parameters that do not fit into the start URL and to terminate itself.

The API is represented by CUWOCallback object in the global JavaScript namespace. To inject that object into the global JavaScript namespace, we will either use WebView.addJavaScriptInterface() or provide a JavaScript file that contains an implementation of the callback using the Channel Messaging API. This is an implementation detail and transparent to the custom workflow logic.

The CUWOCallback object defines methods for the following use cases:

  • Getting input parameters and context information for the workflow
  • Terminating the workflow with the three cases of success, failure, and cancelation

Methods related to workflow parameters & context

The CUWO callback has various methods that provide the CUWO with information about its input parameters (e.g., getWorkflowParameters) and information about the execution context (e.g., getOrganizationInfo).

getStartURL

The getStartURL method can be used to determine the URL that was used to start the CUWO.

The method is defined as:

/**
 * Returns the start URL of the custom workflow.
 */
public getStartURL(): string

The method is available for all types of CUWOs.

getOrganizationInfo

The getOrganizationInfo method can be used to determine the enfore-"organization context" that the CUWO is executed in.

The method is defined as:

/**
 * Returns information about organization entity for which the
 * custom workflow is performed.
 * 
 * Note that the "externalID" is currently not supported by
 * the platform.
 */
public getOrganizationInfo() : string<OrganizationInfo>

The return value is a string holding the NFON-serialization of an OrganizationInfo structure.

This structure has the following form:

{
    "@type" : "n4.cuwo.OrganizationInfo",
    "name" : "...",
    "enforeID" : "...",
    "externalID" : "..."
}

The method is available for all types of CUWOs.

getSalesChannelInfo

The getSalesChannelInfo method can be used to determine the enfore-"saleschannel" that the CUWO is executed for.

The method is defined as:

/**
 * Returns information about sales channel for which the
 * custom workflow is performed.
 * 
 * Note that the "externalID" is currently not supported by
 * the platform.
 */
public getSalesChannelInfo() : string<SalesChannelInfo>

The return value is a string holding the NFON-serialization of a SalesChannelInfo structure.

This structure has the following form:

{
    "@type" : "n4.cuwo.SalesChannelInfo",
    "name" : "...",
    "enforeID" : "...",
    "externalID" : "..."
}

The method is available for all types of CUWOs.

getRegisterInfo

The getRegisterInfo method can be used to determine the enfore-"register" device that the CUWO is executed on.

The method is defined as:

/**
 * Returns information about register for which the custom
 * workflow is performed.
 * 
 * Note that the "externalID" is currently not supported by
 * the platform.
 */
public getRegisterInfo() : string<RegisterInfo>

The return value is a string holding the NFON-serialization of a RegisterInfo structure.

This structure has the following form:

{
    "@type" : "n4.cuwo.RegisterInfo",
    "name" : "...",
    "enforeID" : "...",
    "externalID" : "..."
}

The method is available for all types of CUWOs.

getCUWOContextInformation

The getCUWOContextInformation method is used to provide the CUWO with information about the context it rus in.

The method is defined as:

/**
 * Returns information about the context the CUWO is executed in.
 */
public getCUWOContextInformation() : string<CUWOContextInformation>

The return value is a string holding the NFON-serialization of a subtype CUWOContextInformation structure.

The structure is defined as:

/**
 * Information about the context a CUWO is executed in.
 */
class CUWOContextInformation {
    readonly "@type" : string = "n4.cuwo.CUWOContextInformation";

    /**
     * Information about the organization the CUWO is executed for.
     */
    public organization : OrganizationInfo;

    /**
     * Information about the POS location the CUWO is executed at.
     */
    public posLocation : POSLocationReference;
    
    /**
     * Information about the device the CUWO is executed on.
     */
    public device : DeviceReference

    /**
     * Information about the cash register the CUWO is executed on.
     */
    public cashRegister? : CashRegisterReference

    /**
     * Information about the staff member the CUWO is executed by.
     */
    public staffMember? : StaffMemberReference

    /**
     * The languages that the client UI uses. This can be used by the cuwo
     * implementation to provide localized texts matching the client languaue.
     * 
     * The first language is the prefered language. Additional languages are
     * fallbacks, sorted by priority. The items in the lists are "language tags"
     * (see https://www.w3.org/TR/ltli/#dfn-language-tag).
     */
    public clientLanguages? : List<String>;
}

getWorkflowParameters

The getWorkflowParameters method is used to provide the CUWO with the parameters it needs to do its job.

The method is defined as:

/**
 * Returns the parameters for the custom workflow.
 * 
 * Depending on the type of workflow, the returned structure
 * is of a different subtype of WorkflowParameters.
 */
public getWorkflowParameters() : string<? extends WorkflowParameters>

The return value is a string holding the NFON-serialization of a subtype WorkflowParameters structure. What subtype is returned depends on the type of the workflow. For example a CapturePayment workflow receives a CapturePaymentWorkflowParameters structure.

For now, this method is only available for the CUWOs:

  • AuthorizeOrCapturePayment
  • CapturePayment
  • CancelPayment
  • RefundPayment
  • GrantPayout
  • CancelPayout

getLineItems

WARNING: This method is planned to be deprecated in a future API version. Likely to be replaced by getWorkflowParameters.

The getLineItems method can be used to access information about the line items to be processed by the CUWO.

The method is defined as:

/**
 * Returns information about the line item(s) for the custom workflow.
 */
public getLineItems() : string<DataList<LineItem>>

The return value is a string holding the NFON-serialization of a DataList of LineItem structures.

This structure has the following form:

[
    {
        "@type" : "n4.cuwo.callbacks.lineitems.LineItem",
        "id" : "...",
        "product" : null,               // n4.apis.shared.ProductReference
        "lot" : null,                   // n4.apis.shared.LotReference
        "quantity" : null,              // n4.model.common.Quantity
        "basePriceAndQuantity" : null,  // n4.apis.shared.ProductPriceAndQuantity
        "dependency" : null,            // n4.apis.basket.items.LineItemDependency
        "extraChargeType" : null,       // n4.apis.shared.ExtraChargeType
        "externalID" : "...",
        "externalData" : "...",
    },
    // ...
]

The method is only available for the CUWOs:

  • AssembleProduct
  • CancelLineItem
  • RefundLineItem

getLineItemInfo

WARNING: This method is planned to be deprecated in a future API version. Likely to be replaced by getWorkflowParameters.

The getLineItemInfo method can be used to access information about the line item to be processed by the CUWO.

The method is defined as:

/**
 * Returns information about the line item for the custom workflow.
 */
public getLineItemInfo() : string<LineItemInfo>

The return value is a string holding the NFON-serialization of a LineItemInfo structure.

This structure has the following form:

{
    "@type" : "n4.cuwo.LineItemInfo",
    "enforeID" : "...",
    "externalID" : "...",
    "type" : null,            // n4.metacompany.jobs.LineItemType
    "name" : "...",
    "product" : null,         // n4.cuwo.ProductInfo
    "totalPriceNet" : null,   // n4.model.common.Money
    "totalPriceGross" : null, // n4.model.common.Money
    "pricePerUnit" : null,    // n4.model.common.Money
    "quantityUnit" : null,    // n4.model.common.Quantity
    "priceIsGross" : true,
    "externalData" : "...",
    "requiresCustomCancelFlow" : false,
    "requiresCustomRefundFlow" : false,
}

The method is only available for the CUWOs:

  • AssembleProduct
  • CancelLineItem
  • RefundLineItem

getProductInfo

WARNING: This method is planned to be deprecated in a future API version. Likely to be replaced by getWorkflowParameters.

The getProductInfo method can be used to access information about the product to be processed by the CUWO. The product is either the product whose representation in the sales item navigation was activated (for ConfigureLineItem) or the product that is referenced by the line item (AssembleProduct, CancelLineItem, and RefundLineItem).

The method is defined as:

/**
 * Returns information about the product for the custom workflow.
 * 
 * The product is either the product whose representation in
 * the sales item navigation was activated (for ConfigureLineItem)
 * or the product that is referenced by the line item
 * (AssembleProduct, CancelLineItem, and RefundLineItem).
 */
public getProductInfo() : string<ProductInfo>

The return value is a string holding the NFON-serialization of a ProductInfo structure.

This structure has the following form:

{
    "@type" : "n4.cuwo.ProductInfo",
    "enforeID" : "...",
    "name" : "...",
    "gtin" : "...",
    "productID" : null,
    "pricePerUnit" : null,    // n4.model.common.Money
    "quantityUnit" : null,    // n4.model.common.Quantity
    "priceIsGross" : true,
    "taxCategory" : "..."
}

The method is only available for the CUWOs:

  • ConfigureLineItem
  • AssembleProduct
  • CancelLineItem
  • RefundLineItem

Methods related to workflow termination

The CUWO callback has various methods that allow the CUWO to terminate itself after success or failure or on cancelation.

terminateSuccess

The terminateSuccess method must be called by the CUWO when it has successfully performed its job and wants to let the enfore runtime know that it is done and that the web view can be closed.

The method is defined as:

/**
 * Notify container of successful completion of the workflow
 * and terminate it.
 *
 * The actual result type depends on the extension point the
 * workflow was called for.
 * 
 * @param result - The NFON-serialized workflow-specific result structure.
 */
public terminateSuccess(
    result : string<? extends WorkflowResult>,
) : void

The method receives a single parameter that is of type string. The string must contain the NFON-serialization of the workflow-specific subtype of WorkflowResult. For example, for a RefundLineItem workflow, the string must contain a serialized RefundLineItemWorkflowResult.

The method is available for all types of CUWOs.

terminateFailure

The terminateFailure method must be called by the CUWO when it has failed to perform its job and wants to let the enfore runtime know that it is done and that the web view can be closed.

The method is defined as:

/**
 * Notify container of failure of the workflow and terminate it.
 * 
 * @param failure - Depending on workflow type, the NFON-serialized
 *                  workflow-specific failure structure or the error
 *                  message to be shown to the user.
 */
public terminateFailure(
    failure : string<? extends WorkflowFailure> | string,
) : void

The method receives a single parameter that is of type string. For newer CUWOs, the string must contain the NFON-serialization of the workflow-specific subtype of WorkflowFailure. For older CUWOs, the string is just a debug message.

The method is available for all types of CUWOs.

The following CUWOs use dedicated WorkflowFailure structures:

  • AuthorizeOrCapturePayment
  • CapturePayment
  • CancelPayment
  • RefundPayment
  • GrantPayout
  • CancelPayout

The following CUWOs use a plain-string debug message instead:

  • ConfigureLineItem
  • AssembleProduct
  • CancelLineItem
  • RefundLineItem
  • Kiosk

terminateCanceled

The terminateCanceled method must be called by the CUWO when it was canceled and wants to let the enfore runtime know that it is done and that the web view can be closed.

The method is defined as:

/**
 * Notify container of cancelation of the workflow and terminate it.
 * 
 * @param cancelation - The NFON-serialized workflow-specific cancelation structure.
 */
public terminateCanceled(
    cancelation : string<? extends WorkflowCancelation>,
) : void

The method receives a single parameter that is of type string and must contain the NFON-serialization of the workflow-specific subtype of WorkflowCancelation.

The method is only available for the CUWOs:

  • AuthorizeOrCapturePayment
  • GrantPayout

Type definitions

The following diagrams show the types used as part of the CUWO Callback API.

General overview

Workflow result: ConfigureLineItemWorkflowResult

alt_text

Callback data: getLineItems()

alt_text

As described in the section about NFON, the JSON representation of each type requires an @type attribute with the FQN of the type.

The types FixedPoint6, Currency, and the various UnitOfMeasure subtypes require additional explanation.

n4.lang.FixedPoint6

An instance of n4.lang.FixedPoint6 represents a numerical value with 6 decimal digits. It is serialized to NFON by placing the numerical value in a value attribute, encoding it as a string of numbers with 6 decimal digits and without a decimal separator.

Example NFON:

{
  "@type": "n4.lang.FixedPoint6",
  "value": "1250750000" // i.e. 1,250.75
}

n4.model.common.Currency

For purposes of the custom workflow logic the type Currency behaves like an enumeration. The allowed values are a subset of the ISO 4217 currency codes. For purposes of CUWOs, the value “EUR” seems sufficient.

Example NFON:

{
    "@type": "n4.model.common.Currency",
    "name": "EUR"
}

n4.model.common.UnitOfMeasure and its subtypes

Similar to Currency, the subtypes of UnitOfMeasure behave like an enumeration for purposes of custom workflow logic. The most likely used values for purposes of CUWOs are:

  • UnitOfQuantity
    • PIECES (i.e., Stück)
  • UnitOfLength
    • MILLIMETERS
    • CENTIMETERS
    • METERS
  • UnitOfMass
    • MILLIGRAMS
    • GRAMS
    • KILOGRAMS

Example NFON:

{
    "@type": "n4.model.common.UnitOfMeasure",
    "name": "PIECES"
}

NFON examples

Here are some NFON examples for the various workflow result structures.

EP1: ConfigureLineItem

{
  "@type": "n4.cuwo.workflows.configurelineitem.ConfigureLineItemWorkflowResult",
  "lineItems": [
    {
      "@type": "n4.apis.basket.items.LineItem",
      "id": "1",
      "name": "Burger with extra Bacon",
      "product": {
        "@type": "n4.apis.shared.ProductReference",
        "articleID": "XY_burger"
      },
      "quantity": {
        "@type": "n4.model.common.Quantity",
        "value": {
          "@type": "n4.lang.FixedPoint6",
          "value": "1000000"
        },
        "unit": {
          "@type": "n4.model.common.UnitOfQuantity",
          "name": "PIECES"
        }
      },
      "basePriceAndQuantity": {
        "@type": "n4.apis.shared.ProductPriceAndQuantity",
        "price": {
          "@type": "n4.model.common.Money",
          "amount": {
            "@type": "n4.lang.FixedPoint6",
            "value": "5000000"
          },
          "unit": {
            "@type": "n4.model.common.Currency",
            "name": "EUR"
          }
        },
        "quantity": {
          "@type": "n4.model.common.Quantity",
          "value": {
            "@type": "n4.lang.FixedPoint6",
            "value": "1000000"
          },
          "unit": {
            "@type": "n4.model.common.UnitOfQuantity",
            "name": "PIECES"
          }
        }
      },
      "externalID": "1234",
      "externalData": "abcdefg",
      "requiresCustomCancelFlow": false,
      "requiresCustomRefundFlow": true
    },
    {
      "@type": "n4.apis.basket.items.LineItem",
      "id": "2",
      "name": "Extra Bacon",
      "product": {
        "@type": "n4.apis.shared.ProductReference",
        "articleID": "XY_bacon"
      },
      "quantity": {
        "@type": "n4.model.common.Quantity",
        "value": {
          "@type": "n4.lang.FixedPoint6",
          "value": "2000000"
        },
        "unit": {
          "@type": "n4.model.common.UnitOfQuantity",
          "name": "PIECES"
        }
      },
      "basePriceAndQuantity": {
        "@type": "n4.apis.shared.ProductPriceAndQuantity",
        "price": {
          "@type": "n4.model.common.Money",
          "amount": {
            "@type": "n4.lang.FixedPoint6",
            "value": "600000"
          },
          "unit": {
            "@type": "n4.model.common.Currency",
            "name": "EUR"
          }
        },
        "quantity": {
          "@type": "n4.model.common.Quantity",
          "value": {
            "@type": "n4.lang.FixedPoint6",
            "value": "1000000"
          },
          "unit": {
            "@type": "n4.model.common.UnitOfQuantity",
            "name": "PIECES"
          }
        }
      },
      "dependency": {
        "@type": "n4.apis.basket.items.LineItemDependency",
        "itemID": "1",
        "dependencyType": {
          "@type": "n4.apis.basket.items.LineItemDependencyType",
          "name": "OPTION"
        },
        "optionDefinition": {
          "@type": "n4.apis.basket.items.OptionDefinitionReference",
          "optionGroupID": "123123",
          "optionID": "5"
        }
      }
    }
  ]
}

EP2: assembleProduct

{
    "@type": "n4.cuwo.AssembleProductWorkflowResult",
    "updatedExternalData": "abcdefg"
}

EP3: cancelLineItem

{
    "@type": "n4.cuwo.CancelLineItemWorkflowResult",
    "reason": {
        "@type": "n4.metacompany.jobs.LineItemCancelationReason",
        "value": "TYPING_ERROR"
    },
    "updatedExternalData": "abcdefg"
}

EP4: refundLineItem

{
    "@type": "n4.cuwo.RefundLineItemWorkflowResult",
    "reason": {
        "@type": "n4.metacompany.jobs.LineItemCancelationReason",
        "value": "CUSTOMER_COMPLAINT"
    },
    "updatedExternalData": "abcdefg"
}