Download the PHP package tcgunel/omniship-mng without Composer

On this page you can find all versions of the php package tcgunel/omniship-mng. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package omniship-mng

Omniship MNG Kargo (DHL eCommerce Turkey)

PHP 8.2+ carrier driver for the MNG Kargo / DHL eCommerce REST API, built for the Omniship multi-carrier shipping library.

History. MNG Kargo was acquired by DHL Group in 2023 and rebranded as DHL eCommerce in Turkey (May 2025). The legacy SOAP API at service.mngkargo.com.tr/musterikargosiparis/musterisiparisnew.asmx is being phased out — versions of this package up to v0.1.x targeted that endpoint and are deprecated. From v0.2.0 onward this package targets the new REST API on apizone, fronted by IBM API Connect.


Table of contents


Setup checklist

Before you write any code, you need to provision the API access. This is a one-time-per-environment job that has to happen on MNG's side; without it the package will just throw 401 Unauthorized — Cannot find valid subscription.

1. Register on the apizone portal. Sandbox: https://sandbox.mngkargo.com.tr · Production: https://apizone.mngkargo.com.tr. Same flow for both — they're separate accounts.

2. Create an "Application" in the portal. You'll get back two keys: X-IBM-Client-Id and X-IBM-Client-Secret. These identify your integrating platform's app, not the merchant. Store them in .env — every merchant on your platform shares this same key pair.

3. Subscribe the app to all six API products under "API Ürünleri":

Product Used for Required?
Identity 1.0.1 minting JWTs ✅ yes
Standard Command 1.0.0 createOrder, cancelorder ✅ yes
Standard Query 1.0.0 tracking ✅ yes
Barcode Command 1.0.0 createbarcode, cancelshipment ✅ yes
Plus Command 1.0.0 createRecipient (3-stage flow) ✅ yes
CBS Info 1.0.0 city/district codes ✅ yes

4. Production migration ritual. After repeating the apizone steps on the production portal, email [email protected] with your app name + DHL eCommerce customer number + outbound static IP to whitelist. Production subscriptions need MNG approval per-API.

5. Per-merchant credentials. Each merchant gives you their MNG customerNumber + password (their own panel login, not a temporary password — see Gotchas). These plus your platform IBM keys are everything you need.


Quick start


3-stage shipment flow

MNG's integration team frames a three-stage flow as a recommendation. In practice it's mandatory — without it, calling createOrder and createbarcode back-to-back consistently fails with 20001 VARIŞ ŞUBESİ BULUNAMADI because MNG hasn't finished resolving the destination branch from the recipient address. Even spreading createOrder and createbarcode 10–15 seconds apart isn't enough; MNG needs minutes of background processing. Pre-registering via Plus Command at order-placement time is what gives them that runway.

The recommended flow:

This package's createShipment() collapses stages 2 and 3 into one method for callers that don't want to manage the lifecycle. It calls createOrder then createbarcode back-to-back. As long as createRecipient was called earlier (stage 1), this works reliably.

If you must do it without the recipient pre-registration step, expect occasional failures and either retry or insert a delay between createOrder and createbarcode.

The host application is responsible for stage 1. A typical wiring is to dispatch a queued job from the order-placed event:


API reference

createRecipient

POST /mngapi/api/pluscmdapi/createRecipient

Pre-registers a recipient with DHL eCommerce. Idempotent on MNG's side; safe to retry. The response carries shipperBranchCode but no customerId, so you don't need to store anything from it — just track "did this fire successfully" locally.

createShipment

Two HTTP calls under the hood:

  1. POST /mngapi/api/standardcmdapi/createOrder
  2. POST /mngapi/api/barcodecmdapi/createbarcode

Both must succeed for isSuccessful() to return true. Each call does one Identity token fetch unless caching is configured.

Making the barcode step optional

The second call (createbarcode) is what invoices the order and returns the printable ZPL label + scannable barcode. Not every merchant wants or can use it:

