Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ jobs:
- name: Test - GoExpress.Shipping
run: dotnet test tests/Parcel.NET.GoExpress.Shipping.Tests/Parcel.NET.GoExpress.Shipping.Tests.csproj -c Release --no-build -f ${{ matrix.target-framework }}

- name: Test - LetterXpress.Letters
run: dotnet test tests/Parcel.NET.LetterXpress.Letters.Tests/Parcel.NET.LetterXpress.Letters.Tests.csproj -c Release --no-build -f ${{ matrix.target-framework }}

- name: Check for vulnerable packages
if: matrix.target-framework == 'net10.0'
run: |
Expand Down Expand Up @@ -117,3 +120,4 @@ jobs:
check_changes "src/Parcel.NET.Abstractions/" "abstractions" "Parcel.NET.Abstractions"
check_changes "src/Parcel.NET.Dhl/" "dhl" "Parcel.NET.Dhl"
check_changes "src/Parcel.NET.GoExpress/" "goexpress" "Parcel.NET.GoExpress"
check_changes "src/Parcel.NET.LetterXpress/" "letterxpress" "Parcel.NET.LetterXpress"
3 changes: 3 additions & 0 deletions .github/workflows/create-release-tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ on:
- goexpress
- goexpress-shipping
- goexpress-tracking
- letterxpress
- letterxpress-letters
- dhl-all
- goexpress-all
- letterxpress-all
- all
version:
description: 'SemVer version (without v prefix, e.g. 1.0.0)'
Expand Down
19 changes: 19 additions & 0 deletions .github/workflows/release-letterxpress-all.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Release Parcel.NET.LetterXpress.All

on:
push:
tags: ['letterxpress-all/v*']
workflow_dispatch:

permissions:
contents: write

jobs:
release:
uses: ./.github/workflows/release-package.yml
with:
package: 'letterxpress-all'
csproj-path: 'src/Parcel.NET.LetterXpress.All/Parcel.NET.LetterXpress.All.csproj'
title-prefix: 'Parcel.NET.LetterXpress.All'
secrets:
nuget-api-key: ${{ secrets.NUGET_API_KEY }}
19 changes: 19 additions & 0 deletions .github/workflows/release-letterxpress-letters.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Release Parcel.NET.LetterXpress.Letters

on:
push:
tags: ['letterxpress-letters/v*']
workflow_dispatch:

permissions:
contents: write

jobs:
release:
uses: ./.github/workflows/release-package.yml
with:
package: 'letterxpress-letters'
csproj-path: 'src/Parcel.NET.LetterXpress.Letters/Parcel.NET.LetterXpress.Letters.csproj'
title-prefix: 'Parcel.NET.LetterXpress.Letters'
secrets:
nuget-api-key: ${{ secrets.NUGET_API_KEY }}
19 changes: 19 additions & 0 deletions .github/workflows/release-letterxpress.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Release Parcel.NET.LetterXpress

on:
push:
tags: ['letterxpress/v*']
workflow_dispatch:

permissions:
contents: write

