@extends('layouts.app') @section('title', 'NMI Payment Links') @section('body_class', 'nmi-admin-page') @push('styles') @endpush @section('content')
Send a secure NMI payment link by SMS, email, or both. Enter at least a phone number or an email address, plus the amount; tax is calculated automatically and the customer pays with 3D Secure on the hosted NMI checkout.
NMI keys, tax, link expiry, and layaway options are in Setting → NMI Payment. @if(!$settings->isConfigured()) Add both NMI keys and enable the feature there before sending links. @endif
@elseif(!$settings->isConfigured())NMI Payment Links is not configured yet. Ask an admin to set keys in Setting → NMI Payment.
@endif @if(auth()->user()?->isAdmin()) @php $overviewFilter = $overviewFilter ?? ['year' => (int) date('Y'), 'month' => (int) date('n'), 'label' => '']; $overviewSeries = $overviewSeries ?? []; $overviewMonth = $overviewMonth ?? []; $overviewYears = $overviewYears ?? []; $overviewMonths = $overviewMonths ?? []; $selectedOverviewPoint = collect($overviewSeries)->firstWhere('month', (int) ($overviewFilter['month'] ?? 0)) ?? [ 'amount' => 0, 'count' => 0, ]; @endphpPayment links · Layaway (card + cash) · Instagram Story
| Month | # | Amount | Tax |
|---|---|---|---|
| {{ $point['label_full'] }} | {{ $point['count'] }} | ${{ number_format((float) $point['amount'], 2) }} | ${{ number_format((float) ($point['tax_amount'] ?? 0), 2) }} |
| No paid NMI collections yet this year. | |||
Enter customer contact, sale amount, and options — then send a secure hosted checkout link.
Recent notifications, payments, declines, refunds, voids, and CCAF events. Use Open to jump straight to the payment or layaway plan.
No recent activity yet. Sends, reminders, payments, declines, refunds, voids, and CCAF updates will appear here.
@else{{ $event['title'] ?? $event['summary'] ?? 'Activity' }}
Track plan totals, balances, and payments. Send balance reminders manually (email + SMS when a phone is on file). Weekly reminders and layaway terms are configured in Setting → NMI Payment.
@if(($layawayPlans ?? collect())->isEmpty()){{ $layawayFiltersActive ? 'No layaway plans match your filters.' : 'No layaway plans yet.' }}
@else| Image | Created | Customer | Salesperson | Subtotal | Tax | Total | Paid | Balance | Payments | SMS delivery | Email delivery | Plan status | Plan expires | Actions | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @if($plan->productImageUrl()) @elseif($plan->needsManualProductImage()) @else @endif | @if($plan->created_at) @php $at = $plan->created_at->timezone('America/New_York'); @endphp {{ $at->format('n/j/y') }} {{ $at->format('g:i A') }} @endif | @if($plan->formattedOrderNumber()) Order #{{ $plan->formattedOrderNumber() }} @elseif($plan->needsManualTicketNumber()) @endif @if($planCustomerName) {{ $planCustomerName }} @endif @if($planCustomerEmail) {{ $planCustomerEmail }} @endif @if($planPhone) {{ $planPhone }} @endif @if($plan->source === 'story_purchase')Story@endif | {{ $plan->salesperson?->full_name ?? '—' }} | ${{ number_format($plan->subtotal, 2) }} | @if($plan->hasTax())${{ number_format($plan->tax_amount, 2) }}@else—@endif | ${{ number_format($plan->total_amount, 2) }} | ${{ number_format($plan->amount_paid, 2) }} | ${{ number_format($plan->balance_due, 2) }} | @if($paymentCount === 0) None yet @else @endif |
invitationSmsDeliveryTitle()) title="{{ $smsDeliveryTitle }}"@endif>{{ $plan->invitationSmsDeliveryLabel() }}
@if($plan->hasInvitationSmsLinkViewed())
invitationSmsLinkViewedTitle()) title="{{ $smsTitle }}"@endif>Viewed
@endif
@if($plan->last_reminder_sms_status === 'sent' && $plan->lastReminderLabel())
Reminder {{ $plan->lastReminderLabel() }}
@endif
|
invitationEmailDeliveryTitle()) title="{{ $emailTitle }}"@endif>{{ $plan->invitationEmailDeliveryLabel() }} @if($plan->lastReminderLabel()) Reminder {{ $plan->lastReminderLabel() }} @endif | {{ $plan->statusLabel() }} | @if($plan->plan_expires_at) {{ $plan->plan_expires_at->timezone('America/New_York')->format('n/j/y g:i A') }} @elseif($plan->invitation_expires_at && in_array($plan->status, ['pending_first_payment', 'invitation_expired'], true)) Invite: {{ $plan->invitation_expires_at->timezone('America/New_York')->format('n/j/y g:i A') }} @else — @endif |
Open
@if($plan->canReactivateExpiredInvitation())
@endif
@if($plan->canEditPlanTotal())
@endif
@if($plan->canRecordCashPayment())
@endif
@if(($isNmiAdmin ?? false) && $plan->canCancelAndRefund())
@endif
@if($plan->status === 'active' && $plan->balance_due > 0)
@endif
|
|||||||||||||||||
|
Payment history
@php
$historyBits = array_values(array_filter([
$planCustomerName,
$planCustomerEmail,
$planPhone,
]));
@endphp
{{ $historyBits !== [] ? implode(' · ', $historyBits) : 'Layaway plan' }}
|
|||||||||||||||||||||||||||||||
Last synced from NMI: {{ $nmiLastSyncedAt->timezone('America/New_York')->format('M j, Y g:i A T') }}
@endifDelivery and payment badges update automatically every 45 seconds — no page refresh needed.
{{ $paymentFiltersActive ? 'No payment links match your filters.' : 'No payment links sent yet.' }}
@else| Date | Phone | Salesperson | Subtotal | Tax | Total | SMS delivery | Email delivery | Payment | 3DS | CCAF | Ready to ship | @if(auth()->user()?->isAdmin())SKU | @endifActions |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @php $listAt = $item->listDisplayAt()?->timezone('America/New_York'); @endphp @if($listAt) {{ $listAt->format('n/j/y') }} {{ $listAt->format('g:i A') }} @else — @endif | @if($item->isLayawayPayment()) Layaway @elseif($item->showStoryPendingLabel()) Story @else @if($item->displayPhone()) {{ $item->displayPhone() }} @endif @if($item->customer_name) {{ $item->customer_name }} @endif @if($item->customer_email) {{ $item->customer_email }} @endif @endif | {{ $item->salesperson?->full_name ?? '—' }} | ${{ number_format($item->subtotal, 2) }} | @if($item->hasTax())${{ number_format($item->tax_amount, 2) }}@else—@endif | ${{ number_format($item->total_amount, 2) }} |
smsDeliveryTitle()) title="{{ $smsDeliveryTitle }}"@endif>{{ $item->smsDeliveryLabel() }}
@if($item->hasSmsLinkViewed())
smsLinkViewedTitle()) title="{{ $smsTitle }}"@endif>Viewed
@endif
|
emailDeliveryTitle()) title="{{ $title }}"@endif>{{ $item->emailDeliveryLabel() }} | declineDetailTitle()) title="{{ $declineTitle }}"@endif>{{ $item->paymentStatusLabel() }} @include('nmi_payment.partials.decline-info-btn', ['payment' => $item]) @if($itemExpiresLabel = $item->pendingExpiresLabel()) {{ $itemExpiresLabel }} @endif @if($item->payment_status === 'paid' && $item->nmi_transaction_id) #{{ $item->nmi_transaction_id }} @if($item->hasDeclineHistory() && ($declineCount = count($item->declineAttemptsList())) > 0) {{ $declineCount }} prior decline{{ $declineCount === 1 ? '' : 's' }} @endif @elseif($item->payment_status === 'refunded' && $item->nmi_transaction_id) #{{ $item->nmi_transaction_id }} @if($item->nmi_refund_transaction_id) ref #{{ $item->nmi_refund_transaction_id }} @endif @elseif($item->payment_status === 'voided' && $item->nmi_transaction_id) #{{ $item->nmi_transaction_id }} @elseif($item->hasOpenDecline() && $item->nmi_decline_transaction_id) decl #{{ $item->nmi_decline_transaction_id }} @if(($declineCount = count($item->declineAttemptsList())) > 1) {{ $declineCount }} tries @endif @if($item->hasHighRiskDifferentDeclineCards()) High risk @endif @endif | @if($item->payment_status === 'paid') {{ $item->threeDsLabel() }} @else — @endif | @include('nmi_payment.partials.ccaf-cell', [ 'payment' => $item, 'riskSummary' => ($item->ccaf_contract_id && isset(($ccafRiskSummaries ?? [])[$item->ccaf_contract_id])) ? ($ccafRiskSummaries ?? [])[$item->ccaf_contract_id] : null, ]) | @if($item->payment_status === 'paid' && $item->ccaf_status === 'signed') {{ $item->readyToShipLabel() }} @else — @endif | @if(auth()->user()?->isAdmin())
@if($item->nmi_product_sku)
{{ $item->nmi_product_sku }}
@else
—
@endif
|
@endif
@if($item->payment_url || $item->canViewNmiReceipt() || $item->canViewNmiRefundReceipt() || $item->canEditPendingDeliveryDetails() || (($isNmiAdmin ?? false) && $item->canCancelAndRefund()))
@if($item->payment_url)
Open
@endif
@if($item->canEditPendingDeliveryDetails())
@endif
@if($item->canViewNmiReceipt())
@include('nmi_payment.partials.receipt-pdf-btn', ['paymentRequest' => $item])
@elseif($item->canViewNmiRefundReceipt())
@include('nmi_payment.partials.refund-receipt-pdf-btn', ['paymentRequest' => $item])
@endif
@if(($isNmiAdmin ?? false) && $item->canCancelAndRefund())
@endif
@if($item->payment_url)
@if($item->canReactivateExpiredLink())
@endif
@if($item->canNotifyCustomer())
@endif
@endif
@else
—
@endif
|