Semakin
Customer

SemaShipping PPL

A PPL shipping plugin for VirtueMart. Customers pick a PPL pick-up point, ParcelBox or AlzaBox from a map right in the cart; the shop then exports shipments straight into PPL (one by one or in bulk) and prints labels — no retyping into the PPL customer portal.

RequirementVersion
Joomla4.x, 5.x
VirtueMart4.x
PHP8.0+
MySQL5.7+ / MariaDB 10.3+
Current version1.0.0

1. Requirements

  • Joomla 4.x or 5.x (VirtueMart does not support Joomla 6 yet)
  • VirtueMart 4.x
  • PHP 8.0 or newer, with the cURL extension
  • MySQL 5.7+ / MariaDB 10.3+
  • An active PPL customer account with a transport contract
  • Enabled access to the CPL API (myAPI2) and your own map widget API key

2. Credentials from PPL

The plugin uses two independent sets of credentials. Do not mix them up — each is obtained elsewhere and serves a different purpose.

CredentialWhere to get itWhat it is for
Client IDOn request from your PPL sales representativeLogging in to the CPL API (shipment export, labels)
Client SecretSame place, together with the Client IDThe secret half of the login, never leaves your server
Widget API key (ak_…)Yourself, at klient.ppl.cz/widgetadminShowing the pick-up point map on the storefront
Product codesGET /codelist/product, or your PPL sales representativeDetermine which service carries the parcel

Client ID and Client Secret (CPL API)

These are not self-service — you cannot generate them in the customer portal. Ask your PPL sales representative (or customer support) to enable OAuth 2.0 access to the CPL API (myAPI2) and issue your client credentials. Include your PPL customer number and mention that this is an e-shop integration using SemaShipping PPL, an approved solution by Semakin.cz — PPL has the solution on record, which speeds the request up.

  • Credentials for production and for the test environment are separate. If you want to test first, ask for both at once and mention that this is an e-shop integration.
  • The plugin keeps the access token and only renews it once it expires (30 minutes of validity). PPL allows just 12 issued tokens per minute, which is why the token is not requested on every call.

Map widget API key

This one you create yourself:

  1. Log in to klient.ppl.cz/widgetadmin with the same credentials as the PPL customer portal.
  2. Create a new widget and generate an API key for it — it starts with the ak_ prefix.
  3. Add the domains the map is allowed to load on.

Mind the domains. The widget loads only on domains explicitly listed for the key. Wildcards (*) do not work yet, and example.com and www.example.com count as two different domains — add both. If you test on a staging domain or a subdomain, add that one too.

Product codes

The product code determines the service used to send the parcel and depends on your contract with PPL. It is set per shipment method (see section 7).

The most common codes:

CodeService
SMARPPL Parcel CZ Smart — delivery to a pick-up point
SBOXPPL Parcel CZ Smart To Box — delivery to a box
PRIVPPL Parcel CZ Private — delivery to a private address
BUSSPPL Parcel CZ Business — delivery to a business address

The actual list of products on your account is returned by GET /codelist/product in the CPL API. If you are unsure, ask your PPL sales representative which products you have contracted.

Check these first

  • Your VirtueMart vendor address is complete — the plugin sends it to PPL as the sender address, and PPL rejects a shipment without one.
  • Your account has cash on delivery enabled, if you plan to offer it.

3. Installation

  1. Download the installation ZIP plg_vmshipment_semappl_X.Y.Z.zip.
  2. Log in to the Joomla administration.
  3. Go to System → Install → Extensions.
  4. Upload the ZIP file.
  5. A confirmation message appears once the plugin is installed.

Upgrade: the same procedure as installation. Joomla uses method="upgrade" and keeps all existing data and settings.

The package also contains the system plugin plg_system_semappl, which is installed and enabled automatically. It provides the bulk export buttons in the VirtueMart order list (see section 11).


4. Enabling the plugin

After installation the shipment plugin must be enabled manually:

  1. Go to Extensions → Plugins.
  2. Search for semappl or PPL.
  3. Click the name SemaShipping PPL – parcel shipping (DHL Group) for VirtueMart (group vmshipment) and set Status = Enabled.
  4. Save.

