|
129 | 129 | <div class="form-section"> |
130 | 130 | <h2>Payment Information</h2> |
131 | 131 | <p class="payment-note">💳 Secure payment powered by Stripe. Your card will be charged after the 14-day trial.</p> |
132 | | - |
| 132 | + |
133 | 133 | <div class="form-group"> |
134 | 134 | <label for="card-element">Credit Card *</label> |
135 | | - <div id="card-element" class="stripe-element"> |
| 135 | + @if (!string.IsNullOrEmpty(_stripeInitError)) |
| 136 | + { |
| 137 | + <div class="alert alert-warning mt-2"> |
| 138 | + <strong>Payment system unavailable:</strong> @_stripeInitError |
| 139 | + </div> |
| 140 | + } |
| 141 | + <div id="card-element" class="stripe-element" style="@(!string.IsNullOrEmpty(_stripeInitError) ? "display:none" : "")"> |
136 | 142 | <!-- Stripe Element will be inserted here --> |
137 | 143 | </div> |
138 | 144 | <div id="card-errors" class="payment-error" role="alert"></div> |
|
161 | 167 |
|
162 | 168 | <div class="alert alert-info mt-3"> |
163 | 169 | <strong>14-Day Free Trial</strong><br/> |
164 | | - Start using the platform immediately. Your card won't be charged until February 23, 2026. |
| 170 | + Start using the platform immediately. Your card won't be charged until @DateTime.Now.AddDays(14).ToString("MMMM d, yyyy"). |
165 | 171 | </div> |
166 | 172 | </div> |
167 | 173 |
|
|
170 | 176 | <div class="alert alert-danger">@errorMessage</div> |
171 | 177 | } |
172 | 178 |
|
173 | | - <button type="submit" class="btn btn-primary btn-lg" disabled="@isSubmitting"> |
| 179 | + <button type="submit" class="btn btn-primary btn-lg" disabled="@(isSubmitting || !string.IsNullOrEmpty(_stripeInitError))"> |
174 | 180 | @if (isSubmitting) |
175 | 181 | { |
176 | 182 | <span>Creating account...</span> |
|
228 | 234 | private bool enableAttachments = false; |
229 | 235 | private bool enableEnrollment = false; |
230 | 236 |
|
| 237 | + private string? _stripeInitError; |
| 238 | + |
231 | 239 | protected override async Task OnAfterRenderAsync(bool firstRender) |
232 | 240 | { |
233 | 241 | if (firstRender) |
|
240 | 248 | { |
241 | 249 | try |
242 | 250 | { |
243 | | - var stripePublishableKey = Configuration["Stripe:PublishableKey"] ?? "pk_test_placeholder"; |
244 | | - await JSRuntime.InvokeVoidAsync("StripeHandler.initialize", stripePublishableKey); |
245 | | - Logger.LogInformation("Stripe initialized successfully"); |
| 251 | + var stripePublishableKey = Configuration["Stripe:PublishableKey"]; |
| 252 | + if (string.IsNullOrEmpty(stripePublishableKey)) |
| 253 | + { |
| 254 | + _stripeInitError = "Payment system is not configured. Please contact support@cloudhealthoffice.com."; |
| 255 | + Logger.LogError("Stripe:PublishableKey is not configured"); |
| 256 | + StateHasChanged(); |
| 257 | + return; |
| 258 | + } |
| 259 | + |
| 260 | + var initError = await JSRuntime.InvokeAsync<string?>("StripeHandler.initialize", stripePublishableKey); |
| 261 | + if (initError != null) |
| 262 | + { |
| 263 | + _stripeInitError = initError; |
| 264 | + Logger.LogError("Stripe initialization failed: {Error}", initError); |
| 265 | + StateHasChanged(); |
| 266 | + } |
| 267 | + else |
| 268 | + { |
| 269 | + Logger.LogInformation("Stripe initialized successfully"); |
| 270 | + } |
246 | 271 | } |
247 | 272 | catch (Exception ex) |
248 | 273 | { |
| 274 | + _stripeInitError = "Failed to load payment form. Please refresh the page and try again."; |
249 | 275 | Logger.LogError(ex, "Failed to initialize Stripe"); |
| 276 | + StateHasChanged(); |
250 | 277 | } |
251 | 278 | } |
252 | 279 |
|
|
0 commit comments