Internetmarke
A node implementation to use the Internetmarke web service of Deutsche Post.
- Installation
- Prerequisites / Required Accounts
- Usage
- 1C4A (One Click For Application Service)
- Portokasse Service
- ProdWS (Product Service)
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';
// or: const { Internetmarke } = require('internetmarke');
const internetmarke = new Internetmarke();
// use 1C4A service
// const oneC4AOptions = { partner: ..., user: ... }
await internetmarke.initOneClickForAppService(oneC4AOptions);
// use Portokasse service
// const portokasseOptions = { user: ... }
await internetmarke.initOneClickForAppService(portokasseOptions);
// use ProdWS service
// const prodWsOptions = { client: ... }
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 // optional, the default voucher layout for all vouchers
};
// this method returns the 1C4A service instance which can be used for all
// related methods as well as the internetmarke instance itself
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();
// get pageFormat by id
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, // optional, the page format template object if you want to generate a PDF, PNG will be used if none is provided
imageItem, // optional, the image item object to attach an image from a gallery to the voucher
voucherLayout: VoucherLayout.FrankingZone // optional if already defined during service init
};
// get product from product service of hand over an obect with the id only
// const product = await internetmarke.getProduct(1);
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, // optional, the image item object to attach an image from a gallery to the voucher
voucherLayout: VoucherLayout.FrankingZone // optional if already defined during service init
position, // optional, the position information object if you want to generate a PDF and need a specific position. Otherwise vouchers will be positioned automatically
sender, // optional, the sender address in SimpleAddress format including name and company if applicable
receiver, // optional, the receiver address in SimpleAddress format. Mandatory if sender is given
};
// get product from product service of hand over an obect with the id only
// const product = await internetmarke.getProduct(1);
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.
// get shopping cart item info
const item = internetmarke.getItemFromShoppingCard(index);
// remove shopping cart item from the cart, this will also retrieve the deleted item
internetmarke.removeItemFromShoppingCard(index);
// get a brief summary of the current shopping cart items
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, // optional, the pre-generated order id that should be used
pageFormat, // optional, the page format template object if you want to generate a PDF, PNG will be used if none is provided
createManifest, // optional, indicates whether to include a manifest PDF to the order
createShippingList, // optional, attach a shipping list with or without addresses
dryrun // optional, simulate checkout and do NOT send a request to the service. This will only validate the shopping cart locally
};
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, // optional, the path where the vouchers should be downloaded to
deleteArchive, // optional, whether to delete the archive after extraction, defaults to true.
extractArchive // optional, extract vouchers in an archive, defaults to true. If false, the archive does not get deleted in any case
};
// const order = await intermetmarke.retrieveOrder(1234);
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'
};
// this will be translated into the final NamedAddress structure:
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' }; // or: const amount = 1000;
const payment = await internetmarke.topUp(amount, PaymentMethod.PayPal);
// payment: { code: 'OK', redirect: 'https://paypal.com/...' }
GiroPay top up
const amount = { value: 10, currency: 'EUR' }; // or: const amount = 1000;
const bic = 'HOLVDEB1XXX';
const payment = await internetmarke.topUp(amount, PaymentMethod.GiroPay, bic);
// payment: { code: 'OK', redirect: 'https://giropay.de/...' }
DirectDebit top up
const amount = { value: 10, currency: 'EUR' }; // or: const amount = 1000;
const payment = await internetmarke.topUp(amount, PaymentMethod.DirectDebit);
// payment: { code: 'OK', redirect: null }
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' // optional, if the id matches the uppercase version of your username
},
ttl: 24 * 3600 // optional, seconds the products will be cached. Defaults to seven days
};
// this method returns the 1C4A service instance which can be used for all
// related methods as well as the internetmarke instance itself
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, // the number of pages
paper, // optional, defines the paper format and grammage that is used for the letter, defaults to DIN A4 with 80 g/m²
envelope, // optional, defines the envelope format and grammage that is used for the letter, defaults to DIN Lang with 90 g/m²
domestic, // optional, whether the letter is sent within Germany, defaults to true
priority, // optional, whether the letter should be sent as priority letter, defaults to false
registered, // optional, 'Einschreiben'; whether the letter should as registered letter letter, defaults to false
tracking // optional, whether the letter should trackable, defaults to false
};
const product = await internetmarke.matchProduct(options);