1<!DOCTYPE html> 2<html lang="en"> 3 4<head> 5 <meta charset="UTF-8"> 6 7 8 <!-- Primary SEO --> 9 <title>XtoSCORM Pricing | SCORM Conversion Credits and Plans</title> 10 <meta name="title" content="XtoSCORM Pricing | SCORM Conversion Credits and Plans"> 11 <meta name="description" content="Explore XtoSCORM pricing and choose the right SCORM conversion plan. Start with free daily credits or purchase one-time credits that never expire to convert PDF, PowerPoint and video files into LMS-ready SCORM packages."> 12 <meta name="keywords" content="XtoSCORM pricing, SCORM converter pricing, SCORM conversion credits, buy SCORM credits, SCORM pricing plans, PDF to SCORM pricing, PPT to SCORM pricing, video to SCORM pricing, SCORM package cost, LMS content conversion credits"> 13 <meta name="robots" content="index, follow"> 14 <meta name="author" content="JustAddWater"> 15 16 <!-- Mobile --> 17 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 18 19 <!-- Canonical --> 20 <link rel="canonical" href="https://xtoscorm.com/pricing"> 21 22 <!-- Open Graph --> 23 <meta property="og:type" content="website"> 24 <meta property="og:url" content="https://xtoscorm.com/pricing"> 25 <meta property="og:title" content="XtoSCORM Pricing | Flexible SCORM Conversion Plans"> 26 <meta property="og:description" content="Start with free SCORM conversion credits or purchase one-time credits that never expire. Convert PDF, PowerPoint and video files into LMS-ready SCORM packages."> 27 <meta property="og:image" content="https://xtoscorm.com/images/meta/pricing_meta.png"> 28 29 <!-- Twitter --> 30 <meta name="twitter:card" content="summary_large_image"> 31 <meta name="twitter:url" content="https://xtoscorm.com/pricing"> 32 <meta name="twitter:title" content="XtoSCORM Pricing | SCORM Conversion Credits and Plans"> 33 <meta name="twitter:description" content="Get free daily SCORM conversion credits or purchase flexible one-time credits that never expire for PDF, PPT and video to SCORM conversion."> 34 <meta name="twitter:image" content="https://xtoscorm.com/images/meta/pricing_meta.png"> 35 36 <!-- Favicon --> 37 <link rel="icon" type="image/png" sizes="96x96" href="https://xtoscorm.com/images/favicon/favicon-96x96.png"> 38 <link rel="icon" type="image/svg+xml" href="https://xtoscorm.com/images/favicon/favicon.svg"> 39 <link rel="icon" type="image/x-icon" href="https://xtoscorm.com/favicon.ico"> 40 <link rel="shortcut icon" href="https://xtoscorm.com/images/favicon/favicon.ico"> 41 <link rel="apple-touch-icon" sizes="180x180" href="https://xtoscorm.com/images/favicon/apple-touch-icon.png"> 42 <meta name="apple-mobile-web-app-title" content="XtoSCORM"> 43 <link rel="manifest" href="https://xtoscorm.com/images/favicon/site.webmanifest"> 44 45 <!-- Performance --> 46 <link rel="preconnect" href="https://fonts.googleapis.com"> 47 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 48 <link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin> 49 50 <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> 51 52 <!-- Google Fonts (Deferred) --> 53 <link rel="preload" as="style" 54 href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700&display=swap" 55 onload="this.onload=null;this.rel='stylesheet'"> 56 <noscript> 57 <link rel="stylesheet" 58 href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700&display=swap"> 59 </noscript> 60 61 <!-- Font Awesome (Deferred) --> 62 <link rel="preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" 63 onload="this.onload=null;this.rel='stylesheet'"> 64 <noscript> 65 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"> 66 </noscript> 67 68 <!-- Custom CSS --> 69 <link rel="stylesheet" href="https://xtoscorm.com/assets/css/style.css?v=1.19"> 70 71
71<script type="application/ld+json"> 72 [ 73 { 74 "@context": "https://schema.org", 75 "@type": "WebPage", 76 "@id": "https://xtoscorm.com/pricing#webpage", 77 "url": "https://xtoscorm.com/pricing", 78 "name": "XtoSCORM Pricing | SCORM Conversion Credits and Plans", 79 "description": "Explore XtoSCORM pricing and choose the right SCORM conversion plan. Start with free daily credits or purchase one-time credits that never expire to convert PDF, PowerPoint and video files into LMS-ready SCORM packages.", 80 "isPartOf": { 81 "@type": "WebSite", 82 "name": "XtoSCORM", 83 "url": "https://xtoscorm.com/" 84 } 85 }, 86 { 87 "@context": "https://schema.org", 88 "@type": "Organization", 89 "@id": "https://xtoscorm.com/#organization", 90 "name": "XtoSCORM", 91 "url": "https://xtoscorm.com/", 92 "logo": { 93 "@type": "ImageObject", 94 "url": "https://xtoscorm.com/images/xtoscorm.png" 95 } 96 } 97] </script>
97 98 99 <link rel="preload" 100 href="https://cdn.kiprotect.com/klaro/v0.7/klaro.min.css" 101 as="style" 102 onload="this.onload=null;this.rel='stylesheet'"> 103 104<noscript> 105 <link rel="stylesheet" 106 href="https://cdn.kiprotect.com/klaro/v0.7/klaro.min.css"> 107</noscript> 108</head> 109 110<body> 111 112 <!-- NAVBAR --> 113 <nav class="navbar navbar-expand-lg bg-white border-bottom py-3 sticky-top" role="navigation" 114 aria-label="Main Navigation"> 115 <div class="container"> 116 117 <a class="navbar-brand" href="https://xtoscorm.com/"> 118 <img src="https://xtoscorm.com/images/xtoscorm.png" alt="Logo" style="width: auto; height: 25px;" /> 119 </a> 120 121 <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarContent" 122 aria-controls="navbarContent" aria-expanded="false" aria-label="Toggle navigation"> 123 <span class="navbar-toggler-icon"></span> 124 </button> 125 126 <div class="collapse navbar-collapse justify-content-end" id="navbarContent"> 127 <ul class="navbar-nav align-items-lg-center gap-lg-2"> 128 129 <li class="nav-item"> 130 <a class="nav-link" href="https://xtoscorm.com/pdf-to-scorm">PDF to SCORM</a> 131 </li> 132 133 <li class="nav-item"> 134 <a class="nav-link" href="https://xtoscorm.com/ppt-to-scorm">PPT to SCORM</a> 135 </li> 136 137 <li class="nav-item"> 138 <a class="nav-link" href="https://xtoscorm.com/video-to-scorm">Video to SCORM</a> 139 </li> 140 <li class="nav-item dropdown"> 141 <a class="nav-link dropdown-toggle "href="#"id="quizDropdown"role="button"data-bs-toggle="dropdown" 142 aria-expanded="false"> 143 SCORM Quiz Builder 144 </a> 145 146 <ul class="dropdown-menu dropdown-menu-end rounded-4 shadow border-0 p-2 mt-2" 147 aria-labelledby="quizDropdown" 148 style="min-width:280px;"> 149 <li> 150 <a class="dropdown-item rounded-3 py-2 d-flex align-items-start gap-3" 151 href="https://xtoscorm.com/ai-scorm-quiz-maker"> 152 <i class="fas fa-wand-magic-sparkles text-dark fs-4 mt-1" style="width:24px;"></i> 153 <div> 154 <div class="fw-semibold text-dark"> 155 AI SCORM Quiz Maker 156 </div> 157 <small class="text-secondary"> 158 Generate quizzes instantly with AI 159 </small> 160 </div> 161 </a> 162 </li> 163 164 165 <li> 166 <a class="dropdown-item rounded-3 py-2 d-flex align-items-start gap-3" 167 href="https://xtoscorm.com/scorm-quiz-maker"> 168 <i class="fas fa-list-check text-dark fs-4 mt-1" style="width:24px;"></i> 169 <div> 170 <div class="fw-semibold text-dark"> 171 SCORM Quiz Maker 172 </div> 173 <small class="text-secondary"> 174 Create standalone quizzes 175 </small> 176 </div> 177 </a> 178 </li> 179 180 <li> 181 <hr class="dropdown-divider my-2"> 182 </li> 183 <li> 184 <a class="dropdown-item rounded-3 py-2 d-flex align-items-start gap-3" 185 href="https://xtoscorm.com/add-quiz-to-pdf"> 186 <i class="fas fa-file-pdf text-dark fs-4 mt-1" style="width:24px;"></i> 187 <div> 188 <div class="fw-semibold text-dark">PDF + Quiz</div> 189 <small class="text-secondary"> 190 Add quizzes to your PDF 191 </small> 192 </div> 193 </a> 194 </li> 195 <li> 196 <a class="dropdown-item rounded-3 py-2 d-flex align-items-start gap-3" 197 href="https://xtoscorm.com/add-quiz-to-ppt"> 198 <i class="fas fa-file-powerpoint text-dark fs-4 mt-1" style="width:24px;"></i> 199 <div> 200 <div class="fw-semibold text-dark">PPT + Quiz</div> 201 <small class="text-secondary"> 202 Add quizzes to your PPT 203 </small> 204 </div> 205 </a> 206 </li> 207 <li> 208 <a class="dropdown-item rounded-3 py-2 d-flex align-items-start gap-3" 209 href="https://xtoscorm.com/add-quiz-to-video" > 210 <i class="fas fa-video text-dark fs-4 mt-1" style="width:24px;"></i> 211 <div> 212 <div class="fw-semibold text-dark">Video + Quiz</div> 213 <small class="text-secondary"> 214 Add quizzes to your videos 215 </small> 216 </div> 217 </a> 218 </li> 219 </ul> 220 </li> 221 <li class="nav-item" id="headerAuthArea"> 222 <a href="https://xtoscorm.com/contact-us" class="btn btn-dark me-2 d-none"> 223 Contact 224 </a> 225 <div class="header-auth-logged-in d-none"> 226 <!-- Dashboard (optional) --> 227 <a href="https://xtoscorm.com/admin/dashboard" class="btn btn-outline-dark me-2"> 228 Dashboard 229 </a> 230 231 <!-- Logout --> 232 <a href="https://xtoscorm.com/logout" class="btn btn-outline-dark d-none"> 233 Logout 234 </a> 235 </div> 236 237 <div class="header-auth-guest "> 238 <!-- Login --> 239 <a href="https://xtoscorm.com/login" class="btn btn-outline-dark me-2"> 240 Login 241 </a> 242 243 <!-- Register --> 244 <a href="https://xtoscorm.com/register" class="btn btn-dark"> 245 Sign Up 246 </a> 247 </div> 248 </li> 249 250 </ul> 251 </div> 252 </div> 253 </nav> 254 <main> 255<style> 256 .marketing-features .mb-3 { 257 font-size: 13px; 258 } 259</style> 260<section class="py-5" style="background:#f5f5f5;min-height:100vh;"> 261 262 <div class="container"> 263 264 <!-- Hero --> 265 266 <div class="text-center py-5"> 267 268 269 270 <h1 class="fw-bold display-4 mb-4"> 271 Pay only for what you need. 272 </h1> 273 274 <p class="text-muted col-lg-6 mx-auto"> 275 Purchase credits to continue converting your files instantly. 276 </p> 277 278 </div> 279 280 281 <!-- Pricing Cards --> 282 283 <!-- Shown while the single products fetch is in flight; keeps the 284 cards below hidden so nothing renders with placeholder numbers 285 or pops into the grid after the fact (which was shifting the 286 Enterprise card over once the Monthly Subscription card 287 un-hid itself). --> 288 <div class="text-center py-5" id="plansLoadingIndicator"> 289 <div class="spinner-border text-dark" role="status">
290 <span class="visually-hidden">Loadingâ¦</span> 291 </div> 292 <p class="text-muted small mt-3 mb-0">Loading plansâ¦</p> 293 </div> 294 295 <div class="row g-4 justify-content-center d-none" id="plansContainer"> 296 <div class="col-lg-3 col-md-6"> 297 <div class="card border-0 rounded-4 h-100 bg-white"> 298 <div class="card-body p-4 d-flex flex-column text-center"> 299 300 <h3 class="fw-bold">Free</h3> 301 <div class="display-4 fw-bold mt-3">$0</div> 302 303 <p class="text-muted small mb-4">5 Daily Conversion Credits </p> 304 305 <div class="border rounded-4 p-3 text-start mb-4 bg-light marketing-features"> 306 307 <div class="mb-3">â Low Processing Priority</div> 308 <div class="mb-3">â Limited Upload Size <i class="fa-regular fa-circle-question text-muted ms-1" 309 style="cursor:pointer;" 310 data-bs-toggle="popover" 311 data-bs-trigger="click" 312 data-bs-placement="right" 313 data-bs-html="true" 314 data-bs-title="Upload Limits" 315 data-bs-content=" 316 <table class="table table-sm table-bordered mb-0" style="
316min-width:200px;font-size:0.72rem;"> 317 <thead class="table-dark"> 318 <tr><th>Type</th><th>Free</th><th>Credit</th></tr> 319 </thead> 320 <tbody> 321 <tr><td>PDF</td><td>15 MB</td><td>60 MB</td></tr> 322 <tr><td>PPT</td><td>15 MB</td><td>60 MB</td></tr> 323 <tr><td>Video</td><td>50 MB</td><td>200 MB</td></tr> 324 </tbody> 325 </table>"></i></div> 326 <div class="mb-3">â No Sign Up Required</div> 327 <div class="mb-3">â Email Support</div> 328 329 <hr> 330 331 <div class="d-flex justify-content-between py-2"> 332 <span class="text-muted">Credits</span><strong>5/day</strong> 333 </div> 334 335 <hr class="my-1"> 336 337 <div class="d-flex justify-content-between py-2"> 338 <span class="text-muted">Cost / Credit </span><strong>0</strong> 339 </div> 340 341 342 343 </div> 344 345 <div class="mt-auto"> 346 <div class="border rounded-3 w-100 py-2 fw-semibold dark_btn"> 347 <div class="fw-bold">Free Plan</div> 348 </div> 349 350 </div> 351 </div> 352 </div> 353 </div> 354 <div class="col-lg-3 col-md-6" id="credit_pack"> 355 <div class="card border-0 rounded-4 h-100 bg-white"> 356 <div class="card-body p-4 d-flex flex-column text-center"> 357 358 <h3 class="fw-bold">Credit Package</h3> 359 <div class="display-4 fw-bold mt-3">$<span id="pack_cost">9</span></div> 360 361 <p class="text-muted small mb-2">One-time payment.<br />Credits never expire.</p> 362 <div class="px-1 mb-2"> 363 <div class="d-flex justify-content-between mb-1" id="sliderLabels" style="font-size:11px; color:#999;"></div> 364 <input type="range" class="form-range" id="packSlider" min="0" max="3" step="1" value="0"> 365 </div> 366 367 <div class="border rounded-4 p-3 text-start mb-4 bg-light marketing-features"> 368 369 <div class="mb-3">â High Processing Priority</div> 370 <div class="mb-3">â 4x More Upload Limit <i class="fa-regular fa-circle-question text-muted ms-1" 371 style="cursor:pointer;" 372 data-bs-toggle="popover" 373 data-bs-trigger="click" 374 data-bs-placement="right" 375 data-bs-html="true" 376 data-bs-title="Upload Limits" 377 data-bs-content=" 378 <table class="table table-sm table-bordered mb-0" style="
378min-width:200px;font-size:0.72rem;"> 379 <thead class="table-dark"> 380 <tr><th>Type</th><th>Free</th><th>Credit</th></tr> 381 </thead> 382 <tbody> 383 <tr><td>PDF</td><td>15 MB</td><td>60 MB</td></tr> 384 <tr><td>PPT</td><td>15 MB</td><td>60 MB</td></tr> 385 <tr><td>Video</td><td>50 MB</td><td>200 MB</td></tr> 386 </tbody> 387 </table>"></i></div> 388 <div class="mb-3">â Priority Support</div> 389 390 <hr> 391 <div class="d-flex justify-content-between py-2"> 392 <span class="text-muted">Credits</span><strong id="credit_count">20</strong> 393 </div> 394 395 <hr class="my-1"> 396 397 <div class="d-flex justify-content-between py-2"> 398 <span class="text-muted">Cost / Credit </span><strong id="credit_cost">0.45</strong> 399 </div> 400 401 402 403 </div> 404 405 406 <div class="mt-auto"> 407 <button id="buyCreditsBtn" 408 class="btn btn-dark w-100 py-2 fw-semibold dark_btn" 409 > 410 Buy Credits 411 </button> 412 </div> 413 </div> 414 </div> 415 </div> 416 417 <!-- Monthly Subscription card. Fully data-driven: every product 418 the API returns matching plan === 'subscription' AND 419 period === 'monthly' is treated as a monthly tier and 420 rendered here, with no hardcoded prices, credit amounts, 421 or team sizes. --> 422 <div class="col-lg-3 col-md-6 d-none" id="monthly_sub_pack"> 423 <div class="card border-0 rounded-4 h-100 bg-white"> 424 <div class="card-body p-4 d-flex flex-column text-center"> 425 426 <h3 class="fw-bold">Subscription</h3> 427 <div class="display-4 fw-bold mt-3"> 428 $<span id="monthly_sub_cost"></span><span class="text-muted" style="font-size:1rem;">/mo</span> 429 </div> 430 431 <p class="text-muted small mb-2">Billed monthly.<br />Cancel anytime.</p> 432 <div class="px-1 mb-2"> 433 <div class="d-flex justify-content-between mb-1" id="monthlySubSliderLabels" style="font-size:11px; color:#999;"></div> 434 <input type="range" class="form-range" id="monthlySubSlider" min="0" max="1" step="1" value="0"> 435 </div> 436 437 <div class="border rounded-4 p-3 text-start mb-4 bg-light marketing-features"> 438 <div class="mb-3 fw-bold " style="font-style: italic;"> Everything from Credit Packs, plus:</div> 439 <div class="mb-3 fw-bold">â <span id="monthly_sub_team">â</span> Users</div> 440 <div class="mb-3">â Shared Credit Pool<i class="fa-regular fa-circle-question text-muted ms-1" 441 style="cursor:pointer;" 442 data-bs-toggle="popover" 443 data-bs-trigger="click" 444 data-bs-placement="right" 445 data-bs-html="true" 446 data-bs-title="Shared Credit Pool" 447 data-bs-content=" 448 <div style="font-size:0.78rem;max-width:260px;"> 449 <p class="mb-2">All team members draw from a single credit pool instead of individual allowances.</p> 450 <ul class="mb-0 ps-3"> 451 <li>Credits refresh at the start of every billing cycle.</li> 452 <li>Any member on the team can use credits from the shared pool.</li> 453 <li>Unused credits do not roll over to the next cycle.</li> 454 <li>Admins can track who used what in Team Analytics.</li> 455 </ul> 456 </div>"></i></div> 457 <div class="mb-3">â Team Management & Analytics </div> 458 459 <hr> 460 <div class="d-flex justify-content-between py-2">
461 <span class="text-muted">Credits</span><strong id="monthly_sub_credit_count"></strong> 462 </div> 463 464 <hr class="my-1"> 465 466 <div class="d-flex justify-content-between py-2"> 467 <span class="text-muted">Cost / Credit</span><strong id="monthly_sub_cost_per_credit">0.00</strong> 468 </div> 469 470 </div> 471 472 <div class="mt-auto"> 473 <button id="buyMonthlySubBtn" 474 class="btn btn-dark w-100 py-2 fw-semibold dark_btn" 475 > 476 Subscribe 477 </button> 478 </div> 479 </div> 480 </div> 481 </div> 482 483 <!-- Yearly Subscription card. Static markup, values filled in 484 by loadSubscription() from the API product with 485 plan === 'subscription' AND period === 'yearly'. Only 486 rendered when the server flags showSubscription == 1. --> 487 488 <!-- Daily Subscription card. Same pattern as the Yearly card 489 above: static markup, values filled in by 490 loadDailySubscription() from the API product with 491 plan === 'subscription' AND period === 'daily'. Only 492 rendered when the server flags showSubscription == 2. --> 493 494 <div class="col-lg-3 col-md-6"> 495 <div class="card border-0 rounded-4 h-100 bg-white"> 496 <div class="card-body p-4 d-flex flex-column text-center"> 497 498 <h3 class="fw-bold">Enterprise</h3> 499 <div class="display-4 fw-bold mt-3 mb-4" style="font-size:32px;">Custom</div> 500 501 <p class="text-muted small mb-4">Custom plans for large-scale workloads.</p> 502 503 <div class="border rounded-4 p-3 text-start mb-4 bg-light marketing-features"> 504 505 <div class="mb-3">â MCP Server Access</div> 506 <div class="mb-3">â API Access</div> 507 <div class="mb-3">â SSO / SAML 2.0</div> 508 <div class="mb-3">â Custom Contracts & NDAs</div> 509 <div class="mb-3">â Dedicated + Integration Support</div> 510 511 <hr> 512 513 <div class="d-flex justify-content-between py-2"> 514 <span class="text-muted">Credits</span><strong>N/A</strong> 515 </div> 516 517 <hr class="my-1"> 518 519 <div class="d-flex justify-content-between py-2"> 520 <span class="text-muted">Cost / Credit </span><strong>N/A</strong> 521 </div> 522 </div> 523 524 <div class="mt-auto"> 525 <button class="btn btn-dark w-100 py-2 fw-semibold dark_btn" data-bs-toggle="modal"data-bs-target="#salesModal" > Contact Sales </button> 526 </div> 527 </div> 528 </div> 529 </div> 530 531 </div> 532 533 534 <div class="bg-white border rounded-4 p-5 mt-5"> 535 536 <div class="text-center mb-5"> 537 538 <h2 class="fw-bold mb-3"> 539 Why Buy Credits? 540 </h2> 541 542 <p class="text-muted col-lg-6 mx-auto"> 543 Everything you need to convert, package, and deliver SCORM-ready 544 learning content efficiently. 545 </p> 546 547 </div> 548 549 <div class="row text-center"> 550 <div class="col-md-3"> 551 <i class="fa-solid fa-cloud-arrow-up fa-2x mb-2"></i> 552 <h5 class="fw-semibold"> 553 4x More Upload Limits 554 <i class="fa-regular fa-circle-question text-muted ms-1" 555 style="cursor:pointer;" 556 data-bs-toggle="popover" 557 data-bs-trigger="click" 558 data-bs-placement="right" 559 data-bs-html="true" 560 data-bs-title="Upload Limits" 561 data-bs-content=" 562 <table class="table table-sm table-bordered mb-0" style="
562min-width:200px;font-size:0.72rem;"> 563 <thead class="table-dark"> 564 <tr><th>Type</th><th>Free</th><th>Credit</th></tr> 565 </thead> 566 <tbody> 567 <tr><td>PDF</td><td>15 MB</td><td>60 MB</td></tr> 568 <tr><td>PPT</td><td>15 MB</td><td>60 MB</td></tr> 569 <tr><td>Video</td><td>50 MB</td><td>200 MB</td></tr> 570 </tbody> 571 </table>"></i> 572 </h5> 573 <p class="text-muted small px-3"> 574 Convert large files into SCORM packages. 575 </p> 576 </div> 577 <div class="col-md-3"> 578 <i class="fa-solid fa-coins fa-2x mb-2"></i> 579 <h5 class="fw-semibold"> 580 Credits Never Expire 581 </h5> 582 <p class="text-muted small px-3"> 583 Purchase once and use credits whenever needed. 584 </p> 585 </div> 586 <div class="col-md-3"> 587 <i class="fa-solid fa-bolt fa-2x mb-2"></i> 588 <h5 class="fw-semibold"> 589 Faster Processing 590 </h5> 591 <p class="text-muted small px-3"> 592 Skip queues and generate SCORM packages more quickly. 593 </p> 594 </div> 595 <div class="col-md-3"> 596 <i class="fa-solid fa-headset fa-2x mb-2"></i> 597 <h5 class="fw-semibold"> 598 Priority Support 599 </h5> 600 <p class="text-muted small px-3"> 601 Get quick assistance and faster issue resolution. 602 </p> 603 </div> 604 </div> 605 606 </div> 607 608 609 <!-- Security Section --> 610 611 <div class="bg-white border rounded-4 p-5 mt-5"> 612 613 <div class="text-center"> 614 615 <h2 class="fw-bold mb-3"> 616 Secure Payments & Trusted Checkout 617 </h2> 618 619 <p class="text-muted col-lg-7 mx-auto mb-5"> 620 Your payments are securely processed using encrypted
621 payment infrastructure with enterprise-grade protection. 622 </p> 623 624 </div> 625 626 627 <div class="row text-center"> 628 629 <div class="col-md-4 mb-4"> 630 631 <div class="border rounded-4 p-4 h-100"> 632 633 <h5 class="fw-bold"> 634 PCI DSS Level 1 635 </h5> 636 637 <p class="small text-muted mb-0"> 638 Transactions are processed using PCI DSS 639 Level 1 compliant payment infrastructure. 640 </p> 641 642 </div> 643 644 </div> 645 646 647 <div class="col-md-4 mb-4"> 648 649 <div class="border rounded-4 p-4 h-100"> 650 651 <h5 class="fw-bold"> 652 Secure Encryption 653 </h5> 654 655 <p class="small text-muted mb-0"> 656 Checkout sessions and transactions are protected 657 with encrypted communication. 658 </p> 659 660 </div> 661 662 </div> 663 664 665 <div class="col-md-4 mb-4"> 666 667 <div class="border rounded-4 p-4 h-100"> 668 669 <h5 class="fw-bold"> 670 Trusted Payment Gateway 671 </h5> 672 673 <p class="small text-muted mb-0"> 674 Payments are handled securely through trusted 675 payment processing systems. 676 </p> 677 678 </div> 679 680 </div> 681 682 </div> 683 684 </div> 685 <!-- FAQ Section --> 686 687 <div class="bg-white border rounded-4 p-5 mt-5"> 688 689 <h5 class="fw-semibold text-center mb-5 h2"> 690 XtoSCORM Pricing â Frequently Asked Questions 691 </h5> 692 693 <div class="accordion accordion-flush shadow-sm rounded-3 bg-white p-3" 694 id="faqAccordion"> 695 696 <!-- FAQ 1 --> 697 698 <div class="accordion-item"> 699 700 <h5 class="accordion-header" id="heading1"> 701 702 <button class="accordion-button" 703 type="button" 704 data-bs-toggle="collapse" 705 data-bs-target="#faq1" 706 aria-expanded="true"> 707 708 How do XtoSCORM credits work? 709 710 </button> 711 712 </h5> 713 714 <div id="faq1" 715 class="accordion-collapse collapse show" 716 data-bs-parent="#faqAccordion"> 717 718 <div class="accordion-body"> 719 720 721 1 credit = 1 conversion. Credits are consumed each time you convert a file â whether it's a PDF, PowerPoint, or video â into a SCORM package. Standard conversions always cost 1 credit. 722 723 </div> 724 725 </div> 726 727 </div> 728 729 730 <!-- FAQ 2 --> 731 732 <div class="accordion-item"> 733 734 <h5 class="accordion-header" id="heading2"> 735 736 <button class="accordion-button collapsed" 737 type="button" 738 data-bs-toggle="collapse" 739 data-bs-target="#faq2"> 740 741 Do purchased credits expire? 742 743 </button> 744 745 </h5> 746 747 <div id="faq2" 748 class="accordion-collapse collapse" 749 data-bs-parent="#faqAccordion"> 750 751 <div class="accordion-body"> 752 753 No. Purchased credits remain available 754 permanently in your account and can be 755 used whenever you need them. 756 757 </div> 758 759 </div> 760 761 </div> 762 763 764 <!-- FAQ 3 --> 765 766 <div class="accordion-item"> 767 768 <h5 class="accordion-header" id="heading3"> 769 770 <button class="accordion-button collapsed" 771 type="button" 772 data-bs-toggle="collapse" 773 data-bs-target="#faq3"> 774
775 What content types can I convert? 776 777 </button> 778 779 </h5> 780 781 <div id="faq3" 782 class="accordion-collapse collapse" 783 data-bs-parent="#faqAccordion"> 784 785 <div class="accordion-body"> 786 787 XtoSCORM supports PDFs, presentations, 788 videos and learning materials that can 789 be packaged into SCORM-ready content. 790 791 </div> 792 793 </div> 794 795 </div> 796 797 798 <!-- FAQ 4 --> 799 800 <div class="accordion-item"> 801 802 <h5 class="accordion-header" id="heading4"> 803 804 <button class="accordion-button collapsed" 805 type="button" 806 data-bs-toggle="collapse" 807 data-bs-target="#faq4"> 808 809 Which LMS platforms are supported? 810 811 </button> 812 813 </h5> 814 815 <div id="faq4" 816 class="accordion-collapse collapse" 817 data-bs-parent="#faqAccordion"> 818 819 <div class="accordion-body"> 820 821 Generated SCORM packages work with 822 Moodle, Blackboard, TalentLMS and 823 most SCORM-compatible LMS systems. 824 825 </div> 826 827 </div> 828 829 </div> 830 831 832 <!-- FAQ 5 --> 833 834 <div class="accordion-item"> 835 836 <h5 class="accordion-header" id="heading5"> 837 838 <button class="accordion-button collapsed" 839 type="button" 840 data-bs-toggle="collapse" 841 data-bs-target="#faq5"> 842 843 Is payment secure? 844 845 </button> 846 847 </h5> 848 849 <div id="faq5" 850 class="accordion-collapse collapse" 851 data-bs-parent="#faqAccordion"> 852 853 <div class="accordion-body"> 854 855 Payments are processed using encrypted
856 secure payment infrastructure with 857 trusted transaction protection systems. 858 859 </div> 860 861 </div> 862 863 </div> 864 865 866 <!-- FAQ 6 --> 867 868 <div class="accordion-item"> 869 870 <h5 class="accordion-header" id="heading6"> 871 872 <button class="accordion-button collapsed" 873 type="button" 874 data-bs-toggle="collapse" 875 data-bs-target="#faq6"> 876 877 Do you offer enterprise plans? 878 879 </button> 880 881 </h5> 882 883 <div id="faq6" 884 class="accordion-collapse collapse" 885 data-bs-parent="#faqAccordion"> 886 887 <div class="accordion-body"> 888 889 Yes. Enterprise plans include custom 890 pricing, larger usage limits and 891 dedicated support for teams. 892 893 </div> 894 895 </div> 896 897 </div> 898 899 900 <!-- FAQ 7 --> 901 902 <div class="accordion-item"> 903 904 <h5 class="accordion-header" id="heading7"> 905 906 <button class="accordion-button collapsed" 907 type="button" 908 data-bs-toggle="collapse" 909 data-bs-target="#faq7"> 910 911 How is the Subscription different from Credit Packs? 912 913 </button> 914 915 </h5> 916 917 <div id="faq7" 918 class="accordion-collapse collapse" 919 data-bs-parent="#faqAccordion"> 920 921 <div class="accordion-body"> 922 923 Subscription plans include everything in a 924 Credit Package, plus a recurring credit 925 allowance, multiple team member seats, a shared 926 credit pool, and Team Management & Analytics. 927 They're billed on a recurring cycle (daily, 928 monthly, or yearly depending on the tier) and 929 can be cancelled anytime, while Credit Packs are 930 a one-time purchase of credits that never expire. 931 932 </div> 933 934 </div> 935 936 </div> 937 938 939 <!-- FAQ 8 --> 940 941 <div class="accordion-item"> 942 943 <h5 class="accordion-header" id="heading8"> 944 945 <button class="accordion-button collapsed" 946 type="button" 947 data-bs-toggle="collapse" 948 data-bs-target="#faq8"> 949 950 What is the Shared Credit Pool? 951 952 </button> 953 954 </h5> 955 956 <div id="faq8" 957 class="accordion-collapse collapse" 958 data-bs-parent="#faqAccordion"> 959 960 <div class="accordion-body"> 961 962 Instead of assigning separate credit allowances to 963 each team member, subscription plans draw from one 964 shared pool. Any member on the team can use credits 965 from that pool, it refreshes each billing cycle, 966 and unused credits do not roll over to the next 967 cycle. 968 969 </div> 970 971 </div> 972 973 </div> 974 975 976 <!-- FAQ 9 --> 977 978 <div class="accordion-item"> 979 980 <h5 class="accordion-header" id="heading9"> 981 982 <button class="accordion-button collapsed" 983 type="button" 984 data-bs-toggle="collapse" 985 data-bs-target="#faq9"> 986 987 What does Team Management & Analytics include? 988 989 </button> 990 991 </h5> 992 993 <div id="faq9" 994 class="accordion-collapse collapse" 995 data-bs-parent="#faqAccordion"> 996 997 <div class="accordion-body"> 998 999 Team admins can invite and remove members, assign 1000 roles, and view usage analytics that break down 1001 credit consumption and conversions by member, file 1002 type, and time period â making it easier to 1003 monitor usage and plan future credit needs. 1004 1005 </div> 1006 1007 </div> 1008 1009 </div> 1010 1011 1012 <!-- FAQ 10 --> 1013 1014 <div class="accordion-item"> 1015 1016 <h5 class="accordion-header" id="heading10"> 1017 1018 <button class="accordion-button collapsed" 1019 type="button" 1020 data-bs-toggle="collapse" 1021 data-bs-target="#faq10"> 1022 1023 Can I cancel or change my subscription plan? 1024 1025 </button> 1026 1027 </h5> 1028 1029 <div id="faq10" 1030 class="accordion-collapse collapse" 1031 data-bs-parent="#faqAccordion"> 1032 1033 <div class="accordion-body"> 1034 1035 Yes. Subscriptions can be cancelled at any 1036 time and remain active until the end of the current 1037 billing cycle. You can also move between subscription 1038 tiers to match your team's size and usage. 1039 1040 </div> 1041 1042 </div> 1043 1044 </div> 1045 1046 </div> 1047 1048 </div> 1049 </div> 1050 1051</section> 1052<!-- SALES CONTACT MODAL --> 1053<div class="modal fade" id="salesModal" tabindex="-1"> 1054 <div class="modal-dialog"> 1055 <form id="salesContactForm" class="modal-content" data-url="https://xtoscorm.com/sales/contact"> 1056 <input type="hidden" name="csrf_test_name" value="92104aaa044bd7b97fab9a39a048b0c8"> <div class="modal-header"> 1057 <h5 class="modal-title">Contact Sales</h5> 1058 <button type="button" class="btn-close" data-bs-dismiss="modal"></button> 1059 </div> 1060 <div class="modal-body"> 1061 <p class="text-muted small mb-3"> 1062 Tell us about your requirements and our sales team will get back to you. 1063 </p> 1064 <div id="salesSuccessMsg" class="alert alert-success d-none"> 1065 â Your request has been submitted successfully. 1066 </div> 1067 <div id="salesErrorMsg" class="alert alert-danger d-none"> </div> 1068 1069 <input type="text" name="name" class="form-control mb-2" placeholder="Name" required> 1070 <input type="email" name="email" class="form-control mb-2" placeholder="Business Email" required> 1071 <input type="text" name="company" class="form-control mb-2" placeholder="Company Name"> 1072 <textarea name="message" class="form-control" rows="4" placeholder="Tell us about your requirements" required></textarea> 1073 </div> 1074 <div class="modal-footer"> 1075 <button type="button" class="btn btn-secondary me-auto" data-bs-dismiss="modal"> Close </button> 1076 <button type="submit" id="salesContactSubmitBtn" class="btn btn-dark">
1077 <span class="btn-text"> Send </span> 1078 <span class="btn-loader d-none"> 1079 <span class="spinner-border spinner-border-sm"></span> 1080 Sending... 1081 </span> 1082 </button> 1083 </div> 1084 </form> 1085 </div> 1086</div>
1087<script> 1088 window.API_PRODUCTS = 1089 "https://xtoscorm.com/billing/products"; 1090 1091 window.CHECKOUT_API = 1092 "https://xtoscorm.com/billing/create-checkout"; 1093 1094 window.LOGIN_URL = 1095 "https://xtoscorm.com/signup"; 1096 1097 window.TOKEN = 1098 ""; 1099 1100 window.IS_LOGGED_IN = 1101 false; 1102 1103 1104 window.buyCredits = 1105 async function(productCode, productCredits) { 1106 1107 if (!window.IS_LOGGED_IN) { 1108 1109 window.location.href = 1110 `${window.LOGIN_URL}?buy=${productCode}`; 1111 1112 return; 1113 } 1114 1115 try { 1116 1117 const res = 1118 await fetch( 1119 window.CHECKOUT_API, { 1120 method: 'POST', 1121 1122 headers: { 1123 'Content-Type': 'application/json', 1124 1125 Authorization: 'Bearer ' + 1126 window.TOKEN 1127 }, 1128 1129 body: JSON.stringify({ 1130 1131 product_code: productCode, 1132 product_credits: productCredits 1133 1134 }) 1135 1136 } 1137 ); 1138 1139 const data = 1140 await res.json(); 1141 1142 if (data.checkout_url) { 1143 1144 window.location.href = 1145 data.checkout_url; 1146 1147 } else { 1148 1149 alert( 1150 data.message || 1151 'Unable to start payment' 1152 ); 1153 1154 } 1155 1156 } catch (e) { 1157 1158 console.log(e); 1159 1160 alert( 1161 'Payment failed' 1162 ); 1163 1164 } 1165 1166 } 1167 1168 1169 1170 // A product is a MONTHLY subscription tier based on API data: 1171 // plan === 'subscription' AND period === 'monthly'. period is the 1172 // source of truth for cadence (NOT is_recurring, since a yearly or 1173 // daily plan can also have is_recurring === true). Any monthly tier 1174 // the API returns â new prices, new credit amounts, new team sizes, 1175 // or additional tiers beyond two â shows up automatically without any 1176 // code change here. 1177 function isMonthlySubProduct(p) { 1178 return p.plan?.toLowerCase() === 'subscription' && p.period?.toLowerCase() === 'monthly'; 1179 } 1180 1181 // --- Single shared fetch --------------------------------------------- 1182 // All plan cards (one-time credit packs, monthly subscription, yearly 1183 // subscription, daily subscription) need the same /billing/products 1184 // payload. Instead of each one calling fetch() on its own, we fetch 1185 // once, cache the promise, and let every consumer await the same 1186 // result. If the first call fails, the cache is cleared so a later 1187 // retry is possible instead of everything being stuck on a rejected 1188 // promise forever. 1189 let productsPromise = null; 1190 1191 function fetchProducts() { 1192 if (!productsPromise) { 1193 productsPromise = fetch(window.API_PRODUCTS) 1194 .then(res => res.json()) 1195 .catch(err => { 1196 productsPromise = null; // allow retry on next call 1197 throw err; 1198 }); 1199 } 1200 return productsPromise; 1201 } 1202 1203 function loadPlans(products) { 1204 try { 1205 const plans = [...products] 1206 .filter(p => p.plan?.toLowerCase() !== 'subscription'); 1207 if (!plans.length) return; 1208 1209 // Sort by price ascending so slider goes low â high 1210 plans.sort((a, b) => a.price - b.price); 1211 1212 // Build slider labels 1213 const labels = document.getElementById('sliderLabels'); 1214 labels.innerHTML = plans.map(p => `<span>${p.plan}</span>`).join(''); 1215 1216 // Set slider max to match plan count 1217 const slider = document.getElementById('packSlider'); 1218 slider.min = 0; 1219 slider.max = plans.length - 1; 1220 slider.value = 0; 1221 1222 function applyPlan(idx) { 1223 const p = plans[idx]; 1224 const baseCostPerCredit = plans[0].price / plans[0].credits; 1225 const thisCostPerCredit = p.price / p.credits; 1226 const savingPct = Math.round((1 - thisCostPerCredit / baseCostPerCredit) * 100); 1227 1228 document.getElementById('pack_cost').textContent = p.price; 1229 document.getElementById('credit_count').textContent = p.credits; 1230 1231 const costEl = document.getElementById('credit_cost'); 1232 costEl.innerHTML = 1233 (savingPct > 0 ? 1234 ` <span class="badge bg-success ms-1" style="font-size:0.7rem;margin-right: 5px;background-color:#45c389!important;">Save ${savingPct}%</span>` : 1235 '') + thisCostPerCredit.toFixed(2); 1236 1237 document.getElementById('buyCreditsBtn').onclick = () => buyCredits(p.product_code, p.credits); 1238 } 1239 1240 slider.addEventListener('input', () => applyPlan(+slider.value)); 1241 applyPlan(0); 1242 1243 } catch (e) { 1244 document.getElementById('plansContainer').innerHTML = ` 1245 <div class="col-12"> 1246 <div class="alert bg-white border text-center">Unable to load plans</div> 1247 </div>`; 1248 } 1249 } 1250 1251 // MONTHLY SUBSCRIPTION card â fully dynamic. Every product matching 1252 // isMonthlySubProduct() (any count, any price, any credits, any team 1253 // size) is pulled straight from the API response and rendered; nothing 1254 // about a specific tier is hardcoded in this file. 1255 function loadMonthlySubscription(allProducts) { 1256 try { 1257 const monthlyPlans = allProducts 1258 .filter(isMonthlySubProduct) 1259 .sort((a, b) => a.price - b.price); 1260 1261 const card = document.getElementById('monthly_sub_pack'); 1262 if (!monthlyPlans.length) { 1263 // Nothing matched isMonthlySubProduct(). Log what the API 1264 // actually returned so a mismatch (wrong `plan` value, or 1265 // `period` missing/not "monthly") is visible in the console 1266 // instead of just a hidden card. 1267 console.warn( 1268 'Monthly subscription card hidden: no product matched isMonthlySubProduct(). ' + 1269 'Products with plan === "subscription":', 1270 allProducts.filter(p => p.plan?.toLowerCase() === 'subscription') 1271 ); 1272 card.classList.add('d-none'); 1273 return; 1274 } 1275 card.classList.remove('d-none'); 1276 1277 const labels = document.getElementById('monthlySubSliderLabels'); 1278 labels.innerHTML = monthlyPlans.map(p => `<span>$${p.price}</span>`).join(''); 1279 1280 const slider = document.getElementById('monthlySubSlider'); 1281 slider.min = 0; 1282 slider.max = monthlyPlans.length - 1; 1283 slider.value = 0; 1284 1285 function applyMonthlyPlan(idx) { 1286 const p = monthlyPlans[idx]; 1287 // Team size comes straight from the API's `member` field â 1288 // no local price â team-size map anymore. 1289 const team = p.member ?? 'â'; 1290 const costPerCredit = p.credits > 0 ? Number(p.price) / Number(p.credits) : 0; 1291 const baseCostPerCredit = monthlyPlans[0].credits > 0 ? Number(monthlyPlans[0].price) / Number(monthlyPlans[0].credits) : 0; 1292 const savingPct = baseCostPerCredit > 0 ? Math.round((1 - costPerCredit / baseCostPerCredit) * 100) : 0; 1293 const costElement = document.getElementById('monthly_sub_cost_per_credit'); 1294 1295 document.getElementById('monthly_sub_cost').textContent = p.price; 1296 document.getElementById('monthly_sub_team').textContent = team; 1297 document.getElementById('monthly_sub_credit_count').textContent = `${p.credits}/mo`; 1298 1299 costElement.innerHTML = 1300 (savingPct > 0 1301 ? ` <span class="badge bg-success ms-1" style="font-size:0.7rem;margin-right:5px;background-color:#45c389!important;">Save ${savingPct}%</span>` 1302 : '') + 1303 costPerCredit.toFixed(2); 1304 1305 document.getElementById('buyMonthlySubBtn').onclick = () => buyCredits(p.product_code, p.credits); 1306 } 1307 1308 slider.addEventListener('input', () => applyMonthlyPlan(+slider.value)); 1309 applyMonthlyPlan(0); 1310 1311 } catch (e) { 1312 console.error('Unable to load monthly subscription plans', e); 1313 } 1314 } 1315 1316 // YEARLY SUBSCRIPTION card â only in the DOM when showSubscription == 1 1317 // (server-rendered PHP if-block). Finds the product with 1318 // plan === 'subscription' AND period === 'yearly' and fills the static 1319 // card in place, same pattern as loadDailySubscription() below. 1320 function loadSubscription(products) { 1321 try { 1322 const subscription = products.find( 1323 p => p.plan?.toLowerCase() === 'subscription' && p.period?.toLowerCase() === 'yearly' 1324 ); 1325 1326 if (!subscription) return; 1327 1328 // These elements only exist in the DOM when showSubscription 1329 // == 1 on the server. If the card isn't rendered, skip quietly 1330 // instead of throwing. 1331 const costEl = document.getElementById('sub_pack_cost');
1332 const buyBtn = document.getElementById('buySubscriptionBtn'); 1333 if (!costEl || !buyBtn) return; 1334 1335 const creditsEl = document.getElementById('sub_pack_credits'); 1336 const costPerCreditEl = document.getElementById('sub_pack_cost_per_credit'); 1337 1338 costEl.textContent = subscription.price; 1339 if (creditsEl) creditsEl.textContent = `${subscription.credits}/year`; 1340 if (costPerCreditEl && subscription.credits > 0) { 1341 costPerCreditEl.textContent = `$${(Number(subscription.price) / Number(subscription.credits)).toFixed(2)}`; 1342 } 1343 1344 buyBtn.onclick = () => 1345 buyCredits(subscription.product_code, subscription.credits); 1346 1347 } catch (e) { 1348 console.error('Unable to load subscription plan', e); 1349 } 1350 } 1351 1352 // DAILY SUBSCRIPTION card â only in the DOM when showSubscription == 2 1353 // (server-rendered PHP if-block). Finds the product with 1354 // plan === 'subscription' AND period === 'daily' and fills the static 1355 // card in place. No slider: like the yearly card, this assumes one 1356 // daily tier; if the API ever returns more than one daily product, 1357 // the first (lowest price) one found is used. 1358 function loadDailySubscription(products) { 1359 try { 1360 const dailyPlans = products 1361 .filter(p => p.plan?.toLowerCase() === 'subscription' && p.period?.toLowerCase() === 'daily') 1362 .sort((a, b) => a.price - b.price); 1363 1364 const subscription = dailyPlans[0]; 1365 if (!subscription) return; 1366 1367 // These elements only exist in the DOM when showSubscription 1368 // == 2 on the server. If the card isn't rendered, skip quietly 1369 // instead of throwing. 1370 const costEl = document.getElementById('daily_sub_cost'); 1371 const buyBtn = document.getElementById('buyDailySubBtn'); 1372 if (!costEl || !buyBtn) return; 1373 1374 const teamEl = document.getElementById('daily_sub_team'); 1375 const creditsEl = document.getElementById('daily_sub_credit_count'); 1376 const costPerCreditEl = document.getElementById('daily_sub_cost_per_credit'); 1377 1378 costEl.textContent = subscription.price; 1379 if (teamEl) teamEl.textContent = subscription.member ?? 'â'; 1380 if (creditsEl) creditsEl.textContent = `${subscription.credits}/day`; 1381 if (costPerCreditEl && subscription.credits > 0) { 1382 costPerCreditEl.textContent = (Number(subscription.price) / Number(subscription.credits)).toFixed(2); 1383 } 1384 1385 buyBtn.onclick = () => 1386 buyCredits(subscription.product_code, subscription.credits); 1387 1388 } catch (e) { 1389 console.error('Unable to load daily subscription plan', e); 1390 } 1391 } 1392 1393 // --- Single init: one fetch, all cards render from it ----------------- 1394 // Everything (credit package numbers, monthly subscription card 1395 // visibility, yearly subscription price, daily subscription price) is 1396 // computed first while the row stays hidden behind the spinner. Only 1397 // once every card is fully populated do we swap the spinner out for 1398 // the row, so it appears complete in one paint instead of assembling 1399 // itself in front of the user. 1400 (async function initPlans() { 1401 const loadingEl = document.getElementById('plansLoadingIndicator'); 1402 const containerEl = document.getElementById('plansContainer'); 1403 1404 try { 1405 const data = await fetchProducts(); 1406 const products = data.products || []; 1407 1408 loadPlans(products); 1409 loadMonthlySubscription(products); 1410 loadSubscription(products); 1411 loadDailySubscription(products); 1412 1413 } catch (e) { 1414 containerEl.innerHTML = ` 1415 <div class="col-12"> 1416 <div class="alert bg-white border text-center">Unable to load plans</div> 1417 </div>`; 1418 } finally { 1419 loadingEl.classList.add('d-none'); 1420 containerEl.classList.remove('d-none'); 1421 } 1422 })(); 1423 1424 const salesForm = document.getElementById('salesContactForm'); 1425 if (salesForm) { 1426 salesForm.addEventListener('submit', 1427 async function(e) { 1428 e.preventDefault(); 1429 const submitBtn = document.getElementById('salesContactSubmitBtn'); 1430 const btnText = submitBtn.querySelector('.btn-text'); 1431 const btnLoader = submitBtn.querySelector('.btn-loader'); 1432 const successBox = document.getElementById('salesSuccessMsg'); 1433 const errorBox = document.getElementById('salesErrorMsg'); 1434 1435 successBox.classList.add('d-none'); 1436 errorBox.classList.add('d-none'); 1437 1438 submitBtn.disabled = true; 1439 1440 btnText.classList.add('d-none'); 1441 btnLoader.classList.remove('d-none'); 1442 try { 1443 const formData = new FormData(this); 1444 const response = 1445 await fetch( 1446 this.dataset.url, { 1447 method: 'POST', 1448 body: formData 1449 } 1450 ); 1451 const result = await response.json(); 1452 if (result.success) { 1453 successBox.textContent = result.message; 1454 successBox.classList.remove('d-none'); 1455 this.reset(); 1456 } else { 1457 errorBox.textContent = result.message; 1458 errorBox.classList.remove('d-none'); 1459 } 1460 } catch (error) { 1461 errorBox.textContent = 'Something went wrong.'; 1462 errorBox.classList.remove('d-none'); 1463 console.error(error); 1464 } finally { 1465 submitBtn.disabled = false;
1466 btnText.classList.remove('d-none'); 1467 btnLoader.classList.add('d-none'); 1468 } 1469 } 1470 ); 1471 } 1472 1473 document.addEventListener('DOMContentLoaded', function() { 1474 document.querySelectorAll('[data-bs-toggle="popover"]').forEach(function(el) { 1475 new bootstrap.Popover(el, { 1476 sanitize: false 1477 }); 1478 }); 1479 1480 // Close popover when clicking outside 1481 document.addEventListener('click', function(e) { 1482 if (!e.target.closest('[data-bs-toggle="popover"]')) { 1483 document.querySelectorAll('[data-bs-toggle="popover"]').forEach(function(el) { 1484 bootstrap.Popover.getInstance(el)?.hide(); 1485 }); 1486 } 1487 }); 1488 }); 1489</script>
1489 1490 1491<!-- SEO ENHANCED FOOTER --> 1492<footer style="background-color:black;" class="text-light pt-5 pb-3"> 1493 <div class="container"> 1494 <div class="row text-center text-md-start"> 1495 <!-- About --> 1496 <div class="col-lg-3 col-md-6 mb-4"> 1497 <h5 class="fw-semibold h6">XtoSCORM: All-in-one SCORM Converter</h5> 1498 <p class="small text-light" style="padding-right:20px;"> 1499 X to SCORM Converter is an online tool that converts 1500 PDF, PowerPoint (PPT), and Video files into 1501 SCORM 1.2 and SCORM 2004 compliant LMS-ready packages. 1502 Easily upload and generate trackable eLearning content. 1503 </p> 1504 </div> 1505 1506 <!-- SCORM Conversion Tools --> 1507 <div class="col-lg-2 col-md-6 mb-4"> 1508 <h6 class="fw-semibold">SCORM Conversion Tools</h6> 1509 <ul class="list-unstyled small"> 1510 <li> 1511 <a href="https://xtoscorm.com/pdf-to-scorm" 1512 class="text-light text-decoration-none footer-link"> 1513 PDF to SCORM Converter 1514 </a> 1515 </li> 1516 <li> 1517 <a href="https://xtoscorm.com/ppt-to-scorm" 1518 class="text-light text-decoration-none footer-link"> 1519 PPT to SCORM Converter 1520 </a> 1521 </li> 1522 <li> 1523 <a href="https://xtoscorm.com/video-to-scorm" 1524 class="text-light text-decoration-none footer-link"> 1525 Video to SCORM Converter 1526 </a> 1527 </li> 1528 <li> 1529 <a href="https://xtoscorm.com/scorm-quiz-maker" 1530 class="text-light text-decoration-none footer-link"> 1531 SCORM Quiz Maker 1532 </a> 1533 </li> 1534 <li> 1535 <a href="https://xtoscorm.com/scorm-viewer" 1536 class="text-light text-decoration-none footer-link"> 1537 Free SCORM Player 1538 </a> 1539 </li> 1540 </ul> 1541 </div> 1542 1543 <!-- SCORM Quiz Tools --> 1544 <div class="col-lg-2 col-md-6 mb-4"> 1545 <h6 class="fw-semibold">SCORM Quiz Tools</h6> 1546 <ul class="list-unstyled small"> 1547 <li> 1548 <a href="https://xtoscorm.com/ai-scorm-quiz-maker" 1549 class="text-light text-decoration-none footer-link"> 1550 AI SCORM Quiz Maker 1551 </a> 1552 </li> 1553 1554 <li> 1555 <a href="https://xtoscorm.com/scorm-quiz-maker" 1556 class="text-light text-decoration-none footer-link"> 1557 SCORM Quiz Maker 1558 </a> 1559 </li> 1560 1561 <li> 1562 <a href="https://xtoscorm.com/add-quiz-to-pdf" 1563 class="text-light text-decoration-none footer-link"> 1564 PDF + Quiz 1565 </a> 1566 </li> 1567 1568 <li> 1569 <a href="https://xtoscorm.com/add-quiz-to-ppt" 1570 class="text-light text-decoration-none footer-link"> 1571 PPT + Quiz 1572 </a> 1573 </li> 1574 1575 <li> 1576 <a href="https://xtoscorm.com/add-quiz-to-video" 1577 class="text-light text-decoration-none footer-link"> 1578 Video + Quiz 1579 </a> 1580 </li> 1581 1582 </ul> 1583 </div> 1584 1585 <!-- Useful Links --> 1586 <div class="col-lg-2 col-md-6 mb-4"> 1587 <h6 class="fw-semibold">Useful Links</h6> 1588 <ul class="list-unstyled small"> 1589 <li> 1590 <a href="https://xtoscorm.com/pricing" 1591 class="text-light text-decoration-none footer-link"> 1592 Pricing 1593 </a> 1594 </li> 1595 1596 <li> 1597 <a href="https://xtoscorm.com/blog" 1598 class="text-light text-decoration-none footer-link"> 1599 Blog 1600 </a> 1601 </li> 1602 1603 <li> 1604 <a href="https://chromewebstore.google.com/detail/xtoscorm-pdf-ppt-video-to/fgkhblhfpiabicipahgdcghapmamkbpe" 1605 class="text-light text-decoration-none footer-link" 1606 target="_blank"> 1607 Google Chrome Extension 1608 </a> 1609 </li> 1610 1611 <li> 1612 <a href="https://microsoftedge.microsoft.com/addons/detail/ljfmoalajppmbkgfhjibmkmbmanledfd" 1613 class="text-light text-decoration-none footer-link" 1614 target="_blank"> 1615 Microsoft Edge Extension 1616 </a> 1617 </li> 1618 1619 <li> 1620 <a href="#" 1621 class="text-light text-decoration-none footer-link" 1622 type="button" 1623 data-bs-toggle="modal" 1624 data-bs-target="#contactModal"> 1625 Report an Issue 1626 </a> 1627 </li> 1628 </ul> 1629 </div> 1630 <!-- Company & Support --> 1631 <div class="col-lg-3 col-md-6 mb-4"> 1632 <h6 class="fw-semibold">Company & Support</h6> 1633 <ul class="list-unstyled small"> 1634 <li> 1635 <a href="https://xtoscorm.com/about-us" 1636 class="text-light text-decoration-none footer-link"> 1637 About Us 1638 </a> 1639 </li> 1640 1641 <li> 1642 <a href="https://xtoscorm.com/privacy-policy" 1643 class="text-light text-decoration-none footer-link"> 1644 Privacy Policy 1645 </a> 1646 </li> 1647 1648 <li> 1649 <a href="https://xtoscorm.com/terms-and-conditions" 1650 class="text-light text-decoration-none footer-link"> 1651 Terms & Conditions 1652 </a> 1653 </li> 1654 1655 <li> 1656 <a href="https://xtoscorm.com/contact-us" 1657 class="text-light text-decoration-none footer-link"> 1658 Contact 1659 </a> 1660 </li> 1661 1662 <li> 1663 <a href="#" 1664 onclick="klaro.show(); return false;" 1665 class="text-light text-decoration-none footer-link"> 1666 Cookie Consent Settings 1667 </a> 1668 </li> 1669 </ul> 1670 </div> 1671 1672 </div> 1673 <hr class="border-secondary"> 1674 1675 <!-- Bottom --> 1676 <div class="d-md-flex justify-content-between align-items-center text-center text-md-start small text-light"> 1677 1678 <div> 1679 © 2026 xtoscorm.com. All rights reserved. 1680 </div> 1681 1682 <div class="mt-2 mt-md-0"> 1683 Powered by 1684 <a href="https://justaddwater.in" 1685 target="_blank" 1686 class="text-light text-decoration-none fw-semibold"> 1687 JUSTADDWATER 1688 </a> 1689 </div> 1690 1691 </div> 1692 </div> 1693</footer> 1694 1695<!-- CONTACT MODAL --> 1696<div class="modal fade" id="contactModal"> 1697 <div class="modal-dialog"> 1698 <form id="contactForm" class="modal-content" data-email_url="https://xtoscorm.com/email-send"> 1699 <input type="hidden" name="csrf_test_name" value="92104aaa044bd7b97fab9a39a048b0c8"> <div class="modal-header"> 1700 <h5>Report an Issue</h5> 1701 <button class="btn-close" data-bs-dismiss="modal"></button> 1702 </div> 1703 <div class="modal-body"> 1704 <p class="text-muted small mb-3"> 1705 Please fill out the form below and weâll respond as soon as possible. 1706 </p> 1707 1708 <div id="contactSuccessMsg" class="alert alert-success d-none"> 1709 â Your message has been sent successfully. Weâll get back to you shortly. 1710 </div> 1711 1712 <!-- â ERROR MESSAGE --> 1713 <div id="contactErrorMsg" class="alert alert-danger d-none"></div> 1714 <input type="text" name="name" class="form-control mb-2" placeholder="Name" required> 1715 <input type="email" name="email" class="form-control mb-2" placeholder="Email" required> 1716 <textarea name="message" class="form-control" placeholder="Message" required></textarea> 1717 </div> 1718 <div class="modal-footer"> 1719 <button type="button" class="btn btn-secondary me-auto" data-bs-dismiss="modal"> 1720 Close 1721 </button> 1722 <button type="submit" id="contactForm_submitBtn" class="btn btn-dark">
1723 <span class="btn-text"> 1724 <i class="bi bi-send"></i> Send 1725 </span> 1726 <span class="btn-loader d-none"> 1727 <span class="spinner-border spinner-border-sm"></span> 1728 Sending... 1729 </span> 1730 </button> 1731 </div> 1732 </form> 1733 </div> 1734</div> 1735 1736<!-- Scripts -->
1737<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
vendor: 1 bytes, line 1737
1737
1738<script defer src="https://xtoscorm.com/assets/js/custom.js?v=9.34"></script>
vendor: 1 bytes, line 1738
1738
1739<script> 1740 window.klaroConfig = { 1741 version: 1, 1742 translations: { 1743 zz: { 1744 privacyPolicyUrl: "https://xtoscorm.com/privacy-policy", 1745 }, 1746 1747 en: { 1748 consentNotice: { 1749 description: 1750 'We use essential cookies to ensure XtoSCORM works securely and reliably. With your permission, we also use analytics cookies to understand how our website is used and improve your experience. You can manage your preferences at any time.' 1751 }, 1752 consentModal: { 1753 title: 'Cookie Preferences', 1754 description: 1755 'XtoSCORM uses essential cookies to provide core functionality, maintain security, and remember your preferences. Analytics cookies help us understand website usage and improve our services. You can choose which cookies to allow below.' 1756 }, 1757 purposes: { 1758 necessary: 'Necessary', 1759 analytics: 'Analytics' 1760 }, 1761 learnMore: 'Manage Preferences', 1762 decline: 'Reject All', 1763 ok: 'Accept All' 1764 } 1765 }, 1766 elementID: 'klaro', 1767 storageMethod: 'cookie', 1768 storageName: 'klaro', 1769 acceptAll: true, 1770 mustConsent: false, 1771 noticeAsModal: false, 1772 hideDeclineAll: false, 1773 services: [ 1774 { 1775 name: 'essential', 1776 title: 'Essential Cookies', 1777 description: 'Required for sessions, security, fraud prevention, storing your cookie preferences, and processing technical information such as IP addresses necessary for the operation of the website.', 1778 purposes: ['necessary'], 1779 required: true, 1780 cookies: [ 1781 'ci_session', 1782 'klaro' 1783 ] 1784 }, 1785 { 1786 name: 'google-analytics', 1787 title: 'Google Analytics', 1788 purposes: ['analytics'], 1789 cookies: [/^_ga/, /^_gid/, /^_gat/], 1790 callback: function(consent) { 1791 if (consent) { 1792 loadGoogleAnalytics(); 1793 } 1794 } 1795 } 1796 ] 1797 }; 1798 1799 function loadGoogleAnalytics() { 1800 console.log("Call Analytics"); 1801 if (window.gaLoaded) return; 1802 window.gaLoaded = true; 1803 const script = document.createElement('script'); 1804 script.src = 'https://www.googletagmanager.com/gtag/js?id=G-Z3M1TMDN34'; 1805 script.async = true; 1806 document.head.appendChild(script); 1807 1808 window.dataLayer = window.dataLayer || []; 1809 1810 function gtag() { 1811 dataLayer.push(arguments); 1812 } 1813 window.gtag = gtag; 1814 gtag('js', new Date()); 1815 gtag('config', 'G-Z3M1TMDN34'); 1816 } 1817 1818</script>
vendor: 1 bytes, line 1818
1818
1819<script defer data-config="klaroConfig"src="https://cdn.kiprotect.com/klaro/v0.7/klaro.js"></script>
1819 1820</main> 1821</body> 1822</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.