The system plugin plg_system_semappl enables itself during installation — you do not need to switch it on.

The plugin alone shows nothing on the storefront. Shipping appears only once you create a shipment method in VirtueMart (see section 6).


5. Global configuration

In the plugin settings (Extensions → Plugins → click the name) fill in the parameters shared by all shipment methods built on this plugin:

ParameterDescription
API environmentProduction for live operation, Test for trying things out. See section 15.
Client IDIdentifier for the CPL API issued by PPL support.
Client SecretThe secret belonging to the Client ID. Stays on the server, never reaches the storefront.
Map widget API keyThe ak_… key from klient.ppl.cz/widgetadmin. It appears in the page HTML — it is not secret, the list of allowed domains protects it.
Send weight to PPLPPL does not want the weight in the shipment data by default. Enable it only when sending the weight has been explicitly agreed with PPL. Defaults to No.
Default weight (kg)Fallback shipment weight when it cannot be calculated from the products. Used only when sending the weight is enabled. Defaults to 1 kg.
Cash on delivery payment IDsComma separated IDs of VirtueMart payment methods that are COD (see section 13).
Label formatPDF for ordinary printers, ZPL for thermal printers. Also PNG, JPEG, SVG.
Label page sizeA4 = four labels per sheet, Default = one label per page.
Starting position on the sheet1–4. Lets you print onto a partially used A4 sheet.
Default status for exportThe VirtueMart order status code the bulk export list is taken from. Defaults to C (confirmed).

Without the Client ID and Client Secret you cannot export or print labels. Without the widget API key customers will not see the map. Both are required.

Sender address

PPL requires a sender address on every shipment. The plugin takes it from the VirtueMart vendor address (Vendor → billing address), so you usually do not have to fill in anything.

The Sender address tab is there to override that — use it only if you ship from somewhere other than the shop's billing address (an external warehouse, for example). An empty field always means "take it from VirtueMart".

FieldNote
Sender nameCompany or name printed on the label.
Name suffixSecond name line, e.g. a branch designation.
Street and number, City, Postcode, Country (ISO)Postcode and country are mandatory for PPL. Country as two letters, e.g. CZ.
Contact person, Phone, E-mailContact for the driver and for shipment queries.

Check that the VirtueMart vendor address is a real Czech address. The sample address shipped with VirtueMart (Sample Company, Seattle) passes unnoticed inside VirtueMart, but PPL rejects the export with Sender.Country: Invalid value.


6. Creating a shipment method

One plugin installation can back any number of shipment methods — typically one for pick-up points and one for home delivery.

  1. In the VirtueMart administration go to Shop → Shipment Methods.
  2. Click New.
  3. Fill in:
    • Shipment Name: the name customers see (e.g. "PPL — pick-up point")
    • Published: Yes
    • Shipment Method: choose SemaShipping PPL – parcel shipping (DHL Group) for VirtueMart
  4. Switch to the Configuration tab.
  5. Set the parameters from the following sections.
  6. Save.

7. Delivery type and product code

Every method has two key parameters that must match each other.

Delivery type

OptionBehaviour
Pick-up point / boxA button and the PPL map appear in the cart. The customer must choose a location or the order cannot be completed.
Home deliveryJust a radio button with the price, no map. The address comes from the order — shipping address, or billing when there is none.

PPL product code

A text field for the transport service code. It must match the delivery type:

Delivery typeUse the code
Pick-up point / boxSMAR (pick-up points), SBOX (boxes only)
Home deliveryPRIV (private addresses), BUSS (businesses)

Mismatched combinations (e.g. PRIV on a method with a map) fail on export. The list of products on your account is returned by GET /codelist/product — see section 2.

Next to it sits the PPL product code for cash on delivery field. Leave it empty — the plugin derives the COD code by itself. Fill it in only if your contract uses non-standard codes; see section 13 for details.

Other method restrictions

ParameterDescription
CountriesCountries the method is offered for.
Blocked countriesCountries the method is not offered for.
Minimum / maximum weightOrder weight range in which the method appears.
Weight unitKG or LB.

8. Pick-up point map

The plugin uses the PPL map widget 2.0. It opens as an overlay after clicking the "Choose a pick-up point" button.

