Internetmarke

A node implementation to use the Internetmarke web service of Deutsche Post.
Installation
To add internetmarke to your project use npm:
npm i internetmarke
Prerequisites / Required Accounts
To use the module you have to request a partner account from Deutsche Post for
every web service you want to use and your payment account:
-
1C4A (One Click For Application, required!) is used to order and preview
vouchers.
You can get the partner account from the website of Deutsche Post
or request one via mail: pcf-1click@deutschepost.de
This account credentials refer to PartnerCredentials.
-
Prod WS (Product List Web Service) is used to retrieve the list of
available products (the distinct types of stamps for different dimensions
etc.). This is optional if you know the ids and prices of the vouchers you
want to order but recommended as it is easier and supports automatic voucher
updates when prices change.
The client account can be requested via mail (see above) only.
This account credentials refer to ClientCredentials.
-
Further you need your personal Portokasse account with payment information
that is used on checkout. If you do not have one please create one at the web
ortal of Deutsche Post.
This account credentials refer to UserCredentials. For testing use you can
request a test account via the above email address to test voucher generation
without charging your own account for three months. These generated vouchers
are then not valid to be used in production!
Usage
Internetmarke so far handles three services, the One Click For App (1C4A)
Service that handles the voucher checkout process, the Product Service (ProdWS)
that is capable of available products (types of vouchers) and the Portokasse
service to top up the user account to order more vouchers.
Each service can be used separately and has therefore to be initialized with a
specific method call before it can be used. Afterwards you can use the returned
service instance or the internetmarke instance to call the supported service
methods.
Examples: Can be found in the examples directory for easy adoption.
All the examples here are written in TypeScript but of course the package can be
used with JavaScript as well. See examples/complete-example.js.
import { Internetmarke } from 'internetmarke';
const internetmarke = new Internetmarke();
await internetmarke.initOneClickForAppService(oneC4AOptions);
await internetmarke.initOneClickForAppService(portokasseOptions);
await internetmarke.initProductService(prodWsOptions);
1C4A (One Click For Application Service)
To setup the 1C4A service, call the method initOneClickForAppService(options)
of the Internetmarke main instance.
Pass the credentials of your partner and user (Portokasse) accounts to connect
to the 1C4A service.
You can optionally add the default voucher layout for the following orders.
const options: OneClickForAppOptions = {
partner: {
id: 'PARTNER_ID',
secret: 'SCHLUESSEL_DPWN_MARKTPLATZ'
},
user: {
username: 'user-account@example.com',
password: '*****'
},
voucherLayout: VoucherLayout.AddressZone
};
await internetmarke.initOneClickForAppService(options);
User Info
As soon as this initialization is done you can access all the resources of the
1C4A service. In addtion to that you also have access to a few user properties
of your Portokasse account:
const userInfo = await internetmarke.getUserInfo();
The user info holds all the information about your account including your wallet
balance.
In addition you can retrieve the order id of the latest order in this session.
Page Formats
If you wish to generate vouchers in PDF format you may want to list all the
available page templates from the service.
const pageFormats = await internetmarke.retrievePageFormats();
const pageFormat = await internetmarke.retrievePageFormat(1);
Create Order Id
In some cases it might be useful to generate the order id for the next order
before the checkout. This is what the method createShopOrderId() is for:
const orderId = await internetmarke.createShopOrderId();
This order id can be passed to the checkoutShoppingCart() method in the
options object.
Public Gallery Images
The Deutsche Post provides a list of image categories with a few images that
can be accessed by everyone and added to a voucher in FrankingZone mode.
const gallery = await internetmarke.retrievePublicGallery();
Private Gallery Images
Same as with the public gallery you can access the images of your private
gallery that have been uploaded to Deutsche Post before. There are no
categories but only a list of images.
const gallery = await internetmarke.retrievePrivateGallery();
Voucher Preview
You can create a preview voucher before checkout to check if the result matches
your imaginations.
const options: PreviewVoucherOptions = {
pageFormat,
imageItem,
voucherLayout: VoucherLayout.FrankingZone
};
const previewLink = await internetmarke.retrievePreviewVoucher(product, options);
Managing the Shopping Cart
Before the checkout you have to add items to the local shopping cart. This can
be achieved with this method.
const options: ShoppingCartItemOptions = {
imageItem,
voucherLayout: VoucherLayout.FrankingZone
position,
sender,
receiver,
};
const itemIndex = internetmarke.addItemToShoppingCart(product, options);
After you added an item to the shopping cart you can remove or retrieve it's
data with the retrieved index from the addItemToShoppingCart() method.
const item = internetmarke.getItemFromShoppingCard(index);
internetmarke.removeItemFromShoppingCard(index);
const cart = this.getShoppingCartSummary();
Checkout Shopping Cart and Place Order
As soon as you have items in your shopping cart you can order those.
This is the main method where the virtual shopping cart is pushed to the
service, the vouchers are being generated and your Portokasse account gets
charged with the total shopping cart amount.
However you can use the dryrun option to just validate the shopping cart and
log the request payload to the debug namespace internetmarke:1c4a.
const options: CheckoutShoppingCartOptions = {
shopOrderId,
pageFormat,
createManifest,
createShippingList,
dryrun
};
const order = await internetmarke.checkoutShoppingCart(options);
Retrieve Older Orders
Every order can be re-downloaded with their unique order id. The output is the
same as from the checkoutShoppingCart() method.
const order = await internetmarke.retrieveOrder(orderId);
Download Orders
You can download purchased vouchers with the response of checkoutShoppingCart()
or retrieveOrder() to make the files available on your machine.
PNG orders come bundled in a zip archive whereas PDF orders combine all
purchased vouchers in a single document. The filename is the same as the voucher
id for all PNG orders and PDF orders with just a single voucher. If a PDF order
contains more than one voucher the filename equals to the order id with a im-
prefix.
By default archives extract the containing vouchers and get removed afterwards.
The files are downloaded in the temp folder of your computer and create a
directory node-internetmarke however the download folder can be changed.
The response use an object that lists all voucher ids of the given order as keys
with the download path to the corresponding file. For PDF orders the path is
always the same.
const options: DownloadOptions = {
path,
deleteArchive,
extractArchive
};
const links = await internetmarke.downloadOrder(order, options);
Addresses
Addresses can be passed in SimpleAddress format which is flat and does not
contain the structure for the backend services. This will be used to generate
the final address objects
const simple: SimpleAddress = {
company: 'Augustiner-Bräu Wagner KG',
salutation: 'Herrn',
title: 'Dr.',
firstname: 'Martin',
lastname: 'Leibhard',
additional: 'Leitung',
street: 'Landsberger Straße',
houseNo: '31-35',
zip: '80339',
city: 'München'
};
const namedAddress: NamedAddress = {
name: {
companyName: {
company: 'Augustiner-Bräu Wagner KG',
personName: {
salutation: 'Herrn',
title: 'Dr.',
firstname: 'Martin',
lastname: 'Leibhard'
}
}
},
address: {
additional: 'Leitung',
street: 'Landsberger Straße',
houseNo: '31-35',
zip: '80339',
city: 'München',
country: 'DEU'
}
};
Portokasse Service
Wallet Overview
The wallet-overview api endpoint retrieves the wallet balance same as the user
account provided by the 1C4A service. To retrieve this information use the same
method getUserInfo as you do to retrieve 1C4A user informtion
mentioned above. Depending of which services you enabled this will return the
data from the 1C4A or the Portokasse service. If you however initialized both
accounts it will merge the information from 1C4A with the live wallet balance
from the Portokasse service.
Top Up Account
Top up is the main method of the Portokasse service. There are two different
payment methods: PayPal and Giropay. Giropay expects a BIC string to be also
passed to the method. Both methods will result in a redirect link that should
be called by the user to finish the top up request.
Info: The minimum amount to top up is EUR 10,00 which can be defined as an
Amount object or a raw number in Euro Cents.
PayPal top up
const amount = { value: 10, currency: 'EUR' };
const payment = await internetmarke.topUp(amount, PaymentMethod.PayPal);
GiroPay top up
const amount = { value: 10, currency: 'EUR' };
const bic = 'HOLVDEB1XXX';
const payment = await internetmarke.topUp(amount, PaymentMethod.GiroPay, bic);
DirectDebit top up
const amount = { value: 10, currency: 'EUR' };
const payment = await internetmarke.topUp(amount, PaymentMethod.DirectDebit);
Get Journal
The portokasse service supports a history of orders and top ups that can be
requested with a range or start and end date or a number of days from now.
Optional option parameters are offset and rows that refer to a paging
mechanism and default to the first ten entries.
Journal in date range
const range: JournalRange = {
startDate: new Date('2021-08-01'),
endDate: new Date('2021-08-11')
};
const journal = await internetmarke.getJournal(range);
Journal of the latest days
const days = { days: 14 };
const journal = await internetmarke.getJournal(days);
ProdWS (Product Service)
The product list contains all available vouchers that can be ordered. They are
cached and are get updated once a week if not configured otherwise.
To access the product service (Prod WS) a dedicated client account is necessary.
const options: ProductServiceOptions = {
client: {
username: 'username',
password: '********',
id: 'USERNAME'
},
ttl: 24 * 3600
};
await internetmarke.initProductService(options);
If your id (Mandant-ID) differs from the upper case version of the username
you can add it to the client credentials.
Product List
Once the product service is initialized you can retrieve the whole product list
or a single product from the webservice. You can also query one single product
if you know the specific product id.
const products = await internetmarke.getProductList();
const product = await internetmarke.getProduct(1);
Outdated Products
If you however want to retrieve an older product list you can optionally pass a
date that defines the historical date of product list on this date.
If you request an outdated product list this will disable the cache for this
request and request the list on every request which can take a few seconds to
load the data. As of now you cannot request an old product by id so if you look
for a special product of an older date just request the whole list and iterate
through it afterwards and find the right product.
const oldProducts = await internetmarke.getProductList(new Date('2018-02-01'));
Catalog List
The ProdWS has a lot of metadata useful for checkout and general information
around the Internetmarke environment.
Note that catalogs come with strings as their id instead of numeric values.
const catalogs = await internetmarke.getCatalogList();
const catalog = await internetmarke.getCatalog('Entgeltzone');
Match Product for Letter
Your letter is complete are the only thing left is the voucher. But which one is
neccessary for the letter? The matchProduct() method calculates the right one
for you. Depending on your needs and the combination of paper end envelope the
corrept product is retrieved.
const options: MatchProductOptions = {
pages: 1,
paper,
envelope,
domestic,
priority,
registered,
tracking
};
const product = await internetmarke.matchProduct(options);