Plugin Directory

Changeset 3342866


Ignore:
Timestamp:
08/11/2025 12:37:05 PM (7 months ago)
Author:
webtonative
Message:

Deploy plugin version 2.9.2

Location:
webtonative/trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • webtonative/trunk/README.md

    r3335352 r3342866  
    44Requires at least: 2.0.2
    55Tested up to: 6.7.1
    6 Stable tag: 2.9.1
     6Stable tag: 2.9.2
    77License: GPLv2 or later
    88
  • webtonative/trunk/admin/iap/index.php

    r3301312 r3342866  
    1616      'iap_enabled' => false,
    1717      'isTest' => false,
    18       'appStoreSecret' => '',
     18      'appStoreBundleId' => '',
    1919      'cart_button_text' => 'Buy Now',
    2020      'processing_button_text' => 'Processing...',
     
    8383    $iapEnabled = !empty($settings['iap_enabled']) ? true : false;
    8484    $isTest = !empty($settings['isTest']) ? true : false;
    85     $appStoreSecret = !empty($settings['appStoreSecret']) ? $settings['appStoreSecret'] : '';
     85    $appStoreBundleId = !empty($settings['appStoreBundleId']) ? $settings['appStoreBundleId'] : '';
     86    $appStoreKeyId = !empty($settings['appStoreKeyId']) ? $settings['appStoreKeyId'] : '';
     87    $appStoreIssuerId = !empty($settings['appStoreIssuerId']) ? $settings['appStoreIssuerId'] : '';
     88    $appStorePrivateKey = !empty($settings['appStorePrivateKey']) ? $settings['appStorePrivateKey'] : '';
     89
    8690    $cartButtonText = $settings['cart_button_text'];
    8791    $processingButtonText = $settings['processing_button_text'];
     
    99103        'iap_enabled' => isset($_POST['iap_enabled']) ? true : false,
    100104        'isTest' => isset($_POST['isTest']) ? true : false,
    101         'appStoreSecret' => sanitize_text_field($_POST['appStoreSecret']),
     105        'appStoreBundleId' => sanitize_text_field($_POST['appStoreBundleId']),
     106        'appStoreKeyId' => isset($_POST['appStoreKeyId']) ? sanitize_text_field($_POST['appStoreKeyId']) : '',
     107        'appStoreIssuerId' => isset($_POST['appStoreIssuerId']) ? sanitize_text_field($_POST['appStoreIssuerId']) : '',
     108        'appStorePrivateKey' => isset($_POST['appStorePrivateKey']) ? $this->sanitize_p8_key($_POST['appStorePrivateKey']) : '',
     109
    102110        'cart_button_text' => sanitize_text_field($_POST['cart_button_text']),
    103111        'processing_button_text' => sanitize_text_field($_POST['processing_button_text']),
     
    139147          <tr>
    140148            <th scope="row">
    141               <label for="appStoreSecret">App Store Secret</label>
    142             </th>
    143             <td>
    144               <input type="text" name="appStoreSecret" id="appStoreSecret"
    145                 value="<?php echo esc_attr($appStoreSecret); ?>" class="regular-text" />
    146               <p class="description">Enter your App Store secret key.</p>
     149              <label for="appStoreBundleId">App Store Bundle ID</label>
     150            </th>
     151            <td>
     152              <input type="text" name="appStoreBundleId" id="appStoreBundleId"
     153                value="<?php echo esc_attr($appStoreBundleId); ?>" class="regular-text" />
     154              <p class="description">Enter your App Store Bundle ID.</p>
     155            </td>
     156          </tr>
     157          <tr>
     158            <th scope="row">
     159              <label for="appStoreKeyId">App Store Key ID</label>
     160            </th>
     161            <td>
     162              <input type="text" name="appStoreKeyId" id="appStoreKeyId"
     163                value="<?php echo esc_attr($appStoreKeyId); ?>" class="regular-text" />
     164              <p class="description">Enter your App Store Key ID.</p>
     165            </td>
     166          </tr>
     167          <tr>
     168            <th scope="row">
     169              <label for="appStoreIssuerId">App Store Issuer ID</label>
     170            </th>
     171            <td>
     172              <input type="text" name="appStoreIssuerId" id="appStoreIssuerId"
     173                value="<?php echo esc_attr($appStoreIssuerId); ?>" class="regular-text" />
     174              <p class="description">Enter your App Store Issuer ID.</p>
     175            </td>
     176          </tr>
     177          <tr>
     178            <th scope="row">
     179              <label for="appStorePrivateKey">App Store Private Key (.p8)</label>
     180            </th>
     181            <td>
     182              <textarea name="appStorePrivateKey" id="appStorePrivateKey" rows="6"
     183                class="large-text"><?php echo esc_textarea($appStorePrivateKey); ?></textarea>
     184              <p class="description">Paste the content of your .p8 private key file here.</p>
    147185            </td>
    148186          </tr>
     
    190228<?php
    191229  }
     230
     231  /**
     232   * Sanitize .p8 key content.
     233   *
     234   * @param string $input The input .p8 key content.
     235   * @return string Sanitized .p8 key content.
     236   */
     237  public function sanitize_p8_key($input)
     238  {
     239    $input = trim($input);
     240    if (empty($input) || strpos($input, '-----BEGIN PRIVATE KEY-----') !== 0 || strpos($input, '-----END PRIVATE KEY-----') === false) {
     241      add_settings_error(
     242        'wton_apple_p8_key',
     243        'invalid_p8_key',
     244        'Invalid .p8 key format. Please paste the full content of the .p8 file, including BEGIN and END headers.',
     245        'error'
     246      );
     247      return get_option('wton_apple_p8_key', '');
     248    }
     249    return $input;
     250  }
    192251}
     252
     253
    193254
    194255// Initialize the IAP plugin
  • webtonative/trunk/admin/iap/rest.php

    r3322172 r3342866  
    3131  }
    3232
    33   function verify_apple_payment(string $product_id, string $receipt_data, string $product_type)
    34   {
     33  /**
     34   * Decode a JWS string and return the payload as an array.
     35   *
     36   * @param string $jws JWS string to decode
     37   * @param string $context Context for error logging (e.g., 'transaction', 'subscription')
     38   * @return array|null Decoded payload or null on failure
     39   */
     40  private function decode_jws(string $jws, string $context): ?array
     41  {
     42    $parts = explode('.', $jws);
     43    if (count($parts) !== 3) {
     44      error_log("Invalid JWS format in $context");
     45      return null;
     46    }
     47    $decoded = json_decode(base64_decode($parts[1]), true);
     48    if (json_last_error() !== JSON_ERROR_NONE) {
     49      error_log("Failed to decode JWS in $context: " . json_last_error_msg());
     50      return null;
     51    }
     52    return $decoded;
     53  }
     54
     55  /**
     56   * Make an API request with retry logic for sandbox/production environments.
     57   *
     58   * @param string $transaction_id Transaction ID
     59   * @param string $jwt JWT token for authorization
     60   * @param bool $isTest Whether to use sandbox environment initially
     61   * @param string $endpoint_type Endpoint type ('transactions' or 'subscriptions')
     62   * @return array|null Response data or null on failure
     63   */
     64  private function make_api_request(string $transaction_id, string $jwt, bool $isTest, string $endpoint_type): ?array
     65  {
     66    $base_url = $isTest ? 'https://api.storekit-sandbox.itunes.apple.com' : 'https://api.storekit.itunes.apple.com';
     67    $attempts = [
     68      ['base_url' => $base_url, 'is_retry' => false],
     69      ['base_url' => $isTest ? 'https://api.storekit.itunes.apple.com' : 'https://api.storekit-sandbox.itunes.apple.com', 'is_retry' => true]
     70    ];
     71
     72    $response_data = null;
     73    foreach ($attempts as $attempt) {
     74      $url = "{$attempt['base_url']}/inApps/v1/$endpoint_type/$transaction_id";
     75      $response = wp_remote_get($url, [
     76        'method' => 'GET',
     77        'timeout' => 45,
     78        'redirection' => 5,
     79        'httpversion' => '1.0',
     80        'blocking' => true,
     81        'headers' => [
     82          'Authorization' => "Bearer $jwt",
     83          'Content-Type' => 'application/json',
     84        ],
     85        'cookies' => [],
     86      ]);
     87
     88      if (is_wp_error($response)) {
     89        error_log("App Store API $endpoint_type request failed (URL: $url): " . $response->get_error_message());
     90        continue;
     91      }
     92
     93      $response_code = wp_remote_retrieve_response_code($response);
     94      $response_body = wp_remote_retrieve_body($response);
     95      $response_data = json_decode($response_body, true);
     96
     97      error_log("App Store $endpoint_type API Response (URL: $url): " . print_r($response_data, true));
     98
     99      if ($response_code === 200 || !($response_code === 404 || (isset($response_data['errorCode']) && $response_data['errorCode'] === 'InvalidTransaction'))) {
     100        break;
     101      }
     102    }
     103
     104    return ($response_data && $response_code === 200) ? $response_data : null;
     105  }
     106
     107  /**
     108   * Verify an Apple in-app payment.
     109   *
     110   * @param string $product_id Product ID from the iOS app
     111   * @param string $transaction_id Transaction ID from the iOS app
     112   * @param string $product_type Product type ('SUBS' or non-subscription)
     113   * @return array Verification result
     114   */
     115  public function verify_apple_payment(string $product_id, string $transaction_id, string $product_type): array
     116  {
     117    // Retrieve Webtonative settings
    35118    $webtonative_settings = get_option('wtn_iap_settings');
    36 
    37119    if (!$webtonative_settings) {
     120      error_log('Webtonative settings not found');
    38121      return [
    39122        'success' => false,
     
    43126    }
    44127
    45     $app_store_secret = $webtonative_settings['appStoreSecret'] ?? '';
     128    $key_id = $webtonative_settings['appStoreKeyId'] ?? '';
     129    $issuer_id = $webtonative_settings['appStoreIssuerId'] ?? '';
     130    $private_key = $webtonative_settings['appStorePrivateKey'] ?? '';
     131    $bundle_id = $webtonative_settings['appStoreBundleId'] ?? '';
    46132    $isTest = isset($webtonative_settings['isTest']) ? true : false;
    47133
    48     if (empty($app_store_secret)) {
     134    if (empty($key_id) || empty($issuer_id) || empty($private_key) || empty($bundle_id)) {
     135      error_log('App Store API credentials not configured');
    49136      return [
    50137        'success' => false,
    51         'message' => 'App Store secret key not configured',
     138        'message' => 'App Store API credentials not configured',
    52139        'data' => [],
    53140      ];
    54141    }
    55142
    56     $url = $isTest ? 'https://sandbox.itunes.apple.com/verifyReceipt' : 'https://buy.itunes.apple.com/verifyReceipt';
    57 
    58     $post_data = json_encode([
    59       'receipt-data' => $receipt_data,
    60       'password' => $app_store_secret,
    61       'exclude-old-transactions' => false,
    62     ]);
    63 
    64     $response = wp_remote_post($url, [
    65       'method' => 'POST',
    66       'timeout' => 45,
    67       'redirection' => 5,
    68       'httpversion' => '1.0',
    69       'blocking' => true,
    70       'headers' => [
    71         'Content-Type' => 'application/json',
    72       ],
    73       'body' => $post_data,
    74       'cookies' => [],
    75     ]);
    76 
    77     if (is_wp_error($response)) {
     143    if (empty($transaction_id)) {
     144      error_log('Transaction ID is empty');
    78145      return [
    79146        'success' => false,
    80         'message' => 'Verification failed: ' . $response->get_error_message(),
     147        'message' => 'Transaction ID is empty',
    81148        'data' => [],
    82149      ];
    83150    }
    84151
    85     $response_body = wp_remote_retrieve_body($response);
    86     $response_data = json_decode($response_body, true);
    87 
    88     if (!isset($response_data['status']) || $response_data['status'] !== 0) {
     152    // Generate JWT token
     153    $jwt = $this->generate_jwt($private_key, $key_id, $issuer_id, $bundle_id);
     154    if (!$jwt) {
     155      error_log('Failed to generate JWT token');
    89156      return [
    90157        'success' => false,
    91         'message' => 'Receipt validation failed with status: ' . ($response_data['status'] ?? 'unknown'),
     158        'message' => 'Failed to generate JWT token',
    92159        'data' => [],
    93160      ];
    94161    }
    95162
    96     $appStoreProductId = $product_id;
     163    // Validate transaction
     164    error_log("Validating transaction ID: $transaction_id for product ID: $product_id");
     165    $transaction_data = $this->make_api_request($transaction_id, $jwt, $isTest, 'transactions');
     166    if (!$transaction_data) {
     167      error_log('Transaction validation failed');
     168      return [
     169        'success' => false,
     170        'message' => 'Transaction validation failed',
     171        'data' => [],
     172      ];
     173    }
     174
     175    // Decode JWSTransaction
     176    if (!isset($transaction_data['signedTransactionInfo']) || !is_string($transaction_data['signedTransactionInfo'])) {
     177      error_log('Missing or invalid signedTransactionInfo in transaction response');
     178      return [
     179        'success' => false,
     180        'message' => 'Invalid transaction response data',
     181        'data' => [],
     182      ];
     183    }
     184
     185    $transaction = $this->decode_jws($transaction_data['signedTransactionInfo'], 'transaction');
     186    error_log('Decoded transaction data: ' . print_r($transaction, true));
     187    if (!$transaction) {
     188      return [
     189        'success' => false,
     190        'message' => 'Failed to decode transaction data',
     191        'data' => [],
     192      ];
     193    }
     194
     195    // Verify product ID
     196    if ($transaction['productId'] !== $product_id) {
     197      error_log("Transaction product ID {$transaction['productId']} does not match expected $product_id");
     198      return [
     199        'success' => false,
     200        'message' => "Transaction product ID {$transaction['productId']} does not match expected $product_id",
     201        'data' => $transaction,
     202      ];
     203    }
    97204
    98205    if ($product_type === 'SUBS') {
    99       $latestTransactions = $response_data['latest_receipt_info'] ?? [];
    100       $filtered = array_filter($latestTransactions, function ($item) use ($appStoreProductId) {
    101         return $item['product_id'] === $appStoreProductId;
    102       });
    103 
    104       if (empty($filtered)) {
     206      $subscriptionGroupIdentifier = $transaction['subscriptionGroupIdentifier'];
     207      $originalTransactionId = $transaction['originalTransactionId'];
     208
     209      // Validate subscription
     210      $subscription_data = $this->make_api_request($originalTransactionId, $jwt, $isTest, 'subscriptions');
     211      if (!$subscription_data) {
     212        error_log('Subscription validation failed');
    105213        return [
    106214          'success' => false,
    107           'message' => "No transaction found for product: $appStoreProductId",
    108           'data' => [],
     215          'message' => 'Subscription validation failed',
     216          'data' => $transaction,
    109217        ];
    110218      }
    111219
    112       usort($filtered, function ($a, $b) {
    113         return intval($b['expires_date_ms']) <=> intval($a['expires_date_ms']);
    114       });
    115 
    116       $latest = $filtered[0];
    117       $expiration_ms = intval($latest['expires_date_ms'] ?? 0);
     220      // find subscription by subscriptionGroupIdentifier from data array
     221      $subscription_data_by_subs_group_identifier = array_values(array_filter($subscription_data['data'], function ($item) use ($subscriptionGroupIdentifier) {
     222        return isset($item['subscriptionGroupIdentifier']) && $item['subscriptionGroupIdentifier'] === $subscriptionGroupIdentifier;
     223      }));
     224
     225      // If no subscription data found for the given group identifier
     226      if (empty($subscription_data_by_subs_group_identifier)) {
     227        error_log('No subscription data found for the given group identifier');
     228        return [
     229          'success' => false,
     230          'message' => 'No subscription data found for the given group identifier',
     231          'data' => $transaction,
     232        ];
     233      }
     234
     235      // find transaction by originalTransactionId from subscription_data_by_subs_group_identifier in last transactions array
     236      $transaction_by_original_transaction_id = array_values(array_filter($subscription_data_by_subs_group_identifier[0]['lastTransactions'], function ($item) use ($originalTransactionId) {
     237        return isset($item['originalTransactionId']) && $item['originalTransactionId'] === $originalTransactionId;
     238      }));
     239
     240      // If no transaction data found for the given originalTransactionId
     241      if (empty($transaction_by_original_transaction_id)) {
     242        error_log('No transaction data found for the given originalTransactionId');
     243        return [
     244          'success' => false,
     245          'message' => 'No transaction data found for the given originalTransactionId',
     246          'data' => $transaction,
     247        ];
     248      }
     249
     250      $decoded_signedTransactionInfo = $this->decode_jws($transaction_by_original_transaction_id[0]['signedTransactionInfo'], 'subscription transaction');
     251      $decoded_signedRenewalInfo = $this->decode_jws($transaction_by_original_transaction_id[0]['signedRenewalInfo'], 'subscription renewal');
     252
     253      error_log('Latest subscription decoded_signedTransactionInfo: ' . print_r($decoded_signedTransactionInfo, true));
     254      error_log('Latest subscription decoded_signedRenewalInfo: ' . print_r($decoded_signedRenewalInfo, true));
     255
     256      $expiration_ms = intval($decoded_signedTransactionInfo['expiresDate'] ?? 0);
     257      $purchase_date_ms = intval($decoded_signedTransactionInfo['purchaseDate'] ?? 0);
    118258      $now_ms = round(microtime(true) * 1000);
    119       $transaction_id = $latest['transaction_id'] ?? '';
    120       $original_transaction_id = $latest['original_transaction_id'] ?? '';
    121 
    122       // Check if this transaction is already recorded in the database
     259      $original_transaction_id = $decoded_signedTransactionInfo['originalTransactionId'];
     260
     261      // Verify auto_renew_status
     262      $auto_renew_status = $decoded_signedRenewalInfo['autoRenewStatus'] ?? 0;
     263      if ($auto_renew_status !== 1) {
     264        error_log('Subscription is not active (auto_renew_status: ' . $auto_renew_status . ')');
     265        return [
     266          'success' => false,
     267          'message' => 'Subscription is not active (auto_renew_status: ' . $auto_renew_status . ')',
     268          'data' => $decoded_signedTransactionInfo,
     269        ];
     270      }
     271
     272      // Check for cancellation
     273      if (isset($decoded_signedTransactionInfo['revocationDate'])) {
     274        error_log('Subscription was canceled or revoked for transaction: ' . $transaction_id);
     275        return [
     276          'success' => false,
     277          'message' => 'Subscription was canceled or revoked',
     278          'data' => $decoded_signedTransactionInfo,
     279        ];
     280      }
     281
     282      // Check for billing retry
     283      if (isset($decoded_signedRenewalInfo['priceIncreaseStatus']) && $decoded_signedRenewalInfo['priceIncreaseStatus'] === 2) {
     284        error_log('Subscription is in billing retry period for transaction: ' . $transaction_id);
     285        return [
     286          'success' => false,
     287          'message' => 'Subscription is in billing retry period',
     288          'data' => $decoded_signedRenewalInfo,
     289        ];
     290      }
     291
     292      // Check for existing order
    123293      $existing_order = $this->get_order_by_transaction_id($original_transaction_id);
    124 
     294      error_log('Existing order: ' . print_r($existing_order, true));
    125295      if ($existing_order) {
    126         // If the transaction exists, check if it's a renewal or an active subscription
    127296        $existing_expiration = get_post_meta($existing_order->get_id(), '_wtn_subscription_expiration_ms', true);
     297        error_log('Existing expiration: ' . $existing_expiration);
     298        error_log('New expiration: ' . $expiration_ms);
     299
    128300        if ($expiration_ms > $existing_expiration) {
    129           // This is a renewal: update the existing order
    130           update_post_meta($existing_order->get_id(), '_wtn_subscription_expiration_ms', $expiration_ms);
    131           update_post_meta($existing_order->get_id(), '_wtn_subscription_transaction_id', $transaction_id);
     301          // Renewal: update existing order
     302          $existing_oid = $existing_order->get_id();
     303          update_post_meta($existing_oid, '_wtn_subscription_transaction_id', $transaction_id);
     304          update_post_meta($existing_oid, '_wtn_subscription_purchase_date_ms', $purchase_date_ms);
     305          update_post_meta($existing_oid, '_wtn_subscription_expiration_ms', $expiration_ms);
     306
     307          error_log('Subscription renewed for order ID: ' . $existing_order->get_id());
    132308          return [
    133309            'success' => true,
     310            'isRenewal' => true,
     311            'isAlreadyPurchased' => true,
    134312            'message' => 'Subscription renewed',
    135             'data' => $latest,
     313            'data' => $decoded_signedTransactionInfo,
    136314            'order_id' => $existing_order->get_id(),
    137315          ];
    138316        } else {
    139           // Subscription is already active and not renewed
     317          // Subscription already active
     318          error_log('Subscription already active for transaction: ' . $transaction_id);
    140319          return [
    141320            'success' => false,
     
    143322            'message' => 'Subscription already active',
    144323            'expiration' => gmdate("Y-m-d\TH:i:s\Z", $expiration_ms / 1000),
    145             'data' => $latest,
     324            'data' => $decoded_signedTransactionInfo,
    146325          ];
    147326        }
    148327      }
    149328
    150       // No existing order found, this is a new subscription
    151       if ($expiration_ms <= $now_ms) {
     329      // Check for expiration
     330      if ($expiration_ms <= $now_ms && $expiration_ms > 0) {
     331        error_log('Subscription has expired for transaction: ' . $transaction_id);
    152332        return [
    153333          'success' => false,
    154334          'message' => 'Subscription has expired',
    155           'data' => $latest,
     335          'data' => $decoded_signedTransactionInfo,
    156336        ];
    157337      }
    158338
    159       // if ($expiration_ms > $now_ms) {
    160       //   return [
    161       //     'success' => false,
    162       //     'isAlreadyPurchased' => true,
    163       //     'message' => "Subscription already purchased",
    164       //     'expiration' => gmdate("Y-m-d\TH:i:s\Z", $expiration_ms / 1000),
    165       //     'data' => $latest,
    166       //   ];
    167       // }
    168 
     339      error_log('New subscription validated for transaction: ' . $transaction_id);
    169340      return [
    170341        'success' => true,
    171342        'message' => 'New subscription validated',
    172         'data' => $latest,
    173         'transaction_id' => $transaction_id,
    174         'original_transaction_id' => $original_transaction_id,
     343        'data' => $decoded_signedTransactionInfo,
    175344      ];
    176     } else {
    177       $receipt = $response_data['receipt'] ?? [];
    178       $in_app = $receipt['in_app'] ?? [];
    179 
    180       $purchase = null;
    181       foreach ($in_app as $item) {
    182         if ($item['product_id'] === $appStoreProductId) {
    183           $purchase = $item;
    184           break;
    185         }
    186       }
    187 
    188       if (!$purchase) {
    189         return [
    190           'success' => false,
    191           'message' => "No purchase found for product: $appStoreProductId",
    192           'data' => [],
    193         ];
    194       }
    195 
    196       return [
    197         'success' => true,
    198         'message' => '',
    199         'data' => $purchase,
    200       ];
    201     }
     345    }
     346
     347    // Non-subscription product handling
     348    error_log('Non-subscription purchase validated for transaction: ' . $transaction_id);
     349    return [
     350      'success' => true,
     351      'message' => 'Non-subscription purchase validated',
     352      'data' => $transaction,
     353    ];
    202354  }
    203355
     
    284436  {
    285437    // data from apple
    286     $variant_id = $request_body['variantId'];
     438    $variant_id = $request_body['variantId'] ?? null;
    287439    $receipt_data = $request_body['receiptData'];
    288440    $native_product_id = $request_body['nativeProductId'];
    289441    $product_type = $request_body['productType'];
     442    $transaction_id = $request_body['transactionId'];
    290443    $current_user = wp_get_current_user();
    291444
     
    294447      return new WP_REST_Response(['success' => false, 'message' => 'Invalid Request'], 400);
    295448    }
    296     $is_valid = $this->verify_apple_payment($native_product_id, $receipt_data, $product_type);
     449    $is_valid = $this->verify_apple_payment($native_product_id, $transaction_id, $product_type);
    297450
    298451    if ($is_valid['success'] === false && array_key_exists('isAlreadyPurchased', $is_valid) && $is_valid['isAlreadyPurchased'] === true) {
     
    309462      ], 400);
    310463    }
    311 
    312     $verify_data = $is_valid['data'] ?? [];
     464    if (array_key_exists('isRenewal', $is_valid) && $is_valid['isRenewal'] === true) {
     465      return new WP_REST_Response([
     466        'success' => false,
     467        'message' => $is_valid['message'],
     468      ]);
     469    }
     470
     471    $verified_transanction = $is_valid['data'] ?? [];
     472
    313473    $product_data = wc_get_product($product_id);
    314     $order = wc_create_order(array(
    315       'customer_id' => $current_user->ID,
    316     ));
     474    $order = wc_create_order(array('customer_id' => $current_user->ID));
     475
    317476    if ($product_data->is_type('variable') && $variant_id) {
    318477      $variation_product = wc_get_product($variant_id);
     
    321480      $order->add_product($product_data);
    322481    }
    323     // $order->add_product($product_data);
     482
    324483    $order->set_payment_method('webtonative');
    325484    $order->set_status('wc-completed');
    326     // $order->set_customer_id($current_user->ID);
    327485    $order->calculate_totals();
    328486    $order->save();
     
    340498    $native_order = array(
    341499      'productId' => $native_product_id,
    342       'receiptData' => is_scalar($verify_data) ? strval($verify_data) : json_encode($verify_data),
     500      'receiptData' => is_scalar($verified_transanction) ? strval($verified_transanction) : json_encode($verified_transanction),
    343501      'platform' => 'IOS',
    344502    );
     
    350508
    351509    if ($product_type === 'SUBS') {
    352       update_post_meta($order_id, '_wtn_subscription_transaction_id', $verify_data['transaction_id'] ?? '');
    353       update_post_meta($order_id, '_wtn_subscription_original_transaction_id', $verify_data['original_transaction_id'] ?? '');
    354       update_post_meta($order_id, '_wtn_subscription_expiration_ms', $verify_data['expires_date_ms'] ?? '');
     510      error_log('woocommerce order for subscription product' . $order_id);
     511
     512      update_post_meta($order_id, '_wtn_subscription_transaction_id', $verified_transanction['transactionId'] ?? '');
     513      update_post_meta($order_id, '_wtn_subscription_original_transaction_id', $verified_transanction['originalTransactionId'] ?? '');
     514      update_post_meta($order_id, '_wtn_subscription_expiration_ms', $verified_transanction['expiresDate'] ?? '');
     515
     516      update_post_meta($order_id, '_wtn_subscription_original_purchase_date_ms', $verified_transanction['originalPurchaseDate']);
    355517    }
    356518
     
    545707  }
    546708
     709  /**
     710   * Retrieve a WooCommerce order by its original transaction ID using WP_Query.
     711   *
     712   * @param string $original_transaction_id The original transaction ID stored in order meta.
     713   * @return WC_Order|null The order object if found, null otherwise.
     714   */
    547715  function get_order_by_transaction_id(string $original_transaction_id)
    548716  {
     717    if (empty($original_transaction_id)) {
     718      return null;
     719    }
     720
    549721    $args = [
    550       'post_type' => 'shop_order',
    551       'post_status' => array_keys(wc_get_order_statuses()),
    552       'meta_query' => [
     722      'post_type'      => 'shop_order_placehold',
     723      'post_status'    => 'any', // Fetch orders of any status
     724      'meta_query'     => [
    553725        [
    554           'key' => '_wtn_subscription_original_transaction_id',
    555           'value' => $original_transaction_id,
     726          'key'     => '_wtn_subscription_original_transaction_id',
     727          'value'   => $original_transaction_id,
    556728          'compare' => '=',
    557729        ],
    558730      ],
     731      'posts_per_page' => 1,
    559732    ];
    560733
    561     $orders = wc_get_orders($args);
    562     return !empty($orders) ? $orders[0] : null;
     734    $query = new WP_Query($args);
     735
     736    if ($query->have_posts()) {
     737      $order_id = $query->posts[0]->ID;
     738      $order = wc_get_order($order_id);
     739      if ($order instanceof WC_Order) {
     740        return $order;
     741      }
     742    }
     743
     744    return null;
     745  }
     746
     747  /**
     748   * Generate JWT for Apple App Store Connect API using OpenSSL.
     749   * Fixed version that properly handles ES256 signing and P8 key format.
     750   *
     751   * @param string $p8_key The .p8 private key content (as string, not file path).
     752   * @param string $key_id The Apple Key ID (from App Store Connect).
     753   * @param string $issuer_id The Apple Issuer ID (from App Store Connect).
     754   * @return string|false The generated JWT or false on failure.
     755   */
     756  private function generate_jwt($p8_key, $key_id, $issuer_id, $bundle_id)
     757  {
     758    if (!extension_loaded('openssl')) {
     759      error_log('Webtonative: OpenSSL PHP extension is not enabled.');
     760      return false;
     761    }
     762
     763    // Prepare JWT header
     764    $header = [
     765      'alg' => 'ES256',
     766      'kid' => $key_id,
     767      'typ' => 'JWT',
     768    ];
     769
     770    // Prepare JWT payload
     771    $payload = [
     772      'iss' => $issuer_id,
     773      'iat' => time(),
     774      'exp' => time() + 1200, // 20 minutes
     775      'aud' => 'appstoreconnect-v1',
     776      "bid" => $bundle_id
     777    ];
     778
     779    // Encode header and payload
     780    $encoded_header = $this->base64url_encode(json_encode($header, JSON_UNESCAPED_SLASHES));
     781    $encoded_payload = $this->base64url_encode(json_encode($payload, JSON_UNESCAPED_SLASHES));
     782
     783    $data_to_sign = $encoded_header . '.' . $encoded_payload;
     784
     785    // Clean and format the P8 key properly
     786    $p8_key_cleaned = $this->clean_p8_key($p8_key);
     787
     788    // Load EC private key
     789    $private_key = openssl_pkey_get_private($p8_key_cleaned);
     790    if ($private_key === false) {
     791      error_log('Webtonative: Invalid private key format: ' . openssl_error_string());
     792      error_log('Webtonative: P8 key preview: ' . substr($p8_key_cleaned, 0, 100) . '...');
     793      return false;
     794    }
     795
     796    // Verify key details for debugging
     797    $key_details = openssl_pkey_get_details($private_key);
     798    if ($key_details && isset($key_details['type'])) {
     799      error_log('Webtonative: Key type: ' . $key_details['type'] . ' (should be ' . OPENSSL_KEYTYPE_EC . ' for EC)');
     800    }
     801
     802    // Sign the data using ES256 (ECDSA with SHA-256)
     803    $signature = '';
     804    if (!openssl_sign($data_to_sign, $signature, $private_key, OPENSSL_ALGO_SHA256)) {
     805      error_log('Webtonative: Signing failed: ' . openssl_error_string());
     806      return false;
     807    }
     808
     809    // For ES256, we need to convert the DER signature to IEEE P1363 format
     810    // Apple expects the signature in this specific format
     811    $ieee_signature = $this->der_to_ieee_p1363($signature);
     812    if ($ieee_signature === false) {
     813      error_log('Webtonative: Failed to convert signature to IEEE P1363 format');
     814      return false;
     815    }
     816
     817    // Encode signature
     818    $encoded_signature = $this->base64url_encode($ieee_signature);
     819
     820    // Build the JWT
     821    $jwt = $data_to_sign . '.' . $encoded_signature;
     822
     823    // Log JWT parts for debugging (remove in production)
     824    error_log('Webtonative: JWT Header: ' . $encoded_header);
     825    error_log('Webtonative: JWT Payload: ' . $encoded_payload);
     826    error_log('Webtonative: JWT Signature length: ' . strlen($encoded_signature));
     827
     828    return $jwt;
     829  }
     830
     831  /**
     832   * Clean and format P8 private key content
     833   *
     834   * @param string $p8_key Raw P8 key content
     835   * @return string Properly formatted P8 key
     836   */
     837  private function clean_p8_key($p8_key)
     838  {
     839    // Remove any extra whitespace and normalize line breaks
     840    $key = trim($p8_key);
     841
     842    // Ensure proper PEM format
     843    if (strpos($key, '-----BEGIN PRIVATE KEY-----') === false) {
     844      // If missing header, add it
     845      $key = "-----BEGIN PRIVATE KEY-----\n" . $key;
     846    }
     847
     848    if (strpos($key, '-----END PRIVATE KEY-----') === false) {
     849      // If missing footer, add it
     850      $key = $key . "\n-----END PRIVATE KEY-----";
     851    }
     852
     853    // Normalize line breaks and ensure proper formatting
     854    $key = str_replace(["\r\n", "\r"], "\n", $key);
     855
     856    // Split into lines and reconstruct
     857    $lines = explode("\n", $key);
     858    $formatted_lines = [];
     859
     860    foreach ($lines as $line) {
     861      $line = trim($line);
     862      if (!empty($line)) {
     863        $formatted_lines[] = $line;
     864      }
     865    }
     866
     867    return implode("\n", $formatted_lines);
     868  }
     869
     870  /**
     871   * Convert DER signature to IEEE P1363 format required by Apple
     872   *
     873   * @param string $der_signature DER encoded signature from OpenSSL
     874   * @return string|false IEEE P1363 format signature or false on failure
     875   */
     876  private function der_to_ieee_p1363($der_signature)
     877  {
     878    // Parse DER signature
     879    $offset = 0;
     880    $length = strlen($der_signature);
     881
     882    if ($length < 6 || ord($der_signature[0]) !== 0x30) {
     883      return false; // Not a valid DER sequence
     884    }
     885
     886    $offset = 2; // Skip sequence tag and length
     887
     888    // Read R value
     889    if (ord($der_signature[$offset]) !== 0x02) {
     890      return false; // Expected integer tag
     891    }
     892    $offset++;
     893
     894    $r_length = ord($der_signature[$offset]);
     895    $offset++;
     896
     897    $r = substr($der_signature, $offset, $r_length);
     898    $offset += $r_length;
     899
     900    // Read S value
     901    if (ord($der_signature[$offset]) !== 0x02) {
     902      return false; // Expected integer tag
     903    }
     904    $offset++;
     905
     906    $s_length = ord($der_signature[$offset]);
     907    $offset++;
     908
     909    $s = substr($der_signature, $offset, $s_length);
     910
     911    // Remove leading zero bytes if present (DER encoding adds them for positive numbers)
     912    while (strlen($r) > 32 && ord($r[0]) === 0x00) {
     913      $r = substr($r, 1);
     914    }
     915    while (strlen($s) > 32 && ord($s[0]) === 0x00) {
     916      $s = substr($s, 1);
     917    }
     918
     919    // Pad to 32 bytes if necessary (P-256 curve uses 32-byte coordinates)
     920    $r = str_pad($r, 32, "\x00", STR_PAD_LEFT);
     921    $s = str_pad($s, 32, "\x00", STR_PAD_LEFT);
     922
     923    return $r . $s;
     924  }
     925
     926  /**
     927   * Encode data to base64url format (RFC 7515).
     928   *
     929   * @param string $data The data to encode.
     930   * @return string The base64url-encoded string.
     931   */
     932  private function base64url_encode($data)
     933  {
     934    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
    563935  }
    564936}
  • webtonative/trunk/admin/iap/woo-commerce.php

    r3322172 r3342866  
    155155      $this->init_settings();
    156156      $this->enabled = $this->get_option('enabled');
    157       $this->appStoreSecret = $this->get_option('appStoreSecret');
    158       $this->isTest = $this->get_option('isTest');
     157      // $this->appStoreSecret = $this->get_option('appStoreSecret');
     158      // $this->isTest = $this->get_option('isTest');
    159159
    160160      // This action hook saves the settings
  • webtonative/trunk/index.php

    r3335352 r3342866  
    33  Plugin Name: webtonative
    44  Description: webtonative Plugin
    5   Version: 2.9.1
     5  Version: 2.9.2
    66  Author: webtonative
    77*/
  • webtonative/trunk/website/iap.php

    r3329535 r3342866  
    2020  {
    2121    $saved_settings = get_option('wtn_iap_settings', array());
    22     $webtonative_settings = get_option('woocommerce_webtonative_settings');
     22    // $webtonative_settings = get_option('woocommerce_webtonative_settings');
    2323
    24     wp_register_script('webtonative-iap', plugins_url('scripts/woocommerce.js?var=6.14.7', __FILE__), array('webtonative', 'jquery'), filemtime(plugin_dir_path(__FILE__) . 'scripts/woocommerce.js'), true);
     24    wp_register_script('webtonative-iap', plugins_url('scripts/woocommerce.js?var=6.14.9', __FILE__), array('webtonative', 'jquery'), filemtime(plugin_dir_path(__FILE__) . 'scripts/woocommerce.js'), true);
    2525    wp_localize_script('webtonative-iap', 'wtn_biometric_settings', array(
    2626      'btn_proccessing_text' => $saved_settings['processing_button_text'],
     
    3030      'iap_enabled' => $saved_settings['iap_enabled'],
    3131      'isLoggedIn'     => is_user_logged_in(),
    32       'iosSecretKey' => $saved_settings['appStoreSecret'],
     32
     33      'appStoreBundleId' => $saved_settings['appStoreBundleId'] ?? '',
     34      'appStoreKeyId' => $saved_settings['appStoreKeyId'] ?? '',
     35      'appStoreIssuerId' => $saved_settings['appStoreIssuerId'] ?? '',
     36      'appStorePrivateKey' => $saved_settings['appStorePrivateKey'] ?? '',
    3337    ));
    3438    wp_localize_script('webtonative-iap', 'webtonative_payment_settings', array(
  • webtonative/trunk/website/index.php

    r3296993 r3342866  
    1919  function __construct()
    2020  {
    21     wp_enqueue_script('webtonative', plugin_dir_url(__FILE__) . 'scripts/webtonative.min.js', array(), '1.0.66', true);
     21    wp_enqueue_script('webtonative', plugin_dir_url(__FILE__) . 'scripts/webtonative.min.js?ver=1.0.0', array(), '1.0.66', true);
    2222    $this->social = new WebtonativeSocialLoginWebsite();
    2323    // $this->biometric = new WebtonativeBiometricWebsite();
  • webtonative/trunk/website/scripts/webtonative.min.js

    r3296993 r3342866  
    1 !function(){"use strict";var e={d:function(n,t){for(var i in t)e.o(t,i)&&!e.o(n,i)&&Object.defineProperty(n,i,{enumerable:!0,get:t[i]})},o:function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},r:function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},n={};e.r(n),e.d(n,{addToSiri:function(){return ee},appFirstLoad:function(){return ne},clearAppCache:function(){return z},closeApp:function(){return Q},customFileDownload:function(){return V},default:function(){return re},deviceInfo:function(){return H},downloadBlobFile:function(){return J},downloadFile:function(){return L},enablePullToRefresh:function(){return j},forceUpdateCookies:function(){return te},hideSplashScreen:function(){return W},isAndroidApp:function(){return C},isDeviceGPSEnabled:function(){return q},isIosApp:function(){return B},isNativeApp:function(){return m},loadOfferCard:function(){return $},openUrlInBrowser:function(){return K},platform:function(){return h},printFunction:function(){return Y},shareFile:function(){return X},shareLink:function(){return G},showDateTimePicker:function(){return Z},showInAppReview:function(){return x},showPermission:function(){return ie},statusBar:function(){return U},updateAppIcon:function(){return oe}});var t={};e.r(t),e.d(t,{addTrigger:function(){return Pe},addTriggers:function(){return Ae},getPlayerId:function(){return ae},getTriggerValue:function(){return fe},getTriggers:function(){return pe},logoutEmail:function(){return De},logoutSMSNumber:function(){return ge},optInUser:function(){return _e},optOutUser:function(){return Se},removeExternalUserId:function(){return ce},removeTrigger:function(){return le},removeTriggers:function(){return de},setEmail:function(){return Ie},setExternalUserId:function(){return se},setSMSNumber:function(){return Oe},setTags:function(){return ue}});var i={};e.r(i),e.d(i,{BarcodeScan:function(){return ye},Format:function(){return we},Types:function(){return Re}});var o={};e.r(o),e.d(o,{bannerAd:function(){return Te},fullScreenAd:function(){return be},rewardsAd:function(){return ke}});var r={};e.r(r),e.d(r,{logEvent:function(){return Fe},setCustomerUserId:function(){return Ee}});var a={};e.r(a),e.d(a,{send:function(){return Ce},sendPurchase:function(){return Be}});var s={};e.r(s),e.d(s,{hide:function(){return We},show:function(){return Ue}});var c={};e.r(c),e.d(c,{getAll:function(){return Je},getPermissionStatus:function(){return Le}});var u={};e.r(u),e.d(u,{start:function(){return Ve},stop:function(){return He}});var P={};e.r(P),e.d(P,{keepScreenNormal:function(){return qe},keepScreenOn:function(){return xe}});var A={};e.r(A),e.d(A,{get:function(){return Ge},set:function(){return Ke}});var l={};e.r(l),e.d(l,{prompt:function(){return je}});var d={};e.r(d),e.d(d,{checkStatus:function(){return ze},deleteSecret:function(){return Qe},saveSecret:function(){return Xe},show:function(){return Ze}});var f={};e.r(f),e.d(f,{request:function(){return Ye},status:function(){return $e}});var p={};e.r(p),e.d(p,{logEvent:function(){return rn},logScreen:function(){return an},setCollection:function(){return en},setDefaultEventParameters:function(){return on},setUserId:function(){return nn},setUserProperty:function(){return tn}});var I={};e.r(I),e.d(I,{events:function(){return p}});var O={};e.r(O),e.d(O,{getFCMToken:function(){return un},subscribe:function(){return sn},unsubscribe:function(){return cn}});var D={};e.r(D),e.d(D,{Analytics:function(){return p},Messaging:function(){return O}});var g={};e.r(g),e.d(g,{trigger:function(){return Pn}});var _={};e.r(_),e.d(_,{pauseMedia:function(){return ln},playMedia:function(){return An},stopMedia:function(){return dn}});var S={};e.r(S),e.d(S,{setPrintSize:function(){return fn}});var N={};e.r(N),e.d(N,{checkNotificationPermission:function(){return pn},openAppNotificationPage:function(){return In}});var v={};e.r(v),e.d(v,{pairDevice:function(){return Dn},startBluetoothScan:function(){return On},unpairDevice:function(){return gn}});var w="undefined"!=typeof window,R=w&&window.WebToNativeInterface||{},y=w&&window.webkit&&window.webkit.messageHandlers&&window.webkit.messageHandlers.webToNativeInterface,h=R.getAndroidVersion?"ANDROID_APP":y?"IOS_APP":"WEBSITE",m=w&&"WEBSITE"!==h,T={},b=1,k=null;m&&(R.androidCBHook=function(e){var n=e;try{n=JSON.parse(e)}catch(e){console.log(e)}for(var t in n.type,T){var i=T[t],o=i.cb,r=i.ignoreDelete,a=void 0!==r&&r;n&&n.reqType?t==n.reqType&&(o(n),a||delete T[t]):(o(n),a||delete T[t])}},window.iOSAdMobCBHook=R.androidAdMobCBHook=function(e){var n=JSON.parse(e);k&&k(n)},window.iosCBHook=function(e){var n=e;try{n=JSON.parse(e)}catch(e){console.log(e)}for(var t in T){var i=T[t],o=i.cb,r=i.ignoreDelete,a=void 0!==r&&r;n&&n.reqType?t==n.reqType&&(o(n),a||delete T[t]):(o(n),a||delete T[t])}});var M=function(e,n){"function"==typeof e&&(n&&n.key?T[n.key]={cb:e,ignoreDelete:!!n.ignoreDelete}:(T[b]={cb:e,ignoreDelete:!(!n||!n.ignoreDelete)},b+=1))},E=function(e){"function"==typeof e&&(k=e)},F=function(){k&&(k=null)},C="ANDROID_APP"===h,B="IOS_APP"===h,W=function(){m&&R.hideSplashScreen()},U=function(e){m&&(C?R.statusBar(JSON.stringify(e)):B&&y.postMessage({action:"statusBar",color:e.color,style:e.style}))},L=function(e){m&&(C||B&&y.postMessage({action:"downloadFile",downloadUrl:e}))},J=function(e){var n=e.fileName,t=e.downloadUrl;["IOS_APP"].includes(h)&&B&&y.postMessage({action:"downloadBlobFile",fileName:n,url:t})},V=function(e){var n=e.downloadUrl,t=e.fileName,i=e.isBlob,o=e.mimeType,r=e.cookies,a=e.userAgent,s=e.openFileAfterDownload;["ANDROID_APP"].includes(h)&&"ANDROID_APP"===h&&R.downloadFile(JSON.stringify({url:n,fileName:t,isBlob:i,mimeType:o,cookies:r,userAgent:a,openFileAfterDownload:s}))},H=function(){return new Promise((function(e,n){M((function(t){t?e(t):n({err:"Error getting device info"})}),{key:"deviceInfo"}),"ANDROID_APP"===h?R.getDeviceInfo():"IOS_APP"===h?y.postMessage({action:"deviceInfo"}):n("This function will work in Native App Powered By WebToNative")}))},x=function(){m&&R.showInAppReview()},q=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["ANDROID_APP","IOS_APP"].includes(h)&&(M((function(e){"isDeviceGPSEnabled"===e.type&&n&&n(e)})),"ANDROID_APP"===h&&R.isLocationServiceEnabled())},G=function(e){var n=e.url,t=void 0===n?"":n;if(!t)throw"url is mandatory";C&&R.openShareIntent(t),B&&y.postMessage({action:"share",url:t})},K=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";if(!e)throw"url is mandatory";C&&R.openUrlInBrowser(e)},j=function(e){C&&R.enableSwipeRefresh(e)},z=function(e){C&&R.clearWebViewCache(JSON.stringify({reload:e}))},X=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;C&&R.shareFile(e,n,t)},Q=function(){C&&R.closeApp(),B&&y.postMessage({action:"closeApp"})},Z=function(e){if(["ANDROID_APP"].includes(h)){var n=e.callback,t=e.showDate,i=e.showTime;M((function(e){"DATE_TIME_PICKER"===e.type&&n&&n(e)})),C&&R.pickDateTime(JSON.stringify({showDate:t,showTime:i}))}},Y=function(e){if(["ANDROID_APP"].includes(h)){var n=e.type,t=void 0===n?"url":n,i=e.url,o=void 0===i?"":i;C&&R.print(JSON.stringify({type:t,url:o}))}},$=function(e){["ANDROID_APP","IOS_APP"].includes(h)&&(C&&R.showOfferCard(JSON.stringify(e)),e.data&&(e.data=JSON.stringify(e.data)),B&&y.postMessage(e))},ee=function(e){["IOS_APP"].includes(h)&&(e.data&&(e.data=JSON.stringify(e.data)),B&&y.postMessage(e))},ne=function(){return new Promise((function(e,n){M((function(t){t?e(t):n({err:"Error getting request"})}),{key:"firstCallWhenAppStarted"}),"ANDROID_APP"===h?R.firstCallWhenAppStarted():"IOS_APP"===h?y.postMessage({action:"firstCallWhenAppStarted"}):n("This function will work in Native App Powered By WebToNative")}))},te=function(){["ANDROID_APP"].includes(h)&&C&&R.forceUpdateCookies()},ie=function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.callback,t=e.permissionType;M((function(e){var t=e.type,i=e.typeValue;"showPermission"!==t&&"showPermission"!==i||n&&n(e)})),C&&R.showPermission(t),B&&y.postMessage({action:"showPermission",type:t})}},oe=function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.active,t=void 0!==n&&n,i=e.iconName,o=void 0===i?null:i;C&&R.updateAppIcon(JSON.stringify({active:t,iconName:o})),B&&y.postMessage({action:"updateAppIcon",iconName:o,active:t})}},re={isAndroidApp:C,isIosApp:B,hideSplashScreen:W,statusBar:U,deviceInfo:H,showInAppReview:x,shareLink:G,platform:h,isNativeApp:m,isDeviceGPSEnabled:q,openUrlInBrowser:K,enablePullToRefresh:j,shareFile:X,clearAppCache:z,closeApp:Q,showDateTimePicker:Z,downloadBlobFile:J,customFileDownload:V,printFunction:Y,loadOfferCard:$,appFirstLoad:ne,addToSiri:ee,showPermission:ie,forceUpdateCookies:te,updateAppIcon:oe},ae=function(){return new Promise((function(e,n){M((function(t){t.isSuccess?e(t.playerId):n(t)}),{key:"getPlayerId"}),"ANDROID_APP"===h?R.getOneSignalId():"IOS_APP"===h?y.postMessage({action:"getPlayerId"}):n("This function will work in Native App Powered By WebToNative")}))},se=function(e){if(!e)throw"userId is required";if("ANDROID_APP"===h)return m&&R.setExternalUserId(e);"IOS_APP"===h&&y.postMessage({action:"setExternalUserId",userId:e})},ce=function(){if("ANDROID_APP"===h)return m&&R.removeExternalUserId();"IOS_APP"===h&&y.postMessage({action:"removeExternalUserId"})},ue=function(e){var n=e.tags;if(n){if("ANDROID_APP"===h)return m&&R.setUserTags(JSON.stringify(n));"IOS_APP"===h&&y.postMessage({action:"setUserTags",tags:n})}},Pe=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.key,t=e.value;"ANDROID_APP"===h?R.addTrigger(JSON.stringify({key:n,value:t})):"IOS_APP"===h&&y.postMessage({action:"addTrigger",key:n,value:t})},Ae=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.triggers;"ANDROID_APP"===h?R.addTriggers(JSON.stringify({triggers:n})):"IOS_APP"===h&&y.postMessage({action:"addTriggers",triggers:n})},le=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.key;"ANDROID_APP"===h?R.removeTriggerForKey(n):"IOS_APP"===h&&y.postMessage({action:"removeTrigger",key:n})},de=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.keys;"ANDROID_APP"===h?R.removeTriggersForKeys(JSON.stringify({keys:n})):"IOS_APP"===h&&y.postMessage({action:"removeTriggers",keys:n})},fe=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.key,t=e.callback;["ANDROID_APP","IOS_APP"].includes(h)&&(M((function(e){"getTriggerValue"===e.type&&t&&t(e)})),"ANDROID_APP"===h?R.getTriggerValueForKey(n):"IOS_APP"===h&&y.postMessage({action:"getTriggerValue",key:n}))},pe=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["ANDROID_APP","IOS_APP"].includes(h)&&(M((function(e){"getTriggers"===e.type&&n&&n(e)})),"ANDROID_APP"===h?R.getTriggers():"IOS_APP"===h&&y.postMessage({action:"getTriggers"}))},Ie=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.emailId;["ANDROID_APP","IOS_APP"].includes(h)&&"ANDROID_APP"===h&&R.setEmail(n)},Oe=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.smsNumber;["ANDROID_APP","IOS_APP"].includes(h)&&"ANDROID_APP"===h&&R.setSMSNumber(n)},De=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.emailId;["ANDROID_APP","IOS_APP"].includes(h)&&"ANDROID_APP"===h&&R.logoutEmail(n)},ge=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.smsNumber;["ANDROID_APP","IOS_APP"].includes(h)&&"ANDROID_APP"===h&&R.logoutSMSNumber(n)},_e=function(){"ANDROID_APP"===h?R.optInOneSignalPermissionDialog():"IOS_APP"===h&&y.postMessage({action:"optInOneSignalPermissionDialog"})},Se=function(){"ANDROID_APP"===h?R.optOutOneSignalPermissionDialog():"IOS_APP"===h&&y.postMessage({action:"optOutOneSignalPermissionDialog"})},Ne=void 0,ve=null,we={UNKNOWN:-1,ALL_FORMATS:0,CODE_128:1,CODE_39:2,CODE_93:4,CODABAR:8,DATA_MATRIX:16,EAN_13:32,EAN_8:64,ITF:128,QR_CODE:256,UPC_A:512,UPC_E:1024,PDF417:2048,AZTEC:4096},Re={UNKNOWN:0,CONTACT_INFO:1,EMAIL:2,ISBN:3,PHONE:4,PRODUCT:5,SMS:6,TEXT:7,URL:8,WIFI:9,GEO:10,CALENDAR_EVENT:11,DRIVER_LICENSE:12},ye=function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.onBarcodeSearch,t=e.format;M((function(e){var t=e.type,i=e.value;"BARCODE_SCAN"===t&&n&&n(i)})),"ANDROID_APP"===h&&R.startScanner(JSON.stringify({formats:t?[t]:[]})),"IOS_APP"===h&&y.postMessage({action:"barcodeScan",barcodeFormat:String(t||we.ALL_FORMATS)})}},he=void 0,me=null,Te=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(["ANDROID_APP","IOS_APP"].includes(h))return"IOS_APP"===h&&y.postMessage({action:"showBannerAd",adId:e.adId||""}),"ANDROID_APP"===h&&R.showBannerAd(JSON.stringify(e)),he},be=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.fullScreenAdCallback;return E((function(e){var n=e.status;me&&me(e),"adDismissed"===n&&(me=null),["adDismissed","adLoadError","adError"].indexOf(n)>-1&&F()})),"IOS_APP"===h&&y.postMessage({action:"showFullScreenAd",adId:e.adId||""}),"ANDROID_APP"===h&&R.showFullScreenAd(JSON.stringify(e)),"function"==typeof n&&(me=n),he}},ke=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.rewardsAdCallback;return E((function(e){var n=e.status;me&&me(e),"adDismissed"===n&&(me=null),["adDismissed","adLoadError","adError"].indexOf(n)>-1&&F()})),"IOS_APP"===h&&y.postMessage({action:"showRewardAd",adId:e.adId||""}),"ANDROID_APP"===h&&R.showRewardsAd(JSON.stringify(e)),"function"==typeof n&&(me=n),he}},Me={facebook:{login:function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.callback,t=e.scope;M((function(e){"fbLoginToken"===e.type&&n&&n(e)})),"ANDROID_APP"===h&&R.loginWithFacebook(),"IOS_APP"===h&&y.postMessage({action:"fbSignIn",scope:t})}},logout:function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.callback,t=e.scope;M((function(e){"fbLogOut"===e.type&&n&&n(e)})),"ANDROID_APP"===h&&R.logoutWithFacebook(),"IOS_APP"===h&&y.postMessage({action:"fbSignOut",scope:t})}}},google:{login:function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.callback,t=e.scope;M((function(e){"googleLoginToken"===e.type&&n&&n(e)})),"ANDROID_APP"===h&&R.signInWithGoogle(),"IOS_APP"===h&&y.postMessage({action:"googleSignIn",scope:t})}},logout:function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.callback,t=e.scope;M((function(e){"googleLogOut"===e.type&&n&&n(e)})),"ANDROID_APP"===h&&R.signOutWithGoogle(),"IOS_APP"===h&&y.postMessage({action:"googleSignOut",scope:t})}}},apple:{login:function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.callback,t=e.scope;M((function(e){"appleLoginToken"===e.type&&n&&n(e)})),"IOS_APP"===h&&y.postMessage({action:"appleSignIn",scope:t})}}}},Ee=function(e){["ANDROID_APP","IOS_APP"].includes(h)&&("ANDROID_APP"===h&&R.setAppsFlyerUserId(e),"IOS_APP"===h&&y.postMessage({action:"setAppsFlyerUserId",userId:e}))},Fe=function(e,n){["ANDROID_APP","IOS_APP"].includes(h)&&("ANDROID_APP"===h&&R.addEventToAppsFlyer(e,JSON.stringify(n)),"IOS_APP"===h&&y.postMessage({action:"addEventToAppsFlyer",eventName:e,eventValues:n}))},Ce=function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.event,t=e.valueToSum,i=e.parameters;"ANDROID_APP"===h&&R.addFbEvents(n,i),"IOS_APP"===h&&y.postMessage({action:"sendFBEvent",eventName:n,valueToSum:t,parameters:i})}},Be=function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.amount,t=e.currency,i=e.parameters;"ANDROID_APP"===h&&R.addFbPurchaseEvent(n,t,i),"IOS_APP"===h&&y.postMessage({action:"sendFBPurchaseEvent",currency:t,amount:n,parameters:i})}},We=function(){["ANDROID_APP","IOS_APP"].includes(h)&&("ANDROID_APP"===h&&R.showHideStickyFooter(!1),"IOS_APP"===h&&y.postMessage({action:"showHideStickyFooter",show:!1}))},Ue=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.key;["ANDROID_APP","IOS_APP"].includes(h)&&("ANDROID_APP"===h&&R.showHideStickyFooter(!0),"IOS_APP"===h&&y.postMessage({action:"showHideStickyFooter",show:!0,key:n}))},Le=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["ANDROID_APP","IOS_APP"].includes(h)&&(M((function(e){"contactPermissionStatus"===e.type&&n&&n(e)})),"ANDROID_APP"===h&&R.getPermissionStatus(),"IOS_APP"===h&&y.postMessage({action:"askUserForContactPermission"}))},Je=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["ANDROID_APP","IOS_APP"].includes(h)&&(M((function(e){"contactDetails"===e.type&&n&&n(e)})),"ANDROID_APP"===h&&R.getAll(),"IOS_APP"===h&&y.postMessage({action:"getUserContactDetails"}))},Ve=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.data,t=e.callback,i=e.backgroundIndicator,o=void 0!==i&&i,r=e.pauseAutomatically,a=void 0===r||r,s=e.distanceFilter,c=void 0===s?0:s,u=e.desiredAccuracy,P=void 0===u?"best":u,A=e.activityType,l=void 0===A?"other":A,d=e.apiUrl,f=e.timeout;M((function(e){"LOCATION_UPDATE"===e.type&&t&&t(e)}),{key:"LOCATION_UPDATE",ignoreDelete:!0}),"IOS_APP"===h&&y.postMessage({action:"startLocation",data:n,backgroundIndicator:o,pauseAutomatically:a,distanceFilter:c,desiredAccuracy:P,activityType:l,apiUrl:d,timeout:f}),"ANDROID_APP"===h&&R.startTrackingLocation(JSON.stringify({action:"startLocation",data:n,interval:f,callback:t,apiUrl:d,displacement:c}))}},He=function(){["ANDROID_APP","IOS_APP"].includes(h)&&(delete T["LOCATION_UPDATE"],"IOS_APP"===h&&y.postMessage({action:"stopLocation"}),"ANDROID_APP"===h&&R.stopTrackingLocation())},xe=function(){["ANDROID_APP","IOS_APP"].includes(h)&&("IOS_APP"===h&&y.postMessage({action:"keepScreenOn",flag:!0}),"ANDROID_APP"===h&&R.keepScreenOn())},qe=function(){["ANDROID_APP","IOS_APP"].includes(h)&&("IOS_APP"===h&&y.postMessage({action:"keepScreenOn",flag:!1}),"ANDROID_APP"===h&&R.keepScreenNormal())},Ge=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["ANDROID_APP","IOS_APP"].includes(h)&&(M((function(e){"CLIPBOARD_CONTENT"===e.type&&n&&n(e)})),"IOS_APP"===h&&y.postMessage({action:"getClipBoardData"}),"ANDROID_APP"===h&&R.getText())},Ke=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};["ANDROID_APP","IOS_APP"].includes(h)&&("IOS_APP"===h&&y.postMessage({action:"setClipBoardData",text:e.data||""}),"ANDROID_APP"===h&&R.setText(e.data||""))},je=function(){["ANDROID_APP","IOS_APP"].includes(h)&&("IOS_APP"===h&&y.postMessage({action:"showAppRating"}),"ANDROID_APP"===h&&R.showInAppReview())},ze=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["ANDROID_APP","IOS_APP"].includes(h)&&(M((function(e){"checkBiometricStatus"===e.type&&n&&n(e)})),"ANDROID_APP"===h&&R.checkBiometricStatus(),"IOS_APP"===h&&y.postMessage({action:"checkBiometricStatus"}))},Xe=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback,t=e.secret;["ANDROID_APP","IOS_APP"].includes(h)&&(M((function(e){"saveBiometricSecret"===e.type&&n&&n(e)})),"ANDROID_APP"===h&&R.saveSecret(t),"IOS_APP"===h&&y.postMessage({action:"saveBiometricSecret",secret:t}))},Qe=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["ANDROID_APP","IOS_APP"].includes(h)&&(M((function(e){"deleteBiometricSecret"===e.type&&n&&n(e)})),"ANDROID_APP"===h&&R.deleteSecret(),"IOS_APP"===h&&y.postMessage({action:"deleteBiometricSecret"}))},Ze=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback,t=e.prompt;["ANDROID_APP","IOS_APP"].includes(h)&&(M((function(e){"showBiometric"===e.type&&n&&n(e)})),"ANDROID_APP"===h&&R.callBiometric(t||"Authenticate to continue!"),"IOS_APP"===h&&y.postMessage({action:"showBiometric",prompt:t||""}))},Ye=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["IOS_APP"].includes(h)&&(M((function(e){"requestTrackingConsent"===e.type&&n&&n(e)})),"IOS_APP"===h&&y.postMessage({action:"requestTrackingAuthorization"}))},$e=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["IOS_APP"].includes(h)&&(M((function(e){"trackingConsentStatus"===e.type&&n&&n(e)})),"IOS_APP"===h&&y.postMessage({action:"trackingConsentStatus"}))},en=function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.enabled;"IOS_APP"===h&&y.postMessage({action:"setFirebaseAnalyticsCollection",enabled:n}),"ANDROID_APP"===h&&R.setFirebaseAnalyticsCollection(n)}},nn=function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.userId;"IOS_APP"===h&&y.postMessage({action:"setFirebaseUserId",userId:n}),"ANDROID_APP"===h&&R.setFirebaseUserId(n)}},tn=function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.key,t=e.value;"IOS_APP"===h&&y.postMessage({action:"setFirebaseUserProp",key:n,value:t}),"ANDROID_APP"===h&&R.setFirebaseUserProp(n,t)}},on=function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.parameters;"IOS_APP"===h&&y.postMessage({action:"setFirebaseDefaultParam",parameters:n}),"ANDROID_APP"===h&&R.setFirebaseDefaultParam(n)}},rn=function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.eventName,t=e.parameters;"IOS_APP"===h&&y.postMessage({action:"logFirebaseEvent",eventName:n,parameters:t}),"ANDROID_APP"===h&&R.logFirebaseEvent(n,t)}},an=function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.screenName,t=e.screenClass;"IOS_APP"===h&&y.postMessage({action:"logFirebaseScreenView",screenName:n,screenClass:t}),"ANDROID_APP"===h&&R.logFirebaseScreenView(n,t)}},sn=function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.toTopic;"IOS_APP"===h&&y.postMessage({action:"firebaseSubscribeToTopic",topic:n}),"ANDROID_APP"===h&&R.subscribeToTopic(n)}},cn=function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.fromTopic;"IOS_APP"===h&&y.postMessage({action:"firebaseUnsubscribeFromTopic",topic:n}),"ANDROID_APP"===h&&R.unsubscribeFromTopic(n)}},un=function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.callback;M((function(e){"getFCMToken"===e.type&&("ANDROID_APP"===h&&(e.token=e.fcm_registration_token),n&&n(e))})),"IOS_APP"===h&&y.postMessage({action:"getFCMToken"}),"ANDROID_APP"===h&&R.getRegistrationToken()}},Pn=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};["ANDROID_APP","IOS_APP"].includes(h)&&"IOS_APP"===h&&y.postMessage({action:"haptikEffect",effect:e.effect})},An=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url,t=e.imageUrl,i=void 0===t?"https://images.freeimages.com/images/large-previews/3b2/prague-conference-center-1056491.jpg":t;["ANDROID_APP","IOS_APP"].includes(h)&&"ANDROID_APP"===h&&R.playMedia(JSON.stringify({url:n,imageUrl:i}))},ln=function(){["ANDROID_APP","IOS_APP"].includes(h)&&"ANDROID_APP"===h&&R.pausePlaying()},dn=function(){["ANDROID_APP","IOS_APP"].includes(h)&&"ANDROID_APP"===h&&R.stopPlaying()},fn=function(e){if(["ANDROID_APP"].includes(h)){var n=e.printSize,t=void 0===n?"ISO_A4":n,i=e.label,o=void 0===i?"":i;"ANDROID_APP"===h&&R.setPrintSize(JSON.stringify({printSize:t,label:o}))}},pn=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["ANDROID_APP","IOS_APP"].includes(h)&&(M((function(e){"checkNotificationPermission"===e.type&&n&&n(e)})),"ANDROID_APP"===h&&R.checkNotificationPermission(),"IOS_APP"===h&&y.postMessage({action:"checkNotificationPermission"}))},In=function(){["ANDROID_APP","IOS_APP"].includes(h)&&("ANDROID_APP"===h&&R.openAppNotificationPage(),"IOS_APP"===h&&y.postMessage({action:"openAppNotificationPage"}))},On=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["ANDROID_APP"].includes(h)&&(M((function(e){"startBluetoothScan"===e.type&&n&&n(e)})),"ANDROID_APP"===h&&R.startBluetoothScan())},Dn=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback,t=e.address,i=e.timeout,o=void 0===i?10:i;["ANDROID_APP"].includes(h)&&(M((function(e){"pairWithDevice"===e.type&&n&&n(e)})),"ANDROID_APP"===h&&R.pairWithDevice(JSON.stringify({address:t,timeout:o})))},gn=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback,t=e.address;["ANDROID_APP"].includes(h)&&(M((function(e){"unpairDevice"===e.type&&n&&n(e)})),"ANDROID_APP"===h&&R.unpairDevice(JSON.stringify({address:t})))};window.WTN=n,window.WTN.OneSignal=t,window.WTN.VoiceSearch=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.onVoiceSearch;return M((function(e){var n=e.type,t=e.results;"VOICE_SEARCH_RESULT"===n&&(ve&&ve(t),ve=null)})),m&&R.openVoiceSearch(),"function"==typeof n&&(ve=n),Ne},window.WTN.Barcode=i,window.WTN.AdMob=o,window.WTN.socialLogin=Me,window.WTN.inAppPurchase=function(e){if(["ANDROID_APP","IOS_APP"].includes(h)){var n=e.callback,t=e.productId,i=e.productType,o=e.isConsumable,r=void 0!==o&&o;M((function(e){"inAppPurchase"===e.type&&n&&n(e)})),"IOS_APP"===h&&y.postMessage({action:"inAppPurchase",productId:t}),"ANDROID_APP"===h&&R.inAppPurchase(JSON.stringify({action:"inAppPurchase",productId:t,productType:i,isConsumable:r}))}},window.WTN.getAllPurchases=function(e){if(["ANDROID_APP"].includes(h)){var n=e.callback;M((function(e){"purchaseList"===e.type&&n&&n(e)})),"ANDROID_APP"===h&&R.getAllPurchases({action:"purchaseList"})}},window.WTN.getReceiptData=function(e){if(["IOS_APP"].includes(h)){var n=e.callback;M((function(e){"getReceiptData"===e.type&&n&&n(e)})),"IOS_APP"===h&&y.postMessage({action:"getReceiptData"})}},window.WTN.appsflyer=r,window.WTN.bottomNavigation=s,window.WTN.contacts=c,window.WTN.screen=P,window.WTN.backgroundLocation=u,window.WTN.clipboard=A,window.WTN.appReview=l,window.WTN.Biometric=d,window.WTN.ATTConsent=f,window.WTN.facebook={events:a},window.WTN.firebaseAnalytics=I,window.WTN.haptics=g,window.WTN.Firebase=D,window.WTN.MediaPlayer=_,window.WTN.Printing=S,window.WTN.Notification=N,window.WTN.Bluetooth=v,window&&window.WebToNativeInterface&&window.WebToNativeInterface.getAndroidVersion?window.navigator.share=function(e){return new Promise((function(n,t){window.WebToNativeInterface.openShareIntent(e.url),n()}))}:WTN.isIosApp&&(window.navigator.share=function(e){return new Promise((function(n,t){y.postMessage({action:"share",url:e.url}),n()}))})}();
     1!function(){"use strict";var e={d:function(n,t){for(var i in t)e.o(t,i)&&!e.o(n,i)&&Object.defineProperty(n,i,{enumerable:!0,get:t[i]})},o:function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},r:function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},n={};e.r(n),e.d(n,{addToSiri:function(){return ie},appFirstLoad:function(){return oe},checkPermission:function(){return de},clearAppCache:function(){return Q},closeApp:function(){return Y},customBackHandling:function(){return Pe},customFileDownload:function(){return H},default:function(){return pe},deviceInfo:function(){return x},disableScreenshot:function(){return ue},downloadBlobFile:function(){return j},downloadFile:function(){return V},enablePullToRefresh:function(){return X},forceUpdateCookies:function(){return re},getAddOnStatus:function(){return le},getSafeArea:function(){return Ae},hideSplashScreen:function(){return L},isAndroidApp:function(){return B},isDeviceGPSEnabled:function(){return K},isIosApp:function(){return U},isNativeApp:function(){return T},loadOfferCard:function(){return te},nfcSupported:function(){return ne},openAppSettingForPermission:function(){return ae},openUrlInBrowser:function(){return z},platform:function(){return b},printFunction:function(){return ee},setOrientation:function(){return fe},shareFile:function(){return Z},shareLink:function(){return G},showDateTimePicker:function(){return $},showInAppReview:function(){return q},showPermission:function(){return ce},statusBar:function(){return J},updateAppIcon:function(){return se}});var t={};e.r(t),e.d(t,{addTrigger:function(){return Se},addTriggers:function(){return _e},getPlayerId:function(){return Oe},getTriggerValue:function(){return ye},getTriggers:function(){return me},logoutEmail:function(){return we},logoutSMSNumber:function(){return be},optInUser:function(){return Te},optOutUser:function(){return ke},removeExternalUserId:function(){return Ie},removeTrigger:function(){return ve},removeTriggers:function(){return Ne},setEmail:function(){return Re},setExternalUserId:function(){return ge},setSMSNumber:function(){return he},setTags:function(){return De}});var i={};e.r(i),e.d(i,{BarcodeScan:function(){return We},Format:function(){return Ee},Types:function(){return Ce}});var o={};e.r(o),e.d(o,{bannerAd:function(){return Le},fullScreenAd:function(){return Je},rewardsAd:function(){return Ve}});var r={};e.r(r),e.d(r,{logEvent:function(){return xe},setCustomerUserId:function(){return He}});var a={};e.r(a),e.d(a,{send:function(){return qe},sendPurchase:function(){return Ke}});var c={};e.r(c),e.d(c,{hide:function(){return Ge},show:function(){return ze}});var s={};e.r(s),e.d(s,{getAll:function(){return Qe},getPermissionStatus:function(){return Xe}});var u={};e.r(u),e.d(u,{start:function(){return Ze},stop:function(){return Ye}});var P={};e.r(P),e.d(P,{keepScreenNormal:function(){return en},keepScreenOn:function(){return $e}});var A={};e.r(A),e.d(A,{get:function(){return nn},set:function(){return tn}});var l={};e.r(l),e.d(l,{prompt:function(){return on}});var d={};e.r(d),e.d(d,{biometricAuthWithDismissOnCancel:function(){return un},checkStatus:function(){return rn},deleteSecret:function(){return cn},saveSecret:function(){return an},show:function(){return sn}});var f={};e.r(f),e.d(f,{request:function(){return Pn},status:function(){return An}});var p={};e.r(p),e.d(p,{logEvent:function(){return On},logScreen:function(){return gn},setCollection:function(){return ln},setDefaultEventParameters:function(){return pn},setUserId:function(){return dn},setUserProperty:function(){return fn}});var O={};e.r(O),e.d(O,{events:function(){return p}});var g={};e.r(g),e.d(g,{getFCMToken:function(){return Sn},subscribe:function(){return In},unsubscribe:function(){return Dn}});var I={};e.r(I),e.d(I,{Analytics:function(){return p},Messaging:function(){return g}});var D={};e.r(D),e.d(D,{trigger:function(){return _n}});var S={};e.r(S),e.d(S,{pauseMedia:function(){return Nn},playMedia:function(){return vn},stopMedia:function(){return yn}});var _={};e.r(_),e.d(_,{setPrintSize:function(){return mn}});var v={};e.r(v),e.d(v,{checkNotificationPermission:function(){return Rn},openAppNotificationPage:function(){return hn}});var N={};e.r(N),e.d(N,{pairDevice:function(){return bn},startBluetoothScan:function(){return wn},unpairDevice:function(){return Tn}});var y={};e.r(y),e.d(y,{makeTapToPay:function(){return Fn}});var m={};e.r(m),e.d(m,{checkIfAppUpdateAvailable:function(){return En},updateApplication:function(){return Cn}});var R="undefined"!=typeof window,h=R&&window.WebToNativeInterface||{},w=R&&window.webkit&&window.webkit.messageHandlers&&window.webkit.messageHandlers.webToNativeInterface,b=h.getAndroidVersion?"ANDROID_APP":w?"IOS_APP":"WEBSITE",T=R&&"WEBSITE"!==b,k={},M=1,F=null;T&&(h.androidCBHook=function(e){var n=e;try{n=JSON.parse(e)}catch(e){console.log(e)}for(var t in n.type,k){var i=k[t],o=i.cb,r=i.ignoreDelete,a=void 0!==r&&r;n&&n.reqType?t==n.reqType&&(o(n),a||delete k[t]):(o(n),a||delete k[t])}},window.iOSAdMobCBHook=h.androidAdMobCBHook=function(e){var n=JSON.parse(e);F&&F(n)},window.iosCBHook=function(e){var n=e;try{n=JSON.parse(e)}catch(e){console.log(e)}for(var t in k){var i=k[t],o=i.cb,r=i.ignoreDelete,a=void 0!==r&&r;n&&n.reqType?t==n.reqType&&(o(n),a||delete k[t]):(o(n),a||delete k[t])}});var E=function(e,n){"function"==typeof e&&(n&&n.key?k[n.key]={cb:e,ignoreDelete:!!n.ignoreDelete}:(k[M]={cb:e,ignoreDelete:!(!n||!n.ignoreDelete)},M+=1))},C=function(e){"function"==typeof e&&(F=e)},W=function(){F&&(F=null)},B="ANDROID_APP"===b,U="IOS_APP"===b,L=function(){T&&h.hideSplashScreen()},J=function(e){T&&(B?h.statusBar(JSON.stringify(e)):U&&w.postMessage({action:"statusBar",color:e.color,style:e.style}))},V=function(e){T&&(B||U&&w.postMessage({action:"downloadFile",downloadUrl:e}))},j=function(e){var n=e.fileName,t=e.downloadUrl;["IOS_APP"].includes(b)&&U&&w.postMessage({action:"downloadBlobFile",fileName:n,url:t})},H=function(e){var n=e.downloadUrl,t=e.fileName,i=e.isBlob,o=e.mimeType,r=e.cookies,a=e.userAgent,c=e.openFileAfterDownload;["ANDROID_APP"].includes(b)&&"ANDROID_APP"===b&&h.downloadFile(JSON.stringify({url:n,fileName:t,isBlob:i,mimeType:o,cookies:r,userAgent:a,openFileAfterDownload:c}))},x=function(){return new Promise((function(e,n){E((function(t){t?e(t):n({err:"Error getting device info"})}),{key:"deviceInfo"}),"ANDROID_APP"===b?h.getDeviceInfo():"IOS_APP"===b?w.postMessage({action:"deviceInfo"}):n("This function will work in Native App Powered By WebToNative")}))},q=function(){T&&h.showInAppReview()},K=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["ANDROID_APP","IOS_APP"].includes(b)&&(E((function(e){"isDeviceGPSEnabled"===e.type&&n&&n(e)})),"ANDROID_APP"===b&&h.isLocationServiceEnabled())},G=function(e){var n=e.url,t=void 0===n?"":n;if(!t)throw"url is mandatory";B&&h.openShareIntent(t),U&&w.postMessage({action:"share",url:t})},z=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";if(!e)throw"url is mandatory";B&&h.openUrlInBrowser(e)},X=function(e){B&&h.enableSwipeRefresh(e)},Q=function(e){B&&h.clearWebViewCache(JSON.stringify({reload:e}))},Z=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;B&&h.shareFile(e,n,t)},Y=function(){B&&h.closeApp(),U&&w.postMessage({action:"closeApp"})},$=function(e){if(["ANDROID_APP"].includes(b)){var n=e.callback,t=e.showDate,i=e.showTime;E((function(e){"DATE_TIME_PICKER"===e.type&&n&&n(e)})),B&&h.pickDateTime(JSON.stringify({showDate:t,showTime:i}))}},ee=function(e){if(["ANDROID_APP"].includes(b)){var n=e.type,t=void 0===n?"url":n,i=e.url,o=void 0===i?"":i;B&&h.print(JSON.stringify({type:t,url:o}))}},ne=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.callback;E((function(e){"nfcSupported"===e.type&&n&&n(e)})),B&&h.nfcSupported(),U&&w.postMessage({action:"nfcSupported"})}},te=function(e){["ANDROID_APP","IOS_APP"].includes(b)&&(B&&h.showOfferCard(JSON.stringify(e)),e.data&&(e.data=JSON.stringify(e.data)),U&&w.postMessage(e))},ie=function(e){["IOS_APP"].includes(b)&&(e.data&&(e.data=JSON.stringify(e.data)),U&&w.postMessage(e))},oe=function(){return new Promise((function(e,n){E((function(t){"firstCallWhenAppStarted"===t.type&&(t?e(t):n({err:"Error getting request"}))}),{key:"firstCallWhenAppStarted"}),"ANDROID_APP"===b?h.firstCallWhenAppStarted():"IOS_APP"===b?w.postMessage({action:"firstCallWhenAppStarted"}):n("This function will work in Native App Powered By WebToNative")}))},re=function(){["ANDROID_APP"].includes(b)&&B&&h.forceUpdateCookies()},ae=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.callback,t=e.values;E((function(e){var t=e.type;e.typeValue,"openAppSettingForPermission"===t&&n&&n(e)})),B&&h.openAppSettingForPermission(t),U&&w.postMessage({action:"openAppSettingForPermission",values:t})}},ce=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.callback,t=e.permission,i=e.openAppSetting,o=void 0!==i&&i,r=e.alertDialogStyle;E((function(e){var t=e.type,i=e.typeValue;"showPermission"!==t&&"showPermission"!==i||n&&n(e)})),B&&h.showPermission(JSON.stringify({permission:t,openAppSetting:o,alertDialogStyle:r})),U&&w.postMessage({action:"showPermission",permission:t,openAppSetting:o,alertDialogStyle:r})}},se=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.active,t=void 0!==n&&n,i=e.iconName,o=void 0===i?null:i;B&&h.updateAppIcon(JSON.stringify({active:t,iconName:o})),U&&w.postMessage({action:"updateAppIcon",iconName:o,active:t})}},ue=function(e){if(["IOS_APP"].includes(b)){var n=e.ssKey,t=void 0!==n&&n;U&&w.postMessage({action:"disableScreenshotForPage",ssKey:t})}},Pe=function(e){if(["ANDROID_APP"].includes(b)){var n=e.enable,t=void 0!==n&&n;B&&h.customBackHandling(JSON.stringify({enable:t}))}},Ae=function(e){if(["IOS_APP"].includes(b)){var n=e.callback;E((function(e){"getSafeArea"===e.type&&n&&n(e)})),U&&w.postMessage({action:"getSafeArea"})}},le=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.callback,t=e.addOnName;E((function(e){"getAddOnStatus"===e.type&&n&&n(e)})),B&&h.getAddOnStatus(JSON.stringify({addOnName:t})),U&&w.postMessage({action:"getAddOnStatus",addOnName:t})}},de=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.callback,t=e.permissionName;E((function(e){"checkPermission"===e.type&&n&&n(e)})),B&&h.checkPermission(JSON.stringify(t)),U&&w.postMessage({action:"checkPermission",permissionName:t})}},fe=function(e){if(["ANDROID_APP"].includes(b)){var n=e.orientation,t=e.forceOrientation,i=void 0!==t&&t;B&&h.setOrientation(JSON.stringify({orientation:n,forceOrientation:i}))}},pe={isAndroidApp:B,isIosApp:U,hideSplashScreen:L,statusBar:J,deviceInfo:x,showInAppReview:q,shareLink:G,platform:b,isNativeApp:T,isDeviceGPSEnabled:K,openUrlInBrowser:z,enablePullToRefresh:X,shareFile:Z,clearAppCache:Q,closeApp:Y,showDateTimePicker:$,downloadBlobFile:j,customFileDownload:H,printFunction:ee,loadOfferCard:te,appFirstLoad:oe,addToSiri:ie,showPermission:ce,forceUpdateCookies:re,updateAppIcon:se,disableScreenshot:ue,getSafeArea:Ae,getAddOnStatus:le,setOrientation:fe,checkPermission:de,openAppSettingForPermission:ae,customBackHandling:Pe},Oe=function(){return new Promise((function(e,n){E((function(t){t.isSuccess?e(t.playerId):n(t)}),{key:"getPlayerId"}),"ANDROID_APP"===b?h.getOneSignalId():"IOS_APP"===b?w.postMessage({action:"getPlayerId"}):n("This function will work in Native App Powered By WebToNative")}))},ge=function(e){if(!e)throw"userId is required";if("ANDROID_APP"===b)return T&&h.setExternalUserId(e);"IOS_APP"===b&&w.postMessage({action:"setExternalUserId",userId:e})},Ie=function(){if("ANDROID_APP"===b)return T&&h.removeExternalUserId();"IOS_APP"===b&&w.postMessage({action:"removeExternalUserId"})},De=function(e){var n=e.tags;if(n){if("ANDROID_APP"===b)return T&&h.setUserTags(JSON.stringify(n));"IOS_APP"===b&&w.postMessage({action:"setUserTags",tags:n})}},Se=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.key,t=e.value;"ANDROID_APP"===b?h.addTrigger(JSON.stringify({key:n,value:t})):"IOS_APP"===b&&w.postMessage({action:"addTrigger",key:n,value:t})},_e=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.triggers;"ANDROID_APP"===b?h.addTriggers(JSON.stringify({triggers:n})):"IOS_APP"===b&&w.postMessage({action:"addTriggers",triggers:n})},ve=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.key;"ANDROID_APP"===b?h.removeTriggerForKey(n):"IOS_APP"===b&&w.postMessage({action:"removeTrigger",key:n})},Ne=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.keys;"ANDROID_APP"===b?h.removeTriggersForKeys(JSON.stringify({keys:n})):"IOS_APP"===b&&w.postMessage({action:"removeTriggers",keys:n})},ye=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.key,t=e.callback;["ANDROID_APP","IOS_APP"].includes(b)&&(E((function(e){"getTriggerValue"===e.type&&t&&t(e)})),"ANDROID_APP"===b?h.getTriggerValueForKey(n):"IOS_APP"===b&&w.postMessage({action:"getTriggerValue",key:n}))},me=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["ANDROID_APP","IOS_APP"].includes(b)&&(E((function(e){"getTriggers"===e.type&&n&&n(e)})),"ANDROID_APP"===b?h.getTriggers():"IOS_APP"===b&&w.postMessage({action:"getTriggers"}))},Re=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.emailId;["ANDROID_APP","IOS_APP"].includes(b)&&"ANDROID_APP"===b&&h.setEmail(n)},he=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.smsNumber;["ANDROID_APP","IOS_APP"].includes(b)&&"ANDROID_APP"===b&&h.setSMSNumber(n)},we=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.emailId;["ANDROID_APP","IOS_APP"].includes(b)&&"ANDROID_APP"===b&&h.logoutEmail(n)},be=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.smsNumber;["ANDROID_APP","IOS_APP"].includes(b)&&"ANDROID_APP"===b&&h.logoutSMSNumber(n)},Te=function(){"ANDROID_APP"===b?h.optInOneSignalPermissionDialog():"IOS_APP"===b&&w.postMessage({action:"optInOneSignalPermissionDialog"})},ke=function(){"ANDROID_APP"===b?h.optOutOneSignalPermissionDialog():"IOS_APP"===b&&w.postMessage({action:"optOutOneSignalPermissionDialog"})},Me=void 0,Fe=null,Ee={UNKNOWN:-1,ALL_FORMATS:0,CODE_128:1,CODE_39:2,CODE_93:4,CODABAR:8,DATA_MATRIX:16,EAN_13:32,EAN_8:64,ITF:128,QR_CODE:256,UPC_A:512,UPC_E:1024,PDF417:2048,AZTEC:4096},Ce={UNKNOWN:0,CONTACT_INFO:1,EMAIL:2,ISBN:3,PHONE:4,PRODUCT:5,SMS:6,TEXT:7,URL:8,WIFI:9,GEO:10,CALENDAR_EVENT:11,DRIVER_LICENSE:12},We=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.onBarcodeSearch,t=e.format;E((function(e){var t=e.type,i=e.value;"BARCODE_SCAN"===t&&n&&n(i)})),"ANDROID_APP"===b&&h.startScanner(JSON.stringify({formats:t?[t]:[]})),"IOS_APP"===b&&w.postMessage({action:"barcodeScan",barcodeFormat:String(t||Ee.ALL_FORMATS)})}},Be=void 0,Ue=null,Le=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(["ANDROID_APP","IOS_APP"].includes(b))return"IOS_APP"===b&&w.postMessage({action:"showBannerAd",adId:e.adId||""}),"ANDROID_APP"===b&&h.showBannerAd(JSON.stringify(e)),Be},Je=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.fullScreenAdCallback;return C((function(e){var n=e.status;Ue&&Ue(e),"adDismissed"===n&&(Ue=null),["adDismissed","adLoadError","adError"].indexOf(n)>-1&&W()})),"IOS_APP"===b&&w.postMessage({action:"showFullScreenAd",adId:e.adId||""}),"ANDROID_APP"===b&&h.showFullScreenAd(JSON.stringify(e)),"function"==typeof n&&(Ue=n),Be}},Ve=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.rewardsAdCallback;return C((function(e){var n=e.status;Ue&&Ue(e),"adDismissed"===n&&(Ue=null),["adDismissed","adLoadError","adError"].indexOf(n)>-1&&W()})),"IOS_APP"===b&&w.postMessage({action:"showRewardAd",adId:e.adId||""}),"ANDROID_APP"===b&&h.showRewardsAd(JSON.stringify(e)),"function"==typeof n&&(Ue=n),Be}},je={facebook:{login:function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.callback,t=e.scope;E((function(e){"fbLoginToken"===e.type&&n&&n(e)})),"ANDROID_APP"===b&&h.loginWithFacebook(),"IOS_APP"===b&&w.postMessage({action:"fbSignIn",scope:t})}},logout:function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.callback,t=e.scope;E((function(e){"fbLogOut"===e.type&&n&&n(e)})),"ANDROID_APP"===b&&h.logoutWithFacebook(),"IOS_APP"===b&&w.postMessage({action:"fbSignOut",scope:t})}}},google:{login:function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.callback,t=e.scope;E((function(e){"googleLoginToken"===e.type&&n&&n(e)})),"ANDROID_APP"===b&&h.signInWithGoogle(),"IOS_APP"===b&&w.postMessage({action:"googleSignIn",scope:t})}},logout:function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.callback,t=e.scope;E((function(e){"googleLogOut"===e.type&&n&&n(e)})),"ANDROID_APP"===b&&h.signOutWithGoogle(),"IOS_APP"===b&&w.postMessage({action:"googleSignOut",scope:t})}}},apple:{login:function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.callback,t=e.scope;E((function(e){"appleLoginToken"===e.type&&n&&n(e)})),"IOS_APP"===b&&w.postMessage({action:"appleSignIn",scope:t})}}}},He=function(e){["ANDROID_APP","IOS_APP"].includes(b)&&("ANDROID_APP"===b&&h.setAppsFlyerUserId(e),"IOS_APP"===b&&w.postMessage({action:"setAppsFlyerUserId",userId:e}))},xe=function(e,n){["ANDROID_APP","IOS_APP"].includes(b)&&("ANDROID_APP"===b&&h.addEventToAppsFlyer(e,JSON.stringify(n)),"IOS_APP"===b&&w.postMessage({action:"addEventToAppsFlyer",eventName:e,eventValues:n}))},qe=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.event,t=e.valueToSum,i=e.parameters;"ANDROID_APP"===b&&h.addFbEvents(n,i),"IOS_APP"===b&&w.postMessage({action:"sendFBEvent",eventName:n,valueToSum:t,parameters:i})}},Ke=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.amount,t=e.currency,i=e.parameters;"ANDROID_APP"===b&&h.addFbPurchaseEvent(n,t,i),"IOS_APP"===b&&w.postMessage({action:"sendFBPurchaseEvent",currency:t,amount:n,parameters:i})}},Ge=function(){["ANDROID_APP","IOS_APP"].includes(b)&&("ANDROID_APP"===b&&h.showHideStickyFooter(!1),"IOS_APP"===b&&w.postMessage({action:"showHideStickyFooter",show:!1}))},ze=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.key;["ANDROID_APP","IOS_APP"].includes(b)&&("ANDROID_APP"===b&&h.showHideStickyFooter(!0),"IOS_APP"===b&&w.postMessage({action:"showHideStickyFooter",show:!0,key:n}))},Xe=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["ANDROID_APP","IOS_APP"].includes(b)&&(E((function(e){"contactPermissionStatus"===e.type&&n&&n(e)})),"ANDROID_APP"===b&&h.getPermissionStatus(),"IOS_APP"===b&&w.postMessage({action:"askUserForContactPermission"}))},Qe=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["ANDROID_APP","IOS_APP"].includes(b)&&(E((function(e){"contactDetails"===e.type&&n&&n(e)})),"ANDROID_APP"===b&&h.getAll(),"IOS_APP"===b&&w.postMessage({action:"getUserContactDetails"}))},Ze=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.data,t=e.callback,i=e.backgroundIndicator,o=void 0!==i&&i,r=e.pauseAutomatically,a=void 0===r||r,c=e.distanceFilter,s=void 0===c?0:c,u=e.desiredAccuracy,P=void 0===u?"best":u,A=e.activityType,l=void 0===A?"other":A,d=e.apiUrl,f=e.timeout;E((function(e){"LOCATION_UPDATE"===e.type&&t&&t(e)}),{key:"LOCATION_UPDATE",ignoreDelete:!0}),"IOS_APP"===b&&w.postMessage({action:"startLocation",data:n,backgroundIndicator:o,pauseAutomatically:a,distanceFilter:s,desiredAccuracy:P,activityType:l,apiUrl:d,timeout:f}),"ANDROID_APP"===b&&h.startTrackingLocation(JSON.stringify({action:"startLocation",data:n,interval:f,callback:t,apiUrl:d,displacement:s}))}},Ye=function(){["ANDROID_APP","IOS_APP"].includes(b)&&(delete k["LOCATION_UPDATE"],"IOS_APP"===b&&w.postMessage({action:"stopLocation"}),"ANDROID_APP"===b&&h.stopTrackingLocation())},$e=function(){["ANDROID_APP","IOS_APP"].includes(b)&&("IOS_APP"===b&&w.postMessage({action:"keepScreenOn",flag:!0}),"ANDROID_APP"===b&&h.keepScreenOn())},en=function(){["ANDROID_APP","IOS_APP"].includes(b)&&("IOS_APP"===b&&w.postMessage({action:"keepScreenOn",flag:!1}),"ANDROID_APP"===b&&h.keepScreenNormal())},nn=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["ANDROID_APP","IOS_APP"].includes(b)&&(E((function(e){"CLIPBOARD_CONTENT"===e.type&&n&&n(e)})),"IOS_APP"===b&&w.postMessage({action:"getClipBoardData"}),"ANDROID_APP"===b&&h.getText())},tn=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};["ANDROID_APP","IOS_APP"].includes(b)&&("IOS_APP"===b&&w.postMessage({action:"setClipBoardData",text:e.data||""}),"ANDROID_APP"===b&&h.setText(e.data||""))},on=function(){["ANDROID_APP","IOS_APP"].includes(b)&&("IOS_APP"===b&&w.postMessage({action:"showAppRating"}),"ANDROID_APP"===b&&h.showInAppReview())},rn=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["ANDROID_APP","IOS_APP"].includes(b)&&(E((function(e){"checkBiometricStatus"===e.type&&n&&n(e)})),"ANDROID_APP"===b&&h.checkBiometricStatus(),"IOS_APP"===b&&w.postMessage({action:"checkBiometricStatus"}))},an=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback,t=e.secret;["ANDROID_APP","IOS_APP"].includes(b)&&(E((function(e){"saveBiometricSecret"===e.type&&n&&n(e)})),"ANDROID_APP"===b&&h.saveSecret(t),"IOS_APP"===b&&w.postMessage({action:"saveBiometricSecret",secret:t}))},cn=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["ANDROID_APP","IOS_APP"].includes(b)&&(E((function(e){"deleteBiometricSecret"===e.type&&n&&n(e)})),"ANDROID_APP"===b&&h.deleteSecret(),"IOS_APP"===b&&w.postMessage({action:"deleteBiometricSecret"}))},sn=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback,t=e.prompt;["ANDROID_APP","IOS_APP"].includes(b)&&(E((function(e){"showBiometric"===e.type&&n&&n(e)})),"ANDROID_APP"===b&&h.callBiometric(t||"Authenticate to continue!"),"IOS_APP"===b&&w.postMessage({action:"showBiometric",prompt:t||""}))},un=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback,t=e.prompt,i=e.isAuthenticationOptional,o=void 0!==i&&i;["ANDROID_APP"].includes(b)&&(E((function(e){"biometricAuthWithDismissOnCancel"===e.type&&n&&n(e)})),"ANDROID_APP"===b&&h.biometricAuthWithDismissOnCancel(JSON.stringify({prompt:t||"Authenticate to continue!",isAuthenticationOptional:o})))},Pn=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["IOS_APP"].includes(b)&&(E((function(e){"requestTrackingConsent"===e.type&&n&&n(e)})),"IOS_APP"===b&&w.postMessage({action:"requestTrackingAuthorization"}))},An=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["IOS_APP"].includes(b)&&(E((function(e){"trackingConsentStatus"===e.type&&n&&n(e)})),"IOS_APP"===b&&w.postMessage({action:"trackingConsentStatus"}))},ln=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.enabled;"IOS_APP"===b&&w.postMessage({action:"setFirebaseAnalyticsCollection",enabled:n}),"ANDROID_APP"===b&&h.setFirebaseAnalyticsCollection(n)}},dn=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.userId;"IOS_APP"===b&&w.postMessage({action:"setFirebaseUserId",userId:n}),"ANDROID_APP"===b&&h.setFirebaseUserId(n)}},fn=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.key,t=e.value;"IOS_APP"===b&&w.postMessage({action:"setFirebaseUserProp",key:n,value:t}),"ANDROID_APP"===b&&h.setFirebaseUserProp(n,t)}},pn=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.parameters;"IOS_APP"===b&&w.postMessage({action:"setFirebaseDefaultParam",parameters:n}),"ANDROID_APP"===b&&h.setFirebaseDefaultParam(n)}},On=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.eventName,t=e.parameters;"IOS_APP"===b&&w.postMessage({action:"logFirebaseEvent",eventName:n,parameters:t}),"ANDROID_APP"===b&&h.logFirebaseEvent(n,t)}},gn=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.screenName,t=e.screenClass;"IOS_APP"===b&&w.postMessage({action:"logFirebaseScreenView",screenName:n,screenClass:t}),"ANDROID_APP"===b&&h.logFirebaseScreenView(n,t)}},In=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.toTopic;"IOS_APP"===b&&w.postMessage({action:"firebaseSubscribeToTopic",topic:n}),"ANDROID_APP"===b&&h.subscribeToTopic(n)}},Dn=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.fromTopic;"IOS_APP"===b&&w.postMessage({action:"firebaseUnsubscribeFromTopic",topic:n}),"ANDROID_APP"===b&&h.unsubscribeFromTopic(n)}},Sn=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.callback;E((function(e){"getFCMToken"===e.type&&("ANDROID_APP"===b&&(e.token=e.fcm_registration_token),n&&n(e))})),"IOS_APP"===b&&w.postMessage({action:"getFCMToken"}),"ANDROID_APP"===b&&h.getRegistrationToken()}},_n=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};["ANDROID_APP","IOS_APP"].includes(b)&&"IOS_APP"===b&&w.postMessage({action:"haptikEffect",effect:e.effect})},vn=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url,t=e.imageUrl,i=void 0===t?"https://images.freeimages.com/images/large-previews/3b2/prague-conference-center-1056491.jpg":t;["ANDROID_APP","IOS_APP"].includes(b)&&("ANDROID_APP"===b&&h.playMedia(JSON.stringify({url:n,imageUrl:i})),"IOS_APP"===b&&w.postMessage({action:"playMedia",url:n,image:i}))},Nn=function(){["ANDROID_APP","IOS_APP"].includes(b)&&("ANDROID_APP"===b&&h.pausePlaying(),"IOS_APP"===b&&w.postMessage({action:"pauseMedia"}))},yn=function(){["ANDROID_APP","IOS_APP"].includes(b)&&("ANDROID_APP"===b&&h.stopPlaying(),"IOS_APP"===b&&w.postMessage({action:"stopMedia"}))},mn=function(e){if(["ANDROID_APP"].includes(b)){var n=e.printSize,t=void 0===n?"ISO_A4":n,i=e.label,o=void 0===i?"":i;"ANDROID_APP"===b&&h.setPrintSize(JSON.stringify({printSize:t,label:o}))}},Rn=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["ANDROID_APP","IOS_APP"].includes(b)&&(E((function(e){"checkNotificationPermission"===e.type&&n&&n(e)})),"ANDROID_APP"===b&&h.checkNotificationPermission(),"IOS_APP"===b&&w.postMessage({action:"checkNotificationPermission"}))},hn=function(){["ANDROID_APP","IOS_APP"].includes(b)&&("ANDROID_APP"===b&&h.openAppNotificationPage(),"IOS_APP"===b&&w.postMessage({action:"openAppNotificationPage"}))},wn=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback;["ANDROID_APP"].includes(b)&&(E((function(e){"startBluetoothScan"===e.type&&n&&n(e)})),"ANDROID_APP"===b&&h.startBluetoothScan())},bn=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback,t=e.address,i=e.timeout,o=void 0===i?10:i;["ANDROID_APP"].includes(b)&&(E((function(e){"pairWithDevice"===e.type&&n&&n(e)})),"ANDROID_APP"===b&&h.pairWithDevice(JSON.stringify({address:t,timeout:o})))},Tn=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.callback,t=e.address;["ANDROID_APP"].includes(b)&&(E((function(e){"unpairDevice"===e.type&&n&&n(e)})),"ANDROID_APP"===b&&h.unpairDevice(JSON.stringify({address:t})))};function kn(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,i)}return t}function Mn(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}var Fn=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.callback,t=e.apiUrl,i=void 0===t?null:t,o=e.amount,r=e.currency,a=e.isSimulated,c=void 0!==a&&a,s=e.captureMethod,u=void 0===s?"automatic":s,P=e.connectionToken,A=e.stripeLocationId,l=e.clientSecret,d=void 0===l?null:l;E((function(e){"makeTapToPayStripePayment"===e.type&&n&&n(e)}));var f={secretToken:P,amount:o,currency:r,isSimulated:c,captureMethod:u,locationId:A};i&&(f.apiUrl=i),d&&(f.client_secret=d),"ANDROID_APP"===b&&h.makeTapToPayStripePayment(JSON.stringify(f)),"IOS_APP"===b&&w.postMessage(function(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?kn(Object(t),!0).forEach((function(n){Mn(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):kn(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}({action:"makeTapToPayStripePayment"},f))}},En=function(e){if(["ANDROID_APP"].includes(b)){var n=e.callback;E((function(e){"checkIfAppUpdateAvailable"===e.type&&n&&n(e)})),"ANDROID_APP"===b&&h.checkIfAppUpdateAvailable()}},Cn=function(e){if(["ANDROID_APP"].includes(b)){var n=e.updateType,t=void 0===n?"immediate":n,i=e.callback;E((function(e){"updateApplication"===e.type&&i&&i(e)})),"ANDROID_APP"===b&&h.updateApplication(t)}};window.WTN=n,window.WTN.OneSignal=t,window.WTN.VoiceSearch=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.onVoiceSearch;return E((function(e){var n=e.type,t=e.results;"VOICE_SEARCH_RESULT"===n&&(Fe&&Fe(t),Fe=null)})),T&&h.openVoiceSearch(),"function"==typeof n&&(Fe=n),Me},window.WTN.Barcode=i,window.WTN.AdMob=o,window.WTN.socialLogin=je,window.WTN.inAppPurchase=function(e){if(["ANDROID_APP","IOS_APP"].includes(b)){var n=e.callback,t=e.productId,i=e.productType,o=e.isConsumable,r=void 0!==o&&o;E((function(e){"inAppPurchase"===e.type&&n&&n(e)})),"IOS_APP"===b&&w.postMessage({action:"inAppPurchase",productId:t}),"ANDROID_APP"===b&&h.inAppPurchase(JSON.stringify({action:"inAppPurchase",productId:t,productType:i,isConsumable:r}))}},window.WTN.getAllPurchases=function(e){if(["ANDROID_APP"].includes(b)){var n=e.callback;E((function(e){"purchaseList"===e.type&&n&&n(e)})),"ANDROID_APP"===b&&h.getAllPurchases({action:"purchaseList"})}},window.WTN.getReceiptData=function(e){if(["IOS_APP"].includes(b)){var n=e.callback;E((function(e){"getReceiptData"===e.type&&n&&n(e)})),"IOS_APP"===b&&w.postMessage({action:"getReceiptData"})}},window.WTN.appsflyer=r,window.WTN.bottomNavigation=c,window.WTN.contacts=s,window.WTN.screen=P,window.WTN.backgroundLocation=u,window.WTN.clipboard=A,window.WTN.appReview=l,window.WTN.Biometric=d,window.WTN.ATTConsent=f,window.WTN.facebook={events:a},window.WTN.firebaseAnalytics=O,window.WTN.haptics=D,window.WTN.Firebase=I,window.WTN.MediaPlayer=S,window.WTN.Printing=_,window.WTN.Notification=v,window.WTN.Bluetooth=N,window.WTN.Stripe=y,window.WTN.InAppUpdate=m,window&&window.WebToNativeInterface&&window.WebToNativeInterface.getAndroidVersion?window.navigator.share=function(e){return new Promise((function(n,t){window.WebToNativeInterface.openShareIntent(e.url),n()}))}:WTN.isIosApp&&(window.navigator.share=function(e){return new Promise((function(n,t){w.postMessage({action:"share",url:e.url}),n()}))})}();
  • webtonative/trunk/website/scripts/woocommerce.js

    r3329535 r3342866  
    1818  if (!isIAPEnabled) return;
    1919
    20   const iosSecretKey = wtn_biometric_settings.iosSecretKey;
     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
    2125  const btnTexts = {
    2226    buyNow: wtn_biometric_settings?.btn_buy_now_text ?? 'Buy Now',
     
    9195            productType: productType,
    9296            variantId,
    93             ...(WTN.isIosApp ? { receiptData: data.receiptData } : data),
     97            ...(WTN.isIosApp ? { receiptData: data.receiptData, transactionId: data.transactionId } : data),
    9498          };
    9599
     
    211215    }
    212216
    213     if (WTN.isIosApp && !iosSecretKey) {
    214       alert('Please configure App store secret key in settings');
     217    if (WTN.isIosApp && (!appStoreBundleId || !appStorePrivateKey || !appStoreIssuerId || !appStoreKeyId)) {
     218      alert('Please configure App store settings in settings');
    215219      return;
    216220    }
  • webtonative/trunk/webtonative-biometric/assets/biometric.js

    r3313015 r3342866  
    149149  function showBiometricPrompt() {
    150150    window.WTN.Biometric.show({
    151       isAuthenticationOptional: true,
    152151      prompt: 'Authenticate to continue!',
    153152      callback: function (data) {
     
    165164  async function authenticateBiometric(promptText) {
    166165    return new Promise((resolve) => {
    167       window.WTN.Biometric.show({
     166      const isIOSApp = window.WTN?.isIosApp || false;
     167      const showBiometricHandler = isIOSApp ? window.WTN.Biometric.show : window.WTN.Biometric.biometricAuthWithDismissOnCancel;
     168      showBiometricHandler({
    168169        isAuthenticationOptional: true,
    169170        prompt: promptText,
  • webtonative/trunk/webtonative-biometric/webtonative-biometric.php

    r3313015 r3342866  
    1313function wtn_biometric_enqueue_scripts()
    1414{
    15     wp_enqueue_script('wtn-biometric-js', plugins_url('assets/biometric.js?ver=1.1.11', __FILE__), ['jquery'], '1.0.0', true);
     15    wp_enqueue_script('wtn-biometric-js', plugins_url('assets/biometric.js?ver=1.1.12', __FILE__), ['jquery'], '1.0.0', true);
    1616
    1717    wp_localize_script('wtn-biometric-js', 'WTN_Biometric_Settings', [
     
    232232            // Biometric Login Button Click
    233233            loginButton.addEventListener('click', () => {
    234                 window.WTN.Biometric.show({
     234                const isIOSApp = window.WTN?.isIosApp || false;
     235                const showBiometricHandler = isIOSApp ? window.WTN.Biometric.show : window.WTN.Biometric.biometricAuthWithDismissOnCancel;
     236                showBiometricHandler({
    235237                    isAuthenticationOptional: true,
    236238                    prompt: "Authenticate to login",
Note: See TracChangeset for help on using the changeset viewer.