Map settings per method

ParameterDescription
Widget countryISO code of the country whose locations the map offers (e.g. CZ, SK). Defaults to CZ.
Displayed location typesAll (ParcelShop, ParcelBox, AlzaBox) / ParcelShops only / Boxes only.
Cash on delivery locations onlyLimits the map to locations that accept cash on delivery. Enable it for a method used together with COD.

What the plugin stores from the selection

The location code, name, type (ParcelShop / ParcelBox / AlzaBox) and address. The code is what goes to PPL; the rest is for display — to the customer in the order summary, to you in the administration.

The selection survives cart changes

The chosen location is kept in the session. When the customer changes the payment, the shipping method or the cart contents, the selection stays. It is cleared once the order is placed.

Widget version 1.x is discontinued on 31 August 2026. This plugin uses version 2.0 exclusively, so the end of support does not affect you — just remember that the ak_… key is mandatory for version 2.0.


9. Shipping price

ParameterDescription
Shipment costThe base price.
Packaging feeAdded to the shipping cost.
Tax ruleThe VirtueMart tax rule for the shipping price.
Free shipping fromOrder amount from which shipping is free. Empty = never.

The resulting price is Shipment cost + Packaging fee, or 0 once the free shipping threshold is reached.


10. Exporting shipments to PPL

How PPL processes shipments

Unlike most carriers, PPL accepts shipments in batches and processes them in the background. The plugin submits a batch, receives its identifier and then asks PPL whether it is finished. This usually takes a few seconds.

That is why an order has three possible states in the administration:

StateWhat it meansWhat to do
Not exportedThe shipment has not been sent to PPL yetThe Create shipment in PPL button
PPL is processing the batchThe batch was submitted, the shipment number has not arrived yetThe Refresh status button
DoneThe shipment has a numberThe Download label button

Exporting a single order

  1. Open the order in VirtueMart → Orders.
  2. In the shipping panel click Create shipment in PPL.
  3. Once finished, the shipment number and the label button appear.

If you see a message that PPL is still processing the batch, wait a few seconds and click Refresh status.

What gets sent to PPL

  • The order number as the shipment reference
  • Recipient name and address, phone, e-mail
  • For a business order the company goes on the first line and the person's name becomes the contact
  • The pick-up location code (for methods with a map)
  • The order number once more as the external number (code CUST) — PPL prints it on the label and passes it on to invoicing
  • Cash on delivery, when the order is a COD order
  • The customer note

The sender address is always sent — PPL rejects a request without it. The plugin takes it from the VirtueMart vendor and the global configuration can override it.

When the export fails

The error message from PPL is shown right in the administration. A shipment PPL rejects does not exist on their side, so the order returns to the not exported state and you can retry once the data is fixed.


11. Bulk export

After installation, two buttons appear in the toolbar of VirtueMart → Orders.

Export to PPL

Sends all not yet exported orders in the chosen status as a single batch. The result is listed above the order list — shipment numbers for successes, the reason for failures. An error on one order does not stop the others.

The order status the list is taken from is set in the global configuration (Default status for export, C by default).

Download labels

Appears as soon as at least one exported order exists. Downloads labels for all exported orders in the given status.

Standalone bulk export page

If you need to switch between order statuses, open the Open bulk export link at the bottom of the plugin settings. The page does the same and adds a status filter.


12. Printing labels

A single shipment

The Download label button in the order detail.

Several shipments at once

The Download labels button in the order list. What you get depends on how many batches the shipments came from:

  • Orders from one batch → a single file with all labels.
  • Orders from several batches → a ZIP archive with one file per batch.

PPL cannot merge labels across batches into one file. If you want to print in one go, export the orders together — one export run is one batch.

The format, page size and starting position live in the global configuration (section 5). With A4 four labels fit on a sheet; Starting position 1–4 lets you print onto a sheet you have already peeled labels off.


13. Cash on delivery

  1. Find the ID of the COD payment method: VirtueMart → Shop → Payment Methods, open the method and read virtuemart_paymentmethod_id from the URL.
  2. Enter it into the Cash on delivery payment IDs parameter in the global configuration. Separate multiple IDs with commas (e.g. 3,7).

