# Web Integration

Current state

The web SDK is still in development and its functionalities are reduced to simple authentication methods and displaying, deleting and managing of bills as well as managing content area data.

Currently available modules:

@anybill/auth - Basic authentication methods

@anybill/bill - Displaying, adding and managing of bills

@anybill/contentarea - Displaying of content areas

@anybill/store - Fetching of store information

The anybill web SDK is based on async/await syntax (opens new window). Although it is technically possible to use Promise based syntax we recommend the async/await syntax in conjunction with try/catch.

TIP

The anybill web SDK is based on async/await syntax (opens new window). Although it is technically possible to use Promise based syntax we recommend the async/await syntax in conjunction with try/catch.

# Getting Started

# Resolving the SDK

The anybill SDK for web is hosted in a private npm registry (anybill-npm) that has also access to the public npm registry. This means there is no need to install peer dependecies as they get resolved in the registry itself.
That said here is how to resolve the SDK with scoped access from the anybill-npm registry:

  1. Add a .npmrc file to the root directory of your project containing the following:
_auth = <AUTH_TOKEN>
email = youremail@email.com
always-auth = true
registry = https://anybill.jfrog.io/artifactory/api/npm/anybill_web_sdk/

[DEPRECATED]

Due to changes in Artifactory following file structure is deprecated

@anybill:registry=https://anybill.jfrog.io/artifactory/api/npm/anybill-npm/
//anybill.jfrog.io/artifactory/api/npm/anybill-npm/:_password=<BASE64_PASSWORD>
//anybill.jfrog.io/artifactory/api/npm/anybill-npm/:username=<USERNAME>
//anybill.jfrog.io/artifactory/api/npm/anybill-npm/:email=youremail@email.com
//anybill.jfrog.io/artifactory/api/npm/anybill-npm/:always-auth=true

SECRET

This file should not be checked into version control!

  1. Now you can install modules via:

npm:

npm install @anybill/<module_name>

yarn:

yarn add @anybill/<module_name>

# Usage

# Initialization / Login with Token

To authenticate a user with received token information (AccessToken, RefreshToken) call following login function from AuthProvider instance.

import { AuthProvider } from "@anybill/auth";

// acquire access and refresh token ...

await AuthProvider.instance.loginTokenUser(
      accessToken, refreshToken,
      "my-client-id",
    );

API environments

The SDK tries to figure out automatically which API to use based on the NODE_ENV environment variable, most commonly used by web frameworks.
If you are not using a framework or changed the default behavior use the override method instead!
Per default the STG environment gets used if no NODE_ENV is set.

If you want override what API gets used (for testing purposes etc.) initialize like this:

import { AuthProvider, ApiEnvironment } from "@anybill/auth";

/*
  ApiEnvironments available:
    PROD_API_URL = "https://app.anybill.de/api/",
    STG_API_URL  = "https://app.stg.anybill.de/api/",
    TEST_API_URL = "https://app.test.anybill.de/api/",
*/

// acquire access and refresh token ...

await AuthProvider.instance.loginTokenUser(
    accessToken, refreshToken,
    "my-client-id",
    ApiEnvironment.TEST_API_URL
);

After intializing the SDK you can use it anywhere!

# Getting user information

After logging in an anybill user with the received token, user information can be acquired using following methods:

import { AuthProvider } from "@anybill/auth";

// User Model including id (anybill Id), externalId (usually your id) and more
const user = await AuthProvider.instance.getUserData();

// Data object which can be displayed as QR Code to receive bills by scanning of the users device
const userQRCodeData = await AuthProvider.instance.getQRCodeData();

# Getting user bills

Querying for bills of an user is done via getBills provided by the BillProvider utility class:

import { BillProvider } from "@anybill/bill";

const bills = await BillProvider.instance.getBills();
const billsSince = await BillProvider.instance
    .getBills({ since: new Date().toISOString() });
const billsWithPagination = await BillProvider.instance
    .getBills({ skip: 5, take: 1000 }); // defaults are skip = 0 and take = 100

// or if you only need a specific bill
const singleBill = await BillProvider.instance
    .getBillByID("913cd9a6-9ff1-4fe3-8f8b-aa0add6a885c");

Bill object

