# C# Integration

Before the integration can begin, artifactory must be added as source so that the NuGet packages can be installed. Instructions on how to do this can be found here.

# Required Packages

The following packages must be installed:

  • anybill.POS.Client
  • anybill.POS.Client.Abstractions

If DependencyInjection is used, the following package must also be installed:

  • anybill.POS.Client.Microsoft.Extensions.DependencyInjection

# Initialization

After all required packages are installed, you can continue with the initialization of the AnybillClientFactory and the creation of the AnybillClient. For this the following parameters are necessary:

  • Username
  • Password
  • ClientId
var clientFactory = new AnybillClientFactory();
var anybillClient = clientFactory.Create(x => x.WithUsername(username).WithPassword(password).WithClientId(clientId), AnybillEnvironment.Staging);

The environment can be optionally added when creating the AnybillClient. By default, Production is stored here.

# Authentication

After the AnybillClient exists, the authentication can be executed in a second step. An AccessToken is requested and stored internally.

await anybillClient.Authentication.EnsureAsync();

# Register new bill

If you want to display a QR code already during the checkout process and before the purchase is completed, you can request a new BillId using the ProRegisterIdAsyncduction method.

var registerBillId = new RegisterBillId
{
    StoreId = storeId
};

var registerBillIdResponse = await anybillClient.Bill.RegisterIdAsync(registerBillId);

switch (registerBillIdResponse)
{
    case IRegisterBillIdUrlResponse registerBillIdUrlResponse:
        // do something
        break;
    case IRegisterBillIdExternalIdResponse registerBillIdExternalResponse:
        // do something
        break;
}

The result is an interface of type IRegisterBillIdUrlResponse or IRegisterBillIdExternalIdResponse. The difference between the 2 interfaces is that the IRegisterBillIdExternalIdResponse only contains the BillId, while the IRegisterBillIdUrlResponse additionally contains the Url to display the QR code. Since IRegisterBillIdExternalIdResponse has already been assigned to a user, it is no longer necessary to display the QR code here.

# Add Bill

Adding the bill is composed of the bill itself and the associated billOptions. As a result one of the following interfaces is returned:

  • IExternalIdResponse
  • ILoyaltyCardResponse
  • IMatchedBillResponse
  • IUrlBillResponse
  • IUserIdResponse
var billResponse = await anybillClient.Bill.CreateAsync(bill, billOptions);

switch (billResponse)
{
    case IExternalIdResponse externalIdResponse:
        // do something
        break;
    case ILoyaltyCardResponse loyaltyCardResponse:
        // do something
        break;
    case IMatchedBillResponse matchedBillResponse:
        // do something
        break;
    case IUrlBillResponse urlBillResponse:
        // do something
        break;
    case IUserIdResponse userIdResponse:
        // do something
        break;
}

# Exception Handling

The following list describe all exceptions which can occur in case of an error.

  • AuthenticationException: Occurs when authentication fails, e.g. when no username is specified.
  • BadRequestException: Occurs when the request fails. For example due to a validation error.
  • ForbiddenException: Occurs when the user does not have the necessary rights to access this endpoint.
  • NotFoundException: Occurs when the endpoint could not be found.
  • UnauthorizedException: Occurs when the user is not authenticated.
  • UnhandledException: Occurs if an unexpected error occurs.

# Example

The following example shows the simplest implementation of the C# SDK and should serve as a help.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using anybill.POS.Client.Exceptions;
using anybill.POS.Client.Factories;
using anybill.POS.Client.Models.Bill;
using anybill.POS.Client.Models.Bill.CashRegister;
using anybill.POS.Client.Models.Bill.Data;
using anybill.POS.Client.Models.Bill.Data.VatAmount;
using anybill.POS.Client.Models.Bill.Head;
using anybill.POS.Client.Models.Bill.Misc;
using anybill.POS.Client.Models.Bill.Misc.Extension;
using anybill.POS.Client.Models.Bill.Response;
using anybill.POS.Client.Models.Bill.Security;
using anybill.POS.Client.Models.Bill.Security.Extension;
using anybill.POS.Client.Options;

