Plugin Directory

Changeset 3778798


Ignore:
Timestamp:
11/02/2026 01:08:31 AM (78 minutes ago)
Author:
onetrace
Message:

Update to version 1.15.0 from GitHub

Location:
onetrace-for-woocommerce
Files:
26 edited
1 copied

Legend:

Unmodified
Added
Removed
  • onetrace-for-woocommerce/tags/1.15.0/languages/onetrace-for-woocommerce-ru_RU.po

    r3763672 r3778798  
    44"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/onetrace-for-"
    55"woocommerce\n"
    6 "POT-Creation-Date: 2026-10-24T18:48:10+00:00\n"
     6"POT-Creation-Date: 2026-11-02T00:39:09+00:00\n"
    77"PO-Revision-Date: 2026-10-08T17:53:43+00:00\n"
    88"Last-Translator: \n"
    … …  
    6060"настройки сохранятся."
    6161
    62 #: src/Admin.php:45 src/Admin.php:277 src/Admin.php:362
     62#: src/Admin.php:48 src/Admin.php:292 src/Admin.php:377
    6363msgid "Settings"
    6464msgstr "Настройки"
    6565
    66 #: src/Admin.php:60
     66#: src/Admin.php:63
    6767msgid "Set in wp-config.php."
    6868msgstr "Задано в wp-config.php."
    6969
    70 #: src/Admin.php:73
     70#: src/Admin.php:76
    7171msgid "Connection"
    7272msgstr "Подключение"
    7373
    74 #: src/Admin.php:73
     74#: src/Admin.php:76
    7575msgid "Keys are in the \"API keys\" section of your OneTrace project."
    7676msgstr "Ключи — в разделе «Ключи API» вашего проекта OneTrace."
    7777
    78 #: src/Admin.php:74
     78#: src/Admin.php:77
    7979msgid "Platform address"
    8080msgstr "Адрес платформы"
    8181
    82 #: src/Admin.php:74
     82#: src/Admin.php:77
    8383msgid "The address you open the platform at: the domain of your brand."
    8484msgstr "Адрес, по которому вы открываете платформу: домен вашего бренда."
    8585
    86 #: src/Admin.php:75 src/Admin.php:231
     86#: src/Admin.php:78 src/Admin.php:246
    8787msgid "Write key"
    8888msgstr "Ключ записи"
    8989
    90 #: src/Admin.php:75
     90#: src/Admin.php:78
    9191msgid "For the tracker on the storefront."
    9292msgstr "Для трекера на витрине."
    9393
    94 #: src/Admin.php:76 src/Admin.php:231
     94#: src/Admin.php:79 src/Admin.php:246
    9595msgid "Secret key"
    9696msgstr "Секретный ключ"
    9797
    98 #: src/Admin.php:76
     98#: src/Admin.php:79
    9999msgid ""
    100100"For orders, customers and the catalog; needs the products.write permission."
    101101msgstr "Для заказов, покупателей и каталога; нужно право products.write."
    102102
    103 #: src/Admin.php:79
     103#: src/Admin.php:80
     104msgid "Identity key"
     105msgstr "Ключ подписи"
     106
     107#: src/Admin.php:80
     108msgid ""
     109"Signs the id of the signed-in customer for the tracker, so OneTrace trusts "
     110"it when the project requires signed user ids. It is in OneTrace → Site → "
     111"Connection → Server."
     112msgstr ""
     113"Подписывает id вошедшего покупателя для трекера, и OneTrace принимает его, "
     114"когда в проекте включено «Требовать подпись». Ключ — в OneTrace → Сайт → "
     115"Подключение → Сервер."
     116
     117#: src/Admin.php:83
    104118msgid "What to send"
    105119msgstr "Что передавать"
    106120
    107 #: src/Admin.php:80
     121#: src/Admin.php:84
    108122msgid "Tracker"
    109123msgstr "Трекер"
    110124
    111 #: src/Admin.php:80
     125#: src/Admin.php:84
    112126msgid "Page and product views on the storefront"
    113127msgstr "Просмотры страниц и товаров на витрине"
    114128
    115 #: src/Admin.php:81
     129#: src/Admin.php:85
    116130msgid "Cookie consent"
    117131msgstr "Согласие на cookie"
    118132
    119 #: src/Admin.php:81
     133#: src/Admin.php:85
    120134msgid ""
    121135"Load the tracker after the visitor agrees to statistics cookies (with a "
    … …  
    125139"плагином согласия, который поддерживает WP Consent API)"
    126140
    127 #: src/Admin.php:82
     141#: src/Admin.php:86
    128142msgid "Orders"
    129143msgstr "Заказы"
    130144
    131 #: src/Admin.php:82
     145#: src/Admin.php:86
    132146msgid ""
    133147"Placed, paid, shipped, delivered, cancelled and refunded orders with the "
    … …  
    137151"возвраты с данными покупателя"
    138152
    139 #: src/Admin.php:83
     153#: src/Admin.php:87
    140154msgid "Cart"
    141155msgstr "Корзина"
    142156
    143 #: src/Admin.php:83
     157#: src/Admin.php:87
    144158msgid ""
    145159"Adding to and removing from the cart, opening the checkout — for abandoned "
    … …  
    149163"брошенной корзины"
    150164
    151 #: src/Admin.php:84
     165#: src/Admin.php:88
    152166msgid "Wishlist"
    153167msgstr "Избранное"
    154168
    155 #: src/Admin.php:84
     169#: src/Admin.php:88
    156170msgid ""
    157171"Adding to and removing from the wishlist of YITH WooCommerce Wishlist or TI "
    … …  
    161175"WooCommerce Wishlist — для цепочек по избранному"
    162176
    163 #: src/Admin.php:85
     177#: src/Admin.php:89
    164178msgid "Product catalog"
    165179msgstr "Каталог товаров"
    166180
    167 #: src/Admin.php:85
     181#: src/Admin.php:89
    168182msgid ""
    169183"Products, categories and stock for recommendations, emails and catalog "
    … …  
    173187"при изменении товаров и остатков и раз в сутки"
    174188
    175 #: src/Admin.php:86
     189#: src/Admin.php:90
    176190msgid "Product id"
    177191msgstr "ID товара"
    178192
    179 #: src/Admin.php:86
     193#: src/Admin.php:90
    180194msgid "Post ID"
    181195msgstr "ID записи"
    182196
    183 #: src/Admin.php:86
     197#: src/Admin.php:90
    184198msgid "SKU (the post ID for products without a SKU)"
    185199msgstr "Артикул (ID записи, если артикула нет)"
    186200
    187 #: src/Admin.php:86
     201#: src/Admin.php:90
    188202msgid ""
    189203"Choose SKU if your OneTrace project already has the catalog and history "
    … …  
    193207"артикулам, например после переезда с другой платформы."
    194208
    195 #: src/Admin.php:89
     209#: src/Admin.php:93
    196210msgid "Newsletter consent"
    197211msgstr "Согласие на рассылку"
    198212
    199 #: src/Admin.php:89
     213#: src/Admin.php:93
    200214msgid ""
    201215"A checkbox subscribes the customer to marketing emails in OneTrace. Without "
    … …  
    205219"согласие не передаётся."
    206220
    207 #: src/Admin.php:90
     221#: src/Admin.php:94
    208222msgid "Checkout"
    209223msgstr "Оформление заказа"
    210224
    211 #: src/Admin.php:90
     225#: src/Admin.php:94
    212226msgid "Checkbox at checkout (classic and block)"
    213227msgstr "Галочка при оформлении заказа (классическом и блочном)"
    214228
    215 #: src/Admin.php:91
     229#: src/Admin.php:95
    216230msgid "Registration"
    217231msgstr "Регистрация"
    218232
    219 #: src/Admin.php:91
     233#: src/Admin.php:95
    220234msgid "Checkbox in the registration form"
    221235msgstr "Галочка в форме регистрации"
    222236
    223 #: src/Admin.php:92
     237#: src/Admin.php:96
    224238msgid "Account"
    225239msgstr "Личный кабинет"
    226240
    227 #: src/Admin.php:92
     241#: src/Admin.php:96
    228242msgid "Subscribe and unsubscribe on the account details page"
    229243msgstr "Подписка и отписка на странице данных аккаунта"
    230244
    231 #: src/Admin.php:93
     245#: src/Admin.php:97
    232246msgid "Checkbox text"
    233247msgstr "Текст галочки"
    234248
    235 #: src/Admin.php:93 src/Settings.php:97
     249#: src/Admin.php:97 src/Settings.php:102
    236250msgid "Send me news and special offers by email"
    237251msgstr "Присылать новости и специальные предложения по email"
    238252
    239 #: src/Admin.php:94
     253#: src/Admin.php:98
    240254msgid "Subscription topic"
    241255msgstr "Тема подписки"
    242256
    243 #: src/Admin.php:94
     257#: src/Admin.php:98
    244258msgid "Empty — the whole email channel."
    245259msgstr "Пусто — весь канал email."
    246260
    247 #: src/Admin.php:95
     261#: src/Admin.php:99
    248262msgid "Newsletters in My account"
    249263msgstr "Рассылки в личном кабинете"
    250264
    251 #: src/Admin.php:95
     265#: src/Admin.php:99
    252266msgid ""
    253267"My account → Newsletters: subscription topics by channel, frequency, a pause "
    … …  
    259273"profiles.read и profiles.write)"
    260274
    261 #: src/Admin.php:95
     275#: src/Admin.php:99
    262276msgid ""
    263277"Topics and their names are set up in OneTrace → Messaging rules → "
    … …  
    267281"подписки»."
    268282
    269 #: src/Admin.php:98
     283#: src/Admin.php:102
    270284msgid "Recommendations, search and Web Push"
    271285msgstr "Рекомендации, поиск и Web Push"
    272286
    273 #: src/Admin.php:98
     287#: src/Admin.php:102
    274288msgid ""
    275289"Widget ids are in the \"Site → Widgets\" section of the platform. Anywhere "
    … …  
    279293"другом месте используйте шорткод [onetrace_widget id=\"…\"]."
    280294
    281 #: src/Admin.php:99
     295#: src/Admin.php:103
    282296msgid "Widget on the product page"
    283297msgstr "Виджет на странице товара"
    284298
    285 #: src/Admin.php:100
     299#: src/Admin.php:104
    286300msgid "Widget in the cart"
    287301msgstr "Виджет в корзине"
    288302
    289 #: src/Admin.php:101
     303#: src/Admin.php:105
    290304msgid "Web Push"
    291305msgstr "Web Push"
    292306
    293 #: src/Admin.php:101
     307#: src/Admin.php:105
    294308msgid ""
    295309"Serve /cdp-sw.js from the store root; put the [onetrace_push_button] "
    … …  
    299313"поставьте там, где посетители подписываются"
    300314
    301 #: src/Admin.php:102
     315#: src/Admin.php:106
    302316msgid "Product search"
    303317msgstr "Поиск по товарам"
    304318
    305 #: src/Admin.php:102
     319#: src/Admin.php:106
    306320msgid ""
    307321"Results of the store search and suggestions while typing come from OneTrace "
    … …  
    312326"товарам должен быть в тарифе проекта); при ошибке — обычный поиск WordPress"
    313327
    314 #: src/Admin.php:103
     328#: src/Admin.php:107
    315329msgid "OneTrace search widget"
    316330msgstr "Виджет поиска OneTrace"
    317331
    318 #: src/Admin.php:103
     332#: src/Admin.php:107
    319333msgid ""
    320334"The search page shows the results widget of OneTrace — facets, sorting, "
    … …  
    326340"полями поиска открывается слой поиска (нужен трекер)"
    327341
    328 #: src/Admin.php:103
     342#: src/Admin.php:107
    329343msgid ""
    330344"Turn the widget on and set up its look in OneTrace → Site → Search. While it "
    … …  
    334348"выключен или OneTrace недоступен, страница поиска остаётся прежней."
    335349
    336 #: src/Admin.php:104
     350#: src/Admin.php:108
    337351msgid "Notify when available"
    338352msgstr "Сообщить о поступлении"
    339353
    340 #: src/Admin.php:104
     354#: src/Admin.php:108
    341355msgid ""
    342356"Show the “Notify when available” form on the page of a product that is out "
    … …  
    345359"Показывать форму «Сообщить о поступлении» на странице товара не в наличии"
    346360
    347 #: src/Admin.php:104
     361#: src/Admin.php:108
    348362msgid ""
    349363"The form itself is set up in OneTrace → Site → Forms (kind “Notify when "
    … …  
    353367"поступлении»); без активной формы этого вида ничего не показывается."
    354368
    355 #: src/Admin.php:105
     369#: src/Admin.php:109
    356370msgid "Ask AI about a product"
    357371msgstr "Спросить ИИ о товаре"
    358372
    359 #: src/Admin.php:105
     373#: src/Admin.php:109
    360374msgid "Show \"Ask AI about this product\" on product pages"
    361375msgstr "Показывать «Спросить ИИ о товаре» на страницах товаров"
    362376
    363 #: src/Admin.php:105
     377#: src/Admin.php:109
    364378msgid ""
    365379"It appears only when the widget is turned on in OneTrace → Site → Product "
    … …  
    369383msgstr ""
    370384"Появляется, только когда виджет включён в OneTrace → Сайт → Вопрос о товаре; "
    371 "ИИ отвечает по описанию товара и базе знаний магазина. Чтобы поставить его "
    372 "в другое место, выключите эту настройку и используйте шорткод [onetrace_ask]."
    373 
    374 #: src/Admin.php:108
     385"ИИ отвечает по описанию товара и базе знаний магазина. Чтобы поставить его в "
     386"другое место, выключите эту настройку и используйте шорткод [onetrace_ask]."
     387
     388#: src/Admin.php:112
    375389msgid "Loyalty program"
    376390msgstr "Программа лояльности"
    377391
    378 #: src/Admin.php:108
     392#: src/Admin.php:112
    379393msgid ""
    380394"The program is set up in the \"Loyalty\" section of the platform. Signed-in "
    … …  
    386400"видят баллы в «Мой аккаунт → Бонусные баллы»."
    387401
    388 #: src/Admin.php:109 src/LoyaltyAccount.php:73 src/LoyaltyBlocks.php:78
     402#: src/Admin.php:113 src/LoyaltyAccount.php:73 src/LoyaltyBlocks.php:78
    389403#: src/LoyaltyCart.php:52 src/LoyaltyCart.php:53
    390404msgid "Bonus points"
    391405msgstr "Бонусные баллы"
    392406
    393 #: src/Admin.php:109
     407#: src/Admin.php:113
    394408msgid ""
    395409"Show the balance and use points in the cart and at checkout (the secret key "
    … …  
    399413"ключу нужны права loyalty.read и loyalty.write)"
    400414
    401 #: src/Admin.php:110
     415#: src/Admin.php:114
    402416msgid "Referrals"
    403417msgstr "Приглашения"
    404418
    405 #: src/Admin.php:110
     419#: src/Admin.php:114
    406420msgid ""
    407421"The \"Friend's code\" field in the registration form. Without it the code of "
    … …  
    411425"ref=) всё равно засчитывается: трекер сохраняет его в cookie."
    412426
    413 #: src/Admin.php:113
     427#: src/Admin.php:117
    414428msgid "Promo codes"
    415429msgstr "Промокоды"
    416430
    417 #: src/Admin.php:113
     431#: src/Admin.php:117
    418432msgid ""
    419433"Unique codes of OneTrace promo code pools become WooCommerce coupons every 5 "
    … …  
    427441"привяжите его к ключу пула из раздела «Промокоды» платформы."
    428442
    429 #: src/Admin.php:114
     443#: src/Admin.php:118
    430444msgid "Pools and template coupons"
    431445msgstr "Пулы и купоны-образцы"
    432446
    433 #: src/Admin.php:114
     447#: src/Admin.php:118
    434448msgid ""
    435449"One per line: pool key = template coupon code. The secret key needs the "
    … …  
    439453"право promo.read."
    440454
    441 #: src/Admin.php:117
     455#: src/Admin.php:121
    442456msgid "AI chat bot: store MCP"
    443457msgstr "ИИ-бот чата: MCP магазина"
    444458
    445 #: src/Admin.php:117
     459#: src/Admin.php:121
    446460msgid ""
    447461"The AI bot of the OneTrace chat answers customers with live data of the "
    … …  
    455469"на email. Секретному ключу нужно право chats.manage."
    456470
    457 #: src/Admin.php:118
     471#: src/Admin.php:122
    458472msgid "Store MCP server"
    459473msgstr "MCP-сервер магазина"
    460474
    461 #: src/Admin.php:118
     475#: src/Admin.php:122
    462476msgid "Connect the store to the AI chat bot"
    463477msgstr "Подключить магазин к ИИ-боту чата"
    464478
    465 #: src/Admin.php:119
     479#: src/Admin.php:123
    466480msgid "What the bot may do"
    467481msgstr "Что разрешено боту"
    468482
    469 #: src/Admin.php:119
     483#: src/Admin.php:123
    470484msgid ""
    471485"Reading is safe; actions change orders and run only after the customer "
    … …  
    475489"покупателя в чате."
    476490
    477 #: src/Admin.php:130
     491#: src/Admin.php:134
    478492msgid "Send a confirmation code"
    479493msgstr "Отправлять код подтверждения"
    480494
    481 #: src/Admin.php:131
     495#: src/Admin.php:135
    482496msgid "Check the confirmation code"
    483497msgstr "Проверять код подтверждения"
    484498
    485 #: src/Admin.php:132
     499#: src/Admin.php:136
    486500msgid "Read the confirmed customer"
    487501msgstr "Читать подтверждённого покупателя"
    488502
    489 #: src/Admin.php:133
     503#: src/Admin.php:137
    490504msgid "Read the customer's orders"
    491505msgstr "Читать заказы покупателя"
    492506
    493 #: src/Admin.php:134
     507#: src/Admin.php:138
    494508msgid "Read an order"
    495509msgstr "Читать заказ"
    496510
    497 #: src/Admin.php:135
     511#: src/Admin.php:139
    498512msgid "Read parcel tracking"
    499513msgstr "Читать отслеживание посылки"
    500514
    501 #: src/Admin.php:136
     515#: src/Admin.php:140
    502516msgid "Read stock and prices"
    503517msgstr "Читать наличие и цены"
    504518
    505 #: src/Admin.php:137
     519#: src/Admin.php:141
    506520msgid "Read delivery methods"
    507521msgstr "Читать способы доставки"
    508522
    509 #: src/Admin.php:138
     523#: src/Admin.php:142
    510524msgid "Read the return policy"
    511525msgstr "Читать условия возврата"
    512526
    513 #: src/Admin.php:139
     527#: src/Admin.php:143
    514528msgid "Action: cancel an unpaid order"
    515529msgstr "Действие: отменять неоплаченный заказ"
    516530
    517 #: src/Admin.php:140
     531#: src/Admin.php:144
    518532msgid "Action: pass a return request to the shop"
    519533msgstr "Действие: передавать магазину заявку на возврат"
    520534
    521 #: src/Admin.php:141
     535#: src/Admin.php:145
    522536msgid "Action: pass a delivery change request to the shop"
    523537msgstr "Действие: передавать магазину запрос на изменение доставки"
    524538
    525 #: src/Admin.php:155
     539#: src/Admin.php:160
    526540msgid "Saved — enter a new key to replace it"
    527541msgstr "Сохранён — введите новый ключ, чтобы заменить"
    528542
    529543#. translators: %s: project name
    530 #: src/Admin.php:221
     544#: src/Admin.php:236
    531545#, php-format
    532546msgid "Write key: project \"%s\"."
    … …  
    534548
    535549#. translators: %s: project name
    536 #: src/Admin.php:223
     550#: src/Admin.php:238
    537551#, php-format
    538552msgid "Secret key: project \"%s\"."
    539553msgstr "Секретный ключ: проект «%s»."
    540554
    541 #: src/Admin.php:225
     555#: src/Admin.php:240
    542556msgid ""
    543557"The key has no products.write permission: the catalog will not be uploaded."
    544558msgstr "У ключа нет права products.write: каталог не будет выгружаться."
    545559
    546 #: src/Admin.php:226
     560#: src/Admin.php:241
    547561msgid ""
    548562"The key has no loyalty.read and loyalty.write permissions: bonus points will "
    … …  
    552566"будут."
    553567
    554 #: src/Admin.php:227
     568#: src/Admin.php:242
    555569msgid ""
    556570"The key has no promo.read permission: promo codes will not become coupons."
    557571msgstr "У ключа нет права promo.read: промокоды не станут купонами."
    558572
    559 #: src/Admin.php:228
     573#: src/Admin.php:243
    560574msgid ""
    561575"The key has no profiles.read and profiles.write permissions: the Newsletters "
    … …  
    565579"не будет."
    566580
    567 #: src/Admin.php:236
     581#: src/Admin.php:251
    568582msgid "Enter the platform address and the keys first."
    569583msgstr "Сначала укажите адрес платформы и ключи."
    570584
    571 #: src/Admin.php:253
     585#: src/Admin.php:268
    572586msgid "The catalog upload has started; it runs in the background."
    573587msgstr "Выгрузка каталога началась, она идёт в фоне."
    574588
    575 #: src/Admin.php:275
     589#: src/Admin.php:290
    576590msgid ""
    577591"OneTrace: sending is paused because the platform rejected the key. Check the "
    … …  
    581595"ключи и сохраните настройки."
    582596
    583 #: src/Admin.php:288
     597#: src/Admin.php:303
    584598msgid "Status"
    585599msgstr "Состояние"
    586600
    587 #: src/Admin.php:291
     601#: src/Admin.php:306
    588602msgid "Queue"
    589603msgstr "Очередь"
    590604
    591605#. translators: 1: items waiting, 2: items waiting for a retry
    592 #: src/Admin.php:294
     606#: src/Admin.php:309
    593607#, php-format
    594608msgid "%1$d waiting, %2$d of them after an error"
    595609msgstr "Ждут отправки: %1$d, из них после ошибки: %2$d"
    596610
    597 #: src/Admin.php:301
     611#: src/Admin.php:316
    598612msgid "Last error"
    599613msgstr "Последняя ошибка"
    600614
    601 #: src/Admin.php:309
     615#: src/Admin.php:324
    602616msgid "AI chat bot"
    603617msgstr "ИИ-бот чата"
    604618
    605619#. translators: %s: tools the bot uses
    606 #: src/Admin.php:312
     620#: src/Admin.php:327
    607621#, php-format
    608622msgid "Connected: %s"
    609623msgstr "Подключён: %s"
    610624
    611 #: src/Admin.php:318
     625#: src/Admin.php:333
    612626msgid "Test connection"
    613627msgstr "Проверить подключение"
    614628
    615 #: src/Admin.php:320
     629#: src/Admin.php:335
    616630msgid "Upload the whole catalog"
    617631msgstr "Выгрузить весь каталог"
    618632
    619 #: src/Admin.php:330
     633#: src/Admin.php:345
    620634msgid "Store emails"
    621635msgstr "Письма магазина"
    622636
    623 #: src/Admin.php:331
     637#: src/Admin.php:346
    624638msgid ""
    625639"Emails of WooCommerce, WordPress and other plugins can go out through the "
    … …  
    638652"Письмо, которое OneTrace не принял, магазин отправляет сам."
    639653
    640 #: src/Admin.php:340 src/Admin.php:343
     654#: src/Admin.php:355 src/Admin.php:358
    641655msgid "State"
    642656msgstr "Состояние"
    643657
    644 #: src/Admin.php:340
     658#: src/Admin.php:355
    645659msgid "Enter the platform address and the secret key."
    646660msgstr "Укажите адрес платформы и секретный ключ."
    647661
    648 #: src/Admin.php:343
     662#: src/Admin.php:358
    649663msgid "Not available — the store sends its emails itself."
    650664msgstr "Недоступно — магазин отправляет письма сам."
    651665
    652 #: src/Admin.php:346
     666#: src/Admin.php:361
    653667msgid "Order placed"
    654668msgstr "Заказ оформлен"
    655669
    656 #: src/Admin.php:347
     670#: src/Admin.php:362
    657671msgid "Order paid"
    658672msgstr "Заказ оплачен"
    659673
    660 #: src/Admin.php:348
     674#: src/Admin.php:363
    661675msgid "Order shipped"
    662676msgstr "Заказ отправлен"
    663677
    664 #: src/Admin.php:349
     678#: src/Admin.php:364
    665679msgid "Order delivered"
    666680msgstr "Заказ доставлен"
    667681
    668 #: src/Admin.php:350
     682#: src/Admin.php:365
    669683msgid "Order cancelled"
    670684msgstr "Заказ отменён"
    671685
    672 #: src/Admin.php:351
     686#: src/Admin.php:366
    673687msgid "Order refunded"
    674688msgstr "Возврат по заказу"
    675689
    676 #: src/Admin.php:355
     690#: src/Admin.php:370
    677691msgid "All store emails"
    678692msgstr "Все письма магазина"
    679693
    680 #: src/Admin.php:356
     694#: src/Admin.php:371
    681695msgid ""
    682696"Through OneTrace: emails without a OneTrace template go out as the store "
    … …  
    686700"магазин"
    687701
    688 #: src/Admin.php:357
     702#: src/Admin.php:372
    689703msgid "Sent by the store"
    690704msgstr "Отправляет магазин"
    691705
    692 #: src/Admin.php:358
     706#: src/Admin.php:373
    693707msgid "Order emails from OneTrace templates"
    694708msgstr "Письма о заказе по шаблонам OneTrace"
    695709
    696 #: src/Admin.php:358
     710#: src/Admin.php:373
    697711msgid "None"
    698712msgstr "Нет"
    699713
    700 #: src/Admin.php:363
     714#: src/Admin.php:378
    701715msgid "Store emails in OneTrace"
    702716msgstr "Письма магазина в OneTrace"
    703717
    704 #: src/Admin.php:364
     718#: src/Admin.php:379
    705719msgid "OneTrace → Store emails"
    706720msgstr "OneTrace → Письма магазина"
    707721
    708 #: src/Admin.php:408
     722#: src/Admin.php:423
    709723msgid "You are not allowed to do this."
    710724msgstr "У вас нет прав на это действие."
    … …  
    9991013msgstr "(необязательно)"
    10001014
    1001 #: src/Storefront.php:293
     1015#: src/Storefront.php:295
    10021016msgid "Get notifications"
    10031017msgstr "Получать уведомления"
  • onetrace-for-woocommerce/tags/1.15.0/languages/onetrace-for-woocommerce.pot

    r3763672 r3778798  
    33msgid ""
    44msgstr ""
    5 "Project-Id-Version: OneTrace for WooCommerce 1.14.0\n"
     5"Project-Id-Version: OneTrace for WooCommerce 1.15.0\n"
    66"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/onetrace-for-woocommerce\n"
    77"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
    … …  
    1010"Content-Type: text/plain; charset=UTF-8\n"
    1111"Content-Transfer-Encoding: 8bit\n"
    12 "POT-Creation-Date: 2026-10-24T18:48:10+00:00\n"
     12"POT-Creation-Date: 2026-11-02T00:39:09+00:00\n"
    1313"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
    1414"X-Generator: WP-CLI 2.12.0\n"
    … …  
    4646msgstr ""
    4747
    48 #: src/Admin.php:45
    49 #: src/Admin.php:277
    50 #: src/Admin.php:362
     48#: src/Admin.php:48
     49#: src/Admin.php:292
     50#: src/Admin.php:377
    5151msgid "Settings"
    5252msgstr ""
    5353
    54 #: src/Admin.php:60
     54#: src/Admin.php:63
    5555msgid "Set in wp-config.php."
    5656msgstr ""
    5757
    58 #: src/Admin.php:73
     58#: src/Admin.php:76
    5959msgid "Connection"
    6060msgstr ""
    6161
    62 #: src/Admin.php:73
     62#: src/Admin.php:76
    6363msgid "Keys are in the \"API keys\" section of your OneTrace project."
    6464msgstr ""
    6565
    66 #: src/Admin.php:74
     66#: src/Admin.php:77
    6767msgid "Platform address"
    6868msgstr ""
    6969
    70 #: src/Admin.php:74
     70#: src/Admin.php:77
    7171msgid "The address you open the platform at: the domain of your brand."
    7272msgstr ""
    7373
    74 #: src/Admin.php:75
    75 #: src/Admin.php:231
     74#: src/Admin.php:78
     75#: src/Admin.php:246
    7676msgid "Write key"
    7777msgstr ""
    7878
    79 #: src/Admin.php:75
     79#: src/Admin.php:78
    8080msgid "For the tracker on the storefront."
    8181msgstr ""
    8282
    83 #: src/Admin.php:76
    84 #: src/Admin.php:231
     83#: src/Admin.php:79
     84#: src/Admin.php:246
    8585msgid "Secret key"
    8686msgstr ""
    8787
    88 #: src/Admin.php:76
     88#: src/Admin.php:79
    8989msgid "For orders, customers and the catalog; needs the products.write permission."
    9090msgstr ""
    9191
    92 #: src/Admin.php:79
     92#: src/Admin.php:80
     93msgid "Identity key"
     94msgstr ""
     95
     96#: src/Admin.php:80
     97msgid "Signs the id of the signed-in customer for the tracker, so OneTrace trusts it when the project requires signed user ids. It is in OneTrace → Site → Connection → Server."
     98msgstr ""
     99
     100#: src/Admin.php:83
    93101msgid "What to send"
    94102msgstr ""
    95103
    96 #: src/Admin.php:80
     104#: src/Admin.php:84
    97105msgid "Tracker"
    98106msgstr ""
    99107
    100 #: src/Admin.php:80
     108#: src/Admin.php:84
    101109msgid "Page and product views on the storefront"
    102110msgstr ""
    103111
    104 #: src/Admin.php:81
     112#: src/Admin.php:85
    105113msgid "Cookie consent"
    106114msgstr ""
    107115
    108 #: src/Admin.php:81
     116#: src/Admin.php:85
    109117msgid "Load the tracker after the visitor agrees to statistics cookies (with a consent plugin that supports the WP Consent API)"
    110118msgstr ""
    111119
    112 #: src/Admin.php:82
     120#: src/Admin.php:86
    113121msgid "Orders"
    114122msgstr ""
    115123
    116 #: src/Admin.php:82
     124#: src/Admin.php:86
    117125msgid "Placed, paid, shipped, delivered, cancelled and refunded orders with the customer data"
    118126msgstr ""
    119127
    120 #: src/Admin.php:83
     128#: src/Admin.php:87
    121129msgid "Cart"
    122130msgstr ""
    123131
    124 #: src/Admin.php:83
     132#: src/Admin.php:87
    125133msgid "Adding to and removing from the cart, opening the checkout — for abandoned cart journeys"
    126134msgstr ""
    127135
    128 #: src/Admin.php:84
     136#: src/Admin.php:88
    129137msgid "Wishlist"
    130138msgstr ""
    131139
    132 #: src/Admin.php:84
     140#: src/Admin.php:88
    133141msgid "Adding to and removing from the wishlist of YITH WooCommerce Wishlist or TI WooCommerce Wishlist — for wishlist journeys"
    134142msgstr ""
    135143
    136 #: src/Admin.php:85
     144#: src/Admin.php:89
    137145msgid "Product catalog"
    138146msgstr ""
    139147
    140 #: src/Admin.php:85
     148#: src/Admin.php:89
    141149msgid "Products, categories and stock for recommendations, emails and catalog journeys, updated when products or their stock change and daily"
    142150msgstr ""
    143151
    144 #: src/Admin.php:86
     152#: src/Admin.php:90
    145153msgid "Product id"
    146154msgstr ""
    147155
    148 #: src/Admin.php:86
     156#: src/Admin.php:90
    149157msgid "Post ID"
    150158msgstr ""
    151159
    152 #: src/Admin.php:86
     160#: src/Admin.php:90
    153161msgid "SKU (the post ID for products without a SKU)"
    154162msgstr ""
    155163
    156 #: src/Admin.php:86
     164#: src/Admin.php:90
    157165msgid "Choose SKU if your OneTrace project already has the catalog and history under SKUs, e.g. after moving from another platform."
    158166msgstr ""
    159167
    160 #: src/Admin.php:89
     168#: src/Admin.php:93
    161169msgid "Newsletter consent"
    162170msgstr ""
    163171
    164 #: src/Admin.php:89
     172#: src/Admin.php:93
    165173msgid "A checkbox subscribes the customer to marketing emails in OneTrace. Without it no consent is sent."
    166174msgstr ""
    167175
    168 #: src/Admin.php:90
     176#: src/Admin.php:94
    169177msgid "Checkout"
    170178msgstr ""
    171179
    172 #: src/Admin.php:90
     180#: src/Admin.php:94
    173181msgid "Checkbox at checkout (classic and block)"
    174182msgstr ""
    175183
    176 #: src/Admin.php:91
     184#: src/Admin.php:95
    177185msgid "Registration"
    178186msgstr ""
    179187
    180 #: src/Admin.php:91
     188#: src/Admin.php:95
    181189msgid "Checkbox in the registration form"
    182190msgstr ""
    183191
    184 #: src/Admin.php:92
     192#: src/Admin.php:96
    185193msgid "Account"
    186194msgstr ""
    187195
    188 #: src/Admin.php:92
     196#: src/Admin.php:96
    189197msgid "Subscribe and unsubscribe on the account details page"
    190198msgstr ""
    191199
    192 #: src/Admin.php:93
     200#: src/Admin.php:97
    193201msgid "Checkbox text"
    194202msgstr ""
    195203
    196 #: src/Admin.php:93
    197 #: src/Settings.php:97
     204#: src/Admin.php:97
     205#: src/Settings.php:102
    198206msgid "Send me news and special offers by email"
    199207msgstr ""
    200208
    201 #: src/Admin.php:94
     209#: src/Admin.php:98
    202210msgid "Subscription topic"
    203211msgstr ""
    204212
    205 #: src/Admin.php:94
     213#: src/Admin.php:98
    206214msgid "Empty — the whole email channel."
    207215msgstr ""
    208216
    209 #: src/Admin.php:95
     217#: src/Admin.php:99
    210218msgid "Newsletters in My account"
    211219msgstr ""
    212220
    213 #: src/Admin.php:95
     221#: src/Admin.php:99
    214222msgid "My account → Newsletters: subscription topics by channel, frequency, a pause and unsubscribing from everything, as in the OneTrace preference center (the secret key needs the profiles.read and profiles.write permissions)"
    215223msgstr ""
    216224
    217 #: src/Admin.php:95
     225#: src/Admin.php:99
    218226msgid "Topics and their names are set up in OneTrace → Messaging rules → Subscription topics."
    219227msgstr ""
    220228
    221 #: src/Admin.php:98
     229#: src/Admin.php:102
    222230msgid "Recommendations, search and Web Push"
    223231msgstr ""
    224232
    225 #: src/Admin.php:98
     233#: src/Admin.php:102
    226234msgid "Widget ids are in the \"Site → Widgets\" section of the platform. Anywhere else use the [onetrace_widget id=\"…\"] shortcode."
    227235msgstr ""
    228236
    229 #: src/Admin.php:99
     237#: src/Admin.php:103
    230238msgid "Widget on the product page"
    231239msgstr ""
    232240
    233 #: src/Admin.php:100
     241#: src/Admin.php:104
    234242msgid "Widget in the cart"
    235243msgstr ""
    236244
    237 #: src/Admin.php:101
     245#: src/Admin.php:105
    238246msgid "Web Push"
    239247msgstr ""
    240248
    241 #: src/Admin.php:101
     249#: src/Admin.php:105
    242250msgid "Serve /cdp-sw.js from the store root; put the [onetrace_push_button] shortcode where visitors subscribe"
    243251msgstr ""
    244252
    245 #: src/Admin.php:102
     253#: src/Admin.php:106
    246254msgid "Product search"
    247255msgstr ""
    248256
    249 #: src/Admin.php:102
     257#: src/Admin.php:106
    250258msgid "Results of the store search and suggestions while typing come from OneTrace (the plan of the project must include product search); on an error — the usual WordPress search"
    251259msgstr ""
    252260
    253 #: src/Admin.php:103
     261#: src/Admin.php:107
    254262msgid "OneTrace search widget"
    255263msgstr ""
    256264
    257 #: src/Admin.php:103
     265#: src/Admin.php:107
    258266msgid "The search page shows the results widget of OneTrace — facets, sorting, infinite scroll and an \"Add to cart\" button — inside your theme, and a search layer opens under the search fields (needs the tracker)"
    259267msgstr ""
    260268
    261 #: src/Admin.php:103
     269#: src/Admin.php:107
    262270msgid "Turn the widget on and set up its look in OneTrace → Site → Search. While it is off there, or OneTrace is unavailable, the search page stays as it is."
    263271msgstr ""
    264272
    265 #: src/Admin.php:104
     273#: src/Admin.php:108
    266274msgid "Notify when available"
    267275msgstr ""
    268276
    269 #: src/Admin.php:104
     277#: src/Admin.php:108
    270278msgid "Show the “Notify when available” form on the page of a product that is out of stock"
    271279msgstr ""
    272280
    273 #: src/Admin.php:104
     281#: src/Admin.php:108
    274282msgid "The form itself is set up in OneTrace → Site → Forms (kind “Notify when available”); without an active form of this kind nothing is shown."
    275283msgstr ""
    276284
    277 #: src/Admin.php:105
     285#: src/Admin.php:109
    278286msgid "Ask AI about a product"
    279287msgstr ""
    280288
    281 #: src/Admin.php:105
     289#: src/Admin.php:109
    282290msgid "Show \"Ask AI about this product\" on product pages"
    283291msgstr ""
    284292
    285 #: src/Admin.php:105
     293#: src/Admin.php:109
    286294msgid "It appears only when the widget is turned on in OneTrace → Site → Product questions; the AI answers from the product description and the knowledge base of the store. To place it elsewhere, turn this off and use the [onetrace_ask] shortcode."
    287295msgstr ""
    288296
    289 #: src/Admin.php:108
     297#: src/Admin.php:112
    290298msgid "Loyalty program"
    291299msgstr ""
    292300
    293 #: src/Admin.php:108
     301#: src/Admin.php:112
    294302msgid "The program is set up in the \"Loyalty\" section of the platform. Signed-in customers pay for part of the order with points in the cart and at checkout and see their points in My account → Bonus points."
    295303msgstr ""
    296304
    297 #: src/Admin.php:109
     305#: src/Admin.php:113
    298306#: src/LoyaltyAccount.php:73
    299307#: src/LoyaltyBlocks.php:78
    … …  
    303311msgstr ""
    304312
    305 #: src/Admin.php:109
     313#: src/Admin.php:113
    306314msgid "Show the balance and use points in the cart and at checkout (the secret key needs the loyalty.read and loyalty.write permissions)"
    307315msgstr ""
    308316
    309 #: src/Admin.php:110
     317#: src/Admin.php:114
    310318msgid "Referrals"
    311319msgstr ""
    312320
    313 #: src/Admin.php:110
     321#: src/Admin.php:114
    314322msgid "The \"Friend's code\" field in the registration form. Without it the code of a referral link (?ref=) still counts: the tracker keeps it in a cookie."
    315323msgstr ""
    316324
    317 #: src/Admin.php:113
     325#: src/Admin.php:117
    318326msgid "Promo codes"
    319327msgstr ""
    320328
    321 #: src/Admin.php:113
     329#: src/Admin.php:117
    322330msgid "Unique codes of OneTrace promo code pools become WooCommerce coupons every 5 minutes: with the discount, restrictions and expiry of a template coupon, one use each. Create the template coupon in Marketing → Coupons and bind it to the pool key from the \"Promo codes\" section of the platform."
    323331msgstr ""
    324332
    325 #: src/Admin.php:114
     333#: src/Admin.php:118
    326334msgid "Pools and template coupons"
    327335msgstr ""
    328336
    329 #: src/Admin.php:114
     337#: src/Admin.php:118
    330338msgid "One per line: pool key = template coupon code. The secret key needs the promo.read permission."
    331339msgstr ""
    332340
    333 #: src/Admin.php:117
     341#: src/Admin.php:121
    334342msgid "AI chat bot: store MCP"
    335343msgstr ""
    336344
    337 #: src/Admin.php:117
     345#: src/Admin.php:121
    338346msgid "The AI bot of the OneTrace chat answers customers with live data of the store and, if you allow it, acts on orders. Customers signed in on the website are confirmed automatically, others with a code the shop sends by email. The secret key needs the chats.manage permission."
    339347msgstr ""
    340348
    341 #: src/Admin.php:118
     349#: src/Admin.php:122
    342350msgid "Store MCP server"
    343351msgstr ""
    344352
    345 #: src/Admin.php:118
     353#: src/Admin.php:122
    346354msgid "Connect the store to the AI chat bot"
    347355msgstr ""
    348356
    349 #: src/Admin.php:119
     357#: src/Admin.php:123
    350358msgid "What the bot may do"
    351359msgstr ""
    352360
    353 #: src/Admin.php:119
     361#: src/Admin.php:123
    354362msgid "Reading is safe; actions change orders and run only after the customer agreed in the chat."
    355363msgstr ""
    356364
    357 #: src/Admin.php:130
     365#: src/Admin.php:134
    358366msgid "Send a confirmation code"
    359367msgstr ""
    360368
    361 #: src/Admin.php:131
     369#: src/Admin.php:135
    362370msgid "Check the confirmation code"
    363371msgstr ""
    364372
    365 #: src/Admin.php:132
     373#: src/Admin.php:136
    366374msgid "Read the confirmed customer"
    367375msgstr ""
    368376
    369 #: src/Admin.php:133
     377#: src/Admin.php:137
    370378msgid "Read the customer's orders"
    371379msgstr ""
    372380
    373 #: src/Admin.php:134
     381#: src/Admin.php:138
    374382msgid "Read an order"
    375383msgstr ""
    376384
    377 #: src/Admin.php:135
     385#: src/Admin.php:139
    378386msgid "Read parcel tracking"
    379387msgstr ""
    380388
    381 #: src/Admin.php:136
     389#: src/Admin.php:140
    382390msgid "Read stock and prices"
    383391msgstr ""
    384392
    385 #: src/Admin.php:137
     393#: src/Admin.php:141
    386394msgid "Read delivery methods"
    387395msgstr ""
    388396
    389 #: src/Admin.php:138
     397#: src/Admin.php:142
    390398msgid "Read the return policy"
    391399msgstr ""
    392400
    393 #: src/Admin.php:139
     401#: src/Admin.php:143
    394402msgid "Action: cancel an unpaid order"
    395403msgstr ""
    396404
    397 #: src/Admin.php:140
     405#: src/Admin.php:144
    398406msgid "Action: pass a return request to the shop"
    399407msgstr ""
    400408
    401 #: src/Admin.php:141
     409#: src/Admin.php:145
    402410msgid "Action: pass a delivery change request to the shop"
    403411msgstr ""
    404412
    405 #: src/Admin.php:155
     413#: src/Admin.php:160
    406414msgid "Saved — enter a new key to replace it"
    407415msgstr ""
    408416
    409417#. translators: %s: project name
    410 #: src/Admin.php:221
     418#: src/Admin.php:236
    411419#, php-format
    412420msgid "Write key: project \"%s\"."
    … …  
    414422
    415423#. translators: %s: project name
    416 #: src/Admin.php:223
     424#: src/Admin.php:238
    417425#, php-format
    418426msgid "Secret key: project \"%s\"."
    419427msgstr ""
    420428
    421 #: src/Admin.php:225
     429#: src/Admin.php:240
    422430msgid "The key has no products.write permission: the catalog will not be uploaded."
    423431msgstr ""
    424432
    425 #: src/Admin.php:226
     433#: src/Admin.php:241
    426434msgid "The key has no loyalty.read and loyalty.write permissions: bonus points will not work."
    427435msgstr ""
    428436
    429 #: src/Admin.php:227
     437#: src/Admin.php:242
    430438msgid "The key has no promo.read permission: promo codes will not become coupons."
    431439msgstr ""
    432440
    433 #: src/Admin.php:228
     441#: src/Admin.php:243
    434442msgid "The key has no profiles.read and profiles.write permissions: the Newsletters tab will not work."
    435443msgstr ""
    436444
    437 #: src/Admin.php:236
     445#: src/Admin.php:251
    438446msgid "Enter the platform address and the keys first."
    439447msgstr ""
    440448
    441 #: src/Admin.php:253
     449#: src/Admin.php:268
    442450msgid "The catalog upload has started; it runs in the background."
    443451msgstr ""
    444452
    445 #: src/Admin.php:275
     453#: src/Admin.php:290
    446454msgid "OneTrace: sending is paused because the platform rejected the key. Check the keys and save the settings."
    447455msgstr ""
    448456
    449 #: src/Admin.php:288
     457#: src/Admin.php:303
    450458msgid "Status"
    451459msgstr ""
    452460
    453 #: src/Admin.php:291
     461#: src/Admin.php:306
    454462msgid "Queue"
    455463msgstr ""
    456464
    457465#. translators: 1: items waiting, 2: items waiting for a retry
    458 #: src/Admin.php:294
     466#: src/Admin.php:309
    459467#, php-format
    460468msgid "%1$d waiting, %2$d of them after an error"
    461469msgstr ""
    462470
    463 #: src/Admin.php:301
     471#: src/Admin.php:316
    464472msgid "Last error"
    465473msgstr ""
    466474
    467 #: src/Admin.php:309
     475#: src/Admin.php:324
    468476msgid "AI chat bot"
    469477msgstr ""
    470478
    471479#. translators: %s: tools the bot uses
    472 #: src/Admin.php:312
     480#: src/Admin.php:327
    473481#, php-format
    474482msgid "Connected: %s"
    475483msgstr ""
    476484
    477 #: src/Admin.php:318
     485#: src/Admin.php:333
    478486msgid "Test connection"
    479487msgstr ""
    480488
    481 #: src/Admin.php:320
     489#: src/Admin.php:335
    482490msgid "Upload the whole catalog"
    483491msgstr ""
    484492
    485 #: src/Admin.php:330
     493#: src/Admin.php:345
    486494msgid "Store emails"
    487495msgstr ""
    488496
    489 #: src/Admin.php:331
     497#: src/Admin.php:346
    490498msgid "Emails of WooCommerce, WordPress and other plugins can go out through the email integration of your OneTrace project, with delivery statuses and history in the customer profile; order emails — from OneTrace templates in the customer's language. This is set up in the \"Store emails\" section of the platform; the secret key needs the \"Send messages manually\" permission (messages.send). An email OneTrace does not accept is sent by the store itself."
    491499msgstr ""
    492500
    493 #: src/Admin.php:340
    494 #: src/Admin.php:343
     501#: src/Admin.php:355
     502#: src/Admin.php:358
    495503msgid "State"
    496504msgstr ""
    497505
    498 #: src/Admin.php:340
     506#: src/Admin.php:355
    499507msgid "Enter the platform address and the secret key."
    500508msgstr ""
    501509
    502 #: src/Admin.php:343
     510#: src/Admin.php:358
    503511msgid "Not available — the store sends its emails itself."
    504512msgstr ""
    505513
    506 #: src/Admin.php:346
     514#: src/Admin.php:361
    507515msgid "Order placed"
    508516msgstr ""
    509517
    510 #: src/Admin.php:347
     518#: src/Admin.php:362
    511519msgid "Order paid"
    512520msgstr ""
    513521
    514 #: src/Admin.php:348
     522#: src/Admin.php:363
    515523msgid "Order shipped"
    516524msgstr ""
    517525
    518 #: src/Admin.php:349
     526#: src/Admin.php:364
    519527msgid "Order delivered"
    520528msgstr ""
    521529
    522 #: src/Admin.php:350
     530#: src/Admin.php:365
    523531msgid "Order cancelled"
    524532msgstr ""
    525533
    526 #: src/Admin.php:351
     534#: src/Admin.php:366
    527535msgid "Order refunded"
    528536msgstr ""
    529537
    530 #: src/Admin.php:355
     538#: src/Admin.php:370
    531539msgid "All store emails"
    532540msgstr ""
    533541
    534 #: src/Admin.php:356
     542#: src/Admin.php:371
    535543msgid "Through OneTrace: emails without a OneTrace template go out as the store makes them"
    536544msgstr ""
    537545
    538 #: src/Admin.php:357
     546#: src/Admin.php:372
    539547msgid "Sent by the store"
    540548msgstr ""
    541549
    542 #: src/Admin.php:358
     550#: src/Admin.php:373
    543551msgid "Order emails from OneTrace templates"
    544552msgstr ""
    545553
    546 #: src/Admin.php:358
     554#: src/Admin.php:373
    547555msgid "None"
    548556msgstr ""
    549557
    550 #: src/Admin.php:363
     558#: src/Admin.php:378
    551559msgid "Store emails in OneTrace"
    552560msgstr ""
    553561
    554 #: src/Admin.php:364
     562#: src/Admin.php:379
    555563msgid "OneTrace → Store emails"
    556564msgstr ""
    557565
    558 #: src/Admin.php:408
     566#: src/Admin.php:423
    559567msgid "You are not allowed to do this."
    560568msgstr ""
    … …  
    843851msgstr ""
    844852
    845 #: src/Storefront.php:293
     853#: src/Storefront.php:295
    846854msgid "Get notifications"
    847855msgstr ""
  • onetrace-for-woocommerce/tags/1.15.0/onetrace-woocommerce.php

    r3763672 r3778798  
    44 * Plugin URI:           https://wordpress.org/plugins/onetrace-for-woocommerce/
    55 * Description:          Connects the store to OneTrace.pro, the customer data platform: orders, customers and consents from the server, the website tracker, the product catalog with stock, wishlists, recommendation widgets, Web Push and the store's emails through OneTrace.
    6  * Version:              1.14.0
     6 * Version:              1.15.0
    77 * Requires at least:    6.6
    88 * Requires PHP:         7.4
    … …  
    4343}
    4444
    45 define('ONETRACE_WC_VERSION', '1.14.0');
     45define('ONETRACE_WC_VERSION', '1.15.0');
    4646define('ONETRACE_WC_FILE', __FILE__);
    4747
  • onetrace-for-woocommerce/tags/1.15.0/readme.txt

    r3763672 r3778798  
    77WC requires at least: 9.0
    88WC tested up to: 11.2
    9 Stable tag: 1.14.0
     9Stable tag: 1.15.0
    1010License: GPLv2 or later
    1111License URI: https://www.gnu.org/licenses/gpl-2.0.html
    … …  
    47472. In your OneTrace project create a write key and a secret key with the products.write permission (API keys section).
    48483. Go to WooCommerce → Settings → OneTrace, enter the platform address and both keys, click "Test connection".
     494. Optionally enter the identity key from Site → Connection → Server of the project: the id of the signed-in customer reaches the tracker signed, and the project can require signed user ids.
    4950
    5051== Frequently Asked Questions ==
    … …  
    9596== Changelog ==
    9697
     98= 1.15.0 =
     99* Signed user ids: the "Identity key" setting (or the ONETRACE_IDENTITY_KEY constant) signs the id of the signed-in customer for the OneTrace tracker, so the project can turn on "Require signature" and no visitor can link their browser to someone else's profile.
     100
    97101= 1.14.0 =
    98102* "Ask AI about this product": the product page gets the place of the OneTrace widget after the add to cart area (classic and block themes; setting "Ask AI about a product", on by default) — it shows only when the widget is turned on in OneTrace → Site → Product questions. The `[onetrace_ask]` shortcode puts it anywhere.
    … …  
    172176== Upgrade Notice ==
    173177
     178= 1.15.0 =
     179The "Identity key" setting: signed user ids for projects that require them.
     180
    174181= 1.14.0 =
    175182"Ask AI about this product" on product pages and product descriptions in the catalog.
  • onetrace-for-woocommerce/tags/1.15.0/src/Admin.php

    r3763672 r3778798  
    1313    public const TAB = 'onetrace';
    1414
     15    /** Password fields that are never printed back, with their placeholders. */
     16    private const HIDDEN_KEYS = ['secret_key' => 'cdp_sk_…', 'identity_key' => 'cdp_ik_…'];
     17
    1518    public static function register(): void
    1619    {
    … …  
    7578            $field('write_key', ['type' => 'text', 'title' => __('Write key', 'onetrace-for-woocommerce'), 'placeholder' => 'cdp_wk_…', 'desc_tip' => __('For the tracker on the storefront.', 'onetrace-for-woocommerce')]),
    7679            $field('secret_key', ['type' => 'password', 'title' => __('Secret key', 'onetrace-for-woocommerce'), 'placeholder' => 'cdp_sk_…', 'desc_tip' => __('For orders, customers and the catalog; needs the products.write permission.', 'onetrace-for-woocommerce')]),
     80            $field('identity_key', ['type' => 'password', 'title' => __('Identity key', 'onetrace-for-woocommerce'), 'placeholder' => 'cdp_ik_…', 'desc_tip' => __('Signs the id of the signed-in customer for the tracker, so OneTrace trusts it when the project requires signed user ids. It is in OneTrace → Site → Connection → Server.', 'onetrace-for-woocommerce')]),
    7781            ['type' => 'sectionend', 'id' => 'onetrace_connection'],
    7882
    … …  
    151155            }
    152156
    153             // The secret key is never printed back: an empty field keeps the stored one.
    154             if (($field['id'] ?? '') === Settings::OPTION . '[secret_key]') {
    155                 $field['placeholder'] = (string) $field['value'] !== '' ? __('Saved — enter a new key to replace it', 'onetrace-for-woocommerce') : 'cdp_sk_…';
    156                 $field['value'] = '';
     157            // The secret and identity keys are never printed back: an empty field keeps the stored one.
     158            foreach (self::HIDDEN_KEYS as $key => $placeholder) {
     159                if (($field['id'] ?? '') === Settings::OPTION . '[' . $key . ']') {
     160                    $field['placeholder'] = (string) $field['value'] !== '' ? __('Saved — enter a new key to replace it', 'onetrace-for-woocommerce') : $placeholder;
     161                    $field['value'] = '';
     162                }
    157163            }
    158164
    … …  
    170176        $settings = get_option(Settings::OPTION, []);
    171177
    172         // An empty password field keeps the stored secret key.
    173         if (\is_array($settings) && \is_array($previous) && ($settings['secret_key'] ?? '') === '' && ($previous['secret_key'] ?? '') !== '') {
    174             $settings['secret_key'] = $previous['secret_key'];
    175             update_option(Settings::OPTION, $settings);
     178        // An empty password field keeps the stored key.
     179        if (\is_array($settings) && \is_array($previous)) {
     180            $kept = $settings;
     181
     182            foreach (array_keys(self::HIDDEN_KEYS) as $key) {
     183                if (($settings[$key] ?? '') === '' && ($previous[$key] ?? '') !== '') {
     184                    $kept[$key] = $previous[$key];
     185                }
     186            }
     187
     188            if ($kept !== $settings) {
     189                update_option(Settings::OPTION, $kept);
     190            }
    176191        }
    177192
  • onetrace-for-woocommerce/tags/1.15.0/src/Connection.php

    r3755877 r3778798  
    3030            $options = [
    3131                $write ? 'write_key' : 'secret_key' => (string) Settings::get($write ? 'write_key' : 'secret_key') ?: null,
     32                'identity_key' => (string) Settings::get('identity_key') ?: null,
    3233                'timeout' => $timeouts[0],
    3334                'connect_timeout' => $timeouts[1],
    … …  
    4748
    4849        return self::$clients[$key];
     50    }
     51
     52    /**
     53     * The signature of the signed-in customer's id for the tracker (identity key); null without the key.
     54     */
     55    public static function userHash(string $userId): ?string
     56    {
     57        return $userId !== '' && (string) Settings::get('identity_key') !== '' ? self::client('write')->userHash($userId) : null;
    4958    }
    5059
  • onetrace-for-woocommerce/tags/1.15.0/src/Settings.php

    r3763672 r3778798  
    77/**
    88 * Plugin settings: the option "onetrace_settings", the keys may also come from wp-config.php constants
    9  * ONETRACE_URL, ONETRACE_WRITE_KEY and ONETRACE_SECRET_KEY (then they are not stored in the database).
     9 * ONETRACE_URL, ONETRACE_WRITE_KEY, ONETRACE_SECRET_KEY and ONETRACE_IDENTITY_KEY (then they are not stored in the
     10 * database).
    1011 */
    1112final class Settings
    1213{
    1314    public const OPTION = 'onetrace_settings';
     15
     16    /** Settings that may come from wp-config.php constants. */
     17    private const CONSTANTS = ['url' => 'ONETRACE_URL', 'write_key' => 'ONETRACE_WRITE_KEY', 'secret_key' => 'ONETRACE_SECRET_KEY', 'identity_key' => 'ONETRACE_IDENTITY_KEY'];
    1418
    1519    /** @var array<string, mixed> */
    … …  
    1822        'write_key' => '',
    1923        'secret_key' => '',
     24        'identity_key' => '',
    2025        'tracker' => 'yes',
    2126        'wait_for_consent' => 'yes',
    … …  
    5055    public static function get(string $key)
    5156    {
    52         $constant = ['url' => 'ONETRACE_URL', 'write_key' => 'ONETRACE_WRITE_KEY', 'secret_key' => 'ONETRACE_SECRET_KEY'][$key] ?? null;
     57        $constant = self::CONSTANTS[$key] ?? null;
    5358
    5459        if ($constant !== null && \defined($constant) && \is_string(\constant($constant)) && \constant($constant) !== '') {
    … …  
    6873    public static function fromConstant(string $key): bool
    6974    {
    70         $constant = ['url' => 'ONETRACE_URL', 'write_key' => 'ONETRACE_WRITE_KEY', 'secret_key' => 'ONETRACE_SECRET_KEY'][$key] ?? null;
     75        $constant = self::CONSTANTS[$key] ?? null;
    7176
    7277        return $constant !== null && \defined($constant);
  • onetrace-for-woocommerce/tags/1.15.0/src/Storefront.php

    r3763672 r3778798  
    7979            . "(function(d,u,s,load){load=function(){if(s)return;s=d.createElement('script');s.async=1;s.src=u;d.head.appendChild(s)};%s})(document,%s);\n"
    8080            . "cdp.init(%s, %s);\ncdp.page();\n"
    81             // The browser follows the signed-in customer: identify after login, reset after logout.
    82             . "(function(u,k){try{k=localStorage.getItem('cdp_uid')}catch(e){}if(u&&k!==u)cdp.identify(u);else if(!u&&k)cdp.reset()})(%s);",
     81            // The browser follows the signed-in customer: identify after login (and with a new signature of the id),
     82            // reset after logout.
     83            . "(function(u,h,k,g){try{k=localStorage.getItem('cdp_uid');g=localStorage.getItem('cdp_uhash')}catch(e){}if(u&&(k!==u||h&&g!==h))cdp.identify(u,{},h?{userHash:h}:{});else if(!u&&k)cdp.reset()})(%s,%s);",
    8384            wp_json_encode(self::STUB_METHODS),
    8485            $waits
    … …  
    8889            wp_json_encode((string) Settings::get('write_key')),
    8990            wp_json_encode($options, JSON_UNESCAPED_SLASHES),
    90             wp_json_encode($userId)
     91            wp_json_encode($userId),
     92            wp_json_encode(Connection::userHash($userId))
    9193        );
    9294
  • onetrace-for-woocommerce/tags/1.15.0/vendor/onetrace-php/src/Client.php

    r3763672 r3778798  
    3636 *
    3737 *     $client = new OneTrace\WooCommerce\Vendor\OneTrace\Client('https://cdp.onetrace.pro', [
    38  *         'write_key' => getenv('ONETRACE_WRITE_KEY'),   // events
    39  *         'secret_key' => getenv('ONETRACE_SECRET_KEY'), // everything else
     38 *         'write_key' => getenv('ONETRACE_WRITE_KEY'),       // recommendations, widgets, search
     39 *         'secret_key' => getenv('ONETRACE_SECRET_KEY'),     // events and everything else
     40 *         'identity_key' => getenv('ONETRACE_IDENTITY_KEY'), // signs user ids for the tracker
    4041 *     ]);
    4142 *     $client->events()->track(['userId' => '42', 'event' => 'order_completed', 'properties' => ['amount' => 9980]]);
     43 *     $hash = $client->userHash('42'); // cdp.identify('42', {}, { userHash: hash }) on the page
    4244 *
    4345 * The address is the platform domain of your account (a white-label brand has its own); "/api/v1" is added
    … …  
    4648final class Client
    4749{
    48     public const VERSION = '1.16.0';
     50    public const VERSION = '1.17.0';
    4951
    5052    /**
    … …  
    174176     *     write_key?: string|null,
    175177     *     secret_key?: string|null,
     178     *     identity_key?: string|null,
    176179     *     timeout?: float,
    177180     *     connect_timeout?: float,
    … …  
    186189     *     sleep?: callable(float): void,
    187190     * } $options
    188      *   - write_key: cdp_wk_… for events, recommendations, widgets, product search and Web Push;
    189      *   - secret_key: cdp_sk_… for everything (never expose it to browsers);
     191     *   - write_key: cdp_wk_… for recommendations, widgets, product search and Web Push, events when there is no
     192     *     secret key;
     193     *   - secret_key: cdp_sk_… for everything, events included (never expose it to browsers);
     194     *   - identity_key: cdp_ik_…, the identity key of the project (Website → Connection → Server) for userHash()
     195     *     and signed user ids of events sent with the write key (never expose it to browsers);
    190196     *   - timeout / connect_timeout: seconds for the built-in cURL transport (10 and 5 by default);
    191197     *   - max_retries: retries of network errors, 429, 5xx (3 by default, 0 disables);
    … …  
    214220            throw new \InvalidArgumentException('Pass "write_key", "secret_key" or both.');
    215221        }
     222
     223        $identityKey = self::key($options['identity_key'] ?? null, 'The identity key must be a string.');
    216224
    217225        $userAgent = sprintf('onetrace-php/%s PHP/%s', self::VERSION, PHP_VERSION);
    … …  
    230238            $userAgent,
    231239            $options['sleep'] ?? null,
    232             isset($options['language']) && $options['language'] !== '' ? $options['language'] : 'en'
     240            isset($options['language']) && $options['language'] !== '' ? $options['language'] : 'en',
     241            $identityKey
    233242        );
    234243    }
    … …  
    388397        /** @var array{type: string, name: string, project: array<string, mixed>, scopes: list<string>} */
    389398        return $this->requester->request('GET', '/key', ['auth' => $key === 'write' ? Requester::AUTH_WRITE : Requester::AUTH_SECRET]);
     399    }
     400
     401    /**
     402     * The signature of a signed-in user's id for the tracker: HMAC-SHA256 of the id with the identity key, hex.
     403     * Print it into the page — cdp.identify(userId, traits, { userHash }) — so that the platform trusts the user id
     404     * of the browser (required when the project turns on "Require signature"). Null when the client has no
     405     * "identity_key".
     406     *
     407     * @param string|int $userId
     408     */
     409    public function userHash($userId): ?string
     410    {
     411        $userId = (string) $userId;
     412
     413        return $userId === '' ? null : $this->requester->userHash($userId);
    390414    }
    391415
    … …  
    470494     * @param mixed $key
    471495     */
    472     private static function key($key): ?string
     496    private static function key($key, string $error = 'API keys must be strings.'): ?string
    473497    {
    474498        if ($key === null || $key === false || $key === '') {
    … …  
    477501
    478502        if (!\is_string($key)) {
    479             throw new \InvalidArgumentException('API keys must be strings.');
    480         }
    481 
    482         return trim($key);
     503            throw new \InvalidArgumentException($error);
     504        }
     505
     506        $key = trim($key);
     507
     508        return $key === '' ? null : $key;
    483509    }
    484510}
  • onetrace-for-woocommerce/tags/1.15.0/vendor/onetrace-php/src/Http/Requester.php

    r3761605 r3778798  
    2424    public const AUTH_WRITE = 'write';
    2525    public const AUTH_SECRET = 'secret';
     26    /** The secret key, or the write key when there is no secret key: events sent by a server. */
     27    public const AUTH_SERVER = 'server';
    2628
    2729    private const MAX_RETRY_AFTER = 60.0;
    … …  
    3234
    3335    private ?string $secretKey;
     36
     37    private ?string $identityKey;
    3438
    3539    private Transport $transport;
    … …  
    5862        string $userAgent,
    5963        ?callable $sleep = null,
    60         string $language = 'en'
     64        string $language = 'en',
     65        ?string $identityKey = null
    6166    ) {
    6267        $this->baseUrl = $baseUrl;
    6368        $this->writeKey = $writeKey;
    6469        $this->secretKey = $secretKey;
     70        $this->identityKey = $identityKey;
    6571        $this->transport = $transport;
    6672        $this->maxRetries = max(0, $maxRetries);
    … …  
    8086     *     idempotent?: bool,
    8187     *     idempotency_key?: string|null,
    82      * } $options auth: AUTH_WRITE accepts either key (write key preferred), AUTH_SECRET needs the secret key;
     88     * } $options auth: AUTH_WRITE accepts either key (write key preferred), AUTH_SERVER — either key (secret key
     89     *             preferred), AUTH_SECRET needs the secret key;
    8390     *             idempotent: send an Idempotency-Key header (generated unless given)
    8491     *
    … …  
    128135    {
    129136        return $this->baseUrl;
     137    }
     138
     139    /**
     140     * Whether a request with this auth goes with the write key.
     141     */
     142    public function usesWriteKey(string $auth): bool
     143    {
     144        return $this->writeKey !== null && ($auth === self::AUTH_WRITE || $this->secretKey === null);
     145    }
     146
     147    /**
     148     * The signature of a user id: HMAC-SHA256 with the identity key, hex; null without the identity key.
     149     */
     150    public function userHash(string $userId): ?string
     151    {
     152        return $this->identityKey === null ? null : hash_hmac('sha256', $userId, $this->identityKey);
    130153    }
    131154
    … …  
    192215        }
    193216
    194         throw new ConfigurationException($auth === self::AUTH_WRITE
     217        if ($auth === self::AUTH_SERVER && $this->writeKey !== null) {
     218            return $this->writeKey;
     219        }
     220
     221        throw new ConfigurationException($auth !== self::AUTH_SECRET
    195222            ? 'Pass "write_key" or "secret_key" to the client to send events.'
    196223            : 'This method needs a secret key: pass "secret_key" to the client.');
  • onetrace-for-woocommerce/tags/1.15.0/vendor/onetrace-php/src/Resource/Events.php

    r3738426 r3778798  
    1212
    1313/**
    14  * Event ingestion: track, identify, page, alias and batches. Works with a write key or a secret key.
     14 * Event ingestion: track, identify, page, alias and batches. Works with a secret key or a write key; the secret key
     15 * is used when both are given (events of the write key do not award loyalty points, and their userId is dropped when
     16 * the project requires signed user ids). With only the write key, messages with a userId get its "userHash"
     17 * signature from the client's identity key.
    1518 *
    1619 * Each message gets a messageId (repeats with the same id within 24 hours are dropped by the server, so retries
    … …  
    128131        $result = ['accepted' => 0, 'duplicates' => 0];
    129132
    130         foreach (self::chunks($messages) as $chunk) {
     133        foreach (self::chunks($this->sign($messages)) as $chunk) {
    131134            $response = $this->requester->request('POST', '/batch', ['auth' => self::auth($chunk), 'json' => ['batch' => $chunk]]);
    132135            $result['accepted'] += self::count($response['accepted'] ?? 0);
    … …  
    201204    private function send(string $type, array $message): array
    202205    {
    203         return $this->requester->request('POST', '/' . $type, ['auth' => self::auth([$message]), 'json' => self::prepare($type, $message)]);
    204     }
    205 
    206     /**
    207      * Consents in identify are accepted only with the secret key; other messages prefer the write key.
     206        return $this->requester->request('POST', '/' . $type, ['auth' => self::auth([$message]), 'json' => $this->sign([self::prepare($type, $message)])[0]]);
     207    }
     208
     209    /**
     210     * Consents in identify are accepted only with the secret key; other messages prefer it too.
    208211     *
    209212     * @param array<array<string, mixed>> $messages
    … …  
    217220        }
    218221
    219         return Requester::AUTH_WRITE;
     222        return Requester::AUTH_SERVER;
     223    }
     224
     225    /**
     226     * Adds "userHash" to messages with a userId when they go with the write key and the identity key is set.
     227     *
     228     * @param list<array<string, mixed>> $messages
     229     *
     230     * @return list<array<string, mixed>>
     231     */
     232    private function sign(array $messages): array
     233    {
     234        if (!$this->requester->usesWriteKey(Requester::AUTH_SERVER)) {
     235            return $messages;
     236        }
     237
     238        foreach ($messages as $index => $message) {
     239            $userId = $message['userId'] ?? null;
     240
     241            if ((\is_string($userId) || \is_int($userId)) && (string) $userId !== '' && !isset($message['userHash'])) {
     242                $hash = $this->requester->userHash((string) $userId);
     243
     244                if ($hash === null) {
     245                    return $messages;
     246                }
     247
     248                $messages[$index]['userHash'] = $hash;
     249            }
     250        }
     251
     252        return $messages;
    220253    }
    221254
  • onetrace-for-woocommerce/tags/1.15.0/vendor/onetrace-php/src/Resource/Push.php

    r3738426 r3778798  
    99/**
    1010 * Web Push subscriptions collected outside of the JS tracker (for example in a native wrapper).
    11  * Works with a write key or a secret key.
     11 * Works with a write key or a secret key; with the write key a userId gets its "userHash" signature from the
     12 * client's identity key.
    1213 */
    1314final class Push extends Resource
    … …  
    2627     * Stores a browser subscription (PushSubscription.toJSON()) and links it to the visitor.
    2728     *
    28      * @param array<string, mixed>                                                 $subscription endpoint and keys
    29      * @param array{anonymousId?: string, userId?: string, publicKey?: string} $params
     29     * @param array<string, mixed>                                                                    $subscription endpoint and keys
     30     * @param array{anonymousId?: string, userId?: string, userHash?: string, publicKey?: string} $params
    3031     *
    3132     * @return array<string, mixed> subscription_id
    … …  
    3334    public function subscribe(array $subscription, array $params = []): array
    3435    {
     36        if (isset($params['userId']) && $params['userId'] !== '' && !isset($params['userHash']) && $this->requester->usesWriteKey(Requester::AUTH_WRITE)) {
     37            $hash = $this->requester->userHash($params['userId']);
     38
     39            if ($hash !== null) {
     40                $params['userHash'] = $hash;
     41            }
     42        }
     43
    3544        return $this->requester->request('POST', '/push/subscriptions', [
    3645            'auth' => Requester::AUTH_WRITE,
  • onetrace-for-woocommerce/trunk/languages/onetrace-for-woocommerce-ru_RU.po

    r3763672 r3778798  
    44"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/onetrace-for-"
    55"woocommerce\n"
    6 "POT-Creation-Date: 2026-10-24T18:48:10+00:00\n"
     6"POT-Creation-Date: 2026-11-02T00:39:09+00:00\n"
    77"PO-Revision-Date: 2026-10-08T17:53:43+00:00\n"
    88"Last-Translator: \n"
    … …  
    6060"настройки сохранятся."
    6161
    62 #: src/Admin.php:45 src/Admin.php:277 src/Admin.php:362
     62#: src/Admin.php:48 src/Admin.php:292 src/Admin.php:377
    6363msgid "Settings"
    6464msgstr "Настройки"
    6565
    66 #: src/Admin.php:60
     66#: src/Admin.php:63
    6767msgid "Set in wp-config.php."
    6868msgstr "Задано в wp-config.php."
    6969
    70 #: src/Admin.php:73
     70#: src/Admin.php:76
    7171msgid "Connection"
    7272msgstr "Подключение"
    7373
    74 #: src/Admin.php:73
     74#: src/Admin.php:76
    7575msgid "Keys are in the \"API keys\" section of your OneTrace project."
    7676msgstr "Ключи — в разделе «Ключи API» вашего проекта OneTrace."
    7777
    78 #: src/Admin.php:74
     78#: src/Admin.php:77
    7979msgid "Platform address"
    8080msgstr "Адрес платформы"
    8181
    82 #: src/Admin.php:74
     82#: src/Admin.php:77
    8383msgid "The address you open the platform at: the domain of your brand."
    8484msgstr "Адрес, по которому вы открываете платформу: домен вашего бренда."
    8585
    86 #: src/Admin.php:75 src/Admin.php:231
     86#: src/Admin.php:78 src/Admin.php:246
    8787msgid "Write key"
    8888msgstr "Ключ записи"
    8989
    90 #: src/Admin.php:75
     90#: src/Admin.php:78
    9191msgid "For the tracker on the storefront."
    9292msgstr "Для трекера на витрине."
    9393
    94 #: src/Admin.php:76 src/Admin.php:231
     94#: src/Admin.php:79 src/Admin.php:246
    9595msgid "Secret key"
    9696msgstr "Секретный ключ"
    9797
    98 #: src/Admin.php:76
     98#: src/Admin.php:79
    9999msgid ""
    100100"For orders, customers and the catalog; needs the products.write permission."
    101101msgstr "Для заказов, покупателей и каталога; нужно право products.write."
    102102
    103 #: src/Admin.php:79
     103#: src/Admin.php:80
     104msgid "Identity key"
     105msgstr "Ключ подписи"
     106
     107#: src/Admin.php:80
     108msgid ""
     109"Signs the id of the signed-in customer for the tracker, so OneTrace trusts "
     110"it when the project requires signed user ids. It is in OneTrace → Site → "
     111"Connection → Server."
     112msgstr ""
     113"Подписывает id вошедшего покупателя для трекера, и OneTrace принимает его, "
     114"когда в проекте включено «Требовать подпись». Ключ — в OneTrace → Сайт → "
     115"Подключение → Сервер."
     116
     117#: src/Admin.php:83
    104118msgid "What to send"
    105119msgstr "Что передавать"
    106120
    107 #: src/Admin.php:80
     121#: src/Admin.php:84
    108122msgid "Tracker"
    109123msgstr "Трекер"
    110124
    111 #: src/Admin.php:80
     125#: src/Admin.php:84
    112126msgid "Page and product views on the storefront"
    113127msgstr "Просмотры страниц и товаров на витрине"
    114128
    115 #: src/Admin.php:81
     129#: src/Admin.php:85
    116130msgid "Cookie consent"
    117131msgstr "Согласие на cookie"
    118132
    119 #: src/Admin.php:81
     133#: src/Admin.php:85
    120134msgid ""
    121135"Load the tracker after the visitor agrees to statistics cookies (with a "
    … …  
    125139"плагином согласия, который поддерживает WP Consent API)"
    126140
    127 #: src/Admin.php:82
     141#: src/Admin.php:86
    128142msgid "Orders"
    129143msgstr "Заказы"
    130144
    131 #: src/Admin.php:82
     145#: src/Admin.php:86
    132146msgid ""
    133147"Placed, paid, shipped, delivered, cancelled and refunded orders with the "
    … …  
    137151"возвраты с данными покупателя"
    138152
    139 #: src/Admin.php:83
     153#: src/Admin.php:87
    140154msgid "Cart"
    141155msgstr "Корзина"
    142156
    143 #: src/Admin.php:83
     157#: src/Admin.php:87
    144158msgid ""
    145159"Adding to and removing from the cart, opening the checkout — for abandoned "
    … …  
    149163"брошенной корзины"
    150164
    151 #: src/Admin.php:84
     165#: src/Admin.php:88
    152166msgid "Wishlist"
    153167msgstr "Избранное"
    154168
    155 #: src/Admin.php:84
     169#: src/Admin.php:88
    156170msgid ""
    157171"Adding to and removing from the wishlist of YITH WooCommerce Wishlist or TI "
    … …  
    161175"WooCommerce Wishlist — для цепочек по избранному"
    162176
    163 #: src/Admin.php:85
     177#: src/Admin.php:89
    164178msgid "Product catalog"
    165179msgstr "Каталог товаров"
    166180
    167 #: src/Admin.php:85
     181#: src/Admin.php:89
    168182msgid ""
    169183"Products, categories and stock for recommendations, emails and catalog "
    … …  
    173187"при изменении товаров и остатков и раз в сутки"
    174188
    175 #: src/Admin.php:86
     189#: src/Admin.php:90
    176190msgid "Product id"
    177191msgstr "ID товара"
    178192
    179 #: src/Admin.php:86
     193#: src/Admin.php:90
    180194msgid "Post ID"
    181195msgstr "ID записи"
    182196
    183 #: src/Admin.php:86
     197#: src/Admin.php:90
    184198msgid "SKU (the post ID for products without a SKU)"
    185199msgstr "Артикул (ID записи, если артикула нет)"
    186200
    187 #: src/Admin.php:86
     201#: src/Admin.php:90
    188202msgid ""
    189203"Choose SKU if your OneTrace project already has the catalog and history "
    … …  
    193207"артикулам, например после переезда с другой платформы."
    194208
    195 #: src/Admin.php:89
     209#: src/Admin.php:93
    196210msgid "Newsletter consent"
    197211msgstr "Согласие на рассылку"
    198212
    199 #: src/Admin.php:89
     213#: src/Admin.php:93
    200214msgid ""
    201215"A checkbox subscribes the customer to marketing emails in OneTrace. Without "
    … …  
    205219"согласие не передаётся."
    206220
    207 #: src/Admin.php:90
     221#: src/Admin.php:94
    208222msgid "Checkout"
    209223msgstr "Оформление заказа"
    210224
    211 #: src/Admin.php:90
     225#: src/Admin.php:94
    212226msgid "Checkbox at checkout (classic and block)"
    213227msgstr "Галочка при оформлении заказа (классическом и блочном)"
    214228
    215 #: src/Admin.php:91
     229#: src/Admin.php:95
    216230msgid "Registration"
    217231msgstr "Регистрация"
    218232
    219 #: src/Admin.php:91
     233#: src/Admin.php:95
    220234msgid "Checkbox in the registration form"
    221235msgstr "Галочка в форме регистрации"
    222236
    223 #: src/Admin.php:92
     237#: src/Admin.php:96
    224238msgid "Account"
    225239msgstr "Личный кабинет"
    226240
    227 #: src/Admin.php:92
     241#: src/Admin.php:96
    228242msgid "Subscribe and unsubscribe on the account details page"
    229243msgstr "Подписка и отписка на странице данных аккаунта"
    230244
    231 #: src/Admin.php:93
     245#: src/Admin.php:97
    232246msgid "Checkbox text"
    233247msgstr "Текст галочки"
    234248
    235 #: src/Admin.php:93 src/Settings.php:97
     249#: src/Admin.php:97 src/Settings.php:102
    236250msgid "Send me news and special offers by email"
    237251msgstr "Присылать новости и специальные предложения по email"
    238252
    239 #: src/Admin.php:94
     253#: src/Admin.php:98
    240254msgid "Subscription topic"
    241255msgstr "Тема подписки"
    242256
    243 #: src/Admin.php:94
     257#: src/Admin.php:98
    244258msgid "Empty — the whole email channel."
    245259msgstr "Пусто — весь канал email."
    246260
    247 #: src/Admin.php:95
     261#: src/Admin.php:99
    248262msgid "Newsletters in My account"
    249263msgstr "Рассылки в личном кабинете"
    250264
    251 #: src/Admin.php:95
     265#: src/Admin.php:99
    252266msgid ""
    253267"My account → Newsletters: subscription topics by channel, frequency, a pause "
    … …  
    259273"profiles.read и profiles.write)"
    260274
    261 #: src/Admin.php:95
     275#: src/Admin.php:99
    262276msgid ""
    263277"Topics and their names are set up in OneTrace → Messaging rules → "
    … …  
    267281"подписки»."
    268282
    269 #: src/Admin.php:98
     283#: src/Admin.php:102
    270284msgid "Recommendations, search and Web Push"
    271285msgstr "Рекомендации, поиск и Web Push"
    272286
    273 #: src/Admin.php:98
     287#: src/Admin.php:102
    274288msgid ""
    275289"Widget ids are in the \"Site → Widgets\" section of the platform. Anywhere "
    … …  
    279293"другом месте используйте шорткод [onetrace_widget id=\"…\"]."
    280294
    281 #: src/Admin.php:99
     295#: src/Admin.php:103
    282296msgid "Widget on the product page"
    283297msgstr "Виджет на странице товара"
    284298
    285 #: src/Admin.php:100
     299#: src/Admin.php:104
    286300msgid "Widget in the cart"
    287301msgstr "Виджет в корзине"
    288302
    289 #: src/Admin.php:101
     303#: src/Admin.php:105
    290304msgid "Web Push"
    291305msgstr "Web Push"
    292306
    293 #: src/Admin.php:101
     307#: src/Admin.php:105
    294308msgid ""
    295309"Serve /cdp-sw.js from the store root; put the [onetrace_push_button] "
    … …  
    299313"поставьте там, где посетители подписываются"
    300314
    301 #: src/Admin.php:102
     315#: src/Admin.php:106
    302316msgid "Product search"
    303317msgstr "Поиск по товарам"
    304318
    305 #: src/Admin.php:102
     319#: src/Admin.php:106
    306320msgid ""
    307321"Results of the store search and suggestions while typing come from OneTrace "
    … …  
    312326"товарам должен быть в тарифе проекта); при ошибке — обычный поиск WordPress"
    313327
    314 #: src/Admin.php:103
     328#: src/Admin.php:107
    315329msgid "OneTrace search widget"
    316330msgstr "Виджет поиска OneTrace"
    317331
    318 #: src/Admin.php:103
     332#: src/Admin.php:107
    319333msgid ""
    320334"The search page shows the results widget of OneTrace — facets, sorting, "
    … …  
    326340"полями поиска открывается слой поиска (нужен трекер)"
    327341
    328 #: src/Admin.php:103
     342#: src/Admin.php:107
    329343msgid ""
    330344"Turn the widget on and set up its look in OneTrace → Site → Search. While it "
    … …  
    334348"выключен или OneTrace недоступен, страница поиска остаётся прежней."
    335349
    336 #: src/Admin.php:104
     350#: src/Admin.php:108
    337351msgid "Notify when available"
    338352msgstr "Сообщить о поступлении"
    339353
    340 #: src/Admin.php:104
     354#: src/Admin.php:108
    341355msgid ""
    342356"Show the “Notify when available” form on the page of a product that is out "
    … …  
    345359"Показывать форму «Сообщить о поступлении» на странице товара не в наличии"
    346360
    347 #: src/Admin.php:104
     361#: src/Admin.php:108
    348362msgid ""
    349363"The form itself is set up in OneTrace → Site → Forms (kind “Notify when "
    … …  
    353367"поступлении»); без активной формы этого вида ничего не показывается."
    354368
    355 #: src/Admin.php:105
     369#: src/Admin.php:109
    356370msgid "Ask AI about a product"
    357371msgstr "Спросить ИИ о товаре"
    358372
    359 #: src/Admin.php:105
     373#: src/Admin.php:109
    360374msgid "Show \"Ask AI about this product\" on product pages"
    361375msgstr "Показывать «Спросить ИИ о товаре» на страницах товаров"
    362376
    363 #: src/Admin.php:105
     377#: src/Admin.php:109
    364378msgid ""
    365379"It appears only when the widget is turned on in OneTrace → Site → Product "
    … …  
    369383msgstr ""
    370384"Появляется, только когда виджет включён в OneTrace → Сайт → Вопрос о товаре; "
    371 "ИИ отвечает по описанию товара и базе знаний магазина. Чтобы поставить его "
    372 "в другое место, выключите эту настройку и используйте шорткод [onetrace_ask]."
    373 
    374 #: src/Admin.php:108
     385"ИИ отвечает по описанию товара и базе знаний магазина. Чтобы поставить его в "
     386"другое место, выключите эту настройку и используйте шорткод [onetrace_ask]."
     387
     388#: src/Admin.php:112
    375389msgid "Loyalty program"
    376390msgstr "Программа лояльности"
    377391
    378 #: src/Admin.php:108
     392#: src/Admin.php:112
    379393msgid ""
    380394"The program is set up in the \"Loyalty\" section of the platform. Signed-in "
    … …  
    386400"видят баллы в «Мой аккаунт → Бонусные баллы»."
    387401
    388 #: src/Admin.php:109 src/LoyaltyAccount.php:73 src/LoyaltyBlocks.php:78
     402#: src/Admin.php:113 src/LoyaltyAccount.php:73 src/LoyaltyBlocks.php:78
    389403#: src/LoyaltyCart.php:52 src/LoyaltyCart.php:53
    390404msgid "Bonus points"
    391405msgstr "Бонусные баллы"
    392406
    393 #: src/Admin.php:109
     407#: src/Admin.php:113
    394408msgid ""
    395409"Show the balance and use points in the cart and at checkout (the secret key "
    … …  
    399413"ключу нужны права loyalty.read и loyalty.write)"
    400414
    401 #: src/Admin.php:110
     415#: src/Admin.php:114
    402416msgid "Referrals"
    403417msgstr "Приглашения"
    404418
    405 #: src/Admin.php:110
     419#: src/Admin.php:114
    406420msgid ""
    407421"The \"Friend's code\" field in the registration form. Without it the code of "
    … …  
    411425"ref=) всё равно засчитывается: трекер сохраняет его в cookie."
    412426
    413 #: src/Admin.php:113
     427#: src/Admin.php:117
    414428msgid "Promo codes"
    415429msgstr "Промокоды"
    416430
    417 #: src/Admin.php:113
     431#: src/Admin.php:117
    418432msgid ""
    419433"Unique codes of OneTrace promo code pools become WooCommerce coupons every 5 "
    … …  
    427441"привяжите его к ключу пула из раздела «Промокоды» платформы."
    428442
    429 #: src/Admin.php:114
     443#: src/Admin.php:118
    430444msgid "Pools and template coupons"
    431445msgstr "Пулы и купоны-образцы"
    432446
    433 #: src/Admin.php:114
     447#: src/Admin.php:118
    434448msgid ""
    435449"One per line: pool key = template coupon code. The secret key needs the "
    … …  
    439453"право promo.read."
    440454
    441 #: src/Admin.php:117
     455#: src/Admin.php:121
    442456msgid "AI chat bot: store MCP"
    443457msgstr "ИИ-бот чата: MCP магазина"
    444458
    445 #: src/Admin.php:117
     459#: src/Admin.php:121
    446460msgid ""
    447461"The AI bot of the OneTrace chat answers customers with live data of the "
    … …  
    455469"на email. Секретному ключу нужно право chats.manage."
    456470
    457 #: src/Admin.php:118
     471#: src/Admin.php:122
    458472msgid "Store MCP server"
    459473msgstr "MCP-сервер магазина"
    460474
    461 #: src/Admin.php:118
     475#: src/Admin.php:122
    462476msgid "Connect the store to the AI chat bot"
    463477msgstr "Подключить магазин к ИИ-боту чата"
    464478
    465 #: src/Admin.php:119
     479#: src/Admin.php:123
    466480msgid "What the bot may do"
    467481msgstr "Что разрешено боту"
    468482
    469 #: src/Admin.php:119
     483#: src/Admin.php:123
    470484msgid ""
    471485"Reading is safe; actions change orders and run only after the customer "
    … …  
    475489"покупателя в чате."
    476490
    477 #: src/Admin.php:130
     491#: src/Admin.php:134
    478492msgid "Send a confirmation code"
    479493msgstr "Отправлять код подтверждения"
    480494
    481 #: src/Admin.php:131
     495#: src/Admin.php:135
    482496msgid "Check the confirmation code"
    483497msgstr "Проверять код подтверждения"
    484498
    485 #: src/Admin.php:132
     499#: src/Admin.php:136
    486500msgid "Read the confirmed customer"
    487501msgstr "Читать подтверждённого покупателя"
    488502
    489 #: src/Admin.php:133
     503#: src/Admin.php:137
    490504msgid "Read the customer's orders"
    491505msgstr "Читать заказы покупателя"
    492506
    493 #: src/Admin.php:134
     507#: src/Admin.php:138
    494508msgid "Read an order"
    495509msgstr "Читать заказ"
    496510
    497 #: src/Admin.php:135
     511#: src/Admin.php:139
    498512msgid "Read parcel tracking"
    499513msgstr "Читать отслеживание посылки"
    500514
    501 #: src/Admin.php:136
     515#: src/Admin.php:140
    502516msgid "Read stock and prices"
    503517msgstr "Читать наличие и цены"
    504518
    505 #: src/Admin.php:137
     519#: src/Admin.php:141
    506520msgid "Read delivery methods"
    507521msgstr "Читать способы доставки"
    508522
    509 #: src/Admin.php:138
     523#: src/Admin.php:142
    510524msgid "Read the return policy"
    511525msgstr "Читать условия возврата"
    512526
    513 #: src/Admin.php:139
     527#: src/Admin.php:143
    514528msgid "Action: cancel an unpaid order"
    515529msgstr "Действие: отменять неоплаченный заказ"
    516530
    517 #: src/Admin.php:140
     531#: src/Admin.php:144
    518532msgid "Action: pass a return request to the shop"
    519533msgstr "Действие: передавать магазину заявку на возврат"
    520534
    521 #: src/Admin.php:141
     535#: src/Admin.php:145
    522536msgid "Action: pass a delivery change request to the shop"
    523537msgstr "Действие: передавать магазину запрос на изменение доставки"
    524538
    525 #: src/Admin.php:155
     539#: src/Admin.php:160
    526540msgid "Saved — enter a new key to replace it"
    527541msgstr "Сохранён — введите новый ключ, чтобы заменить"
    528542
    529543#. translators: %s: project name
    530 #: src/Admin.php:221
     544#: src/Admin.php:236
    531545#, php-format
    532546msgid "Write key: project \"%s\"."
    … …  
    534548
    535549#. translators: %s: project name
    536 #: src/Admin.php:223
     550#: src/Admin.php:238
    537551#, php-format
    538552msgid "Secret key: project \"%s\"."
    539553msgstr "Секретный ключ: проект «%s»."
    540554
    541 #: src/Admin.php:225
     555#: src/Admin.php:240
    542556msgid ""
    543557"The key has no products.write permission: the catalog will not be uploaded."
    544558msgstr "У ключа нет права products.write: каталог не будет выгружаться."
    545559
    546 #: src/Admin.php:226
     560#: src/Admin.php:241
    547561msgid ""
    548562"The key has no loyalty.read and loyalty.write permissions: bonus points will "
    … …  
    552566"будут."
    553567
    554 #: src/Admin.php:227
     568#: src/Admin.php:242
    555569msgid ""
    556570"The key has no promo.read permission: promo codes will not become coupons."
    557571msgstr "У ключа нет права promo.read: промокоды не станут купонами."
    558572
    559 #: src/Admin.php:228
     573#: src/Admin.php:243
    560574msgid ""
    561575"The key has no profiles.read and profiles.write permissions: the Newsletters "
    … …  
    565579"не будет."
    566580
    567 #: src/Admin.php:236
     581#: src/Admin.php:251
    568582msgid "Enter the platform address and the keys first."
    569583msgstr "Сначала укажите адрес платформы и ключи."
    570584
    571 #: src/Admin.php:253
     585#: src/Admin.php:268
    572586msgid "The catalog upload has started; it runs in the background."
    573587msgstr "Выгрузка каталога началась, она идёт в фоне."
    574588
    575 #: src/Admin.php:275
     589#: src/Admin.php:290
    576590msgid ""
    577591"OneTrace: sending is paused because the platform rejected the key. Check the "
    … …  
    581595"ключи и сохраните настройки."
    582596
    583 #: src/Admin.php:288
     597#: src/Admin.php:303
    584598msgid "Status"
    585599msgstr "Состояние"
    586600
    587 #: src/Admin.php:291
     601#: src/Admin.php:306
    588602msgid "Queue"
    589603msgstr "Очередь"
    590604
    591605#. translators: 1: items waiting, 2: items waiting for a retry
    592 #: src/Admin.php:294
     606#: src/Admin.php:309
    593607#, php-format
    594608msgid "%1$d waiting, %2$d of them after an error"
    595609msgstr "Ждут отправки: %1$d, из них после ошибки: %2$d"
    596610
    597 #: src/Admin.php:301
     611#: src/Admin.php:316
    598612msgid "Last error"
    599613msgstr "Последняя ошибка"
    600614
    601 #: src/Admin.php:309
     615#: src/Admin.php:324
    602616msgid "AI chat bot"
    603617msgstr "ИИ-бот чата"
    604618
    605619#. translators: %s: tools the bot uses
    606 #: src/Admin.php:312
     620#: src/Admin.php:327
    607621#, php-format
    608622msgid "Connected: %s"
    609623msgstr "Подключён: %s"
    610624
    611 #: src/Admin.php:318
     625#: src/Admin.php:333
    612626msgid "Test connection"
    613627msgstr "Проверить подключение"
    614628
    615 #: src/Admin.php:320
     629#: src/Admin.php:335
    616630msgid "Upload the whole catalog"
    617631msgstr "Выгрузить весь каталог"
    618632
    619 #: src/Admin.php:330
     633#: src/Admin.php:345
    620634msgid "Store emails"
    621635msgstr "Письма магазина"
    622636
    623 #: src/Admin.php:331
     637#: src/Admin.php:346
    624638msgid ""
    625639"Emails of WooCommerce, WordPress and other plugins can go out through the "
    … …  
    638652"Письмо, которое OneTrace не принял, магазин отправляет сам."
    639653
    640 #: src/Admin.php:340 src/Admin.php:343
     654#: src/Admin.php:355 src/Admin.php:358
    641655msgid "State"
    642656msgstr "Состояние"
    643657
    644 #: src/Admin.php:340
     658#: src/Admin.php:355
    645659msgid "Enter the platform address and the secret key."
    646660msgstr "Укажите адрес платформы и секретный ключ."
    647661
    648 #: src/Admin.php:343
     662#: src/Admin.php:358
    649663msgid "Not available — the store sends its emails itself."
    650664msgstr "Недоступно — магазин отправляет письма сам."
    651665
    652 #: src/Admin.php:346
     666#: src/Admin.php:361
    653667msgid "Order placed"
    654668msgstr "Заказ оформлен"
    655669
    656 #: src/Admin.php:347
     670#: src/Admin.php:362
    657671msgid "Order paid"
    658672msgstr "Заказ оплачен"
    659673
    660 #: src/Admin.php:348
     674#: src/Admin.php:363
    661675msgid "Order shipped"
    662676msgstr "Заказ отправлен"
    663677
    664 #: src/Admin.php:349
     678#: src/Admin.php:364
    665679msgid "Order delivered"
    666680msgstr "Заказ доставлен"
    667681
    668 #: src/Admin.php:350
     682#: src/Admin.php:365
    669683msgid "Order cancelled"
    670684msgstr "Заказ отменён"
    671685
    672 #: src/Admin.php:351
     686#: src/Admin.php:366
    673687msgid "Order refunded"
    674688msgstr "Возврат по заказу"
    675689
    676 #: src/Admin.php:355
     690#: src/Admin.php:370
    677691msgid "All store emails"
    678692msgstr "Все письма магазина"
    679693
    680 #: src/Admin.php:356
     694#: src/Admin.php:371
    681695msgid ""
    682696"Through OneTrace: emails without a OneTrace template go out as the store "
    … …  
    686700"магазин"
    687701
    688 #: src/Admin.php:357
     702#: src/Admin.php:372
    689703msgid "Sent by the store"
    690704msgstr "Отправляет магазин"
    691705
    692 #: src/Admin.php:358
     706#: src/Admin.php:373
    693707msgid "Order emails from OneTrace templates"
    694708msgstr "Письма о заказе по шаблонам OneTrace"
    695709
    696 #: src/Admin.php:358
     710#: src/Admin.php:373
    697711msgid "None"
    698712msgstr "Нет"
    699713
    700 #: src/Admin.php:363
     714#: src/Admin.php:378
    701715msgid "Store emails in OneTrace"
    702716msgstr "Письма магазина в OneTrace"
    703717
    704 #: src/Admin.php:364
     718#: src/Admin.php:379
    705719msgid "OneTrace → Store emails"
    706720msgstr "OneTrace → Письма магазина"
    707721
    708 #: src/Admin.php:408
     722#: src/Admin.php:423
    709723msgid "You are not allowed to do this."
    710724msgstr "У вас нет прав на это действие."
    … …  
    9991013msgstr "(необязательно)"
    10001014
    1001 #: src/Storefront.php:293
     1015#: src/Storefront.php:295
    10021016msgid "Get notifications"
    10031017msgstr "Получать уведомления"
  • onetrace-for-woocommerce/trunk/languages/onetrace-for-woocommerce.pot

    r3763672 r3778798  
    33msgid ""
    44msgstr ""
    5 "Project-Id-Version: OneTrace for WooCommerce 1.14.0\n"
     5"Project-Id-Version: OneTrace for WooCommerce 1.15.0\n"
    66"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/onetrace-for-woocommerce\n"
    77"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
    … …  
    1010"Content-Type: text/plain; charset=UTF-8\n"
    1111"Content-Transfer-Encoding: 8bit\n"
    12 "POT-Creation-Date: 2026-10-24T18:48:10+00:00\n"
     12"POT-Creation-Date: 2026-11-02T00:39:09+00:00\n"
    1313"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
    1414"X-Generator: WP-CLI 2.12.0\n"
    … …  
    4646msgstr ""
    4747
    48 #: src/Admin.php:45
    49 #: src/Admin.php:277
    50 #: src/Admin.php:362
     48#: src/Admin.php:48
     49#: src/Admin.php:292
     50#: src/Admin.php:377
    5151msgid "Settings"
    5252msgstr ""
    5353
    54 #: src/Admin.php:60
     54#: src/Admin.php:63
    5555msgid "Set in wp-config.php."
    5656msgstr ""
    5757
    58 #: src/Admin.php:73
     58#: src/Admin.php:76
    5959msgid "Connection"
    6060msgstr ""
    6161
    62 #: src/Admin.php:73
     62#: src/Admin.php:76
    6363msgid "Keys are in the \"API keys\" section of your OneTrace project."
    6464msgstr ""
    6565
    66 #: src/Admin.php:74
     66#: src/Admin.php:77
    6767msgid "Platform address"
    6868msgstr ""
    6969
    70 #: src/Admin.php:74
     70#: src/Admin.php:77
    7171msgid "The address you open the platform at: the domain of your brand."
    7272msgstr ""
    7373
    74 #: src/Admin.php:75
    75 #: src/Admin.php:231
     74#: src/Admin.php:78
     75#: src/Admin.php:246
    7676msgid "Write key"
    7777msgstr ""
    7878
    79 #: src/Admin.php:75
     79#: src/Admin.php:78
    8080msgid "For the tracker on the storefront."
    8181msgstr ""
    8282
    83 #: src/Admin.php:76
    84 #: src/Admin.php:231
     83#: src/Admin.php:79
     84#: src/Admin.php:246
    8585msgid "Secret key"
    8686msgstr ""
    8787
    88 #: src/Admin.php:76
     88#: src/Admin.php:79
    8989msgid "For orders, customers and the catalog; needs the products.write permission."
    9090msgstr ""
    9191
    92 #: src/Admin.php:79
     92#: src/Admin.php:80
     93msgid "Identity key"
     94msgstr ""
     95
     96#: src/Admin.php:80
     97msgid "Signs the id of the signed-in customer for the tracker, so OneTrace trusts it when the project requires signed user ids. It is in OneTrace → Site → Connection → Server."
     98msgstr ""
     99
     100#: src/Admin.php:83
    93101msgid "What to send"
    94102msgstr ""
    95103
    96 #: src/Admin.php:80
     104#: src/Admin.php:84
    97105msgid "Tracker"
    98106msgstr ""
    99107
    100 #: src/Admin.php:80
     108#: src/Admin.php:84
    101109msgid "Page and product views on the storefront"
    102110msgstr ""
    103111
    104 #: src/Admin.php:81
     112#: src/Admin.php:85
    105113msgid "Cookie consent"
    106114msgstr ""
    107115
    108 #: src/Admin.php:81
     116#: src/Admin.php:85
    109117msgid "Load the tracker after the visitor agrees to statistics cookies (with a consent plugin that supports the WP Consent API)"
    110118msgstr ""
    111119
    112 #: src/Admin.php:82
     120#: src/Admin.php:86
    113121msgid "Orders"
    114122msgstr ""
    115123
    116 #: src/Admin.php:82
     124#: src/Admin.php:86
    117125msgid "Placed, paid, shipped, delivered, cancelled and refunded orders with the customer data"
    118126msgstr ""
    119127
    120 #: src/Admin.php:83
     128#: src/Admin.php:87
    121129msgid "Cart"
    122130msgstr ""
    123131
    124 #: src/Admin.php:83
     132#: src/Admin.php:87
    125133msgid "Adding to and removing from the cart, opening the checkout — for abandoned cart journeys"
    126134msgstr ""
    127135
    128 #: src/Admin.php:84
     136#: src/Admin.php:88
    129137msgid "Wishlist"
    130138msgstr ""
    131139
    132 #: src/Admin.php:84
     140#: src/Admin.php:88
    133141msgid "Adding to and removing from the wishlist of YITH WooCommerce Wishlist or TI WooCommerce Wishlist — for wishlist journeys"
    134142msgstr ""
    135143
    136 #: src/Admin.php:85
     144#: src/Admin.php:89
    137145msgid "Product catalog"
    138146msgstr ""
    139147
    140 #: src/Admin.php:85
     148#: src/Admin.php:89
    141149msgid "Products, categories and stock for recommendations, emails and catalog journeys, updated when products or their stock change and daily"
    142150msgstr ""
    143151
    144 #: src/Admin.php:86
     152#: src/Admin.php:90
    145153msgid "Product id"
    146154msgstr ""
    147155
    148 #: src/Admin.php:86
     156#: src/Admin.php:90
    149157msgid "Post ID"
    150158msgstr ""
    151159
    152 #: src/Admin.php:86
     160#: src/Admin.php:90
    153161msgid "SKU (the post ID for products without a SKU)"
    154162msgstr ""
    155163
    156 #: src/Admin.php:86
     164#: src/Admin.php:90
    157165msgid "Choose SKU if your OneTrace project already has the catalog and history under SKUs, e.g. after moving from another platform."
    158166msgstr ""
    159167
    160 #: src/Admin.php:89
     168#: src/Admin.php:93
    161169msgid "Newsletter consent"
    162170msgstr ""
    163171
    164 #: src/Admin.php:89
     172#: src/Admin.php:93
    165173msgid "A checkbox subscribes the customer to marketing emails in OneTrace. Without it no consent is sent."
    166174msgstr ""
    167175
    168 #: src/Admin.php:90
     176#: src/Admin.php:94
    169177msgid "Checkout"
    170178msgstr ""
    171179
    172 #: src/Admin.php:90
     180#: src/Admin.php:94
    173181msgid "Checkbox at checkout (classic and block)"
    174182msgstr ""
    175183
    176 #: src/Admin.php:91
     184#: src/Admin.php:95
    177185msgid "Registration"
    178186msgstr ""
    179187
    180 #: src/Admin.php:91
     188#: src/Admin.php:95
    181189msgid "Checkbox in the registration form"
    182190msgstr ""
    183191
    184 #: src/Admin.php:92
     192#: src/Admin.php:96
    185193msgid "Account"
    186194msgstr ""
    187195
    188 #: src/Admin.php:92
     196#: src/Admin.php:96
    189197msgid "Subscribe and unsubscribe on the account details page"
    190198msgstr ""
    191199
    192 #: src/Admin.php:93
     200#: src/Admin.php:97
    193201msgid "Checkbox text"
    194202msgstr ""
    195203
    196 #: src/Admin.php:93
    197 #: src/Settings.php:97
     204#: src/Admin.php:97
     205#: src/Settings.php:102
    198206msgid "Send me news and special offers by email"
    199207msgstr ""
    200208
    201 #: src/Admin.php:94
     209#: src/Admin.php:98
    202210msgid "Subscription topic"
    203211msgstr ""
    204212
    205 #: src/Admin.php:94
     213#: src/Admin.php:98
    206214msgid "Empty — the whole email channel."
    207215msgstr ""
    208216
    209 #: src/Admin.php:95
     217#: src/Admin.php:99
    210218msgid "Newsletters in My account"
    211219msgstr ""
    212220
    213 #: src/Admin.php:95
     221#: src/Admin.php:99
    214222msgid "My account → Newsletters: subscription topics by channel, frequency, a pause and unsubscribing from everything, as in the OneTrace preference center (the secret key needs the profiles.read and profiles.write permissions)"
    215223msgstr ""
    216224
    217 #: src/Admin.php:95
     225#: src/Admin.php:99
    218226msgid "Topics and their names are set up in OneTrace → Messaging rules → Subscription topics."
    219227msgstr ""
    220228
    221 #: src/Admin.php:98
     229#: src/Admin.php:102
    222230msgid "Recommendations, search and Web Push"
    223231msgstr ""
    224232
    225 #: src/Admin.php:98
     233#: src/Admin.php:102
    226234msgid "Widget ids are in the \"Site → Widgets\" section of the platform. Anywhere else use the [onetrace_widget id=\"…\"] shortcode."
    227235msgstr ""
    228236
    229 #: src/Admin.php:99
     237#: src/Admin.php:103
    230238msgid "Widget on the product page"
    231239msgstr ""
    232240
    233 #: src/Admin.php:100
     241#: src/Admin.php:104
    234242msgid "Widget in the cart"
    235243msgstr ""
    236244
    237 #: src/Admin.php:101
     245#: src/Admin.php:105
    238246msgid "Web Push"
    239247msgstr ""
    240248
    241 #: src/Admin.php:101
     249#: src/Admin.php:105
    242250msgid "Serve /cdp-sw.js from the store root; put the [onetrace_push_button] shortcode where visitors subscribe"
    243251msgstr ""
    244252
    245 #: src/Admin.php:102
     253#: src/Admin.php:106
    246254msgid "Product search"
    247255msgstr ""
    248256
    249 #: src/Admin.php:102
     257#: src/Admin.php:106
    250258msgid "Results of the store search and suggestions while typing come from OneTrace (the plan of the project must include product search); on an error — the usual WordPress search"
    251259msgstr ""
    252260
    253 #: src/Admin.php:103
     261#: src/Admin.php:107
    254262msgid "OneTrace search widget"
    255263msgstr ""
    256264
    257 #: src/Admin.php:103
     265#: src/Admin.php:107
    258266msgid "The search page shows the results widget of OneTrace — facets, sorting, infinite scroll and an \"Add to cart\" button — inside your theme, and a search layer opens under the search fields (needs the tracker)"
    259267msgstr ""
    260268
    261 #: src/Admin.php:103
     269#: src/Admin.php:107
    262270msgid "Turn the widget on and set up its look in OneTrace → Site → Search. While it is off there, or OneTrace is unavailable, the search page stays as it is."
    263271msgstr ""
    264272
    265 #: src/Admin.php:104
     273#: src/Admin.php:108
    266274msgid "Notify when available"
    267275msgstr ""
    268276
    269 #: src/Admin.php:104
     277#: src/Admin.php:108
    270278msgid "Show the “Notify when available” form on the page of a product that is out of stock"
    271279msgstr ""
    272280
    273 #: src/Admin.php:104
     281#: src/Admin.php:108
    274282msgid "The form itself is set up in OneTrace → Site → Forms (kind “Notify when available”); without an active form of this kind nothing is shown."
    275283msgstr ""
    276284
    277 #: src/Admin.php:105
     285#: src/Admin.php:109
    278286msgid "Ask AI about a product"
    279287msgstr ""
    280288
    281 #: src/Admin.php:105
     289#: src/Admin.php:109
    282290msgid "Show \"Ask AI about this product\" on product pages"
    283291msgstr ""
    284292
    285 #: src/Admin.php:105
     293#: src/Admin.php:109
    286294msgid "It appears only when the widget is turned on in OneTrace → Site → Product questions; the AI answers from the product description and the knowledge base of the store. To place it elsewhere, turn this off and use the [onetrace_ask] shortcode."
    287295msgstr ""
    288296
    289 #: src/Admin.php:108
     297#: src/Admin.php:112
    290298msgid "Loyalty program"
    291299msgstr ""
    292300
    293 #: src/Admin.php:108
     301#: src/Admin.php:112
    294302msgid "The program is set up in the \"Loyalty\" section of the platform. Signed-in customers pay for part of the order with points in the cart and at checkout and see their points in My account → Bonus points."
    295303msgstr ""
    296304
    297 #: src/Admin.php:109
     305#: src/Admin.php:113
    298306#: src/LoyaltyAccount.php:73
    299307#: src/LoyaltyBlocks.php:78
    … …  
    303311msgstr ""
    304312
    305 #: src/Admin.php:109
     313#: src/Admin.php:113
    306314msgid "Show the balance and use points in the cart and at checkout (the secret key needs the loyalty.read and loyalty.write permissions)"
    307315msgstr ""
    308316
    309 #: src/Admin.php:110
     317#: src/Admin.php:114
    310318msgid "Referrals"
    311319msgstr ""
    312320
    313 #: src/Admin.php:110
     321#: src/Admin.php:114
    314322msgid "The \"Friend's code\" field in the registration form. Without it the code of a referral link (?ref=) still counts: the tracker keeps it in a cookie."
    315323msgstr ""
    316324
    317 #: src/Admin.php:113
     325#: src/Admin.php:117
    318326msgid "Promo codes"
    319327msgstr ""
    320328
    321 #: src/Admin.php:113
     329#: src/Admin.php:117
    322330msgid "Unique codes of OneTrace promo code pools become WooCommerce coupons every 5 minutes: with the discount, restrictions and expiry of a template coupon, one use each. Create the template coupon in Marketing → Coupons and bind it to the pool key from the \"Promo codes\" section of the platform."
    323331msgstr ""
    324332
    325 #: src/Admin.php:114
     333#: src/Admin.php:118
    326334msgid "Pools and template coupons"
    327335msgstr ""
    328336
    329 #: src/Admin.php:114
     337#: src/Admin.php:118
    330338msgid "One per line: pool key = template coupon code. The secret key needs the promo.read permission."
    331339msgstr ""
    332340
    333 #: src/Admin.php:117
     341#: src/Admin.php:121
    334342msgid "AI chat bot: store MCP"
    335343msgstr ""
    336344
    337 #: src/Admin.php:117
     345#: src/Admin.php:121
    338346msgid "The AI bot of the OneTrace chat answers customers with live data of the store and, if you allow it, acts on orders. Customers signed in on the website are confirmed automatically, others with a code the shop sends by email. The secret key needs the chats.manage permission."
    339347msgstr ""
    340348
    341 #: src/Admin.php:118
     349#: src/Admin.php:122
    342350msgid "Store MCP server"
    343351msgstr ""
    344352
    345 #: src/Admin.php:118
     353#: src/Admin.php:122
    346354msgid "Connect the store to the AI chat bot"
    347355msgstr ""
    348356
    349 #: src/Admin.php:119
     357#: src/Admin.php:123
    350358msgid "What the bot may do"
    351359msgstr ""
    352360
    353 #: src/Admin.php:119
     361#: src/Admin.php:123
    354362msgid "Reading is safe; actions change orders and run only after the customer agreed in the chat."
    355363msgstr ""
    356364
    357 #: src/Admin.php:130
     365#: src/Admin.php:134
    358366msgid "Send a confirmation code"
    359367msgstr ""
    360368
    361 #: src/Admin.php:131
     369#: src/Admin.php:135
    362370msgid "Check the confirmation code"
    363371msgstr ""
    364372
    365 #: src/Admin.php:132
     373#: src/Admin.php:136
    366374msgid "Read the confirmed customer"
    367375msgstr ""
    368376
    369 #: src/Admin.php:133
     377#: src/Admin.php:137
    370378msgid "Read the customer's orders"
    371379msgstr ""
    372380
    373 #: src/Admin.php:134
     381#: src/Admin.php:138
    374382msgid "Read an order"
    375383msgstr ""
    376384
    377 #: src/Admin.php:135
     385#: src/Admin.php:139
    378386msgid "Read parcel tracking"
    379387msgstr ""
    380388
    381 #: src/Admin.php:136
     389#: src/Admin.php:140
    382390msgid "Read stock and prices"
    383391msgstr ""
    384392
    385 #: src/Admin.php:137
     393#: src/Admin.php:141
    386394msgid "Read delivery methods"
    387395msgstr ""
    388396
    389 #: src/Admin.php:138
     397#: src/Admin.php:142
    390398msgid "Read the return policy"
    391399msgstr ""
    392400
    393 #: src/Admin.php:139
     401#: src/Admin.php:143
    394402msgid "Action: cancel an unpaid order"
    395403msgstr ""
    396404
    397 #: src/Admin.php:140
     405#: src/Admin.php:144
    398406msgid "Action: pass a return request to the shop"
    399407msgstr ""
    400408
    401 #: src/Admin.php:141
     409#: src/Admin.php:145
    402410msgid "Action: pass a delivery change request to the shop"
    403411msgstr ""
    404412
    405 #: src/Admin.php:155
     413#: src/Admin.php:160
    406414msgid "Saved — enter a new key to replace it"
    407415msgstr ""
    408416
    409417#. translators: %s: project name
    410 #: src/Admin.php:221
     418#: src/Admin.php:236
    411419#, php-format
    412420msgid "Write key: project \"%s\"."
    … …  
    414422
    415423#. translators: %s: project name
    416 #: src/Admin.php:223
     424#: src/Admin.php:238
    417425#, php-format
    418426msgid "Secret key: project \"%s\"."
    419427msgstr ""
    420428
    421 #: src/Admin.php:225
     429#: src/Admin.php:240
    422430msgid "The key has no products.write permission: the catalog will not be uploaded."
    423431msgstr ""
    424432
    425 #: src/Admin.php:226
     433#: src/Admin.php:241
    426434msgid "The key has no loyalty.read and loyalty.write permissions: bonus points will not work."
    427435msgstr ""
    428436
    429 #: src/Admin.php:227
     437#: src/Admin.php:242
    430438msgid "The key has no promo.read permission: promo codes will not become coupons."
    431439msgstr ""
    432440
    433 #: src/Admin.php:228
     441#: src/Admin.php:243
    434442msgid "The key has no profiles.read and profiles.write permissions: the Newsletters tab will not work."
    435443msgstr ""
    436444
    437 #: src/Admin.php:236
     445#: src/Admin.php:251
    438446msgid "Enter the platform address and the keys first."
    439447msgstr ""
    440448
    441 #: src/Admin.php:253
     449#: src/Admin.php:268
    442450msgid "The catalog upload has started; it runs in the background."
    443451msgstr ""
    444452
    445 #: src/Admin.php:275
     453#: src/Admin.php:290
    446454msgid "OneTrace: sending is paused because the platform rejected the key. Check the keys and save the settings."
    447455msgstr ""
    448456
    449 #: src/Admin.php:288
     457#: src/Admin.php:303
    450458msgid "Status"
    451459msgstr ""
    452460
    453 #: src/Admin.php:291
     461#: src/Admin.php:306
    454462msgid "Queue"
    455463msgstr ""
    456464
    457465#. translators: 1: items waiting, 2: items waiting for a retry
    458 #: src/Admin.php:294
     466#: src/Admin.php:309
    459467#, php-format
    460468msgid "%1$d waiting, %2$d of them after an error"
    461469msgstr ""
    462470
    463 #: src/Admin.php:301
     471#: src/Admin.php:316
    464472msgid "Last error"
    465473msgstr ""
    466474
    467 #: src/Admin.php:309
     475#: src/Admin.php:324
    468476msgid "AI chat bot"
    469477msgstr ""
    470478
    471479#. translators: %s: tools the bot uses
    472 #: src/Admin.php:312
     480#: src/Admin.php:327
    473481#, php-format
    474482msgid "Connected: %s"
    475483msgstr ""
    476484
    477 #: src/Admin.php:318
     485#: src/Admin.php:333
    478486msgid "Test connection"
    479487msgstr ""
    480488
    481 #: src/Admin.php:320
     489#: src/Admin.php:335
    482490msgid "Upload the whole catalog"
    483491msgstr ""
    484492
    485 #: src/Admin.php:330
     493#: src/Admin.php:345
    486494msgid "Store emails"
    487495msgstr ""
    488496
    489 #: src/Admin.php:331
     497#: src/Admin.php:346
    490498msgid "Emails of WooCommerce, WordPress and other plugins can go out through the email integration of your OneTrace project, with delivery statuses and history in the customer profile; order emails — from OneTrace templates in the customer's language. This is set up in the \"Store emails\" section of the platform; the secret key needs the \"Send messages manually\" permission (messages.send). An email OneTrace does not accept is sent by the store itself."
    491499msgstr ""
    492500
    493 #: src/Admin.php:340
    494 #: src/Admin.php:343
     501#: src/Admin.php:355
     502#: src/Admin.php:358
    495503msgid "State"
    496504msgstr ""
    497505
    498 #: src/Admin.php:340
     506#: src/Admin.php:355
    499507msgid "Enter the platform address and the secret key."
    500508msgstr ""
    501509
    502 #: src/Admin.php:343
     510#: src/Admin.php:358
    503511msgid "Not available — the store sends its emails itself."
    504512msgstr ""
    505513
    506 #: src/Admin.php:346
     514#: src/Admin.php:361
    507515msgid "Order placed"
    508516msgstr ""
    509517
    510 #: src/Admin.php:347
     518#: src/Admin.php:362
    511519msgid "Order paid"
    512520msgstr ""
    513521
    514 #: src/Admin.php:348
     522#: src/Admin.php:363
    515523msgid "Order shipped"
    516524msgstr ""
    517525
    518 #: src/Admin.php:349
     526#: src/Admin.php:364
    519527msgid "Order delivered"
    520528msgstr ""
    521529
    522 #: src/Admin.php:350
     530#: src/Admin.php:365
    523531msgid "Order cancelled"
    524532msgstr ""
    525533
    526 #: src/Admin.php:351
     534#: src/Admin.php:366
    527535msgid "Order refunded"
    528536msgstr ""
    529537
    530 #: src/Admin.php:355
     538#: src/Admin.php:370
    531539msgid "All store emails"
    532540msgstr ""
    533541
    534 #: src/Admin.php:356
     542#: src/Admin.php:371
    535543msgid "Through OneTrace: emails without a OneTrace template go out as the store makes them"
    536544msgstr ""
    537545
    538 #: src/Admin.php:357
     546#: src/Admin.php:372
    539547msgid "Sent by the store"
    540548msgstr ""
    541549
    542 #: src/Admin.php:358
     550#: src/Admin.php:373
    543551msgid "Order emails from OneTrace templates"
    544552msgstr ""
    545553
    546 #: src/Admin.php:358
     554#: src/Admin.php:373
    547555msgid "None"
    548556msgstr ""
    549557
    550 #: src/Admin.php:363
     558#: src/Admin.php:378
    551559msgid "Store emails in OneTrace"
    552560msgstr ""
    553561
    554 #: src/Admin.php:364
     562#: src/Admin.php:379
    555563msgid "OneTrace → Store emails"
    556564msgstr ""
    557565
    558 #: src/Admin.php:408
     566#: src/Admin.php:423
    559567msgid "You are not allowed to do this."
    560568msgstr ""
    … …  
    843851msgstr ""
    844852
    845 #: src/Storefront.php:293
     853#: src/Storefront.php:295
    846854msgid "Get notifications"
    847855msgstr ""
  • onetrace-for-woocommerce/trunk/onetrace-woocommerce.php

    r3763672 r3778798  
    44 * Plugin URI:           https://wordpress.org/plugins/onetrace-for-woocommerce/
    55 * Description:          Connects the store to OneTrace.pro, the customer data platform: orders, customers and consents from the server, the website tracker, the product catalog with stock, wishlists, recommendation widgets, Web Push and the store's emails through OneTrace.
    6  * Version:              1.14.0
     6 * Version:              1.15.0
    77 * Requires at least:    6.6
    88 * Requires PHP:         7.4
    … …  
    4343}
    4444
    45 define('ONETRACE_WC_VERSION', '1.14.0');
     45define('ONETRACE_WC_VERSION', '1.15.0');
    4646define('ONETRACE_WC_FILE', __FILE__);
    4747
  • onetrace-for-woocommerce/trunk/readme.txt

    r3763672 r3778798  
    77WC requires at least: 9.0
    88WC tested up to: 11.2
    9 Stable tag: 1.14.0
     9Stable tag: 1.15.0
    1010License: GPLv2 or later
    1111License URI: https://www.gnu.org/licenses/gpl-2.0.html
    … …  
    47472. In your OneTrace project create a write key and a secret key with the products.write permission (API keys section).
    48483. Go to WooCommerce → Settings → OneTrace, enter the platform address and both keys, click "Test connection".
     494. Optionally enter the identity key from Site → Connection → Server of the project: the id of the signed-in customer reaches the tracker signed, and the project can require signed user ids.
    4950
    5051== Frequently Asked Questions ==
    … …  
    9596== Changelog ==
    9697
     98= 1.15.0 =
     99* Signed user ids: the "Identity key" setting (or the ONETRACE_IDENTITY_KEY constant) signs the id of the signed-in customer for the OneTrace tracker, so the project can turn on "Require signature" and no visitor can link their browser to someone else's profile.
     100
    97101= 1.14.0 =
    98102* "Ask AI about this product": the product page gets the place of the OneTrace widget after the add to cart area (classic and block themes; setting "Ask AI about a product", on by default) — it shows only when the widget is turned on in OneTrace → Site → Product questions. The `[onetrace_ask]` shortcode puts it anywhere.
    … …  
    172176== Upgrade Notice ==
    173177
     178= 1.15.0 =
     179The "Identity key" setting: signed user ids for projects that require them.
     180
    174181= 1.14.0 =
    175182"Ask AI about this product" on product pages and product descriptions in the catalog.
  • onetrace-for-woocommerce/trunk/src/Admin.php

    r3763672 r3778798  
    1313    public const TAB = 'onetrace';
    1414
     15    /** Password fields that are never printed back, with their placeholders. */
     16    private const HIDDEN_KEYS = ['secret_key' => 'cdp_sk_…', 'identity_key' => 'cdp_ik_…'];
     17
    1518    public static function register(): void
    1619    {
    … …  
    7578            $field('write_key', ['type' => 'text', 'title' => __('Write key', 'onetrace-for-woocommerce'), 'placeholder' => 'cdp_wk_…', 'desc_tip' => __('For the tracker on the storefront.', 'onetrace-for-woocommerce')]),
    7679            $field('secret_key', ['type' => 'password', 'title' => __('Secret key', 'onetrace-for-woocommerce'), 'placeholder' => 'cdp_sk_…', 'desc_tip' => __('For orders, customers and the catalog; needs the products.write permission.', 'onetrace-for-woocommerce')]),
     80            $field('identity_key', ['type' => 'password', 'title' => __('Identity key', 'onetrace-for-woocommerce'), 'placeholder' => 'cdp_ik_…', 'desc_tip' => __('Signs the id of the signed-in customer for the tracker, so OneTrace trusts it when the project requires signed user ids. It is in OneTrace → Site → Connection → Server.', 'onetrace-for-woocommerce')]),
    7781            ['type' => 'sectionend', 'id' => 'onetrace_connection'],
    7882
    … …  
    151155            }
    152156
    153             // The secret key is never printed back: an empty field keeps the stored one.
    154             if (($field['id'] ?? '') === Settings::OPTION . '[secret_key]') {
    155                 $field['placeholder'] = (string) $field['value'] !== '' ? __('Saved — enter a new key to replace it', 'onetrace-for-woocommerce') : 'cdp_sk_…';
    156                 $field['value'] = '';
     157            // The secret and identity keys are never printed back: an empty field keeps the stored one.
     158            foreach (self::HIDDEN_KEYS as $key => $placeholder) {
     159                if (($field['id'] ?? '') === Settings::OPTION . '[' . $key . ']') {
     160                    $field['placeholder'] = (string) $field['value'] !== '' ? __('Saved — enter a new key to replace it', 'onetrace-for-woocommerce') : $placeholder;
     161                    $field['value'] = '';
     162                }
    157163            }
    158164
    … …  
    170176        $settings = get_option(Settings::OPTION, []);
    171177
    172         // An empty password field keeps the stored secret key.
    173         if (\is_array($settings) && \is_array($previous) && ($settings['secret_key'] ?? '') === '' && ($previous['secret_key'] ?? '') !== '') {
    174             $settings['secret_key'] = $previous['secret_key'];
    175             update_option(Settings::OPTION, $settings);
     178        // An empty password field keeps the stored key.
     179        if (\is_array($settings) && \is_array($previous)) {
     180            $kept = $settings;
     181
     182            foreach (array_keys(self::HIDDEN_KEYS) as $key) {
     183                if (($settings[$key] ?? '') === '' && ($previous[$key] ?? '') !== '') {
     184                    $kept[$key] = $previous[$key];
     185                }
     186            }
     187
     188            if ($kept !== $settings) {
     189                update_option(Settings::OPTION, $kept);
     190            }
    176191        }
    177192
  • onetrace-for-woocommerce/trunk/src/Connection.php

    r3755877 r3778798  
    3030            $options = [
    3131                $write ? 'write_key' : 'secret_key' => (string) Settings::get($write ? 'write_key' : 'secret_key') ?: null,
     32                'identity_key' => (string) Settings::get('identity_key') ?: null,
    3233                'timeout' => $timeouts[0],
    3334                'connect_timeout' => $timeouts[1],
    … …  
    4748
    4849        return self::$clients[$key];
     50    }
     51
     52    /**
     53     * The signature of the signed-in customer's id for the tracker (identity key); null without the key.
     54     */
     55    public static function userHash(string $userId): ?string
     56    {
     57        return $userId !== '' && (string) Settings::get('identity_key') !== '' ? self::client('write')->userHash($userId) : null;
    4958    }
    5059
  • onetrace-for-woocommerce/trunk/src/Settings.php

    r3763672 r3778798  
    77/**
    88 * Plugin settings: the option "onetrace_settings", the keys may also come from wp-config.php constants
    9  * ONETRACE_URL, ONETRACE_WRITE_KEY and ONETRACE_SECRET_KEY (then they are not stored in the database).
     9 * ONETRACE_URL, ONETRACE_WRITE_KEY, ONETRACE_SECRET_KEY and ONETRACE_IDENTITY_KEY (then they are not stored in the
     10 * database).
    1011 */
    1112final class Settings
    1213{
    1314    public const OPTION = 'onetrace_settings';
     15
     16    /** Settings that may come from wp-config.php constants. */
     17    private const CONSTANTS = ['url' => 'ONETRACE_URL', 'write_key' => 'ONETRACE_WRITE_KEY', 'secret_key' => 'ONETRACE_SECRET_KEY', 'identity_key' => 'ONETRACE_IDENTITY_KEY'];
    1418
    1519    /** @var array<string, mixed> */
    … …  
    1822        'write_key' => '',
    1923        'secret_key' => '',
     24        'identity_key' => '',
    2025        'tracker' => 'yes',
    2126        'wait_for_consent' => 'yes',
    … …  
    5055    public static function get(string $key)
    5156    {
    52         $constant = ['url' => 'ONETRACE_URL', 'write_key' => 'ONETRACE_WRITE_KEY', 'secret_key' => 'ONETRACE_SECRET_KEY'][$key] ?? null;
     57        $constant = self::CONSTANTS[$key] ?? null;
    5358
    5459        if ($constant !== null && \defined($constant) && \is_string(\constant($constant)) && \constant($constant) !== '') {
    … …  
    6873    public static function fromConstant(string $key): bool
    6974    {
    70         $constant = ['url' => 'ONETRACE_URL', 'write_key' => 'ONETRACE_WRITE_KEY', 'secret_key' => 'ONETRACE_SECRET_KEY'][$key] ?? null;
     75        $constant = self::CONSTANTS[$key] ?? null;
    7176
    7277        return $constant !== null && \defined($constant);
  • onetrace-for-woocommerce/trunk/src/Storefront.php

    r3763672 r3778798  
    7979            . "(function(d,u,s,load){load=function(){if(s)return;s=d.createElement('script');s.async=1;s.src=u;d.head.appendChild(s)};%s})(document,%s);\n"
    8080            . "cdp.init(%s, %s);\ncdp.page();\n"
    81             // The browser follows the signed-in customer: identify after login, reset after logout.
    82             . "(function(u,k){try{k=localStorage.getItem('cdp_uid')}catch(e){}if(u&&k!==u)cdp.identify(u);else if(!u&&k)cdp.reset()})(%s);",
     81            // The browser follows the signed-in customer: identify after login (and with a new signature of the id),
     82            // reset after logout.
     83            . "(function(u,h,k,g){try{k=localStorage.getItem('cdp_uid');g=localStorage.getItem('cdp_uhash')}catch(e){}if(u&&(k!==u||h&&g!==h))cdp.identify(u,{},h?{userHash:h}:{});else if(!u&&k)cdp.reset()})(%s,%s);",
    8384            wp_json_encode(self::STUB_METHODS),
    8485            $waits
    … …  
    8889            wp_json_encode((string) Settings::get('write_key')),
    8990            wp_json_encode($options, JSON_UNESCAPED_SLASHES),
    90             wp_json_encode($userId)
     91            wp_json_encode($userId),
     92            wp_json_encode(Connection::userHash($userId))
    9193        );
    9294
  • onetrace-for-woocommerce/trunk/vendor/onetrace-php/src/Client.php

    r3763672 r3778798  
    3636 *
    3737 *     $client = new OneTrace\WooCommerce\Vendor\OneTrace\Client('https://cdp.onetrace.pro', [
    38  *         'write_key' => getenv('ONETRACE_WRITE_KEY'),   // events
    39  *         'secret_key' => getenv('ONETRACE_SECRET_KEY'), // everything else
     38 *         'write_key' => getenv('ONETRACE_WRITE_KEY'),       // recommendations, widgets, search
     39 *         'secret_key' => getenv('ONETRACE_SECRET_KEY'),     // events and everything else
     40 *         'identity_key' => getenv('ONETRACE_IDENTITY_KEY'), // signs user ids for the tracker
    4041 *     ]);
    4142 *     $client->events()->track(['userId' => '42', 'event' => 'order_completed', 'properties' => ['amount' => 9980]]);
     43 *     $hash = $client->userHash('42'); // cdp.identify('42', {}, { userHash: hash }) on the page
    4244 *
    4345 * The address is the platform domain of your account (a white-label brand has its own); "/api/v1" is added
    … …  
    4648final class Client
    4749{
    48     public const VERSION = '1.16.0';
     50    public const VERSION = '1.17.0';
    4951
    5052    /**
    … …  
    174176     *     write_key?: string|null,
    175177     *     secret_key?: string|null,
     178     *     identity_key?: string|null,
    176179     *     timeout?: float,
    177180     *     connect_timeout?: float,
    … …  
    186189     *     sleep?: callable(float): void,
    187190     * } $options
    188      *   - write_key: cdp_wk_… for events, recommendations, widgets, product search and Web Push;
    189      *   - secret_key: cdp_sk_… for everything (never expose it to browsers);
     191     *   - write_key: cdp_wk_… for recommendations, widgets, product search and Web Push, events when there is no
     192     *     secret key;
     193     *   - secret_key: cdp_sk_… for everything, events included (never expose it to browsers);
     194     *   - identity_key: cdp_ik_…, the identity key of the project (Website → Connection → Server) for userHash()
     195     *     and signed user ids of events sent with the write key (never expose it to browsers);
    190196     *   - timeout / connect_timeout: seconds for the built-in cURL transport (10 and 5 by default);
    191197     *   - max_retries: retries of network errors, 429, 5xx (3 by default, 0 disables);
    … …  
    214220            throw new \InvalidArgumentException('Pass "write_key", "secret_key" or both.');
    215221        }
     222
     223        $identityKey = self::key($options['identity_key'] ?? null, 'The identity key must be a string.');
    216224
    217225        $userAgent = sprintf('onetrace-php/%s PHP/%s', self::VERSION, PHP_VERSION);
    … …  
    230238            $userAgent,
    231239            $options['sleep'] ?? null,
    232             isset($options['language']) && $options['language'] !== '' ? $options['language'] : 'en'
     240            isset($options['language']) && $options['language'] !== '' ? $options['language'] : 'en',
     241            $identityKey
    233242        );
    234243    }
    … …  
    388397        /** @var array{type: string, name: string, project: array<string, mixed>, scopes: list<string>} */
    389398        return $this->requester->request('GET', '/key', ['auth' => $key === 'write' ? Requester::AUTH_WRITE : Requester::AUTH_SECRET]);
     399    }
     400
     401    /**
     402     * The signature of a signed-in user's id for the tracker: HMAC-SHA256 of the id with the identity key, hex.
     403     * Print it into the page — cdp.identify(userId, traits, { userHash }) — so that the platform trusts the user id
     404     * of the browser (required when the project turns on "Require signature"). Null when the client has no
     405     * "identity_key".
     406     *
     407     * @param string|int $userId
     408     */
     409    public function userHash($userId): ?string
     410    {
     411        $userId = (string) $userId;
     412
     413        return $userId === '' ? null : $this->requester->userHash($userId);
    390414    }
    391415
    … …  
    470494     * @param mixed $key
    471495     */
    472     private static function key($key): ?string
     496    private static function key($key, string $error = 'API keys must be strings.'): ?string
    473497    {
    474498        if ($key === null || $key === false || $key === '') {
    … …  
    477501
    478502        if (!\is_string($key)) {
    479             throw new \InvalidArgumentException('API keys must be strings.');
    480         }
    481 
    482         return trim($key);
     503            throw new \InvalidArgumentException($error);
     504        }
     505
     506        $key = trim($key);
     507
     508        return $key === '' ? null : $key;
    483509    }
    484510}
  • onetrace-for-woocommerce/trunk/vendor/onetrace-php/src/Http/Requester.php

    r3761605 r3778798  
    2424    public const AUTH_WRITE = 'write';
    2525    public const AUTH_SECRET = 'secret';
     26    /** The secret key, or the write key when there is no secret key: events sent by a server. */
     27    public const AUTH_SERVER = 'server';
    2628
    2729    private const MAX_RETRY_AFTER = 60.0;
    … …  
    3234
    3335    private ?string $secretKey;
     36
     37    private ?string $identityKey;
    3438
    3539    private Transport $transport;
    … …  
    5862        string $userAgent,
    5963        ?callable $sleep = null,
    60         string $language = 'en'
     64        string $language = 'en',
     65        ?string $identityKey = null
    6166    ) {
    6267        $this->baseUrl = $baseUrl;
    6368        $this->writeKey = $writeKey;
    6469        $this->secretKey = $secretKey;
     70        $this->identityKey = $identityKey;
    6571        $this->transport = $transport;
    6672        $this->maxRetries = max(0, $maxRetries);
    … …  
    8086     *     idempotent?: bool,
    8187     *     idempotency_key?: string|null,
    82      * } $options auth: AUTH_WRITE accepts either key (write key preferred), AUTH_SECRET needs the secret key;
     88     * } $options auth: AUTH_WRITE accepts either key (write key preferred), AUTH_SERVER — either key (secret key
     89     *             preferred), AUTH_SECRET needs the secret key;
    8390     *             idempotent: send an Idempotency-Key header (generated unless given)
    8491     *
    … …  
    128135    {
    129136        return $this->baseUrl;
     137    }
     138
     139    /**
     140     * Whether a request with this auth goes with the write key.
     141     */
     142    public function usesWriteKey(string $auth): bool
     143    {
     144        return $this->writeKey !== null && ($auth === self::AUTH_WRITE || $this->secretKey === null);
     145    }
     146
     147    /**
     148     * The signature of a user id: HMAC-SHA256 with the identity key, hex; null without the identity key.
     149     */
     150    public function userHash(string $userId): ?string
     151    {
     152        return $this->identityKey === null ? null : hash_hmac('sha256', $userId, $this->identityKey);
    130153    }
    131154
    … …  
    192215        }
    193216
    194         throw new ConfigurationException($auth === self::AUTH_WRITE
     217        if ($auth === self::AUTH_SERVER && $this->writeKey !== null) {
     218            return $this->writeKey;
     219        }
     220
     221        throw new ConfigurationException($auth !== self::AUTH_SECRET
    195222            ? 'Pass "write_key" or "secret_key" to the client to send events.'
    196223            : 'This method needs a secret key: pass "secret_key" to the client.');
  • onetrace-for-woocommerce/trunk/vendor/onetrace-php/src/Resource/Events.php

    r3738426 r3778798  
    1212
    1313/**
    14  * Event ingestion: track, identify, page, alias and batches. Works with a write key or a secret key.
     14 * Event ingestion: track, identify, page, alias and batches. Works with a secret key or a write key; the secret key
     15 * is used when both are given (events of the write key do not award loyalty points, and their userId is dropped when
     16 * the project requires signed user ids). With only the write key, messages with a userId get its "userHash"
     17 * signature from the client's identity key.
    1518 *
    1619 * Each message gets a messageId (repeats with the same id within 24 hours are dropped by the server, so retries
    … …  
    128131        $result = ['accepted' => 0, 'duplicates' => 0];
    129132
    130         foreach (self::chunks($messages) as $chunk) {
     133        foreach (self::chunks($this->sign($messages)) as $chunk) {
    131134            $response = $this->requester->request('POST', '/batch', ['auth' => self::auth($chunk), 'json' => ['batch' => $chunk]]);
    132135            $result['accepted'] += self::count($response['accepted'] ?? 0);
    … …  
    201204    private function send(string $type, array $message): array
    202205    {
    203         return $this->requester->request('POST', '/' . $type, ['auth' => self::auth([$message]), 'json' => self::prepare($type, $message)]);
    204     }
    205 
    206     /**
    207      * Consents in identify are accepted only with the secret key; other messages prefer the write key.
     206        return $this->requester->request('POST', '/' . $type, ['auth' => self::auth([$message]), 'json' => $this->sign([self::prepare($type, $message)])[0]]);
     207    }
     208
     209    /**
     210     * Consents in identify are accepted only with the secret key; other messages prefer it too.
    208211     *
    209212     * @param array<array<string, mixed>> $messages
    … …  
    217220        }
    218221
    219         return Requester::AUTH_WRITE;
     222        return Requester::AUTH_SERVER;
     223    }
     224
     225    /**
     226     * Adds "userHash" to messages with a userId when they go with the write key and the identity key is set.
     227     *
     228     * @param list<array<string, mixed>> $messages
     229     *
     230     * @return list<array<string, mixed>>
     231     */
     232    private function sign(array $messages): array
     233    {
     234        if (!$this->requester->usesWriteKey(Requester::AUTH_SERVER)) {
     235            return $messages;
     236        }
     237
     238        foreach ($messages as $index => $message) {
     239            $userId = $message['userId'] ?? null;
     240
     241            if ((\is_string($userId) || \is_int($userId)) && (string) $userId !== '' && !isset($message['userHash'])) {
     242                $hash = $this->requester->userHash((string) $userId);
     243
     244                if ($hash === null) {
     245                    return $messages;
     246                }
     247
     248                $messages[$index]['userHash'] = $hash;
     249            }
     250        }
     251
     252        return $messages;
    220253    }
    221254
  • onetrace-for-woocommerce/trunk/vendor/onetrace-php/src/Resource/Push.php

    r3738426 r3778798  
    99/**
    1010 * Web Push subscriptions collected outside of the JS tracker (for example in a native wrapper).
    11  * Works with a write key or a secret key.
     11 * Works with a write key or a secret key; with the write key a userId gets its "userHash" signature from the
     12 * client's identity key.
    1213 */
    1314final class Push extends Resource
    … …  
    2627     * Stores a browser subscription (PushSubscription.toJSON()) and links it to the visitor.
    2728     *
    28      * @param array<string, mixed>                                                 $subscription endpoint and keys
    29      * @param array{anonymousId?: string, userId?: string, publicKey?: string} $params
     29     * @param array<string, mixed>                                                                    $subscription endpoint and keys
     30     * @param array{anonymousId?: string, userId?: string, userHash?: string, publicKey?: string} $params
    3031     *
    3132     * @return array<string, mixed> subscription_id
    … …  
    3334    public function subscribe(array $subscription, array $params = []): array
    3435    {
     36        if (isset($params['userId']) && $params['userId'] !== '' && !isset($params['userHash']) && $this->requester->usesWriteKey(Requester::AUTH_WRITE)) {
     37            $hash = $this->requester->userHash($params['userId']);
     38
     39            if ($hash !== null) {
     40                $params['userHash'] = $hash;
     41            }
     42        }
     43
    3544        return $this->requester->request('POST', '/push/subscriptions', [
    3645            'auth' => Requester::AUTH_WRITE,
Note: See TracChangeset for help on using the changeset viewer.