Plan Picker Integration Guide
Product: Subscription Plans (Print, Digital, Print + Digital) • Checkout Platform: SubscriptionFlow (Hosted Checkout) • Target Audience: Front-end teams, business and integration owners • Goal: Provide a clean, single-step UI for plan selection and redirect to SubscriptionFlow hosted checkout.
Contents
1. Overview
This implementation simplifies the subscriber journey. There is no region selection and no geographic branching. Users see a list of subscription plans with image, title, short description, price, and a Subscribe Now button. Clicking Subscribe Now redirects to the correct SubscriptionFlow hosted checkout URL for that plan. An optional Read More modal can display longer descriptions. Plan metadata lives in one data structure so titles, prices, and links are easy to maintain.
- Reduces decision friction - single step
- Improves conversion by reducing complexity
- Works globally when pricing and currency are handled upstream
- Keeps the UI lightweight and maintainable
2. UI and HTML Structure
Key containers and elements
-
Wrapper container
.container-narrowwith page padding - Header: Choose Your Subscription Plan
-
Responsive grid
#plan-gridwith Bootstrap columns for plan cards - Each plan card includes: image, title, excerpt, Read More link, price, Subscribe Now button
-
Modal
#planModalfor full plan details and CTA
Bootstrap 5 is used for layout, modal, and responsiveness.
3. Styling and UX Details
- CSS variables for brand colors
- Cards use rounded corners and light shadow for hierarchy
- Buttons have strong labels and clear hover feedback
-
Excerpts clamp to approximately three lines using
-webkit-line-clamp -
Responsive grid using Bootstrap
.rowand.col-* - Modal is centered, scrollable, and large enough for easy reading
4. JavaScript Logic and Data Model
Data model
- Image constants: one per plan kind
-
LONG_DESCdictionary for full descriptions - used in the modal -
PLANSarray for all display and checkout metadata: title, price, currency, kind, hosted checkout link, image
Core functions
-
toExcerpt- creates a short preview from the long description -
renderPlans- renders all plan cards into the grid and wires up the modal handlers -
DOMContentLoaded hook calls
renderPlanson page load
5. SubscriptionFlow Integration - API and Hosted Checkout
Each plan button links directly to a SubscriptionFlow hosted checkout URL. This keeps the front end simple and avoids handling payment details in the browser.
If you require server-side subscription creation or advanced flows, use
the SubscriptionFlow API
POST /api/v1/subscriptions/checkout with OAuth2 Bearer token.
Hosted checkout is recommended for the simplest integration.
6. Deployment and Integration Checklist
- Replace placeholder image URLs with your assets
-
Populate
PLANSwith real titles, prices, currencies, kinds, and hosted checkout links - Confirm price formatting and currency symbols
- Test Read More modal and Subscribe Now flows on desktop and mobile
- Configure success and failure redirects in SubscriptionFlow
- Add analytics for clicks and conversion
- Review legal copy for terms, renewal, and cancellation
7. Customization and Future Enhancements
- Monthly vs annual pricing toggle
- Promotions and coupon display
- Customer portal link for managing subscriptions
- Localization for language and currency
- A/B test plan order, copy, and visuals
8. Summary and Business Rationale
This single-step plan picker integrates cleanly with SubscriptionFlow hosted checkout and reduces customer friction. It provides a maintainable front end while delegating subscription and billing to SubscriptionFlow.
9. Appendix - Full Code Snippet
Copy and paste the following HTML into a blank page or an HTML widget. Update the PLANS array and hosted checkout links.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Subscription Picker</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<style>
/* Root CSS variables for brand colors */
:root { --teal:#2aa49a; --ink:#0a0a0a; }
/* Base body background */
body { background:#f7f7f9; }
/* Narrow container for readable line length */
.container-narrow { max-width:1140px; margin:auto; }
/* Card styling for subscription plans */
.subscription-card {
border:0; border-radius:16px; box-shadow:0 8px 22px rgba(16,24,40,.08);
background:#fff; overflow:hidden; margin-bottom:2rem;
}
.subscription-card .card-header { background:#fff; border-bottom:1px solid #eef0f2; padding:1.25rem; }
.subscription-card .card-body { padding:1.5rem; }
/* Primary CTA button */
.btn-subscribe {
background: var(--ink); border:none; color:#fff; font-weight:800;
letter-spacing:.4px; text-transform:uppercase; padding:.9rem 1.2rem;
}
.btn-subscribe:hover { filter: brightness(1.1); }
/* Clamp description preview to about three lines */
.excerpt {
display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical;
overflow:hidden; margin-bottom:0; min-height:4.2em;
}
/* Inline links */
.muted-link { color:#6c757d; text-decoration:none; }
.muted-link:hover { text-decoration:underline; }
.more-link { font-weight:600; cursor:pointer; }
</style>
</head>
<body>
<!-- Main wrapper -->
<div class="container container-narrow py-5">
<h2 class="fw-bold mb-4">Choose Your Subscription Plan</h2>
<div id="plan-grid" class="row g-4"></div> <!-- JS renders plan cards here -->
</div>
<!-- Modal for full plan description -->
<div class="modal fade" id="planModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="planModalTitle">Plan Details</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p id="planModalBody" class="mb-0" style="white-space: pre-line;"></p>
</div>
<div class="modal-footer">
<a id="planModalCta" href="#" target="_blank" class="btn btn-dark">Subscribe Now</a>
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script>
// ------------------------------------------------------------
// Image URLs for each subscription kind
// Replace these with your assets
// ------------------------------------------------------------
const IMG_PRINT = "https://example.com/assets/print-300x300.webp";
const IMG_DIGITAL = "https://example.com/assets/digital-300x300.webp";
const IMG_BOTH = "https://example.com/assets/print-digital-300x300.webp";
// ------------------------------------------------------------
// Long descriptions - shown in the modal
// Keep concise but informative
// ------------------------------------------------------------
const LONG_DESC = {
print: "Printed edition delivered to your door every month. High quality paper. One year term.",
digital: "Digital edition with instant access at release. Read on mobile, tablet, or desktop.",
both: "Get both print delivery and full digital access starting at release time."
};
// ------------------------------------------------------------
// Plan definitions - update title, price, currency, and hosted checkout link
// Each link should point to a SubscriptionFlow hosted checkout URL
// ------------------------------------------------------------
const PLANS = [
{ title: "Annual Print Subscription", price: 64.00, currency: "£", kind: "print", link: "https://yourdomain.subscriptionflow.com/hosted-page/plan-print", img: IMG_PRINT },
{ title: "Annual Digital Subscription", price: 38.00, currency: "£", kind: "digital", link: "https://yourdomain.subscriptionflow.com/hosted-page/plan-digital", img: IMG_DIGITAL },
{ title: "Annual Print and Digital Bundle", price: 83.00, currency: "£", kind: "both", link: "https://yourdomain.subscriptionflow.com/hosted-page/plan-both", img: IMG_BOTH }
];
// Create a short preview paragraph from a longer description
function toExcerpt(text) {
return text.split(/\n\n+/)[0].replace(/\s+/g, " ").trim();
}
// Render all plans into the grid and attach modal handlers
function renderPlans() {
const grid = document.getElementById("plan-grid");
grid.innerHTML = "";
PLANS.forEach(plan => {
const excerpt = toExcerpt(LONG_DESC[plan.kind] || "");
const col = document.createElement("div");
col.className = "col-12 col-md-6 col-lg-4";
col.innerHTML = `
<div class="card subscription-card h-100 shadow-sm">
<img class="card-img-top" src="${plan.img}" alt="${plan.kind} subscription image">
<div class="card-body d-flex flex-column">
<h3 class="h6 fw-bold text-uppercase">${plan.title}</h3>
<p class="text-muted small excerpt">${excerpt}</p>
<div class="mb-2">
<a class="small more-link"
data-title="${plan.title}"
data-body="${encodeURIComponent(LONG_DESC[plan.kind] || "")}"
data-link="${plan.link}">
Read More
</a>
</div>
<div class="d-flex align-items-center justify-content-between mt-auto">
<div class="price fs-5">${plan.currency}${plan.price.toFixed(2)}</div>
<a href="${plan.link}" target="_blank" class="btn btn-subscribe">Subscribe Now</a>
</div>
</div>
</div>`;
grid.appendChild(col);
});
// Attach modal open behavior for each Read More link
grid.querySelectorAll(".more-link").forEach(link => {
link.addEventListener("click", () => {
const title = link.getAttribute("data-title");
const body = decodeURIComponent(link.getAttribute("data-body"));
const href = link.getAttribute("data-link");
document.getElementById("planModalTitle").textContent = title;
document.getElementById("planModalBody").textContent = body;
document.getElementById("planModalCta").setAttribute("href", href);
new bootstrap.Modal(document.getElementById("planModal")).show();
});
});
}
// Initialize on page load
document.addEventListener("DOMContentLoaded", renderPlans);
</script>
</body>
</html>
Tip: For CMS use, paste the code inside an HTML block. For WordPress Elementor, use the HTML widget. For Wix, use a custom elements or embed block that allows raw HTML.
HTMLBootstrap5 SubscriptionFlow Hosted Checkout
End of document.
Comments
0 comments
Please sign in to leave a comment.