Add opt-in custom domains with automatic SSL
Deploy Ladill Merchant / deploy (push) Successful in 29s
Deploy Ladill Merchant / deploy (push) Successful in 29s
Customers can connect their own domain to a merchant page (storefront/event): add a domain, point an A record (apex + www) to the app server, click Verify — DNS is checked, then Ladill Domains' central SSL service issues + installs the Let's Encrypt cert and calls back to flip it live. The custom domain then serves the mapped page (host resolution on /). Feature-gated: only active when a Domains SSL API key is set, so this deploy is inert until wired. - custom_domains table + CustomDomain model - CustomDomainService (DNS verify, request cert), DomainsSslClient, DnsResolver - settings UI panel, signed SSL callback receiver, host resolution on / - feature tests (DNS verify/fail, signed callback, ownership) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
a4974098ee
commit
b2aede5963
@@ -94,6 +94,52 @@
|
||||
</script>
|
||||
@endonce
|
||||
|
||||
@if(!empty($customDomainsEnabled))
|
||||
<div class="rounded-2xl border border-slate-200 bg-white p-5">
|
||||
<h3 class="text-sm font-semibold text-slate-900">Custom domain</h3>
|
||||
<p class="mt-1 text-xs text-slate-500">Serve this storefront on your own domain with automatic SSL. Optional — your <span class="break-all">{{ $publicUrl }}</span> link always works.</p>
|
||||
|
||||
@forelse($customDomains as $cd)
|
||||
<div class="mt-3 rounded-xl border border-slate-200 p-3">
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<span class="break-all text-sm font-medium text-slate-900">{{ $cd->host }}</span>
|
||||
@php $live = $cd->status === 'active' && $cd->ssl_status === 'active'; @endphp
|
||||
<span class="shrink-0 rounded-full px-2 py-0.5 text-[11px] font-medium {{ $live ? 'bg-emerald-50 text-emerald-700' : ($cd->status === 'failed' ? 'bg-red-50 text-red-700' : 'bg-amber-50 text-amber-700') }}">
|
||||
{{ $live ? 'Live (SSL)' : ($cd->status === 'failed' ? 'Failed' : 'Pending') }}
|
||||
</span>
|
||||
</div>
|
||||
@unless($live)
|
||||
<p class="mt-2 text-xs text-slate-500">Point an <strong>A record</strong> for <strong>{{ $cd->host }}</strong>@if($cd->include_www) and <strong>www.{{ $cd->host }}</strong>@endif to <strong>{{ $customDomainServerIp }}</strong>, then verify.</p>
|
||||
@if($cd->last_error)<p class="mt-1 text-xs text-red-600">{{ $cd->last_error }}</p>@endif
|
||||
@endunless
|
||||
<div class="mt-2 flex items-center gap-3">
|
||||
@unless($live)
|
||||
<form method="post" action="{{ route('merchant.custom-domain.verify', $cd) }}">
|
||||
@csrf
|
||||
<button class="text-xs font-semibold text-indigo-600 hover:text-indigo-500">Verify & enable SSL</button>
|
||||
</form>
|
||||
@endunless
|
||||
<form method="post" action="{{ route('merchant.custom-domain.destroy', $cd) }}" onsubmit="return confirm('Remove this custom domain?');">
|
||||
@csrf @method('DELETE')
|
||||
<button class="text-xs font-medium text-slate-500 hover:text-red-600">Remove</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<form method="post" action="{{ route('merchant.custom-domain.store', $qrCode) }}" class="mt-3 flex items-end gap-2">
|
||||
@csrf
|
||||
<div class="flex-1">
|
||||
<label class="block text-xs text-slate-500">Your domain</label>
|
||||
<input type="text" name="host" placeholder="brand.com" required
|
||||
class="mt-1 w-full rounded-xl border-slate-200 text-sm focus:border-indigo-500 focus:ring-indigo-500">
|
||||
</div>
|
||||
<button class="rounded-xl bg-slate-900 px-3.5 py-2 text-sm font-semibold text-white hover:bg-slate-800">Add</button>
|
||||
</form>
|
||||
@error('host')<p class="mt-1 text-xs text-red-600">{{ $message }}</p>@enderror
|
||||
@endforelse
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="post" action="{{ route('merchant.storefronts.destroy', $qrCode) }}"
|
||||
onsubmit="return confirm('Delete this storefront? This cannot be undone.');">
|
||||
@csrf @method('DELETE')
|
||||
|
||||
Reference in New Issue
Block a user