A comprehensive Laravel package for the Checkeeper API v3. Send physical checks via USPS, UPS, or FedEx, or generate PDFs for self-printing.
- Full API Coverage - Complete implementation of Checkeeper API v3
- Type-Safe - Readonly DTOs with typed properties throughout
- Fluent Queries - Powerful filter builder for searching checks
- Webhook Support - Automatic signature verification and event dispatching
- Queue Integration - Async check creation
- Event-Driven - Laravel events for check operations
- Well Tested - Comprehensive Pest test suite
- Laravel 11+ - Built for modern Laravel applications
- Requirements
- Installation
- Configuration
- How It Works
- Creating Checks
- Querying Checks
- Webhooks
- Team & Templates
- Events
- Exception Handling
- Complete Application Example
- Testing Your Integration
- API Reference
- Contributing
- License
- PHP 8.2+
- Laravel 11.0+
Install via Composer:
composer require bhaidar/laravel-checkeeperPublish the configuration file:
php artisan vendor:publish --tag=checkeeper-configAdd your API credentials to .env:
CHECKEEPER_API_KEY=your-api-key-here
CHECKEEPER_WEBHOOK_SECRET=your-webhook-secretOptional queue configuration:
CHECKEEPER_QUEUE_ENABLED=true
CHECKEEPER_QUEUE_CONNECTION=redis
CHECKEEPER_QUEUE_NAME=checkeeperThe package configuration file is located at config/checkeeper.php:
return [
// API authentication
'api_key' => env('CHECKEEPER_API_KEY'),
// API endpoint
'base_url' => env('CHECKEEPER_BASE_URL', 'https://api.checkeeper.com/v3'),
// HTTP timeout (seconds)
'timeout' => 30,
// Webhook configuration
'webhooks' => [
'enabled' => true,
'secret' => env('CHECKEEPER_WEBHOOK_SECRET'),
'route' => 'checkeeper/webhook',
'middleware' => ['api'],
],
// Queue configuration
'queue' => [
'enabled' => true,
'connection' => env('CHECKEEPER_QUEUE_CONNECTION', 'default'),
'queue' => env('CHECKEEPER_QUEUE_NAME', 'checkeeper'),
],
];The Laravel Checkeeper package provides a clean, Laravel-friendly interface to the Checkeeper API. Here's how the components work together:
Your Application
|
Checkeeper Facade
|
CheckkeeperClient (HTTP Client)
|
Resources (Check, Team, Template)
|
Checkeeper API
|
Check Mailing Service
- Facade (
Checkeeper) - Main entry point for all operations - Resources - Organized API endpoints (Checks, Team, Templates)
- DTOs - Type-safe data transfer objects
- Events - Laravel events for check operations and webhooks
- Jobs - Queue jobs for async operations
- Filter Builder - Fluent query builder for searching checks
// 1. Create check data (DTO or array)
$checkData = new CheckData(...);
// 2. Optionally specify delivery method
$delivery = new DeliveryData(method: DeliveryMethod::UspsFirstClass);
// 3. Send to Checkeeper via Facade
$result = Checkeeper::checks()->create($checkData, $delivery);
// 4. Package handles HTTP request with retry logic
// 5. Returns typed CheckStatusData response
echo $result->id; // "check-abc123"
// 6. Webhooks notify you of status changes
// 7. Events fired for your listenersCreate a check using a simple array:
use Bhaidar\Checkeeper\Facades\Checkeeper;
$result = Checkeeper::checks()->create([
'bank' => [
'routing' => '123456789',
'account' => '987654321',
],
'payer' => [
'line1' => 'My Company Inc',
'line2' => '123 Business St',
'line3' => 'Suite 100',
'line4' => 'New York, NY 10001',
],
'payee' => [
'line1' => 'Vendor Services LLC',
'line2' => '456 Supplier Ave',
'line3' => 'Los Angeles, CA 90210',
],
'signer' => [
'type' => 'text',
'value' => 'Jane Smith',
],
'amount' => 50000, // $500.00 (amount in cents)
'number' => 1001,
'date' => '2024-02-29',
'memo' => 'Invoice #12345',
'nonce' => 'unique-id-12345', // prevents duplicates
]);
// Result contains check ID and status
echo $result->id; // "check-abc123"
echo $result->status->value; // "processing"Recommended approach for type safety and IDE autocomplete:
use Bhaidar\Checkeeper\Facades\Checkeeper;
use Bhaidar\Checkeeper\DataTransferObjects\CheckData;
use Bhaidar\Checkeeper\DataTransferObjects\BankData;
use Bhaidar\Checkeeper\DataTransferObjects\PayerData;
use Bhaidar\Checkeeper\DataTransferObjects\PayeeData;
use Bhaidar\Checkeeper\DataTransferObjects\SignerData;
use Bhaidar\Checkeeper\Enums\SignerType;
use Illuminate\Support\Str;
$checkData = new CheckData(
bank: new BankData(
routing: '123456789',
account: '987654321'
),
payer: new PayerData(
line1: 'My Company Inc',
line2: '123 Business St',
line3: 'Suite 100',
line4: 'New York, NY 10001'
),
payee: new PayeeData(
line1: 'Vendor Services LLC',
line2: '456 Supplier Ave',
line3: 'Los Angeles, CA 90210'
),
signer: new SignerData(
type: SignerType::Text,
value: 'Jane Smith'
),
amount: 50000,
number: 1001,
memo: 'Invoice #12345',
nonce: 'payment-' . Str::uuid()
);
$result = Checkeeper::checks()->create($checkData);Adding a Company Logo:
use Illuminate\Support\Facades\Storage;
$payer = new PayerData(
line1: 'My Company Inc',
line2: '123 Business St',
logo: base64_encode(Storage::get('company-logo.png'))
);Using Image Signature:
$signer = new SignerData(
type: SignerType::Png,
value: base64_encode(Storage::get('ceo-signature.png'))
);Delivery is specified separately from check data and passed as the second argument to create() or createBulk(). This matches the Checkeeper API payload structure where delivery is a sibling to checks:
{
"checks": [{ ... }],
"delivery": { "method": "usps.first_class" }
}use Bhaidar\Checkeeper\DataTransferObjects\DeliveryData;
use Bhaidar\Checkeeper\DataTransferObjects\AddressData;
use Bhaidar\Checkeeper\Enums\DeliveryMethod;
// First class mail
$delivery = new DeliveryData(
method: DeliveryMethod::UspsFirstClass
);
$result = Checkeeper::checks()->create($checkData, $delivery);
// Priority mail
$delivery = new DeliveryData(
method: DeliveryMethod::UspsPriority
);
$result = Checkeeper::checks()->create($checkData, $delivery);
// Overnight shipping (bundled to one address)
$delivery = new DeliveryData(
method: DeliveryMethod::UpsNextDay,
bundleAddress: new AddressData(
name: 'John Doe',
line1: '789 Main St',
city: 'Chicago',
state: 'IL',
zip: '60601',
country: 'US',
phone: '555-123-4567'
)
);
$result = Checkeeper::checks()->create($checkData, $delivery);
// PDF return (no mailing, get PDF to print yourself)
$delivery = new DeliveryData(
method: DeliveryMethod::Pdf
);
$result = Checkeeper::checks()->create($checkData, $delivery);No delivery specified defaults to the team's configured delivery method:
$result = Checkeeper::checks()->create($checkData);Available Delivery Methods:
| Enum | Value | Description |
|---|---|---|
DeliveryMethod::UspsFirstClass |
usps.first_class |
USPS First Class Mail |
DeliveryMethod::UspsPriority |
usps.priority |
USPS Priority Mail |
DeliveryMethod::UpsTwoDay |
ups.two_day |
UPS 2-Day Shipping |
DeliveryMethod::UpsNextDay |
ups.next_day |
UPS Next Day Air |
DeliveryMethod::FedexTwoDay |
fedex.two_day |
FedEx 2-Day |
DeliveryMethod::FedexOvernight |
fedex.overnight |
FedEx Overnight |
DeliveryMethod::Pdf |
pdf |
Return PDF only |
Create multiple checks in a single API request. Delivery applies to all checks in the batch:
$checks = [
[
'bank' => ['routing' => '123456789', 'account' => '111111'],
'payer' => ['line1' => 'My Company'],
'payee' => ['line1' => 'Vendor A'],
'signer' => ['type' => 'text', 'value' => 'Jane Smith'],
'amount' => 25000,
'number' => 1001,
'nonce' => 'check-001',
],
[
'bank' => ['routing' => '123456789', 'account' => '111111'],
'payer' => ['line1' => 'My Company'],
'payee' => ['line1' => 'Vendor B'],
'signer' => ['type' => 'text', 'value' => 'Jane Smith'],
'amount' => 35000,
'number' => 1002,
'nonce' => 'check-002',
],
];
// Without delivery (uses team default)
$result = Checkeeper::checks()->createBulk($checks);
// With delivery
$delivery = new DeliveryData(method: DeliveryMethod::UspsPriority);
$result = Checkeeper::checks()->createBulk($checks, $delivery);
// Result contains:
echo "Created: " . count($result['checks']); // New checks
echo "Duplicates: " . count($result['existing']); // Checks with duplicate nonce
echo "Total credits: " . $result['total_credits']; // Cost in creditsUsing DTOs for bulk:
$checksData = [
new CheckData(/* ... */),
new CheckData(/* ... */),
new CheckData(/* ... */),
];
$delivery = new DeliveryData(method: DeliveryMethod::UspsFirstClass);
$result = Checkeeper::checks()->createBulk($checksData, $delivery);Recommended for production to avoid blocking your application:
use Bhaidar\Checkeeper\Jobs\CreateCheckJob;
// Dispatch to queue
CreateCheckJob::dispatch($checkData);
// With delay
CreateCheckJob::dispatch($checkData)->delay(now()->addMinutes(5));
// On specific queue
CreateCheckJob::dispatch($checkData)->onQueue('payments');
// With callback URL (for your own tracking)
CreateCheckJob::dispatch($checkData, callbackUrl: 'https://yourapp.com/check-created');Listen for completion:
// app/Providers/EventServiceProvider.php
use Bhaidar\Checkeeper\Events\CheckCreated;
use App\Listeners\NotifyAccountingOfCheckCreation;
protected $listen = [
CheckCreated::class => [
NotifyAccountingOfCheckCreation::class,
],
];$checks = Checkeeper::checks()->list();
foreach ($checks as $check) {
echo "{$check->id}: {$check->status->value}\n";
}Use the fluent filter builder for powerful queries:
use Bhaidar\Checkeeper\Enums\CheckStatus;
$checks = Checkeeper::checks()
->filter()
->whereEquals('status', CheckStatus::Delivered->value)
->whereGreaterThan('amount', 10000)
->whereBetween('date', '2024-01-01', '2024-12-31')
->whereContains('memo', 'Invoice')
->sortBy('created', 'desc')
->get();Available Filter Methods:
// Equality
->whereEquals('field', 'value')
->whereNotEquals('field', 'value')
// Comparison
->whereLessThan('amount', 10000)
->whereLessThanOrEqual('amount', 10000)
->whereGreaterThan('amount', 10000)
->whereGreaterThanOrEqual('amount', 10000)
// Lists
->whereIn('status', ['delivered', 'printed'])
->whereNotIn('status', ['cancelled'])
// Text search
->whereContains('memo', 'Invoice')
// Ranges
->whereBetween('date', '2024-01-01', '2024-12-31')
// Sorting
->sortBy('created', 'desc')
->sortBy('amount', 'asc')Filterable Fields:
id,request_id,template_idstatus,ship_method,testnumber,date,amount,memo,notepayer_line1,payer_line2,payer_line3,payer_line4payee_line1,payee_line2,payee_line3,payee_line4meta,created,updated
Raw filter array:
$checks = Checkeeper::checks()->list([
'filters[status][$eq]' => 'delivered',
'filters[amount][$gt]' => 10000,
'sort' => 'created:desc',
]);Get current status of a check:
$status = Checkeeper::checks()->status('check-abc123');
echo $status->id; // "check-abc123"
echo $status->status->value; // "delivered"
echo $status->created; // "2024-02-29 10:00:00"
echo $status->updated; // "2024-03-02 14:30:00"
echo $status->trackingUrl; // "https://tools.usps.com/..."Available Check Statuses:
| Status | Description |
|---|---|
Processing |
Check is being prepared |
Ready |
Check is ready for printing |
Printed |
Check has been printed |
Mailed |
Check has been sent |
Delivered |
Check delivered to recipient |
Cancelled |
Check was cancelled |
Returned |
Check returned to sender |
Get detailed tracking information:
$events = Checkeeper::checks()->tracking('check-abc123');
foreach ($events as $event) {
echo "{$event->event}: {$event->eventDate}\n";
if ($event->location) {
echo " Location: {$event->location->city}, {$event->location->state}\n";
}
}Cancel a check before it's printed or mailed:
$cancelled = Checkeeper::checks()->cancel('check-abc123');
if ($cancelled) {
echo "Check cancelled successfully";
}Note: Checks can only be cancelled if they haven't been printed yet.
Download check images as JPG or PDF:
use Illuminate\Support\Facades\Storage;
// Get JPG image
$imageData = Checkeeper::checks()->image('check-abc123', 'jpg');
Storage::put('checks/check-abc123.jpg', $imageData);
// Get PDF
$pdfData = Checkeeper::checks()->image('check-abc123', 'pdf');
Storage::put('checks/check-abc123.pdf', $pdfData);
// Download in controller
public function download($checkId)
{
$pdfData = Checkeeper::checks()->image($checkId, 'pdf');
return response()->streamDownload(function () use ($pdfData) {
echo $pdfData;
}, "check-{$checkId}.pdf");
}Get voucher image:
$voucherData = Checkeeper::checks()->voucherImage('check-abc123');
Storage::put('vouchers/voucher-abc123.jpg', $voucherData);Webhooks allow Checkeeper to notify your application in real-time when check statuses change.
- The webhook route is auto-registered at
/checkeeper/webhook - Configure the URL in Checkeeper dashboard:
https://yourapp.com/checkeeper/webhook - Set webhook secret in
.env:CHECKEEPER_WEBHOOK_SECRET=your-webhook-secret-from-dashboard
The package automatically:
- Verifies webhook signatures using HMAC SHA256
- Dispatches
WebhookReceivedevent - Returns 200 OK immediately
Register listeners in your EventServiceProvider:
use Bhaidar\Checkeeper\Events\WebhookReceived;
use Bhaidar\Checkeeper\Events\CheckCreated;
use Bhaidar\Checkeeper\Events\CheckCancelled;
protected $listen = [
WebhookReceived::class => [
LogWebhookActivity::class,
ProcessCheckStatusUpdate::class,
],
CheckCreated::class => [
SendCheckCreatedNotification::class,
UpdateInvoiceStatus::class,
],
CheckCancelled::class => [
RefundPayment::class,
NotifyAccounting::class,
],
];namespace App\Listeners;
use Bhaidar\Checkeeper\Events\WebhookReceived;
use App\Models\Invoice;
class MarkInvoiceAsPaid
{
public function handle(WebhookReceived $event): void
{
$payload = $event->payload;
if ($payload['event'] !== 'check.delivered') {
return;
}
$invoice = Invoice::where('check_id', $payload['check_id'])->first();
if (! $invoice) {
return;
}
$invoice->update([
'status' => 'paid',
'paid_at' => $payload['delivered_at'],
]);
$invoice->customer->notify(new CheckDeliveredNotification($invoice));
}
}namespace App\Listeners;
use Bhaidar\Checkeeper\Events\WebhookReceived;
use Illuminate\Support\Facades\Log;
class LogWebhookActivity
{
public function handle(WebhookReceived $event): void
{
Log::info('Checkeeper webhook received', [
'event' => $event->payload['event'] ?? 'unknown',
'check_id' => $event->payload['check_id'] ?? null,
'received_at' => $event->receivedAt,
]);
}
}The package automatically verifies webhook signatures using the VerifyWebhookSignature middleware:
- Extracts
X-Checkeeper-Signatureheader - Validates using HMAC SHA256 with your webhook secret
- Rejects invalid signatures with 401 Unauthorized
No additional configuration needed - just ensure your webhook secret is set in .env.
Disable webhooks if needed:
// config/checkeeper.php
'webhooks' => [
'enabled' => false,
],$info = Checkeeper::team()->info();
echo $info['name'];
echo $info['credits'];$templates = Checkeeper::templates()->list();
foreach ($templates as $template) {
echo "{$template['id']}: {$template['name']}\n";
}Use a template when creating checks:
$checkData = new CheckData(
// ... other fields
templateId: 'template-123'
);The package dispatches Laravel events for key operations:
Fired after successful check creation.
use Bhaidar\Checkeeper\Events\CheckCreated;
class SendCheckCreatedEmail
{
public function handle(CheckCreated $event): void
{
$check = $event->check; // CheckStatusData
$metadata = $event->metadata; // array
Mail::to($recipient)->send(new CheckCreatedMail($check));
}
}Fired after check cancellation.
use Bhaidar\Checkeeper\Events\CheckCancelled;
class RefundCancelledCheck
{
public function handle(CheckCancelled $event): void
{
$checkId = $event->checkId;
Refund::create(['check_id' => $checkId]);
}
}Fired when webhook is received and verified.
use Bhaidar\Checkeeper\Events\WebhookReceived;
class ProcessWebhookPayload
{
public function handle(WebhookReceived $event): void
{
$payload = $event->payload; // array
$signature = $event->signature; // string
$receivedAt = $event->receivedAt; // string (ISO 8601)
match ($payload['event']) {
'check.printed' => $this->handlePrinted($payload),
'check.mailed' => $this->handleMailed($payload),
'check.delivered' => $this->handleDelivered($payload),
default => null,
};
}
}The package throws typed exceptions for different error scenarios:
use Bhaidar\Checkeeper\Exceptions\AuthenticationException;
use Bhaidar\Checkeeper\Exceptions\ValidationException;
use Bhaidar\Checkeeper\Exceptions\NotFoundException;
use Bhaidar\Checkeeper\Exceptions\CheckkeeperException;
try {
$result = Checkeeper::checks()->create($checkData);
} catch (AuthenticationException $e) {
// Invalid API key (401/403)
Log::error('Checkeeper auth failed', ['error' => $e->getMessage()]);
} catch (ValidationException $e) {
// Invalid check data (422)
return back()->withErrors($e->errors);
} catch (NotFoundException $e) {
// Check not found (404)
abort(404, 'Check not found');
} catch (CheckkeeperException $e) {
// Other API errors
Log::error('Checkeeper error', [
'status' => $e->statusCode,
'message' => $e->getMessage(),
'errors' => $e->errors,
]);
}Here's a complete example of a vendor payment system:
use Bhaidar\Checkeeper\Facades\Checkeeper;
use Bhaidar\Checkeeper\DataTransferObjects\CheckData;
use Bhaidar\Checkeeper\DataTransferObjects\BankData;
use Bhaidar\Checkeeper\DataTransferObjects\PayerData;
use Bhaidar\Checkeeper\DataTransferObjects\PayeeData;
use Bhaidar\Checkeeper\DataTransferObjects\SignerData;
use Bhaidar\Checkeeper\DataTransferObjects\DeliveryData;
use Bhaidar\Checkeeper\Enums\SignerType;
use Bhaidar\Checkeeper\Enums\DeliveryMethod;
use Bhaidar\Checkeeper\Events\WebhookReceived;
use Bhaidar\Checkeeper\Jobs\CreateCheckJob;
// Step 1: Create payment record
$payment = Payment::create([
'invoice_id' => $invoice->id,
'vendor_id' => $vendor->id,
'amount' => 50000, // $500.00
'status' => 'pending',
]);
// Step 2: Prepare check data
$checkData = new CheckData(
bank: new BankData(
routing: config('company.bank_routing'),
account: config('company.bank_account')
),
payer: new PayerData(
line1: config('company.name'),
line2: config('company.address'),
logo: base64_encode(Storage::get('company-logo.png'))
),
payee: new PayeeData(
line1: $vendor->name,
line2: $vendor->address
),
signer: new SignerData(
type: SignerType::Png,
value: base64_encode(Storage::get('ceo-signature.png'))
),
amount: $payment->amount,
number: $payment->check_number,
memo: "Invoice #{$invoice->number}",
nonce: "payment-{$payment->id}"
);
// Step 3: Create check with delivery method
$delivery = new DeliveryData(method: DeliveryMethod::UspsFirstClass);
$result = Checkeeper::checks()->create($checkData, $delivery);
$payment->update([
'check_id' => $result->id,
'status' => 'sent_to_printer',
]);
// Or queue it for async processing
CreateCheckJob::dispatch($checkData);
// Step 4: Listen for webhook events
// app/Listeners/UpdatePaymentStatus.php
class UpdatePaymentStatus
{
public function handle(WebhookReceived $event): void
{
$payload = $event->payload;
$checkId = $payload['check_id'];
$payment = Payment::where('check_id', $checkId)->first();
if (! $payment) {
return;
}
match ($payload['event']) {
'check.printed' => $payment->update(['status' => 'printed']),
'check.mailed' => $payment->update(['status' => 'mailed']),
'check.delivered' => $payment->update([
'status' => 'delivered',
'delivered_at' => $payload['delivered_at'],
]),
'check.returned' => $payment->update(['status' => 'returned']),
default => null,
};
$payment->vendor->notify(new CheckStatusUpdated($payment));
}
}
// Step 5: Display status to user
// resources/views/payments/show.blade.php<div class="payment-status">
<h3>Payment #{{ $payment->id }}</h3>
<div class="status-badge {{ $payment->status }}">
{{ ucfirst($payment->status) }}
</div>
@if($payment->check_id)
<div class="tracking">
<h4>Tracking</h4>
@foreach($tracking as $event)
<div class="event">
<span>{{ $event->event }}</span>
<span>{{ $event->eventDate }}</span>
<span>{{ $event->location->city ?? '' }}</span>
</div>
@endforeach
</div>
<a href="{{ route('payments.download', $payment) }}" class="btn">
Download Check Image
</a>
@endif
</div>Use HTTP fakes to test your Checkeeper integration:
use Bhaidar\Checkeeper\Facades\Checkeeper;
use Illuminate\Support\Facades\Http;
test('can create vendor payment', function () {
Http::fake([
'api.checkeeper.com/*' => Http::response([
'data' => [
'checks' => [
['id' => 'check-123', 'status' => 'processing']
],
'total_credits' => 1,
],
], 201),
]);
$vendor = Vendor::factory()->create();
$invoice = Invoice::factory()->create(['vendor_id' => $vendor->id]);
$payment = Payment::create([
'invoice_id' => $invoice->id,
'vendor_id' => $vendor->id,
'amount' => 50000,
]);
CreateCheckJob::dispatchSync($checkData);
expect($payment->fresh())
->check_id->toBe('check-123')
->status->toBe('sent_to_printer');
});
test('updates payment status on webhook', function () {
$payment = Payment::factory()->create(['check_id' => 'check-123']);
$payload = json_encode([
'event' => 'check.delivered',
'check_id' => 'check-123',
'delivered_at' => now()->toIso8601String(),
]);
$signature = hash_hmac('sha256', $payload, config('checkeeper.webhooks.secret'));
$this->postJson('/checkeeper/webhook', json_decode($payload, true), [
'X-Checkeeper-Signature' => $signature,
])->assertOk();
expect($payment->fresh()->status)->toBe('delivered');
});// List checks (returns Collection of CheckStatusData)
Checkeeper::checks()->list(array $filters = []): Collection
// Create single check (delivery is separate from check data)
Checkeeper::checks()->create(CheckData|array $data, ?DeliveryData $delivery = null): CheckStatusData
// Create multiple checks (delivery applies to all checks)
Checkeeper::checks()->createBulk(array $checks, ?DeliveryData $delivery = null): array
// Get check status
Checkeeper::checks()->status(string $id): CheckStatusData
// Get tracking events
Checkeeper::checks()->tracking(string $id): Collection
// Cancel check
Checkeeper::checks()->cancel(string $id): bool
// Get check image (jpg or pdf)
Checkeeper::checks()->image(string $id, string $type = 'jpg'): string
// Add attachment
Checkeeper::checks()->attachment(string $id, string $file): bool
// Get voucher image
Checkeeper::checks()->voucherImage(string $id): string
// Fluent filter builder
Checkeeper::checks()->filter(): CheckFilterBuilderCheckeeper::team()->info(): arrayCheckeeper::templates()->list(): Collection| DTO | Description |
|---|---|
CheckData |
Check payload (bank, payer, payee, signer, amount, etc.) |
BankData |
Bank routing and account numbers |
PayerData |
Payer/company info (lines 1-4, logo) |
PayeeData |
Payee/recipient info (lines 1-4) |
SignerData |
Signature (text name or image) |
AddressData |
Full address (name, lines, city, state, zip, country, phone) |
DeliveryData |
Delivery method and optional bundle address |
CheckStatusData |
API response (id, status, created, updated, trackingUrl) |
TrackingEventData |
Tracking event (event, subevent, eventDate, location) |
| Enum | Values |
|---|---|
DeliveryMethod |
UspsFirstClass, UspsPriority, UpsTwoDay, UpsNextDay, FedexTwoDay, FedexOvernight, Pdf |
CheckStatus |
Processing, Ready, Printed, Mailed, Delivered, Cancelled, Returned |
SignerType |
Text, Png, Gif, Jpg |
Run the package test suite:
composer testPlease see CHANGELOG.md for recent changes.
Contributions are welcome! Please see CONTRIBUTING.md for details.
If you discover any security issues, please email security@example.com instead of using the issue tracker.
The MIT License (MIT). Please see LICENSE for more information.