jobs:
release:
uses: ./.github/workflows/release-package.yml
with:
package: 'letterxpress'
csproj-path: 'src/Parcel.NET.LetterXpress/Parcel.NET.LetterXpress.csproj'
title-prefix: 'Parcel.NET.LetterXpress'
secrets:
nuget-api-key: ${{ secrets.NUGET_API_KEY }}
78 changes: 41 additions & 37 deletions Parcel.NET.slnx
Original file line number Diff line number Diff line change
@@ -1,37 +1,41 @@
<Solution>
<Folder Name="/docs/">
<Project Path="docs/Parcel.NET.Docs/Parcel.NET.Docs.csproj" />
<Project Path="docs/Parcel.NET.Docs.Generator/Parcel.NET.Docs.Generator.csproj" />
</Folder>
<Folder Name="/samples/">
<Project Path="samples/Parcel.NET.Samples.Console/Parcel.NET.Samples.Console.csproj" />
</Folder>
<Folder Name="/src/">
<Project Path="src/Parcel.NET.Abstractions/Parcel.NET.Abstractions.csproj" />
<Project Path="src/Parcel.NET.Dhl/Parcel.NET.Dhl.csproj" />
<Project Path="src/Parcel.NET.Dhl.Shipping/Parcel.NET.Dhl.Shipping.csproj" />
<Project Path="src/Parcel.NET.Dhl.Tracking/Parcel.NET.Dhl.Tracking.csproj" />
<Project Path="src/Parcel.NET.Dhl.UnifiedTracking/Parcel.NET.Dhl.UnifiedTracking.csproj" />
<Project Path="src/Parcel.NET.Dhl.Pickup/Parcel.NET.Dhl.Pickup.csproj" />
<Project Path="src/Parcel.NET.Dhl.Returns/Parcel.NET.Dhl.Returns.csproj" />
<Project Path="src/Parcel.NET.Dhl.Internetmarke/Parcel.NET.Dhl.Internetmarke.csproj" />
<Project Path="src/Parcel.NET.Dhl.LocationFinder/Parcel.NET.Dhl.LocationFinder.csproj" />
<Project Path="src/Parcel.NET.GoExpress/Parcel.NET.GoExpress.csproj" />
<Project Path="src/Parcel.NET.GoExpress.Shipping/Parcel.NET.GoExpress.Shipping.csproj" />
<Project Path="src/Parcel.NET.GoExpress.Tracking/Parcel.NET.GoExpress.Tracking.csproj" />
<Project Path="src/Parcel.NET.Dhl.All/Parcel.NET.Dhl.All.csproj" />
<Project Path="src/Parcel.NET.GoExpress.All/Parcel.NET.GoExpress.All.csproj" />
<Project Path="src/Parcel.NET.All/Parcel.NET.All.csproj" />
</Folder>
<Folder Name="/tests/">
<Project Path="tests/Parcel.NET.Dhl.Shipping.Tests/Parcel.NET.Dhl.Shipping.Tests.csproj" />
<Project Path="tests/Parcel.NET.Dhl.Tracking.Tests/Parcel.NET.Dhl.Tracking.Tests.csproj" />
<Project Path="tests/Parcel.NET.Dhl.UnifiedTracking.Tests/Parcel.NET.Dhl.UnifiedTracking.Tests.csproj" />
<Project Path="tests/Parcel.NET.Dhl.Pickup.Tests/Parcel.NET.Dhl.Pickup.Tests.csproj" />
<Project Path="tests/Parcel.NET.Dhl.Returns.Tests/Parcel.NET.Dhl.Returns.Tests.csproj" />
<Project Path="tests/Parcel.NET.Dhl.Internetmarke.Tests/Parcel.NET.Dhl.Internetmarke.Tests.csproj" />
<Project Path="tests/Parcel.NET.Dhl.LocationFinder.Tests/Parcel.NET.Dhl.LocationFinder.Tests.csproj" />
<Project Path="tests/Parcel.NET.GoExpress.Shipping.Tests/Parcel.NET.GoExpress.Shipping.Tests.csproj" />
<Project Path="tests/Parcel.NET.GoExpress.Tracking.Tests/Parcel.NET.GoExpress.Tracking.Tests.csproj" />
</Folder>
</Solution>
<Solution>
<Folder Name="/docs/">
<Project Path="docs/Parcel.NET.Docs/Parcel.NET.Docs.csproj" />
<Project Path="docs/Parcel.NET.Docs.Generator/Parcel.NET.Docs.Generator.csproj" />
</Folder>
<Folder Name="/samples/">
<Project Path="samples/Parcel.NET.Samples.Console/Parcel.NET.Samples.Console.csproj" />
</Folder>
<Folder Name="/src/">
<Project Path="src/Parcel.NET.Abstractions/Parcel.NET.Abstractions.csproj" />
<Project Path="src/Parcel.NET.Dhl/Parcel.NET.Dhl.csproj" />
<Project Path="src/Parcel.NET.Dhl.Shipping/Parcel.NET.Dhl.Shipping.csproj" />
<Project Path="src/Parcel.NET.Dhl.Tracking/Parcel.NET.Dhl.Tracking.csproj" />
<Project Path="src/Parcel.NET.Dhl.UnifiedTracking/Parcel.NET.Dhl.UnifiedTracking.csproj" />
<Project Path="src/Parcel.NET.Dhl.Pickup/Parcel.NET.Dhl.Pickup.csproj" />
<Project Path="src/Parcel.NET.Dhl.Returns/Parcel.NET.Dhl.Returns.csproj" />
<Project Path="src/Parcel.NET.Dhl.Internetmarke/Parcel.NET.Dhl.Internetmarke.csproj" />
<Project Path="src/Parcel.NET.Dhl.LocationFinder/Parcel.NET.Dhl.LocationFinder.csproj" />
<Project Path="src/Parcel.NET.GoExpress/Parcel.NET.GoExpress.csproj" />
<Project Path="src/Parcel.NET.GoExpress.Shipping/Parcel.NET.GoExpress.Shipping.csproj" />
<Project Path="src/Parcel.NET.GoExpress.Tracking/Parcel.NET.GoExpress.Tracking.csproj" />
<Project Path="src/Parcel.NET.LetterXpress/Parcel.NET.LetterXpress.csproj" />
<Project Path="src/Parcel.NET.LetterXpress.Letters/Parcel.NET.LetterXpress.Letters.csproj" />
<Project Path="src/Parcel.NET.Dhl.All/Parcel.NET.Dhl.All.csproj" />
<Project Path="src/Parcel.NET.GoExpress.All/Parcel.NET.GoExpress.All.csproj" />
<Project Path="src/Parcel.NET.LetterXpress.All/Parcel.NET.LetterXpress.All.csproj" />
<Project Path="src/Parcel.NET.All/Parcel.NET.All.csproj" />
</Folder>
<Folder Name="/tests/">
<Project Path="tests/Parcel.NET.Dhl.Shipping.Tests/Parcel.NET.Dhl.Shipping.Tests.csproj" />
<Project Path="tests/Parcel.NET.Dhl.Tracking.Tests/Parcel.NET.Dhl.Tracking.Tests.csproj" />
<Project Path="tests/Parcel.NET.Dhl.UnifiedTracking.Tests/Parcel.NET.Dhl.UnifiedTracking.Tests.csproj" />
<Project Path="tests/Parcel.NET.Dhl.Pickup.Tests/Parcel.NET.Dhl.Pickup.Tests.csproj" />
<Project Path="tests/Parcel.NET.Dhl.Returns.Tests/Parcel.NET.Dhl.Returns.Tests.csproj" />
<Project Path="tests/Parcel.NET.Dhl.Internetmarke.Tests/Parcel.NET.Dhl.Internetmarke.Tests.csproj" />
<Project Path="tests/Parcel.NET.Dhl.LocationFinder.Tests/Parcel.NET.Dhl.LocationFinder.Tests.csproj" />
<Project Path="tests/Parcel.NET.GoExpress.Shipping.Tests/Parcel.NET.GoExpress.Shipping.Tests.csproj" />
<Project Path="tests/Parcel.NET.GoExpress.Tracking.Tests/Parcel.NET.GoExpress.Tracking.Tests.csproj" />
<Project Path="tests/Parcel.NET.LetterXpress.Letters.Tests/Parcel.NET.LetterXpress.Letters.Tests.csproj" />
</Folder>
</Solution>
48 changes: 45 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# Parcel.NET