The plugin then fills in the COD amount, the order currency and the variable symbol automatically for orders using that payment.

The variable symbol may only contain digits according to PPL and is limited to 10 characters. The plugin derives it from the order number by dropping every non-numeric character and keeping the last ten. If your order numbers contain no digits at all, the internal order ID is used instead.

The product code switches itself for COD

PPL uses separate product codes for cash on delivery and rejects COD on a regular code. The plugin handles this for you: on a COD order it switches the code automatically.

Regular codeCOD codeProduct
SMARSMADPPL Parcel CZ Smart (pick-up point)
PRIVPRIDPPL Parcel CZ Private (address)
BUSSBUSDPPL Parcel CZ Business (address)
SBOXSBODPPL Parcel CZ Smart To Box
CONNCONDPPL Parcel Connect
SMEUSMEDPPL Parcel Smart Europe

If your contract uses different codes, enter the right one into the PPL product code for cash on delivery field in the shipment method settings. A filled-in field takes precedence over the automatic switch; an empty one means "switch according to the table". The actual codes of your contract are returned by the /codelist/product method.

On a method with a map also enable Cash on delivery locations only (section 8) — otherwise a customer may pick a location that does not accept COD.

A very long customer e-mail

PPL accepts 50 characters for an e-mail address. A longer one is not sent at all — a truncated address would look valid while belonging to somebody else. The plugin reports it at export time together with the order number; the shipment goes through normally, PPL just sends no e-mail notifications for it. The courier still reaches the customer by phone.

How COD looks on the label

A COD parcel carries a black "Dobirka/COD" strip along the bottom of the label. The COD amount itself is not printed — PPL keeps it in its own system and the driver sees it in the scanner.


14. Cancelling a shipment

A shipment that will not go into transport — the customer cancelled the order, the goods are out of stock, the export was a mistake — has to be cancelled in PPL. This is not optional housekeeping: once the shipment data exists, PPL keeps it on the books as waiting to be handed over until you cancel it.

Only a shipment you have not physically handed over to the driver can be cancelled.

A single order

  1. Open the order in VirtueMart → Orders.
  2. In the shipment panel click Cancel shipment in PPL.

Instead of the label the panel then shows Cancelled with a date and time. Cancelling is irreversible — the shipment cannot be revived, only replaced by a new one.

Several orders at once

In the order list tick the orders you want to cancel and click Cancel in PPL in the toolbar. The button then asks Really cancel (count)? — only the second click performs the cancellation. The question disappears if you do not click within six seconds.

Orders without a PPL shipment are skipped, so you do not have to untick them. The result is printed above the list, per order.

Bulk cancellation deliberately does not work off the status filter the way bulk export does. Cancelling is irreversible, so only the orders you actually tick get cancelled.

Creating a new shipment after cancelling

For a cancelled order the shipment panel offers Create a new shipment. Use it when the parcel does go out after all — typically after fixing the address or the pick-up point. The original shipment number disappears from the order; it stays traceable in the PPL communication log.

What PPL returns

Cancellation is asynchronous on PPL's side: the API confirms receipt immediately, but the shipment flips to Cancelled in their system only after a while. That is why the plugin only records the date and time on success — if the cancellation did not go through on PPL's side, you will find out from their system, not from the shop administration.


15. Test environment

PPL runs a separate test environment with its own database. Shipments created there are not actually transported or invoiced.

  1. Ask PPL support for a Client ID and Client Secret for the test environment — production credentials do not work there.
  2. Switch API environment to Test in the global plugin configuration.
  3. Fill in the test Client ID and Client Secret.

The widget API key does not change — the pick-up point map runs against production data even while testing. Remember to keep your test domain on the key's list of allowed domains.

Once you are done, switch the environment back to Production and replace the credentials. The plugin discards the stored access token by itself whenever the environment or the credentials change.


16. Uninstalling

  1. Extensions → Manage → Extensions
  2. Search for semappl.
  3. Uninstall the shipment plugin SemaShipping PPL – parcel shipping (DHL Group) for VirtueMart.

What gets deleted

  • The shipment plugin (PHP, JS, CSS, language files)
  • The system plugin plg_system_semappl (removed automatically)
  • The #__virtuemart_shipment_plg_semappl table (shipment data attached to orders)