The object returned by the getBills and getBillByID functions is BillDto (opens new window).

Validation

All inputs for the BillProvider functions get validated and throw an exception if validation fails. More about that in error handling

# Downloading user bills

The BillProvider utility has different methods of providing a PDF version of a bill.
Following three functions are available and should be used according to your project setup:

import { BillProvider } from "@anybill/bill";

// best for client side use
const objectURL = await BillProvider.instance
    .getBillPDFasObjectURL(billID);

// flexible usage 
const blob = await BillProvider.instance
    .getBillPDFasBlob(billID);

// best for server side use
const file = await BillProvider.instance
    .getBillPDFasFile(billID);

ObjectURL memory

ObjectURLs generated with getBillPDFasObjectURL are not automagically revoked!
To do so use URL.revokeObjectURL (opens new window) after using the URL.

File name

The File returned by getBillPDFasFile has a name with template:

`anybill-bill-export_${new Date().toLocaleDateString()}.pdf`

# Adding a new bill

Use case

If your POS system displays an anybill QR Code, users can scan these codes with their mobile device camera and navigate to anybill's Digital Receipt Website. When redirecting to your application from anybill's Digital Receipt Website users can then add this bill to their account.

Usually the url of the Digital Receipt Website is going to be including as a parameter in the redirect url.

Default Digital Receipt Website url:

https://getmy.anybill.de/2133912e-d357-421b-a7f7-1d699f62fe84

The UUID being the ID of the new bill.

import { BillProvider } from "@anybill/bill";

/// ... authenticate user by creating a new anbyill user and/or aquiring token information 

// Add bill using the Digital Receipt Website url
await BillProvider.instance.addBillByURL("https://getmy.anybill.de/2133912e-d357-421b-a7f7-1d699f62fe84");

// Add bill using the ID of the bill
await BillProvider.instance.addBillByID("2133912e-d357-421b-a7f7-1d699f62fe84");

# Deleting users bills

Using the BillProvider utility you can delete either a single bill or multiple bills at once by calling following methods with the corresponding billIds.

import { BillProvider } from "@anybill/bill";

// Delete a single bill
await BillProvider.instance.deleteBill(billID);

// Delete multiple bills at once
await BillProvider.instance.deleteBills([billID1, billID2]);

# Mark a bill as favourite

Users bills can be marked as favourite using following function:

import { BillProvider } from "@anybill/bill";

// Mark as favourite
await BillProvider.instance.updateIsFavourite(billID, true);

// Unmark as favourite
await BillProvider.instance.updateIsFavourite(billID, false);

Bill Model

Boolean value BillDto.isFavourite determines whether a bill is marked as favourite.

# Get content area data

Content area data can be fetched via the ContentAreaProvider:

import { ContentAreaProvider } from "@anybill/contentarea";

var area = await ContentAreaProvider.instance.getContentArea("your-area-id");

# Get anybill enabled stores

anybill enabled fetching store information about stores which have anybill enabled. Depening on the client-id, set during initialization, the corresponding stores are returned. Stores can be fetched via the StoreProvider:


  import { StoreProvider } from "@anybill/store";

const stores = await StoreProvider.instance.getStores();
const storesSince = await StoreProvider.instance
    .getStores({ since: new Date().toISOString() });
const storesWithPagination = await StoreProvider.instance
    .getStores({ skip: 5, take: 1000 }); // defaults are skip = 0 and take = 100

getStores() provides default information about stores. To get additional information (e.g. opening hours) the StoreProviderprovides the getStoreDetails() method:


  import { StoreProvider } from "@anybill/store";

  try {
    const response = await StoreProvider.instance.getStoreDetails(store.id);
  } catch (ex) {
    console.error(ex.cause);
  }

# Error handling

The anybill web SDK aims to provider the developer with easily understandable and catchable errors. The following two paragraphs introduce the used error model and how to work with it.

# Error objects

All error objects are based on the internal Error object (opens new window).
This means there are at least the following properties available:

  • message - Human readable error message
  • cause - the plain error thrown

The BillError object extends Error with an additional property:

# Understanding errors

Errors can be nested due to multiple internal catching and throwing. To get the deepest error dive in by repeatedly accessing cause until it returns undefined.