.NET libraries for logistics carrier APIs. Currently supports **DHL** (Shipping, Tracking, Pickup, Returns, Internetmarke, Location Finder) and **GO! Express** (Shipping, Tracking) — all targeting .NET 8, 9, and 10.
.NET libraries for logistics carrier APIs. Currently supports **DHL** (Shipping, Tracking, Pickup, Returns, Internetmarke, Location Finder), **GO! Express** (Shipping, Tracking), and **LetterXpress** (Letters / SMART@MAIL) — all targeting .NET 8, 9, and 10.

[![CI](https://github.com/emuuu/Parcel.NET/actions/workflows/ci.yml/badge.svg)](https://github.com/emuuu/Parcel.NET/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
Expand All @@ -21,9 +21,10 @@
- DHL Unified Location Finder v1 — search by address, geo-coordinates, or keyword
- GO! Express Shipping — create, cancel shipments, label generation
- GO! Express Tracking — track shipments
- LetterXpress API v3 — print jobs, SMART@MAIL e-mail jobs, balance, price, transactions, invoices
- Builder-pattern DI registration with typed `HttpClient` pipeline
- OAuth ROPC, API key, and Basic Auth — handled automatically per carrier
- Sandbox support for DHL and GO! Express
- Sandbox / test mode support for DHL, GO! Express, and LetterXpress

## Packages

Expand All @@ -43,15 +44,19 @@
| `Parcel.NET.GoExpress` | [![NuGet](https://img.shields.io/nuget/v/Parcel.NET.GoExpress.svg)](https://www.nuget.org/packages/Parcel.NET.GoExpress) | GO! Express authentication, configuration, and DI extensions |
| `Parcel.NET.GoExpress.Shipping` | [![NuGet](https://img.shields.io/nuget/v/Parcel.NET.GoExpress.Shipping.svg)](https://www.nuget.org/packages/Parcel.NET.GoExpress.Shipping) | GO! Express Shipping client |
| `Parcel.NET.GoExpress.Tracking` | [![NuGet](https://img.shields.io/nuget/v/Parcel.NET.GoExpress.Tracking.svg)](https://www.nuget.org/packages/Parcel.NET.GoExpress.Tracking) | GO! Express Tracking client |
| **LetterXpress** | | |
| `Parcel.NET.LetterXpress` | [![NuGet](https://img.shields.io/nuget/v/Parcel.NET.LetterXpress.svg)](https://www.nuget.org/packages/Parcel.NET.LetterXpress) | LetterXpress authentication, configuration, and DI extensions |
| `Parcel.NET.LetterXpress.Letters` | [![NuGet](https://img.shields.io/nuget/v/Parcel.NET.LetterXpress.Letters.svg)](https://www.nuget.org/packages/Parcel.NET.LetterXpress.Letters) | LetterXpress API v3 client (print jobs, SMART@MAIL e-mail jobs, price, balance, transactions, invoices) |
| **Meta-Packages** | | |
| `Parcel.NET.Dhl.All` | [![NuGet](https://img.shields.io/nuget/v/Parcel.NET.Dhl.All.svg)](https://www.nuget.org/packages/Parcel.NET.Dhl.All) | All DHL packages |
| `Parcel.NET.GoExpress.All` | [![NuGet](https://img.shields.io/nuget/v/Parcel.NET.GoExpress.All.svg)](https://www.nuget.org/packages/Parcel.NET.GoExpress.All) | All GO! Express packages |
| `Parcel.NET.LetterXpress.All` | [![NuGet](https://img.shields.io/nuget/v/Parcel.NET.LetterXpress.All.svg)](https://www.nuget.org/packages/Parcel.NET.LetterXpress.All) | All LetterXpress packages |
| `Parcel.NET.All` | [![NuGet](https://img.shields.io/nuget/v/Parcel.NET.All.svg)](https://www.nuget.org/packages/Parcel.NET.All) | All Parcel.NET packages |

## Prerequisites

- .NET 8.0, 9.0, or 10.0
- A DHL developer account and/or GO! Express credentials
- A DHL developer account, GO! Express credentials, and/or a LetterXpress account

## Installation

Expand All @@ -60,10 +65,12 @@
dotnet add package Parcel.NET.Dhl.Shipping
dotnet add package Parcel.NET.Dhl.Tracking
dotnet add package Parcel.NET.GoExpress.Shipping
dotnet add package Parcel.NET.LetterXpress.Letters

# Or install everything for a carrier
dotnet add package Parcel.NET.Dhl.All
dotnet add package Parcel.NET.GoExpress.All
dotnet add package Parcel.NET.LetterXpress.All

# Or install all carriers at once
dotnet add package Parcel.NET.All
Expand Down Expand Up @@ -106,6 +113,41 @@ builder.Services.AddGoExpress(options =>
.AddGoExpressTracking();
```

### 2b. Register LetterXpress services

```csharp
builder.Services.AddLetterXpress(options =>
{
options.Username = "your-username";
options.ApiKey = "your-api-key";
options.UseTestMode = true; // jobs go to the Postbox instead of being processed
})
.AddLetterXpressLetters();
```

Send a letter as a print job:

```csharp
var letterXpress = serviceProvider.GetRequiredService<ILetterXpressClient>();

var balance = await letterXpress.GetBalanceAsync();

var job = await letterXpress.CreatePrintJobAsync(new LetterRequest
{
File = await File.ReadAllBytesAsync("invoice.pdf"),
Specification = new LetterSpecification
{
Color = LetterColor.BlackWhite,
Mode = PrintMode.Simplex,
Shipping = ShippingType.National
}
});
```

> **Note:** The LetterXpress API is rate-limited to 120 requests/minute and accepts at most 50 MB per request.
> The client validates the 50 MB limit locally; throttling/retry on HTTP 429 is left to the caller's `HttpClient`
> pipeline (e.g. a `Microsoft.Extensions.Http.Resilience` handler).

### 3. Create a shipment

Use the carrier-agnostic `IShipmentService` or the carrier-specific client:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
<ProjectReference Include="../../src/Parcel.NET.Dhl.Tracking/Parcel.NET.Dhl.Tracking.csproj" />
<ProjectReference Include="../../src/Parcel.NET.GoExpress/Parcel.NET.GoExpress.csproj" />
<ProjectReference Include="../../src/Parcel.NET.GoExpress.Shipping/Parcel.NET.GoExpress.Shipping.csproj" />
<ProjectReference Include="../../src/Parcel.NET.LetterXpress/Parcel.NET.LetterXpress.csproj" />
<ProjectReference Include="../../src/Parcel.NET.LetterXpress.Letters/Parcel.NET.LetterXpress.Letters.csproj" />
</ItemGroup>

</Project>
4 changes: 3 additions & 1 deletion docs/Parcel.NET.Docs.Generator/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ async Task GenerateApiDocs(string wwwrootPath)
typeof(Parcel.NET.Dhl.Shipping.IDhlShippingClient).Assembly,
typeof(Parcel.NET.Dhl.Tracking.DhlTrackingClient).Assembly,
typeof(Parcel.NET.GoExpress.GoExpressOptions).Assembly,
typeof(Parcel.NET.GoExpress.Shipping.IGoExpressShippingClient).Assembly
typeof(Parcel.NET.GoExpress.Shipping.IGoExpressShippingClient).Assembly,
typeof(Parcel.NET.LetterXpress.LetterXpressOptions).Assembly,
typeof(Parcel.NET.LetterXpress.Letters.ILetterXpressClient).Assembly
};

var xmlDocs = new Dictionary<string, XDocument>();
Expand Down
Loading