1// Paddle.Environment.set('sandbox'); 2 3Paddle.Setup({ 4 vendor: 11223, 5}); 6 7function makeFakePurchase() { 8 const data = { 9 product: { 10 id: 24, 11 name: "iShowU Instant Website Test Payment", 12 quantity: 1 13 }, 14 checkout: { 15 id: (Math.random() * 10000).toFixed(), 16 prices: { 17 customer: { 18 total: 23.33, 19 total_tax: 2.12, 20 currency: "NZD", 21 } 22 }, 23 coupon: { 24 coupon_code: "" 25 } 26 } 27 } 28 29 sendGA4Purchase(data, dataLayer); 30} 31 32function sendGA4Purchase(data, dataLayer, buttonObject = null) { 33 /* 34 This is in the form specified by GA4 events for purchase, but it's all meaningless. 35 To actually GET a true event, this is "converted" by a GA4 Event tag (set in GTM). 36 So the payload here can be anything we like. 37 38 In which case, we might as well just send the standard old UA payload. 39 40 We have to define individual variables for EVERY element we want. THEN those can be shoved into the 41 event. Pretty fucking stupid. 42 */ 43 // let transaction = { 44 // 'transaction_id': data.checkout.id, 45 // 'value': data.checkout.prices.customer.total, 46 // 'tax': data.checkout.prices.customer.total_tax, 47 // 'currency': data.checkout.prices.customer.currency, 48 // 'coupon': data.checkout.coupon.coupon_code, 49 // 'items': [ 50 // { 51 // 'item_id': data.product.id, 52 // 'item_name': data.product.name, 53 // 'index': 0, 54 // 'price': data.checkout.prices.customer.total, 55 // 'quantity': data.product.quantity 56 // } 57 // ] 58 // }; 59 60 let olderStylePayload = { 61 'currencyCode': data.checkout.prices.customer.currency, 62 'purchase': { 63 'actionField': { 64 'id': data.checkout.id, 65 'affiliation': 'Paddle Checkout Web', 66 'revenue': data.checkout.prices.customer.total, 67 'tax': data.checkout.prices.customer.total_tax, 68 'coupon': data.checkout.coupon.coupon_code 69 }, 70 'products': [{ 71 'name': data.product.name, 72 'id': data.product.id, 73 'price': data.checkout.prices.customer.total, 74 'quantity': data.product.quantity 75 }] 76 } 77 } 78 79 dataLayer.push({ecommerce: null}); // Clear the previous ecommerce object. 80 dataLayer.push({ 81 'event': 'purchase', 82 'ecommerce': olderStylePayload, 83 'eventCallback': () => { 84 if (buttonObject) { 85 window.location = buttonObject["success"] ? buttonObject.success : "/purchase/complete"; 86 } else { 87 window.location = "/purchase/complete"; 88 } 89 } 90 }); 91} 92 93// function sendUAPurchaseEvent(data, dataLayer) { 94// dataLayer.push({ 95// 'event': 'purchase', 96// 'ecommerce': { 97// 'currencyCode': data.checkout.prices.customer.currency, 98// 'purchase': { 99// 'actionField': { 100// 'id': data.checkout.id, 101// 'affiliation': 'Paddle Checkout Web', 102// 'revenue': data.checkout.prices.customer.total, 103// 'tax': data.checkout.prices.customer.total_tax, 104// 'coupon': data.checkout.coupon.coupon_code 105// }, 106// 'products': [{ 107// 'name': data.product.name, 108// 'id': data.product.id, 109// 'price': data.checkout.prices.customer.total, 110// 'quantity': data.product.quantity 111// }] 112// } 113// }, 114// 'eventCallback': () => { 115// window.location = buttonObject["success"] ? buttonObject.success : "/purchase/complete"; 116// } 117// }); 118// } 119 120// Here as a convenience to let you pass in a JSON object, which is then parsed. 121// New PaddleButton doesn't use it (it encodes JSON to b64, sends it to openPCheckout in canvas-base.html) 122function openPaddleCheckout(buttonObject) { 123 // buttonObject = $.parseJSON(buttonObjectJSON); 124 checkoutOptions = { 125 product: buttonObject.product_id, 126 closeCallback: (data) => { 127 dataLayer.push({'event': 'checkoutClose'}); 128 }, 129 successCallback: (data) => { 130 dataLayer.push({'event': 'checkoutSuccess'}); 131 132 // sendUAPurchaseEvent(data, dataLayer); 133 sendGA4Purchase(data, dataLayer, buttonObject); 134 135 // Just in case. Seems like 'success' isn't redirected to if successCallback is installed 136 // setTimeout(() => { 137 // window.location = buttonObject["success_url"] ? buttonObject.
137success_url : "/purchase/complete"; 138 // }, 10000); 139 } 140 }; 141 142 if (buttonObject.price !== undefined) { 143 checkoutOptions['price'] = buttonObject.price; 144 } 145 if (buttonObject.override !== undefined) { 146 checkoutOptions['override'] = buttonObject.override; 147 } 148 if (buttonObject.passthrough !== undefined) { 149 checkoutOptions['passthrough'] = buttonObject.passthrough; 150 } 151 if (buttonObject.email !== undefined) { 152 checkoutOptions['email'] = buttonObject.email; 153 } 154 if (buttonObject.coupon !== undefined) { 155 checkoutOptions['coupon'] = buttonObject.coupon; 156 } 157 if (buttonObject.disableLogout !== undefined) { 158 checkoutOptions['disableLogout'] = buttonObject.disableLogout; 159 } 160 if (buttonObject.success_url !== undefined) { 161 checkoutOptions['success'] = buttonObject.success_url; 162 } 163 if (buttonObject.success !== undefined) { 164 checkoutOptions['success'] = buttonObject.success; 165 } 166 if (buttonObject.quantity !== undefined) { 167 checkoutOptions['quantity'] = buttonObject.quantity; 168 } 169 if (buttonObject.auth !== undefined) { 170 checkoutOptions['auth'] = buttonObject.auth; 171 } 172 173 Paddle.Checkout.open(checkoutOptions); 174}
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.