1import { Controller } from "@hotwired/stimulus" 2 3export default class extends Controller { 4 static targets = [ "form" ] 5 static values = { 6 class: "paddle-classic-checkout", 7 email: String, 8 environment: {type: String, default: "production"}, 9 override: String, 10 passthrough: String, 11 product: String, 12 redirectUrl: String, 13 vendorId: Number 14 } 15 16 async connect() { 17 await this.addScript("https://cdn.paddle.com/paddle/paddle.js") 18 19 // Ensure class for mounting inline checkout is defined 20 this.element.classList.add(this.classValue) 21 22 Paddle.Environment.set(this.environmentValue) 23 Paddle.Setup({ 24 vendor: this.vendorIdValue, 25 eventCallback: this.callback.bind(this) 26 }) 27 28 // Render checkout, otherwise just include the JS 29 if (this.overrideValue || this.productValue) 30 this.open() 31 } 32 33 disconnect() { 34 delete window.Paddle 35 } 36 37 open() { 38 Paddle.Checkout.open({ 39 ...this.params, 40 product: this.productValue, 41 email: this.emailValue, 42 passthrough: this.passthroughValue, 43 override: this.overrideValue 44 }) 45 } 46 47 checkoutComplete(event) { 48 Paddle.Order.details(event.checkout.id, (checkout) => { 49 Turbo.visit(`/subscriptions/paddle_classic?user_id=${event.user.id}&subscription_id=${checkout.order.subscription_id}`) 50 }) 51 } 52 53 callback(event) { 54 const price = event.eventData.checkout?.recurring_prices?.customer 55 if (price) { 56 document.getElementById("recurringTotal").innerHTML = `${price.total} ${price.currency}` 57 } 58 } 59 60 get params() { 61 return { 62 method: 'inline', 63 allowQuantity: false, 64 disableLogout: true, 65 frameTarget: this.classValue, 66 frameInitialHeight: 450, 67 frameStyle: 'width:100%; background-color: transparent; border: none;', 68 successCallback: this.checkoutComplete.bind(this), 69 displayModeTheme: this.theme 70 } 71 } 72 73 get theme() { 74 return document.documentElement.classList.contains("dark") ? "dark" : "light"; 75 } 76 77 addScript(src) { 78 return new Promise((resolve, reject) => { 79 const s = document.createElement('script') 80 81 s.setAttribute('src', src) 82 s.addEventListener('load', resolve) 83 s.addEventListener('error', reject) 84 85 document.body.appendChild(s) 86 }) 87 } 88}
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.