Pass createBarcode => false to stop after createOrder:

When disabled:

The default is true, preserving the historical two-step behaviour.

Required fields: clientId, clientSecret, customerNumber, password, referenceId, shipTo, recipientCityCode, recipientDistrictCode.

Optional fields with sensible defaults: createBarcode (true), shipmentServiceType (1=STANDART), packagingType (3=PAKET), deliveryType (1=ADRESE_TESLIM), paymentType (PaymentType::SENDER → 1), cashOnDelivery (false), codAmount (0), SMS preferences (all off), marketPlaceShortCode / marketPlaceSaleCode (empty), billOfLandingId / invoiceNumber (empty), content (falls back to first package description), description (same fallback), recipientTaxNumber (falls back to address taxId then nationalId).

referenceId is auto-uppercased before sending. MNG enforces uniqueness per-customer.

Response:

createReturnShipment

POST /mngapi/api/standardcmdapi/createReturnOrder

Creates a return order — the consumer is the shipper, the merchant (your account) is the recipient. Same field shape as createShipment but takes shipFrom (the consumer) instead of shipTo. Returns a returnOrderLabelURL the consumer can use to drop off the parcel.

cancelShipment

PUT /mngapi/api/barcodecmdapi/cancelshipment with body {referenceId, shipmentId}.

Cancels the barcode issued by createbarcode. Cancellation is only valid until the parcel is scanned/accepted at an MNG branch, on the same day the barcode was printed.

cancelOrder

PUT /mngapi/api/standardcmdapi/cancelorder/{referenceId} with no body. Cancels the order created by createOrder.

Per MNG's integration team, full cancellation is two steps when a barcode was issued: first cancelShipment (cancels the barcode), then cancelOrder (cancels the order). When createbarcode never ran (the optional-barcode flow), cancelOrder alone is the correct and only call.

getTrackingStatus

Two HTTP calls:

  1. GET /mngapi/api/standardqueryapi/trackshipment{ByShipmentId}/{id} — list of events
  2. GET /mngapi/api/standardqueryapi/getshipmentstatus{ByShipmentId}/{id} — headline status

The package picks between the two endpoint variants based on the input format: all-digit value → ByShipmentId, otherwise → referenceId. So you can pass either:

Returns an Omniship\Common\TrackingInfo with status, signedBy, events, and a trackingUrl accessor on the response.

getCities / getDistricts (CBS Info)

GET /mngapi/api/cbsinfoapi/getcities and GET /mngapi/api/cbsinfoapi/getdistricts/{cityCode}.

These don't require a JWT — only the IBM headers — so they're cheaper to call. The data is essentially static (Turkish geography). Cache it locally: typical pattern is a one-shot artisan command that seeds local mng_cities / mng_districts tables you then look up at shipment time.

⚠️ City names come back with a plate-code suffix"ADANA 11" rather than "Adana". When matching against your local order data, normalize both sides (lowercase, transliterate Turkish chars, strip trailing whitespace+digits, collapse internal whitespace).


JWT caching

MNG JWTs are valid for 8 hours. Without caching, each send() mints a new one — that's 3-4 wasted token calls per shipment. To enable caching, pass any PSR-16 CacheInterface as tokenCache:

Cache key is omniship_mng_jwt_{env}_{sha1(clientId|customerNumber)} so:

