← {{ __('Courier integrations') }}
{{ $provider?->label() ?? __('Courier') }} · {{ $environment?->label() ?? '' }} {{ __('Platform-shared credentials. Secrets are encrypted at rest and never rendered back into the form.') }}
@if ($isConfigured) {{ __('Configured') }} @else {{ __('Not yet configured') }} @endif @if (! $row->enabled) {{ __('Disabled') }} @endif {{-- Last connection-test outcome. Shown only after a save has been attempted (last_checked_at is set). The `last_error` column is operator-safe — the resolvers' testConnection() implementations are contracted to never persist raw response bodies. --}} @if ($row->last_checked_at) @if ($row->last_error === null) {{ __('Credentials OK · :ago', ['ago' => $row->last_checked_at->diffForHumans()]) }} @else {{ __('Credentials failed · :ago', ['ago' => $row->last_checked_at->diffForHumans()]) }} @endif @endif
@if ($row->last_checked_at && $row->last_error !== null) {{-- Surface the failure reason as a banner — the badge alone is not enough for an operator to act on. Truncated to one line so it doesn't dominate the page layout if the resolver returned a verbose message. --}}
{{ $row->last_error }}
@endif {{-- Super-admin-only debug panel. Renders when the last probe failed AND the resolver captured a debug bundle. Hidden by default — operator clicks to expand. Contains the endpoint URL, target environment, redacted request body, HTTP status, raw response body, and parsed Landmark errors so super-admins can debug credential issues without SSH-ing into the server. Password is fully stripped, username is partially masked, ClientID + TrackingNumber visible. --}} @php $debugBundle = is_array($row->metadata) ? ($row->metadata['last_probe_debug'] ?? null) : null; @endphp @if ($row->last_error !== null && is_array($debugBundle) && auth()->user()?->isSuperAdmin())
{{ __('Diagnostic details (super-admin only)') }}
{{ __('Endpoint') }}
{{ $debugBundle['endpoint'] ?? '—' }}
{{ __('Environment probed') }}
{{ $debugBundle['environment'] ?? '—' }}
{{ __('HTTP status') }}
{{ $debugBundle['http_status'] ?? __('network failure (no response)') }}
{{ __('Probed at') }}
{{ $debugBundle['probed_at'] ?? '—' }}
@if (isset($debugBundle['parsed_errors']) && is_array($debugBundle['parsed_errors']) && $debugBundle['parsed_errors'] !== [])
{{ __('Parsed errors') }}
    @foreach ($debugBundle['parsed_errors'] as $err)
  • [{{ $err['code'] ?? '?' }}] {{ $err['message'] ?? '' }}
  • @endforeach
@endif
{{ __('Request body (password stripped, username masked)') }}
{{ $debugBundle['request_xml_redacted'] ?? '' }}
{{ __('Raw response body') }}
{{ $debugBundle['response_body'] ?? __('(no response captured)') }}
@endif
{{-- Connection settings --}}
{{ __('Connection') }} {{ __('Endpoint + identifiers. Not secret.') }} @php // Per-provider helper text. Anchored to the real API // shapes so operators know which wire field each // input lands on. No secrets in this map. $baseUrlHelp = match ($provider) { \App\Enums\CourierProvider::RoyalMail => __('Example: https://api.royalmail.net (without a path). The /mailpieces/v2 prefix is appended automatically.'), \App\Enums\CourierProvider::Landmark => __('Accepts either the domain (https://api.landmarkglobal.com) or the full endpoint (https://api.landmarkglobal.com/v2/Track.php). /v2/Track.php is appended automatically if missing.'), default => null, }; $baseUrlPlaceholder = match ($provider) { \App\Enums\CourierProvider::RoyalMail => 'https://api.royalmail.net', \App\Enums\CourierProvider::Landmark => 'https://api.landmarkglobal.com/v2/Track.php', default => 'https://api.example.com', }; @endphp
{{ __('Base URL') }} @if ($baseUrlHelp) {{ $baseUrlHelp }} @endif @foreach ($identifierFields as $column => $label) @php $wireKey = match ($column) { 'client_id' => 'clientId', 'username' => 'username', 'account_reference' => 'accountReference', default => null, }; // Per-provider, per-column helper. Names the // exact wire-level destination the value lands // on so operators don't have to read the spec. $fieldHelp = match ([$provider, $column]) { [\App\Enums\CourierProvider::RoyalMail, 'client_id'] => __('Sent as the X-IBM-Client-Id request header to IBM API Connect.'), [\App\Enums\CourierProvider::Landmark, 'username'] => __('Sent inside the request XML as . Required.'), [\App\Enums\CourierProvider::Landmark, 'account_reference'] => __('Sent inside the request XML as . Required by default — Landmark rejects multi-client logins without it. Tick "single-client login" below to omit.'), default => null, }; // Override the column label for Landmark's // account_reference. The enum still labels // it "Client ID (optional)" for backward-compat // — the view now corrects that explicitly. $renderedLabel = ($provider === \App\Enums\CourierProvider::Landmark && $column === 'account_reference') ? __('Client ID') : __($label); @endphp @if ($wireKey) {{ $renderedLabel }} @if ($fieldHelp) {{ $fieldHelp }} @endif @endif @endforeach
{{-- Landmark-only: single-client login toggle. Lets the operator opt out of the required-ClientID rule when their Landmark login is genuinely scoped to a single client. Hidden for Royal Mail (no equivalent concept). --}} @if ($provider === \App\Enums\CourierProvider::Landmark)
{{ __('This Landmark login only has one client; omit ClientID') }}
{{ __('Tick only if your Landmark login is scoped to a single client and you do not have a ClientID to provide. With this off (the default), ClientID is required — Landmark rejects multi-client requests without it with errors like "Request is missing client ID" or "Unable to determine desired client".') }}
@endif
{{ __('Enabled') }}
{{ __('When disabled, ClearDesk will not use this courier for tracking lookups. Shipments matched to this courier will return tracking unavailable until this integration is enabled.') }}
{{-- Secret payload. Inputs render BLANK; blank = keep, non-blank = replace. --}}
{{ __('Secrets') }} {{ __('Encrypted at rest. Inputs are always blank — leave blank to keep the existing value, type a new value to replace it.') }} @if (empty($secretFieldKeys))
{{ __('This provider has no secret fields.') }}
@else
@foreach ($secretFieldKeys as $field) @php $secretHelp = match ([$provider, $field]) { [\App\Enums\CourierProvider::RoyalMail, 'client_secret'] => __('Sent as the X-IBM-Client-Secret request header to IBM API Connect.'), [\App\Enums\CourierProvider::Landmark, 'password'] => __('Sent inside the request XML as . Required.'), default => null, }; @endphp {{ __(str(str_replace('_', ' ', $field))->title()->value()) }} @if ($secretHelp) {{ $secretHelp }} @endif @endforeach
@if ($isConfigured)
{{ __('Clear stored secret') }}
@endif @endif
{{-- Operator notes --}}
{{ __('Notes') }} {{ __('Free-form. No secrets, no PII.') }}
{{-- Sticky save bar --}}
{{ __('Save') }} {{ __('Back') }}