namespace POSLibraryTestProject
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // necessary login data + storeId
            const string username = "";
            const string password = "";
            const string clientId = "";
            const string storeId = "";
            
            // bill object with billOptions
            var bill = new AddBill
            {
                StoreId = storeId,
                Bill = new Bill()
                {
                    CashRegister = new CashRegister()
                    {
                      SerialNumber  = "1234",
                    },
                    Head = new Head()
                    {
                        Date = DateTimeOffset.Now
                    },
                    Data = new Data()
                    {
                        Currency = "EUR",
                        VatAmounts = new List<DataVatAmount>()
                        {
                            new()
                            {
                                Percentage = 7,
                                Vat = (decimal)1.00,
                                ExclVat = (decimal)12.00,
                                InclVat = (decimal)13.00
                            }
                        }
                    },
                    Security = new Security()
                    {
                        Extension = new AnybillSecurityExtension()
                        {
                            TseFailure = true,
                            TseRequired = false
                        }
                    },
                    Misc = new Misc()
                    {
                        Extension = new AnybillMiscExtension()
                        {
                            IsExample = true,
                            IsInvoice = false
                        }
                    }
                }
            };
            var billOptions = new AddBillOptions();

            // registerBillId object
            var registerBillId = new RegisterBillId
            {
                StoreId = storeId
            };

            // create clientFactory and anybillClient
            var clientFactory = new AnybillClientFactory();
            var anybillClient = clientFactory.Create(x => x.WithUsername(username).WithPassword(password).WithClientId(clientId), AnybillEnvironment.Staging);

            try
            {
                // 1. create authentication token
                await anybillClient.Authentication.EnsureAsync();

                // 2. create preGenerated billID (if necessary)
                var registerBillIdResponse = await anybillClient.Bill.RegisterIdAsync(registerBillId);
                switch (registerBillIdResponse)
                {
                    case IRegisterBillIdUrlResponse registerBillIdUrlResponse:
                        Console.WriteLine("BillID: " + registerBillIdUrlResponse.BillId);
                        Console.WriteLine("GetMy website: " + registerBillIdUrlResponse.Url);
                        break;
                    case IRegisterBillIdExternalIdResponse registerBillIdExternalResponse:
                        Console.WriteLine("BillID: " + registerBillIdExternalResponse.BillId);
                        break;
                }

                // 3. add Bill
                var billResponse = await anybillClient.Bill.CreateAsync(bill, billOptions);
                switch (billResponse)
                {
                    case IExternalIdResponse externalIdResponse:
                        Console.WriteLine("IsAssigned: " + externalIdResponse.IsAssigned);
                        break;
                    case ILoyaltyCardResponse loyaltyCardResponse:
                        Console.WriteLine("IsAssigned: " + loyaltyCardResponse.IsAssigned);
                        break;
                    case IMatchedBillResponse matchedBillResponse:
                        Console.WriteLine("IsAssigned: " + matchedBillResponse.IsAssigned);
                        break;
                    case IUrlBillResponse urlBillResponse:
                        Console.WriteLine("GetMy website: " + urlBillResponse.Url);
                        break;
                    case IUserIdResponse userIdResponse:
                        Console.WriteLine("IsAssigned: " + userIdResponse.IsAssigned);
                        break;
                }
            }
            catch (AuthenticationException authenticationException)
            {
                // Authentication failed because username, password or clientId is wrong.
                Console.WriteLine(authenticationException);
            }
            catch (BadRequestException badRequestException)
            {
                // Request failed. e.g. validation error.
                Console.WriteLine(badRequestException.Body);
            }
            catch (ForbiddenException forbiddenException)
            {
                // Request failed because user is not allowed to use the called endpoint.
                Console.WriteLine(forbiddenException);
            }
            catch (NotFoundException notFoundException)
            {
                // Request failed because called endpoint does not exists.
                Console.WriteLine(notFoundException);
            }
            catch (UnauthorizedException unauthorizedException)
            {
                // Request failed because user is not authorized.
                Console.WriteLine(unauthorizedException);
            }
            catch (UnhandledException unhandledException)
            {
                // Request failed for some reason.
                Console.WriteLine(unhandledException);
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception);
            }
        }
    }
}