TTL is hardcoded to 7 hours (1h safety buffer under MNG's 8h validity).

Cache write failures are non-fatal — the JWT is still returned.


Status mapping

shipmentStatusCode from MNG → Omniship\Common\Enum\ShipmentStatus:

MNG Description ShipmentStatus
1 Gönderi Hazırlandı PRE_TRANSIT
2 Transfer Aşamasında IN_TRANSIT
3 Teslimat Birimine Ulaştı IN_TRANSIT
4 Alıcı Adresine Yönlendirildi OUT_FOR_DELIVERY
5 Teslim Edildi DELIVERED
6 Teslim Edilemedi FAILURE
7 Geri Geliyor RETURNED
8 Destek Gerekiyor FAILURE

PaymentType mapping (used by paymentType option):

Omniship MNG numeric
SENDER 1 (Gönderici Öder)
RECEIVER 2 (Alıcı Öder)
THIRD_PARTY 3 (Platform Öder — note: invalid for createOrder, only for createDetailedOrder)

Sandbox vs production

Sandbox Production
Portal sandbox.mngkargo.com.tr apizone.mngkargo.com.tr
Host testapi.mngkargo.com.tr api.mngkargo.com.tr
testMode true false
Account separate registration separate registration
API subscription approval automatic manual via [email protected]
Test credentials provided by integration team merchant's real MNG account

The package picks the host automatically from the testMode flag.


Gotchas, traps, and lessons learned

These are the things you only find out by hitting them. Saved here so the next person doesn't have to.

1. Responses are wrapped in arrays, not objects

The official swagger documents single-object responses for createOrder, createbarcode, getshipmentstatus. MNG actually returns one-element arrays: [{...}] instead of {...}. The package unwraps; if you're hitting the API directly, prepare for it.

2. barcodes[i] has BOTH value AND barcode

value is the ZPL label content (entire ^XA...^XZ blob — a few KB). barcode is the actual scannable barcode string. Don't confuse them. The package exposes them via getLabel() and getBarcode() respectively.

3. customerId and fullName are mutually exclusive on Recipient

MNG validates: "if Recipient.CustomerId is filled, Recipient.FullName must be empty." Since we always send the address-style payload (with fullName), the package omits customerId entirely from the JSON. Don't add it back.

4. TC Kimlik / Vergi number is enforced

recipientTaxNumber must be 11-digit TC Kimlik (individual) or 10-digit Vergi numarası (company). Empty values produce error 26056. For consumer orders without a real TC, 11111111110 (which passes the TC Kimlik checksum) is a safe placeholder. 11111111111 works against the format check but fails the checksum — try the second-digit 1110 form first.

5. recipient.email is required

Despite being conceptually optional, MNG's createOrder rejects empty emails. Always provide a fallback (shop email, platform sentinel like [email protected]).

6. mobilePhoneNumber format is strict

10 digits, no leading 0, no country code. 5551234567 works; 05551234567, +905551234567, 90 555 123 45 67 don't. The package normalizes (strips +90 / 90 / leading 0).

7. Don't use the temporary password

When MNG provisions a new account they email a temporary password. It expires fast. The merchant must log into the panel at least once and set a permanent password before using it via the API. If the merchant later changes their panel password, the API password must be updated to match — they're the same credential.

8. Sandbox keys don't work against production host (and vice versa)

You'll get HTTP 500 from the Identity API with code 20013 and a useless message. Double-check testMode matches which apizone account the keys came from.

9. ZPL labels need a Zebra printer

The label content from getLabel() is ZPL — Zebra command language. Browsers can't render it natively. You either need:

10. Subscriptions are per-API

Subscribing your app to "Identity" doesn't give you access to "Standard Command". Each one is separate. If you forget any, the missing one returns 401 Unauthorized — Cannot find valid subscription for the incoming API request.

11. CBS Info has city plate-code suffixes

City names from getCities() come back like "ADANA 11" (with the plate code and double-space). Normalize by stripping trailing whitespace+digits before matching local data.


Testing

Mock HTTP fixtures live in tests/Helpers.php. The createSequencedMockHttpClient(array $responses, array &$captured) helper returns one response per call and captures every PSR request so tests can assert URL / method / headers / body after the fact. Use createInMemoryCache() to test the JWT caching path.

License

MIT


All versions of omniship-mng with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
tcgunel/omniship-common Version ^0.1
ext-json Version *
psr/simple-cache Version ^1.0 || ^2.0 || ^3.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package tcgunel/omniship-mng contains the following files

Loading the files please wait ...