PageSourceSearch

https://www.cbnrecife.com/wp-content/plugins/webtonative/website/s…/woocommerce.js?var=6.14.9&ver=1790624866

js cbnrecife.com collected 2026-10-02 11:25:17 UTC 8,214 bytes, 237 lines download raw bytes

1function debounce(func, wait) {
2  let timeout;
3  return function (...args) {
4    clearTimeout(timeout);
5    timeout = setTimeout(() => func.apply(this, args), wait);
6  };
7}
8
9(async function ($) {
10  if (!WTN.isAndroidApp && !WTN.isIosApp) return;
11
12  const nonce = webtonative_payment_settings.nonce;
13  const resturl = webtonative_payment_settings.rest_url;
14  const isLoggedIn = wtn_biometric_settings.isLoggedIn === '1';
15  // if (!isLoggedIn) return;
16
17  const isIAPEnabled = wtn_biometric_settings.iap_enabled === '1';
18  if (!isIAPEnabled) return;
19
20  const appStoreBundleId = wtn_biometric_settings.appStoreBundleId;
21  const appStorePrivateKey = wtn_biometric_settings.appStorePrivateKey;
22  const appStoreIssuerId = wtn_biometric_settings.appStoreIssuerId;
23  const appStoreKeyId = wtn_biometric_settings.appStoreKeyId;
24
25  const btnTexts = {
26    buyNow: wtn_biometric_settings?.btn_buy_now_text ?? 'Buy Now',
27    processing: wtn_biometric_settings?.btn_proccessing_text ?? 'Processing...',
28    success: wtn_biometric_settings?.btn_payment_completed_text ?? 'Payment completed',
29    failed: wtn_biometric_settings?.btn_failed_text ?? 'Payment failed',
30  };
31
32  let productListCache = null;
33  let isIAPInitialized = false;
34  let isSettingUpButtons = false;
35
36  async function fetchProductList() {
37    if (productListCache) return productListCache;
38    const response = await fetch(`${resturl}/list`);
39    productListCache = await response.json();
40    return productListCache;
41  }
42
43  function toggleButtonState(button, isProcessing, text) {
44    button.text(text);
45    button.prop('disabled', isProcessing);
46  }
47
48  async function createOrder(orderData) {
49    return $.ajax({
50      url: `${resturl}/order`,
51      type: 'POST',
52      contentType: 'application/json',
53      data: JSON.stringify(orderData),
54      headers: { 'X-WP-Nonce': nonce },
55    });
56  }
57
58  async function processPayment(button) {
59    const productId = button.attr('data-product_id') || button.data('product_id') || button.val();
60    const nativeProductId = button.attr('data-native_product_id');
61
62    if (!productId || !nativeProductId) return;
63
64    const productType = button.attr('data-product_type');
65    const isConsumable = button.attr('data-is_consumable');
66    const variantId = button.attr('data-variant_id');
67
68    toggleButtonState(button, true, btnTexts.processing);
69
70    try {
71      isIAPInitialized = true;
72      const productData = { productId: nativeProductId, productType, isConsumable };
73
74      WTN.inAppPurchase({
75        ...productData,
76        callback: async (data) => {
77          if (!data.isSuccess) {
78            alert(btnTexts.failed);
79            toggleButtonState(button, false, btnTexts.buyNow);
80            isIAPInitialized = false;
81            return;
82          }
83
84          if (data?.isAlreadyPurchased) {
85            alert('Already purchased');
86            toggleButtonState(button, false, btnTexts.buyNow);
87            isIAPInitialized = false;
88            return;
89          }
90
91          const orderPayload = {
92            productId,
93            platform: WTN.isAndroidApp ? 'ANDROID' : 'IOS',
94            nativeProductId: nativeProductId,
95            productType: productType,
96            variantId,
97            ...(WTN.isIosApp ? { receiptData: data.receiptData, transactionId: data.transactionId } : data),
98          };
99
100          try {
101            const orderResponse = await createOrder(orderPayload);
102            if (orderResponse?.success) {
103              toggleButtonState(button, false, btnTexts.success);
104            }
105            isIAPInitialized = false;
106          } catch (orderError) {
107            toggleButtonState(button, false, btnTexts.failed);
108
109            let errorMessage = btnTexts.failed; // Default message
110            if (orderError.status !== undefined) {
111              if (orderError.responseText) {
112                try {
113                  const errorData = JSON.parse(orderError.responseText);
114                  errorMessage = errorData?.message || errorData?.error || errorMessage;
115                } catch (e) {
116                  // If response is not JSON, use it as is (if it's short enough)
117                  if (orderError.responseText.length < 50) {
118                    errorMessage = orderError.responseText;
119                  }
120                }
121              }
122
123              if (orderError.status === 400) {
124                alert(errorMessage);
125                toggleButtonState(button, false, btnTexts.buyNow);
126              }
127            }
128
129            isIAPInitialized = false;
130          }
131        },
132      });
133    } catch (error) {
134      toggleButtonState(button, false, btnTexts.failed);
135      isIAPInitialized = false;
136    }
137  }
138
139  async function setupButtons() {
140    if (isSettingUpButtons) return;
141    isSettingUpButtons = true;
142
143    const productList = await fetchProductList();
144
145    try {
146      $('.single_add_to_cart_button, .add_to_cart_button, .tutor-add-to-cart-button').each(function () {
147        const button = $(this);
148        let productId = button.data('product_id') || button.val();
149        let nativeProductId = null;
150        let productType = null;
151        let isConsumable = null;
152        let variantId = null;
153        let isVariant = false;
154
155        // Try to get base product data (simple product)
156        const baseProdData = productList?.[productId];
157        if (baseProdData) {
158          nativeProductId = baseProdData[WTN.isIosApp ? 'appStore' : 'googlePlay'];
159          productType = baseProdData.productType;
160          isConsumable = baseProdData.isConsumable;
161        }
162
163        // If not found, try to get from variant meta (variable product)
164        if (typeof window.wtn_variant_meta !== 'undefined') {
165          const $form = button.closest('form.variations_form');
166          if ($form.length) {
167            const variation_id = $form.find('input[name="variation_id"]').val();
168            if (variation_id && window.wtn_variant_meta[variation_id]) {
169              const variantMeta = window.wtn_variant_meta[variation_id];
170              nativeProductId = WTN.isIosApp ? variantMeta.appStore : variantMeta.googlePlay;
171              productType = variantMeta.productType;
172              isConsumable = variantMeta.isConsumable;
173              productId = variantMeta.baseProductId; // Use base product ID for reference
174              variantId = variation_id;
175              isVariant = true;
176            }
177          }
178        }
179
180        // Only create the button if we have a native product ID
181        if (nativeProductId) {
182          const existingClasses = button.attr('class').replace('ajax_add_to_cart', '') || '';
183          const newButton = $('<button type="button">')
184            .addClass(`${existingClasses} webtonative-iap`)
185            .text(btnTexts.buyNow)
186            .attr('style', button.attr('style'))
187            .attr('data-product_id', productId)
188            .attr('data-native_product_id', nativeProductId)
189            .attr('data-product_type', productType)
190            .attr('data-is_consumable', isConsumable);
191
192          // If this is a variant, add variant-specific attributes
193          if (isVariant && variantId) {
194            newButton.attr('data-variant_id', variantId).attr('data-variant_name', window.wtn_variant_meta[variantId].name);
195          }
196
197          button.replaceWith(newButton);
198        }
199      });
200    } finally {
201      isSettingUpButtons = false;
202    }
203  }
204
205  $(document).on('click', '.webtonative-iap', function (e) {
206    e.preventDefault();
207    e.stopPropagation();
208    e.stopImmediatePropagation();
209
210    const button = $(this);
211
212    if (!isLoggedIn) {
213      alert('Please login to continue');
214      return;
215    }
216
217    if (WTN.isIosApp && (!appStoreBundleId || !appStorePrivateKey || !appStoreIssuerId || !appStoreKeyId)) {
218      alert('Please configure App store settings in settings');
219      return;
220    }
221
222    processPayment(button);
223  });
224
225  // Initialize
226  await setupButtons();
227
228  $(document).ajaxComplete(async function () {
229    if (isIAPInitialized) return;
230    debounce(setupButtons, 300)();
231  });
232
233  // On variant change, update meta for selected variant
234  $(document).on('found_variation', 'form.variations_form', async function (event, variation) {
235    await setupButtons();
236  });
237})(jQuery);

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.