shadcn.io is not affiliated with official shadcn/ui
Failed Payment Alert Billing Block for Ark UI
A declined card with the unpaid charges as checkbox rows (the plan always first), a foot that works out what is paid now and what stays due, and a Pay button that turns the alert into a Paid summary of the same height.
Installation
Overview
Let customers pay what restores their access first, with this failed payment alert section for React with Ark UI. It shows the account of Ploverfield, a language-learning app, whose Visa ending 4242 was declined on 12 Oct. A hairline frame with a plus mark on each corner holds the alert (one destructive icon and an "Update card" link that says the number goes through the provider's hosted fields) over three unpaid charges. The Studio plan is always paid first and marked "Restores access"; extra seats and usage are Checkbox rows you can tick in. The foot works out the plan from the ticks ("Pay $49.00 now; $32.40 stays due and is retried on 19 Oct") and the one Shine Button says which account it pays from. Pressing it turns the alert into a calm "Paid, in this demo" summary of the same height, which takes focus. It's built from Badge, Button, Checkbox, Field, Shine Button and Guides, with a CSS entrance only. For billing pages and any subscription app.
FAQ
How do I fill it with my charges?
Edit CHARGES: each has an id, a name, a note, an amount in cents and a required flag. A required charge is shown ticked and cannot be unticked; the total paid now is the required ones plus the ticked ones, and what stays due is the rest. Both numbers, the sentence in the foot, the button label and the summary after paying come from the same functions.
What happens when I press Pay?
The alert and the rows are replaced in place by a summary that lists what was paid and what stays due. Both layers share one grid cell, so the panel keeps its height and nothing jumps. Focus moves to the summary's heading, the button reads "Paid" and a polite status message says the result.
Why does Update card not take a number?
A card number belongs in your payment provider's hosted fields, never in your own page. The link only says so in the status line. In your app open the provider's update flow or your billing portal from it.
What stays local, and how do I charge for real?
All of it: no card is charged and the retry date is typed. In your app send the ticked charge ids to your server, collect them from the backup account there and return what was paid and what is still due, then render the summary from that response. Keep the retry date the server gives you.