What stays

  • The #__sema_ppl_log table — audit records of the communication with the PPL API

Why is the log kept? It documents what was sent to PPL and when. You can drop it manually:

DROP TABLE IF EXISTS `#__sema_ppl_log`;

(replace #__ with your actual table prefix)


17. Troubleshooting

The map does not appear

  1. Check that the plugin is enabled.
  2. Check that the shipment method uses the Pick-up point / box delivery type, not Home delivery.
  3. Check that the map widget API key is filled in.
  4. Check the list of allowed domains for the key in klient.ppl.cz/widgetadmin. This is by far the most common cause — the widget simply will not load on a domain that is not listed. example.com and www.example.com are two different domains.
  5. Open the browser console (F12) and look for JavaScript errors.
  6. Check that no Content Security Policy blocks the www.ppl.cz domain.

The customer cannot complete the order

  • On a method with a map the customer must choose a location. The message "Please choose a PPL pick-up point" is correct behaviour.
  • On a home delivery method no location is required — in that case the problem lies elsewhere.

The shipment export fails

  1. Verify the Client ID and Client Secret in the global configuration.
  2. Verify that the right API environment is selected — production credentials do not work in the test environment and vice versa.
  3. Verify the product code on the shipment method. It must come from your contract and match the delivery type (section 7).
  4. Read the error message — the plugin shows the PPL API response including the individual invalid fields.
  5. Request and response details are in the #__sema_ppl_log table.

API login fails

  • Check that PPL has actually enabled CPL API access for you. A customer number alone is not enough, access is granted on request.
  • Verify the credentials belong to the selected environment.
  • PPL limits token issuance to 12 per minute. If you are experimenting and switching credentials, wait a moment.

The order stays in "PPL is processing the batch"

  • Click Refresh status. Processing usually takes a few seconds, longer for large batches.
  • If the state persists, check #__sema_ppl_log — the response will contain either InProcess or an error.

The label does not download

  1. Check that the shipment has a shipment number. Without it there is no label.
  2. Check that the label format matches your printer.
  3. Look into #__sema_ppl_log at the response for the downloadLabel or getBatchLabel action.

The bulk export buttons do not appear

  1. Check that the system plugin plg_system_semappl is installed and enabled (Extensions → Plugins, group system).
  2. Check that you are on the VirtueMart → Orders page — the buttons appear nowhere else.
  3. Check the browser console for JavaScript errors.

Cash on delivery is not set

  • Verify the payment method ID in the Cash on delivery payment IDs parameter. It must match virtuemart_paymentmethod_id from the payment method URL.
  • Separate multiple IDs with commas and no spaces.
  • Verify that your PPL account has COD enabled and that the chosen product supports it.
  • If the export ends with "Unable to get shipment number" (MyApi2.Error.UnableToGetShipmentNumber), the order data is not at fault: your PPL account has no shipment number range assigned for COD products. Ask your PPL sales representative for one, quoting your customer number.

The shipment method does not appear in the cart

  • Check the country settings (allowed and blocked).
  • Check the weight limits.
  • Check that the method is Published in VirtueMart and the plugin is Enabled.

Go-live checklist

  • CPL API access requested from PPL support and approved
  • Client ID and Client Secret filled in
  • API environment matches the issued credentials
  • Widget API key created at klient.ppl.cz/widgetadmin
  • Shop domains added to the widget API key (including the www variant)
  • Default sender address configured in the PPL customer portal
  • Plugin installed and enabled
  • Shipment method created in VirtueMart and published
  • Delivery type chosen
  • Product code filled in and matching the delivery type
  • Map country and location types configured
  • Cash on delivery payment IDs filled in (if you offer COD)
  • Label format and page size chosen
  • Default status for export configured
  • Test order placed and the shipment exported successfully
  • Label downloaded and printed
  • Bulk export tried out in the order list

PPL® is a registered trademark of PPL CZ s.r.o., a DHL Group company. This product is an independent extension and is not affiliated with, or endorsed by, PPL CZ s.r.o. or DHL Group.

Interested in working together?

Get in touch and let's discuss your project. We'll be happy to help you choose the right solution.