Plugin Directory

Changeset 3334077


Ignore:
Timestamp:
07/25/2025 09:26:21 AM (6 months ago)
Author:
smackcoders
Message:

Version 1.2 - Bug fix

Location:
w2s-sync
Files:
39 added
5 edited

Legend:

Unmodified
Added
Removed
  • w2s-sync/trunk/assets/css/style.css

    r3326131 r3334077  
    1919  margin-right: 5px;
    2020}
    21 .custom-dates{
     21#custom-dates{
    2222  display: none;
     23  margin-left: 40px;
     24  margin-top: 10px;
    2325}
    2426.smack-button-group-button{
  • w2s-sync/trunk/includes/modules/class-w2ssyn-swi-customer-sync.php

    r3326131 r3334077  
    154154
    155155    public static function w2ssyn_shopify_to_woo_create_customers($w2ssyn_woo_base_url, $w2ssyn_consumer_key, $w2ssyn_consumer_secret, $w2ssyn_shopify_base_url, $w2ssyn_shopify_token)
    156     {
    157         global $wpdb;
    158         W2SSYN_SWI_Audit_Log::w2ssyn_log_sync_action('customer', 'create', 'success', 'Starting Shopify to WooCommerce customer sync...');
    159 
    160         // Fetch field mappings from the database
    161         $w2ssyn_field_mappings = $wpdb->get_results("SELECT shopify_field, woocommerce_field FROM {$wpdb->prefix}w2ssyn_field_mappings WHERE entity_type = 'customer'", OBJECT_K);
    162 
    163         // Convert mappings to an associative array
    164         $w2ssyn_mappings = array();
    165         foreach ($w2ssyn_field_mappings as $w2ssyn_mapping) {
    166             $w2ssyn_mappings[$w2ssyn_mapping->shopify_field] = $w2ssyn_mapping->woocommerce_field;
    167         }
    168 
    169         // Fetch Shopify customers
    170         $w2ssyn_shopify_url      = "{$w2ssyn_shopify_base_url}customers.json?limit=250";
    171         $w2ssyn_shopify_url      = W2SSYN_Sync_Helper::w2ssyn_add_date_filter($w2ssyn_shopify_url, 'customer');
    172         $w2ssyn_shopify_response = wp_remote_get(
    173             $w2ssyn_shopify_url,
    174             array(
    175                 'headers'   => array(
    176                     'Content-Type'           => 'application/json',
    177                     'X-Shopify-Access-Token' => $w2ssyn_shopify_token,
    178                 ),
    179                 'timeout'   => 30,
    180                 'sslverify' => false,
    181             )
    182         );
    183 
    184         if (is_wp_error($w2ssyn_shopify_response)) {
    185             W2SSYN_SWI_Audit_Log::w2ssyn_log_sync_action('customer', 'create', 'failure', 'Shopify API Error: ' . $w2ssyn_shopify_response->get_error_message());
    186             return;
    187         }
    188 
    189         $w2ssyn_shopify_customers = json_decode(wp_remote_retrieve_body($w2ssyn_shopify_response), true)['customers'] ?? array();
    190 
    191         if (empty($w2ssyn_shopify_customers)) {
    192             W2SSYN_SWI_Audit_Log::w2ssyn_log_sync_action('customer', 'create', 'failure', 'No Shopify customers found.');
    193             return;
    194         }
    195 
    196         // Loop through Shopify customers
    197         foreach ($w2ssyn_shopify_customers as $w2ssyn_shopify_customer) {
    198             $w2ssyn_shopify_customer_id = $w2ssyn_shopify_customer['id'];
    199 
    200             // Check if the customer exists in the local database
    201             $w2ssyn_existing_customer = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}w2ssyn_customers WHERE shopify_customer_id = %s", $w2ssyn_shopify_customer_id));
     156{
     157    global $wpdb;
     158
     159    W2SSYN_SWI_Audit_Log::w2ssyn_log_sync_action('customer', 'create', 'success', 'Starting Shopify to WooCommerce customer sync...');
     160
     161    $w2ssyn_shopify_headers = array(
     162        'Content-Type' => 'application/json',
     163        'X-Shopify-Access-Token' => $w2ssyn_shopify_token,
     164    );
     165
     166    $w2ssyn_shopify_url = "{$w2ssyn_shopify_base_url}customers.json?limit=250";
     167    $w2ssyn_response = wp_remote_get($w2ssyn_shopify_url, [
     168        'headers' => $w2ssyn_shopify_headers,
     169        'timeout' => 30,
     170        'sslverify' => false,
     171    ]);
     172
     173    if (is_wp_error($w2ssyn_response)) {
     174        W2SSYN_SWI_Audit_Log::w2ssyn_log_sync_action('customer', 'create', 'failure', 'Shopify API Error: ' . $w2ssyn_response->get_error_message());
     175        return;
     176    }
     177
     178    $w2ssyn_customers = json_decode(wp_remote_retrieve_body($w2ssyn_response), true)['customers'] ?? [];
     179
     180    if (empty($w2ssyn_customers)) {
     181        W2SSYN_SWI_Audit_Log::w2ssyn_log_sync_action('customer', 'create', 'failure', 'No Shopify customers found.');
     182        return;
     183    }
     184
     185    foreach ($w2ssyn_customers as $w2ssyn_customer) {
     186        $w2ssyn_existing_customer = $wpdb->get_row($wpdb->prepare(
     187            "SELECT * FROM {$wpdb->prefix}w2ssyn_customers WHERE shopify_customer_id = %s",
     188            $w2ssyn_customer['id']
     189        ));
     190
     191        if ($w2ssyn_existing_customer) {
     192            $w2ssyn_woo_customer_id = $w2ssyn_existing_customer->woocommerce_customer_id;
     193
     194            $w2ssyn_check_url = "{$w2ssyn_woo_base_url}customers/{$w2ssyn_woo_customer_id}?consumer_key={$w2ssyn_consumer_key}&consumer_secret={$w2ssyn_consumer_secret}";
     195            $w2ssyn_check_response = wp_remote_get($w2ssyn_check_url, ['sslverify' => false]);
     196
     197            if (!is_wp_error($w2ssyn_check_response) && wp_remote_retrieve_response_code($w2ssyn_check_response) == 200) {
     198                W2SSYN_SWI_Audit_Log::w2ssyn_log_sync_action('customer', 'create', 'success', 'WooCommerce customer exists, skipping ID: ' . $w2ssyn_customer['id']);
     199                continue;
     200            } else {
     201                $w2ssyn_existing_customer = null;
     202                W2SSYN_SWI_Audit_Log::w2ssyn_log_sync_action('customer', 'create', 'warning', 'WooCommerce customer missing, will recreate ID: ' . $w2ssyn_customer['id']);
     203            }
     204        }
     205
     206        $w2ssyn_woo_payload = [
     207            'email' => $w2ssyn_customer['email'],
     208            'first_name' => $w2ssyn_customer['first_name'] ?? '',
     209            'last_name' => $w2ssyn_customer['last_name'] ?? '',
     210        ];
     211
     212        $w2ssyn_create_url = "{$w2ssyn_woo_base_url}customers?consumer_key={$w2ssyn_consumer_key}&consumer_secret={$w2ssyn_consumer_secret}";
     213        $w2ssyn_create_response = wp_remote_post($w2ssyn_create_url, [
     214            'body' => json_encode($w2ssyn_woo_payload),
     215            'headers' => ['Content-Type' => 'application/json'],
     216            'sslverify' => false,
     217            'timeout' => 30,
     218        ]);
     219
     220        $w2ssyn_create_body = json_decode(wp_remote_retrieve_body($w2ssyn_create_response), true);
     221
     222        if (!is_wp_error($w2ssyn_create_response) && isset($w2ssyn_create_body['id'])) {
     223            $w2ssyn_woo_customer_id = $w2ssyn_create_body['id'];
     224
     225            W2SSYN_SWI_Audit_Log::w2ssyn_log_sync_action('customer', 'create', 'success', 'Created WooCommerce customer: ' . $w2ssyn_customer['email']);
    202226
    203227            if ($w2ssyn_existing_customer) {
    204                 // Check if the WooCommerce customer still exists
    205                 $w2ssyn_woo_customer_id    = $w2ssyn_existing_customer->woocommerce_customer_id;
    206                 $w2ssyn_woo_check_url      = "{$w2ssyn_woo_base_url}customers/{$w2ssyn_woo_customer_id}?consumer_key=$w2ssyn_consumer_key&consumer_secret=$w2ssyn_consumer_secret";
    207                 $w2ssyn_woo_check_response = wp_remote_get($w2ssyn_woo_check_url, array('sslverify' => false));
    208 
    209                 if (is_wp_error($w2ssyn_woo_check_response) || wp_remote_retrieve_response_code($w2ssyn_woo_check_response) == 404) {
    210                     W2SSYN_SWI_Audit_Log::w2ssyn_log_sync_action('customer', 'create', 'failure', 'WooCommerce customer missing, recreating ID: ' . $w2ssyn_shopify_customer_id);
    211                     $w2ssyn_existing_customer = null; // Force recreation
    212                 } else {
    213                     W2SSYN_SWI_Audit_Log::w2ssyn_log_sync_action('customer', 'create', 'success', 'WooCommerce customer exists, skipping ID: ' . $w2ssyn_shopify_customer_id);
    214                     continue;
    215                 }
    216             }
    217 
    218             // Map Shopify customer data to WooCommerce format dynamically
    219             $w2ssyn_woo_customer = array();
    220             foreach ($w2ssyn_mappings as $w2ssyn_shopify_field => $w2ssyn_woo_field) {
    221                 if (isset($w2ssyn_shopify_customer[$w2ssyn_shopify_field])) {
    222                     $w2ssyn_woo_customer[$w2ssyn_woo_field] = $w2ssyn_shopify_customer[$w2ssyn_shopify_field];
    223                 }
    224             }
    225 
    226             // Handle address if available
    227             if (!empty($w2ssyn_shopify_customer['default_address'])) {
    228                 $w2ssyn_woo_customer['billing'] = array(
    229                     'address_1' => $w2ssyn_shopify_customer['default_address']['address1'] ?? '',
    230                     'address_2' => $w2ssyn_shopify_customer['default_address']['address2'] ?? '',
    231                     'city'      => $w2ssyn_shopify_customer['default_address']['city'] ?? '',
    232                     'state'     => $w2ssyn_shopify_customer['default_address']['province'] ?? '',
    233                     'postcode'  => $w2ssyn_shopify_customer['default_address']['zip'] ?? '',
    234                     'country'   => $w2ssyn_shopify_customer['default_address']['country'] ?? '',
    235                     'phone'     => $w2ssyn_shopify_customer['default_address']['phone'] ?? '',
    236                 );
    237             }
    238 
    239             W2SSYN_SWI_Audit_Log::w2ssyn_log_sync_action('customer', 'create', 'success', 'Creating WooCommerce Customer for ID: ' . $w2ssyn_shopify_customer_id);
    240 
    241             // Create customer in WooCommerce
    242             $w2ssyn_woo_create_url    = "{$w2ssyn_woo_base_url}customers?consumer_key=$w2ssyn_consumer_key&consumer_secret=$w2ssyn_consumer_secret";
    243             $w2ssyn_woo_post_response = wp_remote_post(
    244                 $w2ssyn_woo_create_url,
    245                 array(
    246                     'headers'   => array('Content-Type' => 'application/json'),
    247                     'body'      => json_encode($w2ssyn_woo_customer),
    248                     'method'    => 'POST',
    249                     'timeout'   => 30,
    250                     'sslverify' => false,
    251                 )
     228                $wpdb->update(
     229                    $wpdb->prefix . 'w2ssyn_customers',
     230                    ['woocommerce_customer_id' => $w2ssyn_woo_customer_id],
     231                    ['id' => $w2ssyn_existing_customer->id]
     232                );
     233            } else {
     234                $wpdb->insert(
     235                    $wpdb->prefix . 'w2ssyn_customers',
     236                    [
     237                        'shopify_customer_id' => $w2ssyn_customer['id'],
     238                        'woocommerce_customer_id' => $w2ssyn_woo_customer_id,
     239                        'first_name' => $w2ssyn_customer['first_name'] ?? '',
     240                        'last_name' => $w2ssyn_customer['last_name'] ?? '',
     241                        'email' => $w2ssyn_customer['email'] ?? '',
     242                        'address' => json_encode($w2ssyn_customer['addresses'] ?? []),
     243                    ]
     244                );
     245            }
     246        } else {
     247            W2SSYN_SWI_Audit_Log::w2ssyn_log_sync_action(
     248                'customer',
     249                'create',
     250                'failure',
     251                'Failed to create WooCommerce customer: ' . $w2ssyn_customer['email'] . ' - ' . wp_remote_retrieve_body($w2ssyn_create_response)
    252252            );
    253 
    254             $w2ssyn_woo_response_raw = wp_remote_retrieve_body($w2ssyn_woo_post_response);
    255             $w2ssyn_woo_post_body    = json_decode($w2ssyn_woo_response_raw, true);
    256 
    257             if (is_wp_error($w2ssyn_woo_post_response)) {
    258                 W2SSYN_SWI_Audit_Log::w2ssyn_log_sync_action('customer', 'create', 'failure', 'WooCommerce API Error: ' . $w2ssyn_woo_post_response->get_error_message());
    259             } elseif (empty($w2ssyn_woo_post_body['id'])) {
    260                 W2SSYN_SWI_Audit_Log::w2ssyn_log_sync_action('customer', 'create', 'failure', 'WooCommerce response error: ' . json_encode($w2ssyn_woo_post_body));
    261             } else {
    262                 W2SSYN_SWI_Audit_Log::w2ssyn_log_sync_action('customer', 'create', 'success', 'Successfully created WooCommerce customer for ID: ' . $w2ssyn_shopify_customer_id);
    263                 $w2ssyn_woo_customer_id = $w2ssyn_woo_post_body['id'];
    264 
    265                 // Update or insert new record in DB
    266                 $wpdb->replace(
    267                     $wpdb->prefix . 'w2ssyn_customers',
    268                     array(
    269                         'shopify_customer_id'     => $w2ssyn_shopify_customer_id,
    270                         'woocommerce_customer_id' => $w2ssyn_woo_customer_id,
    271                         'first_name'              => $w2ssyn_woo_customer['first_name'] ?? '',
    272                         'last_name'               => $w2ssyn_woo_customer['last_name'] ?? '',
    273                         'email'                   => $w2ssyn_woo_customer['email'] ?? '',
    274                         'address'                 => json_encode($w2ssyn_woo_customer['billing'] ?? array()),
    275                     )
    276                 );
    277             }
    278 
    279             // Optional delay to prevent hitting API rate limits
    280             sleep(2);
    281         }
    282 
    283         W2SSYN_SWI_Audit_Log::w2ssyn_log_sync_action('customer', 'create', 'success', 'Shopify to WooCommerce customer sync completed.');
    284     }
     253        }
     254
     255        sleep(2); // Prevent rate limits
     256    }
     257
     258    W2SSYN_SWI_Audit_Log::w2ssyn_log_sync_action('customer', 'create', 'success', 'Shopify to WooCommerce customer sync completed.');
     259}
     260
    285261
    286262
  • w2s-sync/trunk/includes/modules/class-w2ssyn-swi-order-sync.php

    r3326131 r3334077  
    233233                if (is_wp_error($w2ssyn_woo_order_response) || wp_remote_retrieve_response_code($w2ssyn_woo_order_response) === 404) {
    234234                    // If the WooCommerce order does not exist, create it
    235 
     235$w2ssyn_order_data = array(
     236  'status'      => $w2ssyn_order_status,
     237  'customer_id' => $w2ssyn_customer_id,
     238  'line_items'  => $w2ssyn_line_items,
     239  'total'       => $w2ssyn_order_total,
     240  'shipping'    => array(
     241    'address' => array(
     242      'line1'    => $w2ssyn_shopify_order['shipping_address']['address1'] ?? '',
     243      'line2'    => $w2ssyn_shopify_order['shipping_address']['address2'] ?? '',
     244      'city'     => $w2ssyn_shopify_order['shipping_address']['city'] ?? '',
     245      'state'    => $w2ssyn_shopify_order['shipping_address']['province'] ?? '',
     246      'postcode' => $w2ssyn_shopify_order['shipping_address']['zip'] ?? '',
     247      'country'  => $w2ssyn_shopify_order['shipping_address']['country'] ?? '',
     248    ),
     249  ),
     250);
     251
     252// 2. Send it to WooCommerce
     253$w2ssyn_order_response = wp_remote_post(
     254  "{$w2ssyn_woo_base_url}orders",
     255  array(
     256    'method'    => 'POST',
     257    'headers'   => array(
     258      'Content-Type'  => 'application/json',
     259      'Authorization' => 'Basic ' . base64_encode("{$w2ssyn_woo_consumer_key}:{$w2ssyn_woo_consumer_secret}"),
     260    ),
     261    'body'      => json_encode($w2ssyn_order_data),
     262    'sslverify' => false,
     263    'timeout'   => 60,
     264  )
     265);
     266
     267// 3. Log the response
     268$code = wp_remote_retrieve_response_code($w2ssyn_order_response);
     269$body = wp_remote_retrieve_body($w2ssyn_order_response);
     270
     271// 4. On success, save the new order ID
     272if ( $code === 201 ) {
     273  $data = json_decode($body, true);
     274  if ( ! empty($data['id']) ) {
     275    $wpdb->update(
     276      $w2ssyn_table_name,
     277      [ 'woocommerce_order_id' => $data['id'] ],
     278      [ 'shopify_order_id'     => $w2ssyn_shopify_order_id ]
     279    );
     280  }
     281}
    236282                    // Prepare line items for WooCommerce order from Shopify data
    237283                    $w2ssyn_line_items = array();
  • w2s-sync/trunk/readme.txt

    r3329693 r3334077  
    1 === W2S-Sync ===
     1=== W2S Sync – WooCommerce to Shopify Integration ===
    22Contributors: smackcoders, smacksupport
    33Donate link: https://www.smackcoders.com/contact-us.html
    44Requires at least: 5.0
    55Tested up to: 6.8
    6 Version: 1.1
     6Version: 1.2
    77Requires PHP: 7.2
    8 Stable tag: 1.1
     8Stable tag: 1.2
    99Author: smackcoders
    1010Author URI: https://www.smackcoders.com
     
    2121[youtube https://www.youtube.com/watch?v=1-tuqBcU0RM&t=52s]
    2222
     23== Authentication – How to Connect Your Stores ==
     24
     25To begin syncing, you need to securely connect your WooCommerce and Shopify stores by generating API credentials for both platforms:
     26
     27- **WooCommerce**: Generate Consumer Key and Secret from your WordPress admin.
     28- **Shopify**: Create a private app to get your Admin API access token.
     29
     30Follow the step-by-step guide here: 
     31[Authentication Setup Guide](https://www.smackcoders.com/documentation/woocommerce-to-shopify-integration/woocommerce-to-shopify-integration-authentication-setup)
     32
     33Once connected, visual indicators (Green, Yellow, Red) show the status of your authentication.
     34
    2335**Key Benefits:**
    24 - Bi-directional sync between WooCommerce and Shopify
    25 - One-time migration or continuous data synchronization
    26 - Supports syncing of Products, Orders, and Customers
    27 - Easy authentication with WooCommerce API keys and Shopify access token
    28 - Schedule syncs: On Save, Hourly, Daily, Weekly, or within a custom date range
    29 - Auto field mapping and customizable sync actions (Create, Update, Delete)
    30 - Visual indicators for successful authentication and sync status
    31 - Audit Log for detailed activity tracking and debugging
     36- **Bi-Directional Sync** 
     37Sync data both ways: WooCommerce → Shopify, Shopify → WooCommerce, or keep both stores in sync at the same time.
     38- **Real-Time & Scheduled Sync** 
     39Trigger sync instantly on product save or set automatic sync intervals — hourly, daily, weekly, or within a custom date range.
     40- **Sync Key Data Types** 
     41Support for syncing Products, Orders, and Customers. Choose whether to Create, Update, or Delete data.
     42- **Auto Field Mapping** 
     43WooCommerce and Shopify fields are automatically matched — reduce setup effort and avoid mismatches.
     44- **Audit Log** 
     45View a full history of all sync activities, including timestamps, success/failure status, and detailed actions.
     46- **One-Time or Continuous Use** 
     47Use W2S for a single migration or leave it running for continuous integration between your platforms.
     48- **Local Data & Secure Credentials** 
     49Your credentials are stored locally in WordPress and are only used to connect to your own stores. No external services involved.
    3250
    3351**How It Works:**
     
    5977
    6078= Can I schedule a nightly sync? = 
    61 Yeschoose **Daily** under Schedule Sync. Ensure WP-Cron is active.
     79Yes choose **Daily** under Schedule Sync. Ensure WP-Cron is active.
    6280
    6381= Does this support Shopify → WooCommerce product sync? = 
     
    104122
    105123== Changelog ==
     124= 1.2 =
     125* Bug fixes
    106126= 1.1 =
    107127* Bug fix
     
    112132== Upgrade Notice ==
    113133
    114 = 1.1 =
     134= 1.2 =
    115135Upgrade now to get latest update.
    116136apps-fileview.texmex_20250501.00_p3
  • w2s-sync/trunk/w2s-sync.php

    r3326131 r3334077  
    11<?php
     2
    23/**
    34 * Plugin Name:       W2S-Sync
    45 * Plugin URI:        https://www.smackcoders.com/
    56 * Description:       A custom Shopify-WooCommerce integration plugin for WordPress that enables two-way synchronization of customers, products, and orders. It features automated scheduling, configurable sync settings, secure API authentication, detailed audit logs, and customizable field mappings—ensuring seamless data consistency across both eCommerce platforms.
    6  * Version:           1.0
     7 * Version:           1.2
    78 * Requires at least: 6.0
    89 * Requires PHP:      7.4
Note: See TracChangeset for help on using the changeset viewer.