PHPackages                             gigerit/laravel-swiss-post-postcard-api-client - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. gigerit/laravel-swiss-post-postcard-api-client

ActiveLibrary[API Development](/categories/api)

gigerit/laravel-swiss-post-postcard-api-client
==============================================

This is my package laravel-swiss-post-postcard-api-client

1.1.7(2mo ago)2150[1 PRs](https://github.com/gigerIT/laravel-swiss-post-postcard-api-client/pulls)MITPHPPHP ^8.3CI passing

Since Aug 27Pushed 2mo agoCompare

[ Source](https://github.com/gigerIT/laravel-swiss-post-postcard-api-client)[ Packagist](https://packagist.org/packages/gigerit/laravel-swiss-post-postcard-api-client)[ Docs](https://github.com/gigerit/laravel-swiss-post-postcard-api-client)[ GitHub Sponsors](https://github.com/gigerIT)[ RSS](/packages/gigerit-laravel-swiss-post-postcard-api-client/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (9)Dependencies (26)Versions (14)Used By (0)

Laravel Swiss Post Postcard API Client
======================================

[](#laravel-swiss-post-postcard-api-client)

[![Latest Version on Packagist](https://camo.githubusercontent.com/6e03dce838946bb60cf74c0260d0974bfb29e4686cbf56b129a1592f04b369e7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f676967657269742f6c61726176656c2d73776973732d706f73742d706f7374636172642d6170692d636c69656e742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/gigerit/laravel-swiss-post-postcard-api-client)[![GitHub CI Action Status](https://camo.githubusercontent.com/d5640607d85dbacd8caf7250e4c76b817ff5ccf39ed8aaf4e7ce64abff2edaf0/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f676967657269742f6c61726176656c2d73776973732d706f73742d706f7374636172642d6170692d636c69656e742f43492e796d6c3f6272616e63683d6d61696e266c6162656c3d4349267374796c653d666c61742d737175617265)](https://github.com/gigerit/laravel-swiss-post-postcard-api-client/actions?query=workflow%3ACI+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/5d437b0f3914b5166200b1a7acbb5bd18c79137ef33fe3ba5271d97e1f947718/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f676967657269742f6c61726176656c2d73776973732d706f73742d706f7374636172642d6170692d636c69656e742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/gigerit/laravel-swiss-post-postcard-api-client)

A Laravel package for sending physical postcards through the Swiss Post Postcard API. This package provides a complete, type-safe wrapper around the Swiss Post Postcard API, allowing you to programmatically send real postcards with images, addresses, branding, and QR codes.

**Features:**

- 🚀 Complete API coverage for all Swiss Post Postcard endpoints
- 🔐 OAuth2 authentication with automatic token management
- ✅ Client-side validation for addresses, text, and image dimensions
- 🎨 Support for branding (text, images, QR codes, custom stamps)
- 📧 Type-safe DTOs for all request and response data
- 🛡️ Comprehensive error handling with descriptive error codes
- 📱 Laravel facades and dependency injection support
- 🧪 Built with Saloon HTTP client and OAuth2 for robust API communication

Requirements
------------

[](#requirements)

- PHP 8.3 or higher
- Laravel 10.0, 11.0, 12.0, or 13.0
- Swiss Post Postcard API credentials (obtained through contract with Swiss Post)

Installation
------------

[](#installation)

Install the package via Composer:

```
composer require gigerit/laravel-swiss-post-postcard-api-client
```

Publish the configuration file:

```
php artisan vendor:publish --tag="swiss-post-postcard-api-client-config"
```

Configuration
-------------

[](#configuration)

Add your Swiss Post API credentials to your `.env` file:

```
SWISS_POST_POSTCARD_API_CLIENT_ID=your_client_id
SWISS_POST_POSTCARD_API_CLIENT_SECRET=your_client_secret
SWISS_POST_POSTCARD_API_DEFAULT_CAMPAIGN=your_campaign_uuid
```

> **Note:** The URLs shown above are for the integration environment. Swiss Post will provide you with production URLs and credentials upon contract signing.

Quick Start
-----------

[](#quick-start)

### Using Dependency Injection

[](#using-dependency-injection)

```
use Gigerit\PostcardApi\PostcardApi;
use Gigerit\PostcardApi\DTOs\Address\RecipientAddress;

class PostcardController extends Controller
{
    public function __construct(private PostcardApi $postcardApi) {}

    public function sendPostcard()
    {
        // Create recipient address
        $recipient = new RecipientAddress(
            street: 'Musterstrasse',
            zip: '8000',
            city: 'Zürich',
            country: 'CH',
            firstname: 'John',
            lastname: 'Doe',
            houseNr: '123'
        );

        // Send postcard
        $result = $this->postcardApi->postcards()->createComplete(
            recipientAddress: $recipient,
            imagePath: storage_path('postcards/my-image.jpg'),
            senderText: 'Hello from Laravel!'
        );

        return response()->json(['cardKey' => $result->cardKey]);
    }
}
```

### Using Facades

[](#using-facades)

```
use Gigerit\PostcardApi\Facades\PostcardApi;
use Gigerit\PostcardApi\DTOs\Address\RecipientAddress;

// Check campaign quota
$stats = PostcardApi::campaigns()->getDefaultCampaignStatistics();
if ($stats->freeToSendPostcards === 0) {
    throw new Exception('No postcards remaining in campaign');
}

// Create and send postcard
$recipient = new RecipientAddress(/* ... */);
$result = PostcardApi::postcards()->createComplete(
    recipientAddress: $recipient,
    imagePath: 'path/to/image.jpg'
);
```

### Manual Instantiation

[](#manual-instantiation)

```
use Gigerit\PostcardApi\PostcardApi;
use Gigerit\PostcardApi\Connectors\SwissPostConnector;

// Auto-authenticate using configured OAuth2 credentials
$api = new PostcardApi();

// Or provide specific access token
$api = new PostcardApi('your_access_token_here');

// Using Saloon's OAuth2 directly
$connector = new SwissPostConnector();
$authenticator = $connector->getAccessToken(); // Uses client credentials grant
$connector->authenticate($authenticator);
```

Core Concepts
-------------

[](#core-concepts)

### Postcard Workflow

[](#postcard-workflow)

1. **Check quota** - Verify campaign has remaining postcards
2. **Create postcard** - Initialize with recipient address
3. **Upload content** - Add image, sender text, addresses
4. **Add branding** - Optional logos, QR codes, custom stamps
5. **Approve** - Submit for printing and sending

### Image Requirements

[](#image-requirements)

TypeDimensionsFormatPurposeFront Image1819×1311 pxJPEG/PNGMain postcard imageBranding Image777×295 pxJPEG/PNGCompany brandingStamp343×248 pxJPEG/PNGCustom stampAll images should be RGB color mode at 300 DPI for optimal print quality.

### Address Validation

[](#address-validation)

The package validates addresses according to Swiss Post requirements:

- Required fields: street, ZIP, city, country (for recipients)
- Name requirements: firstname/lastname OR company name
- Text length limits enforced
- Character encoding validation (CP850 compatibility)

API Services
------------

[](#api-services)

The package is organized into three main services:

### PostcardService

[](#postcardservice)

```
$postcards = $api->postcards();

// Create postcards
$result = $postcards->create($campaignKey, $postcard);
$result = $postcards->createComplete($recipient, $imagePath, $sender, $text);

// Upload content
$postcards->uploadImage($cardKey, $imagePath);
$postcards->uploadSenderText($cardKey, $text);
$postcards->uploadSenderAddress($cardKey, $senderAddress);
$postcards->uploadRecipientAddress($cardKey, $recipientAddress);

// Manage postcards
$postcards->approve($cardKey);
$state = $postcards->getState($cardKey);
$frontPreview = $postcards->getPreviewFront($cardKey);
$backPreview = $postcards->getPreviewBack($cardKey);
```

### BrandingService

[](#brandingservice)

```
$branding = $api->branding();

// Text branding
$branding->addSimpleText($cardKey, 'Your Company', '#FF0000', '#FFFFFF');

// QR code branding
$branding->addSimpleQRCode($cardKey, 'https://yoursite.com', 'Visit us!');

// Image branding
$branding->uploadImage($cardKey, 'path/to/logo.jpg');
$branding->uploadStamp($cardKey, 'path/to/stamp.jpg');
```

### CampaignService

[](#campaignservice)

```
$campaigns = $api->campaigns();

// Get statistics
$stats = $campaigns->getDefaultCampaignStatistics();
$stats = $campaigns->getStatistics($campaignKey);

// Check quota
$hasQuota = $campaigns->hasRemainingQuota($campaignKey);
$remaining = $campaigns->getRemainingQuota($campaignKey);
```

Error Handling
--------------

[](#error-handling)

The package provides comprehensive error handling:

```
use Gigerit\PostcardApi\Exceptions\SwissPostApiException;
use Gigerit\PostcardApi\Enums\ErrorCode;

try {
    $result = $api->postcards()->create();

    // Check for warnings
    if ($result->hasWarnings()) {
        foreach ($result->getWarningMessages() as $warning) {
            Log::warning("Postcard warning: {$warning}");
        }
    }

} catch (SwissPostApiException $e) {
    // API errors (quota exceeded, invalid data, etc.)
    Log::error("Swiss Post API error: {$e->getMessage()}");

} catch (\InvalidArgumentException $e) {
    // Validation errors (invalid image dimensions, text too long, etc.)
    Log::error("Validation error: {$e->getMessage()}");
}

// Error codes are available as enums
$errorCode = ErrorCode::CAMPAIGN_QUOTA_EXCEEDED;
echo $errorCode->getDescription(); // "Campaign quota exceeded"
```

Validation
----------

[](#validation)

Client-side validation helps catch errors before API calls:

```
use Gigerit\PostcardApi\Validation\PostcardValidator;
use Gigerit\PostcardApi\Enums\ImageDimensions;

// Validate addresses
$errors = PostcardValidator::validateRecipientAddress($recipient);

// Validate text
$errors = PostcardValidator::validateSenderText($text);

// Validate images
$errors = PostcardValidator::validateImageDimensions(
    '/path/to/image.jpg',
    ImageDimensions::FRONT_IMAGE
);

// Disable validation if needed
$api->postcards()->uploadImage($cardKey, $path, null, false); // Skip validation
```

Advanced Usage
--------------

[](#advanced-usage)

For more detailed examples and advanced usage patterns, see [USAGE\_EXAMPLES.md](USAGE_EXAMPLES.md).

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Manu](https://github.com/gigerIT)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

46

—

FairBetter than 92% of packages

Maintenance88

Actively maintained with recent releases

Popularity17

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 57% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~34 days

Recently: every ~42 days

Total

8

Last Release

62d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/6b8b982f1ca65bca2356c040bc612db0d03ee2443fd194bdfa9f44a4c3fa2267?d=identicon)[gigerit](/maintainers/gigerit)

---

Top Contributors

[![mgjgid](https://avatars.githubusercontent.com/u/36155814?v=4)](https://github.com/mgjgid "mgjgid (65 commits)")[![gigerIT](https://avatars.githubusercontent.com/u/64487711?v=4)](https://github.com/gigerIT "gigerIT (31 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (11 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (7 commits)")

---

Tags

laravellaravelgigerITlaravel-swiss-post-postcard-api-client

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/gigerit-laravel-swiss-post-postcard-api-client/health.svg)

```
[![Health](https://phpackages.com/badges/gigerit-laravel-swiss-post-postcard-api-client/health.svg)](https://phpackages.com/packages/gigerit-laravel-swiss-post-postcard-api-client)
```

###  Alternatives

[dedoc/scramble

Automatic generation of API documentation for Laravel applications.

2.1k9.9M90](/packages/dedoc-scramble)[spatie/laravel-pdf

Create PDFs in Laravel apps

1.0k4.3M42](/packages/spatie-laravel-pdf)[defstudio/telegraph

A laravel facade to interact with Telegram Bots

815320.5k3](/packages/defstudio-telegraph)[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3913.7k](/packages/rawilk-profile-filament-plugin)[simplestats-io/laravel-client

Analytics for Laravel. Track visitors, registrations, and payments. Discover which channels actually drive revenue, not just traffic. Server-side, GDPR compliant, ad-blocker proof.

5019.3k](/packages/simplestats-io-laravel-client)[codebar-ag/laravel-docuware

DocuWare integration with Laravel

1122.7k](/packages/codebar-ag-laravel-docuware)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
