Eksempel på en integration til BSBoksen API
Alle eksempler herunder gør det sammen mener skrevet i hhv. C#, Python og Java.
De integrerer til BSBoksens SOAP api på https://services.bsboksen.dk/Service.asmx
Du skal oprette en API nøgler til din debitorgruppe på din konto i BSBoksen, før du kan benytte api’et.
Hvis du ønsker at teste dit api mod vores staging miljø, så tag kontakt til os først.
C#
Eksempel på SOAP kald til BSBoksen
Det viste kode er en console application, som læser de seneste bilag fra bsboksen. Programmet udlæser et bilag af gangen og går videre til næste indtil der ikke er flere. Programmet er rettet mod testmiljøet for bsboksen på adressen https://staging.bsboksen.dk, hvor du kan logge på med dit normale brugernavn og adgangskode. Når du henter et bilag, kan dette bilag bestå af enten en liste af betalingsinformation eller af betalingsaftaler.
//C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BSBoksen.SOAPConsole.Service;
using System.ServiceModel;
namespace BSBoksen.SOAPConsole
{
/// <summary>
/// Opret først et c# project. Jeg brugte Visual Studio 2008
///
/// Tilføj en "Add service reference" til https://staging-services.bsboksen.dk/service.asmx?WSDL
/// Adressen til WDSL for produktion er https://services.bsboksen.dk/service.asmx?WSDL
///
/// Tilføj denne fil i projektet og giv den navnet program.cs
///
/// I projektets -> properties -> application
/// sæt "Output Type" til "Console Application"
///
/// </summary>
public class Program
{
/// <summary>
/// Opret din apiKey på din konto på bsboksen under debitorgrupper -> apinøgle -> Generer Api Key
/// Den kan se sådan ud 4IL79K3hQpaX4cBqze8clORPmpwRtG69GYEoyVnNVkUcQiZjQFabgB0Z5wj7OdLk
/// </summary>
static string apiKey = "4IL79K3hQpaX4cBqze8clORPmpwRtG69GYEoyVnNVkUcQiZjQFabgB0Z5wj7OdLk";
private static void test()
{
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport); // gør SOAP klar til at bruge SSL
binding.MaxBufferSize = 200000; // kan godt sættes højere, det kommer meget an på hvor lang periode der hentes for.
binding.MaxReceivedMessageSize = binding.MaxBufferSize; // MaxReceivedMessageSize skal være det samme som MaxBufferSize
binding.TransferMode = TransferMode.Buffered; // så modtager vi det i en stor klump data
string productionEndpoint = "https://services.bsboksen.dk/service.asmx";
string stagingEndpoint = "https://staging-services.bsboksen.dk/service.asmx";
// hvis du tester, så brug staging miljøet
EndpointAddress endpoint = new EndpointAddress(stagingEndpoint); // Sætter endpoint
Service.ServiceSoapClient client = new ServiceSoapClient(binding, endpoint); // Opretter SOAP clienten.
// angiver at når kaldet har læst et bilag, så skal det sættes som værende læst og derfor ikke læses igen.
bool read = true;
// med hent seneste ulæste bilag, der får du det seneste ulæste. Dette bilag bliver sat som læst, hvis du sætter true
// i parameteren "setLaest".
// Hvis du sætter read = false, så vil du modtage samme senest bilag når du spørger efter næste bilag
BilagType bilag = client.HentSenesteUlaesteBilag(apiKey, read);
while (bilag != null) // bilag bliver null, hvis ikke der er flere bilag at hente
{
Console.WriteLine(bilag.LeveranceTypeId);
// gå gennem alle indbetalingerne og udskriv dem til console
foreach (BetalingType bt in bilag.BetalingList)
{
Console.WriteLine("Indbetaling: {2} kundenr {0}, kr {1}", bt.Kundenr.TrimStart('0') , ((float)bt.IndbetaltBeloeb/100.0).ToString("#0.00"), bt.Transkode.ToString()); // IndbetaltBeloeb og beloeb er angivet i øre
}
// gå gennem alle betalingsaftalerne i bilaget og udskriv dem til console
foreach (Aftale a in bilag.AftaleList)
{
Console.WriteLine("Betalingsaftale: {0}, {1}, {2}", a.Transkode, a.KundeNr, a.Beskrivelse);
}
Console.ReadLine(); // stop her så du kan se hvad den har læst. Tryk på en tast og fortsæt til næste bilag
bilag = client.HentSenesteUlaesteBilag(apiKey, read); // hent det næste ulæste bilag
}
}
static void Main(string[] args)
{
test();
}
}
}
Python
import zeep
# Define the API key
api_key = "4IL79K3hQpaX4cBqze8clORPmpwRtG69GYEoyVnNVkUcQiZjQFabgB0Z5wj7OdLk"
def test():
# Define the WSDL and endpoint
staging_wsdl = "https://staging-services.bsboksen.dk/service.asmx?WSDL"
production_wsdl = "https://services.bsboksen.dk/service.asmx?WSDL"
# Use the staging endpoint for testing
wsdl = staging_wsdl
# Create a zeep client
client = zeep.Client(wsdl=wsdl)
# Specify that when a document is read, it should be marked as read and therefore not read again
read = True
# Get the latest unread document, marking it as read if 'read' is True
bilag = client.service.HentSenesteUlaesteBilag(api_key, read)
while bilag is not None: # bilag becomes None if there are no more documents to retrieve
print(bilag.LeveranceTypeId)
# Iterate over all payments and print them to the console
for bt in bilag.BetalingList:
print(f"Indbetaling: {bt.Transkode} kundenr {bt.Kundenr.lstrip('0')}, kr {bt.IndbetaltBeloeb / 100.0:.2f}")
# Iterate over all payment agreements in the document and print them to the console
for a in bilag.AftaleList:
print(f"Betalingsaftale: {a.Transkode}, {a.KundeNr}, {a.Beskrivelse}")
input("Press any key to continue...") # Pause to allow user to see the read data. Press any key to continue to the next document.
bilag = client.service.HentSenesteUlaesteBilag(api_key, read) # Retrieve the next unread document
if __name__ == "__main__":
test()
Java
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.URL;
import java.util.List;
public class Main {
// Define the API key
static String apiKey = "4IL79K3hQpaX4cBqze8clORPmpwRtG69GYEoyVnNVkUcQiZjQFabgB0Z5wj7OdLk";
public static void main(String[] args) {
test();
}
private static void test() {
try {
// Define the WSDL and endpoint
URL stagingWsdl = new URL("https://staging-services.bsboksen.dk/service.asmx?WSDL");
QName qname = new QName("http://tempuri.org/", "ServiceSoap");
// Use the staging endpoint for testing
Service service = Service.create(stagingWsdl, qname);
ServiceSoap client = service.getPort(ServiceSoap.class);
// Specify that when a document is read, it should be marked as read and therefore not read again
boolean read = true;
// Get the latest unread document, marking it as read if 'read' is True
BilagType bilag = client.hentSenesteUlaesteBilag(apiKey, read);
while (bilag != null) { // bilag becomes null if there are no more documents to retrieve
System.out.println(bilag.getLeveranceTypeId());
// Iterate over all payments and print them to the console
List betalingList = bilag.getBetalingList();
for (BetalingType bt : betalingList) {
System.out.printf("Indbetaling: %s kundenr %s, kr %.2f%n", bt.getTranskode(),
bt.getKundenr().replaceFirst("^0+(?!$)", ""), bt.getIndbetaltBeloeb() / 100.0);
}
// Iterate over all payment agreements in the document and print them to the console
List aftaleList = bilag.getAftaleList();
for (Aftale a : aftaleList) {
System.out.printf("Betalingsaftale: %s, %s, %s%n", a.getTranskode(), a.getKundeNr(), a.getBeskrivelse());
}
System.out.println("Press Enter to continue...");
System.in.read(); // Pause to allow user to see the read data. Press Enter to continue to the next document.
bilag = client.hentSenesteUlaesteBilag(apiKey, read); // Retrieve the next unread document
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Explanation:
Imports: Required libraries for SOAP interactions are imported.
API Key: The API key is defined as a constant.
WSDL and Endpoint: The WSDL URL for the staging environment is used to create the client.
SOAP Client: A `Service` object is created using the WSDL URL and QName, and the client port is obtained.
Main Logic: The main logic for retrieving documents and processing payments and agreements is similar to the C# code.
Console Input: `System.in.read()` is used to pause execution, allowing the user to see the output before continuing to the next document.
You will need to generate the Java classes from the WSDL using a tool like `wsimport`. Here is an example command:
wsimport -keep -s src -d bin https://staging-services.bsboksen.dk/service.asmx?WSDL
This command will generate the necessary Java classes to interact with the SOAP web service. Once generated, you can use these classes in your Java code to replicate the functionality of your original C# code.
Node.js
// First install soap
// npm install soap
const soap = require('soap');
const readline = require('readline');
// Define the API key
const apiKey = "4IL79K3hQpaX4cBqze8clORPmpwRtG69GYEoyVnNVkUcQiZjQFabgB0Z5wj7OdLk";
// Define the WSDL and endpoint
const stagingWsdl = "https://staging-services.bsboksen.dk/service.asmx?WSDL";
// Create a readline interface for pausing the execution
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
async function test() {
try {
// Create a SOAP client
const client = await soap.createClientAsync(stagingWsdl);
// Specify that when a document is read, it should be marked as read and therefore not read again
const read = true;
// Get the latest unread document, marking it as read if 'read' is True
let bilag = await client.HentSenesteUlaesteBilagAsync({ apiKey, read });
while (bilag[0] !== null) { // bilag becomes null if there are no more documents to retrieve
bilag = bilag[0];
console.log(bilag.LeveranceTypeId);
// Iterate over all payments and print them to the console
bilag.BetalingList.BetalingType.forEach(bt => {
console.log(`Indbetaling: ${bt.Transkode} kundenr ${bt.Kundenr.replace(/^0+/, '')}, kr ${(bt.IndbetaltBeloeb / 100.0).toFixed(2)}`);
});
// Iterate over all payment agreements in the document and print them to the console
bilag.AftaleList.Aftale.forEach(a => {
console.log(`Betalingsaftale: ${a.Transkode}, ${a.KundeNr}, ${a.Beskrivelse}`);
});
await new Promise(resolve => rl.question("Press Enter to continue...", resolve));
bilag = await client.HentSenesteUlaesteBilagAsync({ apiKey, read }); // Retrieve the next unread document
}
rl.close();
} catch (error) {
console.error(error);
}
}
test();