From aee3ee8bf74b45b2b2958e5e64395ac1bdb9e499 Mon Sep 17 00:00:00 2001 From: Ernad Husremovic Date: Mon, 9 Mar 2026 15:44:59 +0100 Subject: [PATCH] add missing payment providers and iot modules for 19.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add 19 payment provider modules needed by the sale module: payment_adyen, payment_aps, payment_asiapay, payment_authorize, payment_buckaroo, payment_demo, payment_dpo, payment_flutterwave, payment_iyzico, payment_mercado_pago, payment_mollie, payment_nuvei, payment_paymob, payment_paypal, payment_razorpay, payment_redsys, payment_stripe, payment_worldline, payment_xendit Add 3 IoT modules needed for point_of_sale: iot_base, iot_box_image, iot_drivers Note: Stripe test API keys replaced with placeholders. 🤖 assisted by claude --- .../iot_base/__init__.py | 0 .../iot_base/__manifest__.py | 23 + .../iot_base/i18n/ar.po | 28 + .../iot_base/i18n/az.po | 28 + .../iot_base/i18n/bg.po | 28 + .../iot_base/i18n/ca.po | 32 + .../iot_base/i18n/cs.po | 28 + .../iot_base/i18n/da.po | 28 + .../iot_base/i18n/de.po | 28 + .../iot_base/i18n/el.po | 28 + .../iot_base/i18n/es.po | 28 + .../iot_base/i18n/es_419.po | 32 + .../iot_base/i18n/et.po | 28 + .../iot_base/i18n/fa.po | 28 + .../iot_base/i18n/fi.po | 28 + .../iot_base/i18n/fr.po | 28 + .../iot_base/i18n/he.po | 28 + .../iot_base/i18n/hi.po | 28 + .../iot_base/i18n/hr.po | 28 + .../iot_base/i18n/hu.po | 28 + .../iot_base/i18n/id.po | 28 + .../iot_base/i18n/iot_base.pot | 28 + .../iot_base/i18n/it.po | 28 + .../iot_base/i18n/ja.po | 28 + .../iot_base/i18n/ko.po | 28 + .../iot_base/i18n/ku.po | 28 + .../iot_base/i18n/lt.po | 28 + .../iot_base/i18n/mn.po | 28 + .../iot_base/i18n/my.po | 28 + .../iot_base/i18n/nb.po | 28 + .../iot_base/i18n/nl.po | 28 + .../iot_base/i18n/pl.po | 28 + .../iot_base/i18n/pt.po | 28 + .../iot_base/i18n/pt_BR.po | 32 + .../iot_base/i18n/ro.po | 28 + .../iot_base/i18n/ru.po | 28 + .../iot_base/i18n/sl.po | 28 + .../iot_base/i18n/sr@latin.po | 28 + .../iot_base/i18n/sv.po | 28 + .../iot_base/i18n/th.po | 28 + .../iot_base/i18n/tr.po | 28 + .../iot_base/i18n/uk.po | 28 + .../iot_base/i18n/vi.po | 28 + .../iot_base/i18n/zh_CN.po | 28 + .../iot_base/i18n/zh_TW.po | 32 + .../iot_base/static/src/@types/services.d.ts | 7 + .../iot_base/static/src/device_controller.js | 40 ++ .../iot_base/static/src/network_utils/http.js | 39 + .../static/src/network_utils/longpolling.js | 229 ++++++ .../iot_box_image/.gitignore | 3 + .../iot_box_image/__init__.py | 0 .../iot_box_image/__manifest__.py | 9 + .../iot_box_image/build_image.sh | 94 +++ .../build_utils/download_requirements.sh | 51 ++ .../iot_box_image/build_utils/methods.sh | 22 + .../build_utils/partition_image.sh | 53 ++ .../iot_box_image/build_utils/sparse-checkout | 9 + .../aiortc-1.4.0-py3-none-any.whl | Bin 0 -> 84454 bytes .../configuration/led_manager.sh | 62 ++ .../iot_box_image/configuration/odoo.conf | 11 + .../iot_box_image/configuration/packages.txt | 64 ++ .../configuration/requirements.txt | 20 + .../configuration/setup_ramdisks.sh | 29 + .../etc/cups/cups-files.conf | 93 +++ .../overwrite_after_init/etc/cups/cupsd.conf | 186 +++++ .../overwrite_after_init/etc/default/hostapd | 20 + .../overwrite_after_init/etc/default/ifplugd | 17 + .../overwrite_after_init/etc/dnsmasq.conf | 669 ++++++++++++++++++ .../overwrite_after_init/etc/fstab | 4 + .../etc/hostapd/hostapd.conf | 3 + .../etc/nginx/conf.d/access_point.conf | 11 + .../etc/nginx/conf.d/iot.conf | 39 + .../overwrite_after_init/etc/rc.local | 46 ++ .../etc/ssl/certs/nginx-cert.crt | 23 + .../etc/ssl/private/nginx-cert.key | 28 + .../home/odoo/.config/labwc/autostart | 2 + .../home/odoo/.config/labwc/iot-bg.png | Bin 0 -> 29628 bytes .../home/odoo/.config/labwc/rc.xml | 12 + .../var/www/html/502.html | 95 +++ .../NetworkManager/conf.d/90-dns-none.conf | 2 + .../etc/default/keyboard | 10 + .../overwrite_before_init/etc/default/locale | 3 + .../overwrite_before_init/etc/init_image.sh | 231 ++++++ .../overwrite_before_init/etc/logrotate.conf | 17 + .../etc/logrotate.d/odoo | 6 + .../overwrite_before_init/etc/resolv.conf | 4 + .../etc/systemd/system/labwc.service | 16 + .../systemd/system/odoo-led-manager.service | 12 + .../etc/systemd/system/odoo-ngrok.service | 14 + .../etc/systemd/system/odoo.service | 30 + .../etc/systemd/system/ramdisks.service | 12 + .../etc/udev/rules.d/99-usb.rules | 2 + .../etc/udev/rules.d/99-z-input.rules | 2 + .../overwrite_before_init/home/pi/.vimrc | 31 + .../iot_drivers/__init__.py | 43 ++ .../iot_drivers/__manifest__.py | 27 + .../iot_drivers/browser.py | 128 ++++ .../iot_drivers/cli/genproxytoken.py | 28 + .../iot_drivers/connection_manager.py | 115 +++ .../iot_drivers/controllers/__init__.py | 5 + .../iot_drivers/controllers/driver.py | 96 +++ .../iot_drivers/controllers/homepage.py | 486 +++++++++++++ .../iot_drivers/controllers/proxy.py | 19 + .../iot_drivers/driver.py | 81 +++ .../iot_drivers/event_manager.py | 84 +++ .../iot_drivers/exception_logger.py | 38 + .../iot_drivers/http.py | 41 ++ .../iot_drivers/interface.py | 91 +++ .../iot_handlers/drivers/display_driver_L.py | 150 ++++ .../drivers/keyboard_usb_driver_L.py | 382 ++++++++++ .../iot_handlers/drivers/l10n_eg_drivers.py | 134 ++++ .../drivers/l10n_ke_edi_serial_driver.py | 253 +++++++ .../iot_handlers/drivers/printer_driver_L.py | 273 +++++++ .../iot_handlers/drivers/printer_driver_W.py | 161 +++++ .../drivers/printer_driver_base.py | 277 ++++++++ .../drivers/serial_base_driver.py | 161 +++++ .../drivers/serial_scale_driver.py | 218 ++++++ .../interfaces/display_interface_L.py | 39 + .../interfaces/printer_interface_L.py | 245 +++++++ .../interfaces/printer_interface_W.py | 46 ++ .../interfaces/serial_interface.py | 20 + .../interfaces/usb_interface_L.py | 48 ++ .../iot_drivers/main.py | 181 +++++ .../iot_drivers/server_logger.py | 171 +++++ .../static/img/background-light.svg | 35 + .../iot_drivers/static/img/favicon.png | Bin 0 -> 2036 bytes .../iot_drivers/static/src/app/Homepage.js | 186 +++++ .../src/app/components/FooterButtons.js | 39 + .../static/src/app/components/IconButton.js | 22 + .../src/app/components/LoadingFullScreen.js | 41 ++ .../static/src/app/components/SingleData.js | 48 ++ .../app/components/dialog/BootstrapDialog.js | 63 ++ .../app/components/dialog/CredentialDialog.js | 85 +++ .../src/app/components/dialog/DeviceDialog.js | 90 +++ .../app/components/dialog/HandlerDialog.js | 154 ++++ .../components/dialog/RemoteDebugDialog.js | 139 ++++ .../src/app/components/dialog/ServerDialog.js | 90 +++ .../src/app/components/dialog/SixDialog.js | 83 +++ .../src/app/components/dialog/TimeDialog.js | 74 ++ .../src/app/components/dialog/UpdateDialog.js | 157 ++++ .../src/app/components/dialog/WifiDialog.js | 178 +++++ .../static/src/app/css/homepage.css | 97 +++ .../iot_drivers/static/src/app/css/logs.css | 5 + .../static/src/app/css/status_display.css | 55 ++ .../static/src/app/hooks/useStore.js | 8 + .../iot_drivers/static/src/app/logs.js | 18 + .../iot_drivers/static/src/app/main.js | 17 + .../iot_drivers/static/src/app/status.js | 178 +++++ .../iot_drivers/static/src/app/store.js | 34 + .../iot_drivers/tools/__init__.py | 5 + .../iot_drivers/tools/certificate.py | 143 ++++ .../iot_drivers/tools/helpers.py | 642 +++++++++++++++++ .../iot_drivers/tools/route.py | 31 + .../iot_drivers/tools/system.py | 28 + .../iot_drivers/tools/upgrade.py | 204 ++++++ .../iot_drivers/tools/wifi.py | 327 +++++++++ .../iot_drivers/views/index.html | 45 ++ .../iot_drivers/views/logs.html | 16 + .../iot_drivers/views/status_display.html | 18 + .../iot_drivers/webrtc_client.py | 100 +++ .../iot_drivers/websocket_client.py | 170 +++++ .../payment_adyen/README.md | 87 +++ .../payment_adyen/__init__.py | 15 + .../payment_adyen/__manifest__.py | 29 + .../payment_adyen/const.py | 79 +++ .../payment_adyen/controllers/__init__.py | 3 + .../payment_adyen/controllers/main.py | 340 +++++++++ .../payment_adyen/data/neutralize.sql | 5 + .../data/payment_provider_data.xml | 10 + .../payment_adyen/i18n/af.po | 256 +++++++ .../payment_adyen/i18n/am.po | 256 +++++++ .../payment_adyen/i18n/ar.po | 250 +++++++ .../payment_adyen/i18n/az.po | 235 ++++++ .../payment_adyen/i18n/bg.po | 235 ++++++ .../payment_adyen/i18n/bs.po | 260 +++++++ .../payment_adyen/i18n/ca.po | 251 +++++++ .../payment_adyen/i18n/cs.po | 243 +++++++ .../payment_adyen/i18n/da.po | 244 +++++++ .../payment_adyen/i18n/de.po | 255 +++++++ .../payment_adyen/i18n/el.po | 242 +++++++ .../payment_adyen/i18n/es.po | 253 +++++++ .../payment_adyen/i18n/es_419.po | 275 +++++++ .../payment_adyen/i18n/es_CL.po | 257 +++++++ .../payment_adyen/i18n/et.po | 262 +++++++ .../payment_adyen/i18n/eu.po | 256 +++++++ .../payment_adyen/i18n/fa.po | 239 +++++++ .../payment_adyen/i18n/fi.po | 252 +++++++ .../payment_adyen/i18n/fo.po | 256 +++++++ .../payment_adyen/i18n/fr.po | 253 +++++++ .../payment_adyen/i18n/fr_CA.po | 257 +++++++ .../payment_adyen/i18n/gl.po | 256 +++++++ .../payment_adyen/i18n/gu.po | 256 +++++++ .../payment_adyen/i18n/he.po | 242 +++++++ .../payment_adyen/i18n/hi.po | 256 +++++++ .../payment_adyen/i18n/hr.po | 242 +++++++ .../payment_adyen/i18n/hu.po | 243 +++++++ .../payment_adyen/i18n/id.po | 249 +++++++ .../payment_adyen/i18n/is.po | 260 +++++++ .../payment_adyen/i18n/it.po | 256 +++++++ .../payment_adyen/i18n/ja.po | 248 +++++++ .../payment_adyen/i18n/ka.po | 256 +++++++ .../payment_adyen/i18n/kab.po | 256 +++++++ .../payment_adyen/i18n/km.po | 256 +++++++ .../payment_adyen/i18n/ko.po | 247 +++++++ .../payment_adyen/i18n/ku.po | 256 +++++++ .../payment_adyen/i18n/lb.po | 257 +++++++ .../payment_adyen/i18n/lo.po | 256 +++++++ .../payment_adyen/i18n/lt.po | 245 +++++++ .../payment_adyen/i18n/lv.po | 257 +++++++ .../payment_adyen/i18n/mk.po | 256 +++++++ .../payment_adyen/i18n/mn.po | 240 +++++++ .../payment_adyen/i18n/my.po | 256 +++++++ .../payment_adyen/i18n/nb.po | 242 +++++++ .../payment_adyen/i18n/ne.po | 256 +++++++ .../payment_adyen/i18n/nl.po | 253 +++++++ .../payment_adyen/i18n/payment_adyen.pot | 233 ++++++ .../payment_adyen/i18n/pl.po | 246 +++++++ .../payment_adyen/i18n/pt.po | 248 +++++++ .../payment_adyen/i18n/pt_BR.po | 256 +++++++ .../payment_adyen/i18n/ro.po | 236 ++++++ .../payment_adyen/i18n/ru.po | 288 ++++++++ .../payment_adyen/i18n/sk.po | 262 +++++++ .../payment_adyen/i18n/sl.po | 240 +++++++ .../payment_adyen/i18n/sq.po | 256 +++++++ .../payment_adyen/i18n/sr@latin.po | 236 ++++++ .../payment_adyen/i18n/sv.po | 252 +++++++ .../payment_adyen/i18n/th.po | 247 +++++++ .../payment_adyen/i18n/tr.po | 245 +++++++ .../payment_adyen/i18n/uk.po | 243 +++++++ .../payment_adyen/i18n/vi.po | 253 +++++++ .../payment_adyen/i18n/zh_CN.po | 246 +++++++ .../payment_adyen/i18n/zh_TW.po | 281 ++++++++ .../payment_adyen/models/__init__.py | 5 + .../payment_adyen/models/payment_provider.py | 184 +++++ .../payment_adyen/models/payment_token.py | 11 + .../models/payment_transaction.py | 435 ++++++++++++ .../payment_adyen/static/description/icon.png | Bin 0 -> 587 bytes .../payment_adyen/static/description/icon.svg | 1 + .../static/src/interactions/payment_form.js | 284 ++++++++ .../payment_adyen/tests/__init__.py | 4 + .../payment_adyen/tests/common.py | 52 ++ .../payment_adyen/tests/test_adyen.py | 495 +++++++++++++ .../payment_adyen/utils.py | 63 ++ .../views/payment_adyen_templates.xml | 8 + .../views/payment_form_templates.xml | 27 + .../views/payment_provider_views.xml | 30 + .../payment_adyen/wizards/__init__.py | 2 + .../wizards/payment_capture_wizard.py | 14 + .../wizards/payment_capture_wizard_views.xml | 22 + .../payment_aps/README.md | 34 + .../payment_aps/__init__.py | 14 + .../payment_aps/__manifest__.py | 21 + .../payment_aps/const.py | 19 + .../payment_aps/controllers/__init__.py | 3 + .../payment_aps/controllers/main.py | 82 +++ .../payment_aps/data/neutralize.sql | 6 + .../data/payment_provider_data.xml | 9 + .../payment_aps/i18n/ar.po | 121 ++++ .../payment_aps/i18n/az.po | 116 +++ .../payment_aps/i18n/bg.po | 116 +++ .../payment_aps/i18n/ca.po | 120 ++++ .../payment_aps/i18n/cs.po | 120 ++++ .../payment_aps/i18n/da.po | 120 ++++ .../payment_aps/i18n/de.po | 122 ++++ .../payment_aps/i18n/el.po | 120 ++++ .../payment_aps/i18n/es.po | 124 ++++ .../payment_aps/i18n/es_419.po | 123 ++++ .../payment_aps/i18n/et.po | 116 +++ .../payment_aps/i18n/fa.po | 116 +++ .../payment_aps/i18n/fi.po | 120 ++++ .../payment_aps/i18n/fr.po | 122 ++++ .../payment_aps/i18n/he.po | 116 +++ .../payment_aps/i18n/hi.po | 116 +++ .../payment_aps/i18n/hr.po | 116 +++ .../payment_aps/i18n/hu.po | 120 ++++ .../payment_aps/i18n/id.po | 120 ++++ .../payment_aps/i18n/it.po | 122 ++++ .../payment_aps/i18n/ja.po | 120 ++++ .../payment_aps/i18n/ko.po | 120 ++++ .../payment_aps/i18n/ku.po | 116 +++ .../payment_aps/i18n/lt.po | 116 +++ .../payment_aps/i18n/mn.po | 116 +++ .../payment_aps/i18n/my.po | 116 +++ .../payment_aps/i18n/nb.po | 120 ++++ .../payment_aps/i18n/nl.po | 121 ++++ .../payment_aps/i18n/payment_aps.pot | 116 +++ .../payment_aps/i18n/pl.po | 121 ++++ .../payment_aps/i18n/pt.po | 121 ++++ .../payment_aps/i18n/pt_BR.po | 121 ++++ .../payment_aps/i18n/ro.po | 116 +++ .../payment_aps/i18n/ru.po | 128 ++++ .../payment_aps/i18n/sl.po | 121 ++++ .../payment_aps/i18n/sr@latin.po | 116 +++ .../payment_aps/i18n/sv.po | 120 ++++ .../payment_aps/i18n/th.po | 120 ++++ .../payment_aps/i18n/tr.po | 116 +++ .../payment_aps/i18n/uk.po | 116 +++ .../payment_aps/i18n/vi.po | 121 ++++ .../payment_aps/i18n/zh_CN.po | 120 ++++ .../payment_aps/i18n/zh_TW.po | 128 ++++ .../payment_aps/models/__init__.py | 4 + .../payment_aps/models/payment_provider.py | 75 ++ .../payment_aps/models/payment_transaction.py | 127 ++++ .../payment_aps/static/description/icon.png | Bin 0 -> 1169 bytes .../payment_aps/static/description/icon.svg | 1 + .../payment_aps/tests/__init__.py | 5 + .../payment_aps/tests/common.py | 43 ++ .../tests/test_payment_transaction.py | 72 ++ .../tests/test_processing_flows.py | 90 +++ .../payment_aps/utils.py | 14 + .../views/payment_aps_templates.xml | 20 + .../views/payment_provider_views.xml | 31 + .../payment_asiapay/README.md | 47 ++ .../payment_asiapay/__init__.py | 14 + .../payment_asiapay/__manifest__.py | 21 + .../payment_asiapay/const.py | 154 ++++ .../payment_asiapay/controllers/__init__.py | 3 + .../payment_asiapay/controllers/main.py | 66 ++ .../payment_asiapay/data/neutralize.sql | 5 + .../data/payment_provider_data.xml | 9 + .../payment_asiapay/i18n/ar.po | 177 +++++ .../payment_asiapay/i18n/az.po | 170 +++++ .../payment_asiapay/i18n/bg.po | 170 +++++ .../payment_asiapay/i18n/ca.po | 180 +++++ .../payment_asiapay/i18n/cs.po | 174 +++++ .../payment_asiapay/i18n/da.po | 174 +++++ .../payment_asiapay/i18n/de.po | 178 +++++ .../payment_asiapay/i18n/el.po | 174 +++++ .../payment_asiapay/i18n/es.po | 178 +++++ .../payment_asiapay/i18n/es_419.po | 177 +++++ .../payment_asiapay/i18n/et.po | 176 +++++ .../payment_asiapay/i18n/fa.po | 170 +++++ .../payment_asiapay/i18n/fi.po | 177 +++++ .../payment_asiapay/i18n/fr.po | 179 +++++ .../payment_asiapay/i18n/he.po | 170 +++++ .../payment_asiapay/i18n/hi.po | 170 +++++ .../payment_asiapay/i18n/hr.po | 170 +++++ .../payment_asiapay/i18n/hu.po | 174 +++++ .../payment_asiapay/i18n/id.po | 176 +++++ .../payment_asiapay/i18n/it.po | 179 +++++ .../payment_asiapay/i18n/ja.po | 176 +++++ .../payment_asiapay/i18n/ko.po | 176 +++++ .../payment_asiapay/i18n/ku.po | 170 +++++ .../payment_asiapay/i18n/lt.po | 170 +++++ .../payment_asiapay/i18n/mn.po | 170 +++++ .../payment_asiapay/i18n/my.po | 170 +++++ .../payment_asiapay/i18n/nb.po | 174 +++++ .../payment_asiapay/i18n/nl.po | 179 +++++ .../payment_asiapay/i18n/payment_asiapay.pot | 176 +++++ .../payment_asiapay/i18n/pl.po | 175 +++++ .../payment_asiapay/i18n/pt.po | 179 +++++ .../payment_asiapay/i18n/pt_BR.po | 179 +++++ .../payment_asiapay/i18n/ro.po | 170 +++++ .../payment_asiapay/i18n/ru.po | 199 ++++++ .../payment_asiapay/i18n/sl.po | 175 +++++ .../payment_asiapay/i18n/sr@latin.po | 170 +++++ .../payment_asiapay/i18n/sv.po | 176 +++++ .../payment_asiapay/i18n/th.po | 176 +++++ .../payment_asiapay/i18n/tr.po | 174 +++++ .../payment_asiapay/i18n/uk.po | 170 +++++ .../payment_asiapay/i18n/vi.po | 176 +++++ .../payment_asiapay/i18n/zh_CN.po | 175 +++++ .../payment_asiapay/i18n/zh_TW.po | 190 +++++ .../payment_asiapay/models/__init__.py | 4 + .../models/payment_provider.py | 104 +++ .../models/payment_transaction.py | 155 ++++ .../static/description/icon.png | Bin 0 -> 1302 bytes .../static/description/icon.svg | 1 + .../payment_asiapay/tests/__init__.py | 6 + .../payment_asiapay/tests/common.py | 35 + .../tests/test_payment_provider.py | 39 + .../tests/test_payment_transaction.py | 116 +++ .../tests/test_processing_flows.py | 64 ++ .../views/payment_asiapay_templates.xml | 21 + .../views/payment_provider_views.xml | 37 + .../payment_authorize/README.md | 68 ++ .../payment_authorize/__init__.py | 14 + .../payment_authorize/__manifest__.py | 28 + .../payment_authorize/const.py | 29 + .../payment_authorize/controllers/__init__.py | 3 + .../payment_authorize/controllers/main.py | 41 ++ .../payment_authorize/data/neutralize.sql | 6 + .../data/payment_provider_data.xml | 10 + .../payment_authorize/i18n/af.po | 242 +++++++ .../payment_authorize/i18n/am.po | 242 +++++++ .../payment_authorize/i18n/ar.po | 272 +++++++ .../payment_authorize/i18n/az.po | 245 +++++++ .../payment_authorize/i18n/bg.po | 245 +++++++ .../payment_authorize/i18n/bs.po | 246 +++++++ .../payment_authorize/i18n/ca.po | 273 +++++++ .../payment_authorize/i18n/cs.po | 253 +++++++ .../payment_authorize/i18n/da.po | 252 +++++++ .../payment_authorize/i18n/de.po | 278 ++++++++ .../payment_authorize/i18n/el.po | 252 +++++++ .../payment_authorize/i18n/es.po | 273 +++++++ .../payment_authorize/i18n/es_419.po | 266 +++++++ .../payment_authorize/i18n/es_CL.po | 243 +++++++ .../payment_authorize/i18n/et.po | 248 +++++++ .../payment_authorize/i18n/eu.po | 242 +++++++ .../payment_authorize/i18n/fa.po | 249 +++++++ .../payment_authorize/i18n/fi.po | 277 ++++++++ .../payment_authorize/i18n/fo.po | 242 +++++++ .../payment_authorize/i18n/fr.po | 274 +++++++ .../payment_authorize/i18n/fr_CA.po | 243 +++++++ .../payment_authorize/i18n/gl.po | 242 +++++++ .../payment_authorize/i18n/gu.po | 242 +++++++ .../payment_authorize/i18n/he.po | 253 +++++++ .../payment_authorize/i18n/hi.po | 239 +++++++ .../payment_authorize/i18n/hr.po | 253 +++++++ .../payment_authorize/i18n/hu.po | 253 +++++++ .../payment_authorize/i18n/id.po | 271 +++++++ .../payment_authorize/i18n/is.po | 246 +++++++ .../payment_authorize/i18n/it.po | 275 +++++++ .../payment_authorize/i18n/ja.po | 268 +++++++ .../payment_authorize/i18n/ka.po | 242 +++++++ .../payment_authorize/i18n/kab.po | 242 +++++++ .../payment_authorize/i18n/km.po | 245 +++++++ .../payment_authorize/i18n/ko.po | 267 +++++++ .../payment_authorize/i18n/ku.po | 239 +++++++ .../payment_authorize/i18n/lb.po | 243 +++++++ .../payment_authorize/i18n/lo.po | 242 +++++++ .../payment_authorize/i18n/lt.po | 257 +++++++ .../payment_authorize/i18n/lv.po | 243 +++++++ .../payment_authorize/i18n/mk.po | 242 +++++++ .../payment_authorize/i18n/mn.po | 250 +++++++ .../payment_authorize/i18n/my.po | 239 +++++++ .../payment_authorize/i18n/nb.po | 252 +++++++ .../payment_authorize/i18n/ne.po | 242 +++++++ .../payment_authorize/i18n/nl.po | 277 ++++++++ .../i18n/payment_authorize.pot | 241 +++++++ .../payment_authorize/i18n/pl.po | 257 +++++++ .../payment_authorize/i18n/pt.po | 266 +++++++ .../payment_authorize/i18n/pt_BR.po | 275 +++++++ .../payment_authorize/i18n/ro.po | 246 +++++++ .../payment_authorize/i18n/ru.po | 300 ++++++++ .../payment_authorize/i18n/sk.po | 248 +++++++ .../payment_authorize/i18n/sl.po | 250 +++++++ .../payment_authorize/i18n/sq.po | 242 +++++++ .../payment_authorize/i18n/sr@latin.po | 246 +++++++ .../payment_authorize/i18n/sv.po | 273 +++++++ .../payment_authorize/i18n/th.po | 270 +++++++ .../payment_authorize/i18n/tr.po | 276 ++++++++ .../payment_authorize/i18n/uk.po | 253 +++++++ .../payment_authorize/i18n/vi.po | 272 +++++++ .../payment_authorize/i18n/zh_CN.po | 267 +++++++ .../payment_authorize/i18n/zh_TW.po | 275 +++++++ .../payment_authorize/models/__init__.py | 5 + .../models/authorize_request.py | 358 ++++++++++ .../models/payment_provider.py | 135 ++++ .../payment_authorize/models/payment_token.py | 16 + .../models/payment_transaction.py | 251 +++++++ .../static/description/icon.png | Bin 0 -> 851 bytes .../static/description/icon.svg | 1 + .../static/src/interactions/payment_form.js | 225 ++++++ .../static/src/scss/payment_authorize.scss | 16 + .../payment_authorize/tests/__init__.py | 5 + .../payment_authorize/tests/common.py | 22 + .../payment_authorize/tests/test_authorize.py | 81 +++ .../tests/test_refund_flows.py | 77 ++ .../views/payment_authorize_templates.xml | 57 ++ .../views/payment_provider_views.xml | 35 + .../views/payment_token_views.xml | 16 + .../payment_buckaroo/README.md | 27 + .../payment_buckaroo/__init__.py | 14 + .../payment_buckaroo/__manifest__.py | 21 + .../payment_buckaroo/const.py | 68 ++ .../payment_buckaroo/controllers/__init__.py | 3 + .../payment_buckaroo/controllers/main.py | 105 +++ .../payment_buckaroo/data/neutralize.sql | 4 + .../data/payment_provider_data.xml | 9 + .../payment_buckaroo/i18n/af.po | 92 +++ .../payment_buckaroo/i18n/am.po | 92 +++ .../payment_buckaroo/i18n/ar.po | 114 +++ .../payment_buckaroo/i18n/az.po | 99 +++ .../payment_buckaroo/i18n/bg.po | 99 +++ .../payment_buckaroo/i18n/bs.po | 95 +++ .../payment_buckaroo/i18n/ca.po | 116 +++ .../payment_buckaroo/i18n/cs.po | 113 +++ .../payment_buckaroo/i18n/da.po | 113 +++ .../payment_buckaroo/i18n/de.po | 116 +++ .../payment_buckaroo/i18n/el.po | 112 +++ .../payment_buckaroo/i18n/es.po | 115 +++ .../payment_buckaroo/i18n/es_419.po | 97 +++ .../payment_buckaroo/i18n/es_CL.po | 92 +++ .../payment_buckaroo/i18n/et.po | 98 +++ .../payment_buckaroo/i18n/eu.po | 92 +++ .../payment_buckaroo/i18n/fa.po | 109 +++ .../payment_buckaroo/i18n/fi.po | 113 +++ .../payment_buckaroo/i18n/fo.po | 92 +++ .../payment_buckaroo/i18n/fr.po | 114 +++ .../payment_buckaroo/i18n/fr_CA.po | 92 +++ .../payment_buckaroo/i18n/gl.po | 92 +++ .../payment_buckaroo/i18n/gu.po | 92 +++ .../payment_buckaroo/i18n/he.po | 112 +++ .../payment_buckaroo/i18n/hi.po | 93 +++ .../payment_buckaroo/i18n/hr.po | 113 +++ .../payment_buckaroo/i18n/hu.po | 113 +++ .../payment_buckaroo/i18n/id.po | 110 +++ .../payment_buckaroo/i18n/is.po | 96 +++ .../payment_buckaroo/i18n/it.po | 116 +++ .../payment_buckaroo/i18n/ja.po | 113 +++ .../payment_buckaroo/i18n/ka.po | 92 +++ .../payment_buckaroo/i18n/kab.po | 92 +++ .../payment_buckaroo/i18n/km.po | 92 +++ .../payment_buckaroo/i18n/ko.po | 112 +++ .../payment_buckaroo/i18n/ku.po | 93 +++ .../payment_buckaroo/i18n/lb.po | 92 +++ .../payment_buckaroo/i18n/lo.po | 92 +++ .../payment_buckaroo/i18n/lt.po | 115 +++ .../payment_buckaroo/i18n/lv.po | 92 +++ .../payment_buckaroo/i18n/mk.po | 92 +++ .../payment_buckaroo/i18n/mn.po | 110 +++ .../payment_buckaroo/i18n/my.po | 93 +++ .../payment_buckaroo/i18n/nb.po | 112 +++ .../payment_buckaroo/i18n/ne.po | 92 +++ .../payment_buckaroo/i18n/nl.po | 116 +++ .../i18n/payment_buckaroo.pot | 99 +++ .../payment_buckaroo/i18n/pl.po | 116 +++ .../payment_buckaroo/i18n/pt.po | 105 +++ .../payment_buckaroo/i18n/pt_BR.po | 117 +++ .../payment_buckaroo/i18n/ro.po | 100 +++ .../payment_buckaroo/i18n/ru.po | 115 +++ .../payment_buckaroo/i18n/sk.po | 97 +++ .../payment_buckaroo/i18n/sl.po | 104 +++ .../payment_buckaroo/i18n/sq.po | 92 +++ .../payment_buckaroo/i18n/sr@latin.po | 106 +++ .../payment_buckaroo/i18n/sv.po | 116 +++ .../payment_buckaroo/i18n/th.po | 112 +++ .../payment_buckaroo/i18n/tr.po | 114 +++ .../payment_buckaroo/i18n/uk.po | 113 +++ .../payment_buckaroo/i18n/vi.po | 115 +++ .../payment_buckaroo/i18n/zh_CN.po | 113 +++ .../payment_buckaroo/i18n/zh_TW.po | 112 +++ .../payment_buckaroo/models/__init__.py | 4 + .../models/payment_provider.py | 96 +++ .../models/payment_transaction.py | 109 +++ .../static/description/icon.png | Bin 0 -> 779 bytes .../static/description/icon.svg | 1 + .../payment_buckaroo/tests/__init__.py | 4 + .../payment_buckaroo/tests/common.py | 45 ++ .../payment_buckaroo/tests/test_buckaroo.py | 131 ++++ .../views/payment_buckaroo_templates.xml | 20 + .../views/payment_provider_views.xml | 18 + .../payment_demo/README.md | 35 + .../payment_demo/__init__.py | 14 + .../payment_demo/__manifest__.py | 29 + .../payment_demo/const.py | 6 + .../payment_demo/controllers/__init__.py | 3 + .../payment_demo/controllers/main.py | 17 + .../payment_demo/data/payment_method_data.xml | 15 + .../data/payment_provider_data.xml | 20 + .../payment_demo/i18n/ar.po | 298 ++++++++ .../payment_demo/i18n/az.po | 275 +++++++ .../payment_demo/i18n/bg.po | 275 +++++++ .../payment_demo/i18n/ca.po | 297 ++++++++ .../payment_demo/i18n/cs.po | 282 ++++++++ .../payment_demo/i18n/da.po | 279 ++++++++ .../payment_demo/i18n/de.po | 308 ++++++++ .../payment_demo/i18n/el.po | 279 ++++++++ .../payment_demo/i18n/es.po | 302 ++++++++ .../payment_demo/i18n/es_419.po | 302 ++++++++ .../payment_demo/i18n/et.po | 282 ++++++++ .../payment_demo/i18n/fa.po | 275 +++++++ .../payment_demo/i18n/fi.po | 299 ++++++++ .../payment_demo/i18n/fr.po | 305 ++++++++ .../payment_demo/i18n/he.po | 275 +++++++ .../payment_demo/i18n/hi.po | 275 +++++++ .../payment_demo/i18n/hr.po | 275 +++++++ .../payment_demo/i18n/hu.po | 279 ++++++++ .../payment_demo/i18n/id.po | 303 ++++++++ .../payment_demo/i18n/it.po | 304 ++++++++ .../payment_demo/i18n/ja.po | 297 ++++++++ .../payment_demo/i18n/ko.po | 299 ++++++++ .../payment_demo/i18n/ku.po | 275 +++++++ .../payment_demo/i18n/lt.po | 275 +++++++ .../payment_demo/i18n/mn.po | 275 +++++++ .../payment_demo/i18n/my.po | 275 +++++++ .../payment_demo/i18n/nb.po | 279 ++++++++ .../payment_demo/i18n/nl.po | 302 ++++++++ .../payment_demo/i18n/payment_demo.pot | 282 ++++++++ .../payment_demo/i18n/pl.po | 283 ++++++++ .../payment_demo/i18n/pt.po | 302 ++++++++ .../payment_demo/i18n/pt_BR.po | 302 ++++++++ .../payment_demo/i18n/ro.po | 275 +++++++ .../payment_demo/i18n/ru.po | 323 +++++++++ .../payment_demo/i18n/sl.po | 280 ++++++++ .../payment_demo/i18n/sr@latin.po | 275 +++++++ .../payment_demo/i18n/sv.po | 307 ++++++++ .../payment_demo/i18n/th.po | 297 ++++++++ .../payment_demo/i18n/tr.po | 275 +++++++ .../payment_demo/i18n/uk.po | 275 +++++++ .../payment_demo/i18n/vi.po | 306 ++++++++ .../payment_demo/i18n/zh_CN.po | 296 ++++++++ .../payment_demo/i18n/zh_TW.po | 313 ++++++++ .../payment_demo/models/__init__.py | 5 + .../payment_demo/models/payment_provider.py | 40 ++ .../payment_demo/models/payment_token.py | 33 + .../models/payment_transaction.py | 154 ++++ .../payment_demo/static/description/icon.png | Bin 0 -> 600 bytes .../payment_demo/static/description/icon.svg | 1 + .../payment_demo/static/img/demo.png | Bin 0 -> 2169 bytes .../src/interactions/express_checkout.js | 84 +++ .../src/interactions/payment_demo_mixin.js | 34 + .../static/src/interactions/payment_form.js | 53 ++ .../payment_demo/tests/__init__.py | 5 + .../payment_demo/tests/common.py | 18 + .../tests/test_payment_transaction.py | 81 +++ .../tests/test_processing_flows.py | 23 + .../views/payment_demo_templates.xml | 223 ++++++ .../views/payment_provider_views.xml | 15 + .../views/payment_token_views.xml | 18 + .../views/payment_transaction_views.xml | 33 + .../payment_dpo/README.md | 23 + .../payment_dpo/__init__.py | 14 + .../payment_dpo/__manifest__.py | 20 + .../payment_dpo/const.py | 17 + .../payment_dpo/controllers/__init__.py | 3 + .../payment_dpo/controllers/main.py | 56 ++ .../payment_dpo/data/neutralize.sql | 4 + .../data/payment_provider_data.xml | 9 + .../payment_dpo/i18n/ar.po | 87 +++ .../payment_dpo/i18n/az.po | 87 +++ .../payment_dpo/i18n/bg.po | 87 +++ .../payment_dpo/i18n/ca.po | 93 +++ .../payment_dpo/i18n/cs.po | 87 +++ .../payment_dpo/i18n/da.po | 87 +++ .../payment_dpo/i18n/de.po | 93 +++ .../payment_dpo/i18n/el.po | 87 +++ .../payment_dpo/i18n/es.po | 87 +++ .../payment_dpo/i18n/es_419.po | 94 +++ .../payment_dpo/i18n/et.po | 87 +++ .../payment_dpo/i18n/fa.po | 87 +++ .../payment_dpo/i18n/fi.po | 87 +++ .../payment_dpo/i18n/fr.po | 87 +++ .../payment_dpo/i18n/he.po | 87 +++ .../payment_dpo/i18n/hi.po | 87 +++ .../payment_dpo/i18n/hr.po | 87 +++ .../payment_dpo/i18n/hu.po | 87 +++ .../payment_dpo/i18n/id.po | 87 +++ .../payment_dpo/i18n/it.po | 87 +++ .../payment_dpo/i18n/ja.po | 87 +++ .../payment_dpo/i18n/ko.po | 91 +++ .../payment_dpo/i18n/ku.po | 87 +++ .../payment_dpo/i18n/lt.po | 87 +++ .../payment_dpo/i18n/mn.po | 87 +++ .../payment_dpo/i18n/my.po | 87 +++ .../payment_dpo/i18n/nb.po | 87 +++ .../payment_dpo/i18n/nl.po | 87 +++ .../payment_dpo/i18n/payment_dpo.pot | 87 +++ .../payment_dpo/i18n/pl.po | 87 +++ .../payment_dpo/i18n/pt.po | 87 +++ .../payment_dpo/i18n/pt_BR.po | 93 +++ .../payment_dpo/i18n/ro.po | 87 +++ .../payment_dpo/i18n/ru.po | 87 +++ .../payment_dpo/i18n/sl.po | 87 +++ .../payment_dpo/i18n/sr@latin.po | 87 +++ .../payment_dpo/i18n/sv.po | 87 +++ .../payment_dpo/i18n/th.po | 87 +++ .../payment_dpo/i18n/tr.po | 87 +++ .../payment_dpo/i18n/uk.po | 87 +++ .../payment_dpo/i18n/vi.po | 87 +++ .../payment_dpo/i18n/zh_CN.po | 91 +++ .../payment_dpo/i18n/zh_TW.po | 104 +++ .../payment_dpo/models/__init__.py | 4 + .../payment_dpo/models/payment_provider.py | 56 ++ .../payment_dpo/models/payment_transaction.py | 132 ++++ .../payment_dpo/static/description/icon.png | Bin 0 -> 81989 bytes .../payment_dpo/static/description/icon.svg | 1 + .../payment_dpo/tests/__init__.py | 5 + .../payment_dpo/tests/common.py | 25 + .../tests/test_payment_transaction.py | 39 + .../tests/test_processing_flows.py | 26 + .../views/payment_dpo_templates.xml | 8 + .../views/payment_provider_views.xml | 27 + .../payment_flutterwave/README.md | 39 + .../payment_flutterwave/__init__.py | 14 + .../payment_flutterwave/__manifest__.py | 26 + .../payment_flutterwave/const.py | 54 ++ .../controllers/__init__.py | 3 + .../payment_flutterwave/controllers/main.py | 110 +++ .../payment_flutterwave/data/neutralize.sql | 5 + .../data/payment_provider_data.xml | 10 + .../payment_flutterwave/i18n/ar.po | 144 ++++ .../payment_flutterwave/i18n/az.po | 137 ++++ .../payment_flutterwave/i18n/bg.po | 137 ++++ .../payment_flutterwave/i18n/ca.po | 143 ++++ .../payment_flutterwave/i18n/cs.po | 141 ++++ .../payment_flutterwave/i18n/da.po | 142 ++++ .../payment_flutterwave/i18n/de.po | 147 ++++ .../payment_flutterwave/i18n/el.po | 141 ++++ .../payment_flutterwave/i18n/es.po | 144 ++++ .../payment_flutterwave/i18n/es_419.po | 143 ++++ .../payment_flutterwave/i18n/et.po | 119 ++++ .../payment_flutterwave/i18n/fa.po | 137 ++++ .../payment_flutterwave/i18n/fi.po | 142 ++++ .../payment_flutterwave/i18n/fr.po | 145 ++++ .../payment_flutterwave/i18n/he.po | 137 ++++ .../payment_flutterwave/i18n/hi.po | 137 ++++ .../payment_flutterwave/i18n/hr.po | 137 ++++ .../payment_flutterwave/i18n/hu.po | 141 ++++ .../payment_flutterwave/i18n/id.po | 145 ++++ .../payment_flutterwave/i18n/it.po | 147 ++++ .../payment_flutterwave/i18n/ja.po | 141 ++++ .../payment_flutterwave/i18n/ko.po | 141 ++++ .../payment_flutterwave/i18n/ku.po | 137 ++++ .../payment_flutterwave/i18n/lt.po | 137 ++++ .../payment_flutterwave/i18n/mn.po | 137 ++++ .../payment_flutterwave/i18n/my.po | 137 ++++ .../payment_flutterwave/i18n/nb.po | 141 ++++ .../payment_flutterwave/i18n/nl.po | 147 ++++ .../i18n/payment_flutterwave.pot | 119 ++++ .../payment_flutterwave/i18n/pl.po | 142 ++++ .../payment_flutterwave/i18n/pt.po | 146 ++++ .../payment_flutterwave/i18n/pt_BR.po | 146 ++++ .../payment_flutterwave/i18n/ro.po | 137 ++++ .../payment_flutterwave/i18n/ru.po | 149 ++++ .../payment_flutterwave/i18n/sl.po | 142 ++++ .../payment_flutterwave/i18n/sr@latin.po | 137 ++++ .../payment_flutterwave/i18n/sv.po | 145 ++++ .../payment_flutterwave/i18n/th.po | 142 ++++ .../payment_flutterwave/i18n/tr.po | 141 ++++ .../payment_flutterwave/i18n/uk.po | 137 ++++ .../payment_flutterwave/i18n/vi.po | 145 ++++ .../payment_flutterwave/i18n/zh_CN.po | 141 ++++ .../payment_flutterwave/i18n/zh_TW.po | 143 ++++ .../payment_flutterwave/models/__init__.py | 5 + .../models/payment_provider.py | 112 +++ .../models/payment_token.py | 11 + .../models/payment_transaction.py | 189 +++++ .../static/description/icon.png | Bin 0 -> 2056 bytes .../static/description/icon.svg | 1 + .../static/src/interactions/payment_form.js | 25 + .../payment_flutterwave/tests/__init__.py | 6 + .../payment_flutterwave/tests/common.py | 43 ++ .../tests/test_payment_provider.py | 31 + .../tests/test_payment_transaction.py | 52 ++ .../tests/test_processing_flows.py | 82 +++ .../views/payment_flutterwave_templates.xml | 9 + .../views/payment_provider_views.xml | 28 + .../payment_iyzico/README.md | 29 + .../payment_iyzico/__init__.py | 14 + .../payment_iyzico/__manifest__.py | 20 + .../payment_iyzico/const.py | 42 ++ .../payment_iyzico/controllers/__init__.py | 3 + .../payment_iyzico/controllers/main.py | 69 ++ .../payment_iyzico/data/neutralize.sql | 4 + .../data/payment_provider_data.xml | 9 + .../payment_iyzico/i18n/ar.po | 95 +++ .../payment_iyzico/i18n/az.po | 95 +++ .../payment_iyzico/i18n/bg.po | 95 +++ .../payment_iyzico/i18n/ca.po | 101 +++ .../payment_iyzico/i18n/cs.po | 95 +++ .../payment_iyzico/i18n/da.po | 95 +++ .../payment_iyzico/i18n/de.po | 95 +++ .../payment_iyzico/i18n/el.po | 95 +++ .../payment_iyzico/i18n/es.po | 95 +++ .../payment_iyzico/i18n/es_419.po | 104 +++ .../payment_iyzico/i18n/et.po | 95 +++ .../payment_iyzico/i18n/fa.po | 95 +++ .../payment_iyzico/i18n/fi.po | 95 +++ .../payment_iyzico/i18n/fr.po | 95 +++ .../payment_iyzico/i18n/he.po | 95 +++ .../payment_iyzico/i18n/hi.po | 95 +++ .../payment_iyzico/i18n/hr.po | 95 +++ .../payment_iyzico/i18n/hu.po | 95 +++ .../payment_iyzico/i18n/id.po | 95 +++ .../payment_iyzico/i18n/it.po | 95 +++ .../payment_iyzico/i18n/ja.po | 95 +++ .../payment_iyzico/i18n/ko.po | 99 +++ .../payment_iyzico/i18n/ku.po | 95 +++ .../payment_iyzico/i18n/lt.po | 95 +++ .../payment_iyzico/i18n/mn.po | 95 +++ .../payment_iyzico/i18n/my.po | 95 +++ .../payment_iyzico/i18n/nb.po | 95 +++ .../payment_iyzico/i18n/nl.po | 95 +++ .../payment_iyzico/i18n/payment_iyzico.pot | 95 +++ .../payment_iyzico/i18n/pl.po | 95 +++ .../payment_iyzico/i18n/pt.po | 95 +++ .../payment_iyzico/i18n/pt_BR.po | 103 +++ .../payment_iyzico/i18n/ro.po | 95 +++ .../payment_iyzico/i18n/ru.po | 95 +++ .../payment_iyzico/i18n/sl.po | 95 +++ .../payment_iyzico/i18n/sr@latin.po | 95 +++ .../payment_iyzico/i18n/sv.po | 95 +++ .../payment_iyzico/i18n/th.po | 95 +++ .../payment_iyzico/i18n/tr.po | 95 +++ .../payment_iyzico/i18n/uk.po | 95 +++ .../payment_iyzico/i18n/vi.po | 95 +++ .../payment_iyzico/i18n/zh_CN.po | 95 +++ .../payment_iyzico/i18n/zh_TW.po | 95 +++ .../payment_iyzico/models/__init__.py | 4 + .../payment_iyzico/models/payment_provider.py | 120 ++++ .../models/payment_transaction.py | 148 ++++ .../static/description/icon.png | Bin 0 -> 1907 bytes .../static/description/icon.svg | 19 + .../payment_iyzico/tests/__init__.py | 6 + .../payment_iyzico/tests/common.py | 27 + .../tests/test_payment_provider.py | 17 + .../tests/test_payment_transaction.py | 119 ++++ .../tests/test_processing_flows.py | 33 + .../views/payment_iyzico_templates.xml | 12 + .../views/payment_provider_views.xml | 27 + .../payment_mercado_pago/README.md | 54 ++ .../payment_mercado_pago/__init__.py | 14 + .../payment_mercado_pago/__manifest__.py | 27 + .../payment_mercado_pago/const.py | 153 ++++ .../controllers/__init__.py | 4 + .../controllers/onboarding.py | 86 +++ .../controllers/payment.py | 116 +++ .../payment_mercado_pago/data/neutralize.sql | 3 + .../data/payment_provider_data.xml | 10 + .../payment_mercado_pago/i18n/ar.po | 374 ++++++++++ .../payment_mercado_pago/i18n/az.po | 332 +++++++++ .../payment_mercado_pago/i18n/bg.po | 332 +++++++++ .../payment_mercado_pago/i18n/ca.po | 344 +++++++++ .../payment_mercado_pago/i18n/cs.po | 341 +++++++++ .../payment_mercado_pago/i18n/da.po | 338 +++++++++ .../payment_mercado_pago/i18n/de.po | 383 ++++++++++ .../payment_mercado_pago/i18n/el.po | 335 +++++++++ .../payment_mercado_pago/i18n/es.po | 377 ++++++++++ .../payment_mercado_pago/i18n/es_419.po | 375 ++++++++++ .../payment_mercado_pago/i18n/et.po | 332 +++++++++ .../payment_mercado_pago/i18n/fa.po | 332 +++++++++ .../payment_mercado_pago/i18n/fi.po | 373 ++++++++++ .../payment_mercado_pago/i18n/fr.po | 381 ++++++++++ .../payment_mercado_pago/i18n/he.po | 332 +++++++++ .../payment_mercado_pago/i18n/hi.po | 332 +++++++++ .../payment_mercado_pago/i18n/hr.po | 332 +++++++++ .../payment_mercado_pago/i18n/hu.po | 335 +++++++++ .../payment_mercado_pago/i18n/id.po | 377 ++++++++++ .../payment_mercado_pago/i18n/it.po | 380 ++++++++++ .../payment_mercado_pago/i18n/ja.po | 374 ++++++++++ .../payment_mercado_pago/i18n/ko.po | 373 ++++++++++ .../payment_mercado_pago/i18n/ku.po | 332 +++++++++ .../payment_mercado_pago/i18n/lt.po | 332 +++++++++ .../payment_mercado_pago/i18n/mn.po | 332 +++++++++ .../payment_mercado_pago/i18n/my.po | 332 +++++++++ .../payment_mercado_pago/i18n/nb.po | 335 +++++++++ .../payment_mercado_pago/i18n/nl.po | 376 ++++++++++ .../i18n/payment_mercado_pago.pot | 330 +++++++++ .../payment_mercado_pago/i18n/pl.po | 342 +++++++++ .../payment_mercado_pago/i18n/pt.po | 377 ++++++++++ .../payment_mercado_pago/i18n/pt_BR.po | 378 ++++++++++ .../payment_mercado_pago/i18n/ro.po | 332 +++++++++ .../payment_mercado_pago/i18n/ru.po | 378 ++++++++++ .../payment_mercado_pago/i18n/sl.po | 336 +++++++++ .../payment_mercado_pago/i18n/sr@latin.po | 332 +++++++++ .../payment_mercado_pago/i18n/sv.po | 379 ++++++++++ .../payment_mercado_pago/i18n/th.po | 368 ++++++++++ .../payment_mercado_pago/i18n/tr.po | 353 +++++++++ .../payment_mercado_pago/i18n/uk.po | 332 +++++++++ .../payment_mercado_pago/i18n/vi.po | 380 ++++++++++ .../payment_mercado_pago/i18n/zh_CN.po | 364 ++++++++++ .../payment_mercado_pago/i18n/zh_TW.po | 367 ++++++++++ .../payment_mercado_pago/models/__init__.py | 5 + .../models/payment_provider.py | 323 +++++++++ .../models/payment_token.py | 10 + .../models/payment_transaction.py | 308 ++++++++ .../static/description/icon.png | Bin 0 -> 2126 bytes .../static/description/icon.svg | 1 + .../static/src/interactions/payment_form.js | 166 +++++ .../payment_mercado_pago/tests/__init__.py | 6 + .../payment_mercado_pago/tests/common.py | 34 + .../tests/test_payment_provider.py | 31 + .../tests/test_payment_transaction.py | 89 +++ .../tests/test_processing_flows.py | 44 ++ .../views/payment_form_templates.xml | 12 + .../views/payment_mercado_pago_templates.xml | 38 + .../views/payment_provider_views.xml | 69 ++ .../payment_mollie/README.md | 36 + .../payment_mollie/__init__.py | 14 + .../payment_mollie/__manifest__.py | 22 + .../payment_mollie/const.py | 70 ++ .../payment_mollie/controllers/__init__.py | 3 + .../payment_mollie/controllers/main.py | 72 ++ .../payment_mollie/data/neutralize.sql | 3 + .../data/payment_provider_data.xml | 9 + .../payment_mollie/i18n/ar.po | 97 +++ .../payment_mollie/i18n/az.po | 89 +++ .../payment_mollie/i18n/bg.po | 89 +++ .../payment_mollie/i18n/ca.po | 93 +++ .../payment_mollie/i18n/cs.po | 93 +++ .../payment_mollie/i18n/da.po | 93 +++ .../payment_mollie/i18n/de.po | 95 +++ .../payment_mollie/i18n/el.po | 93 +++ .../payment_mollie/i18n/es.po | 95 +++ .../payment_mollie/i18n/es_419.po | 95 +++ .../payment_mollie/i18n/et.po | 81 +++ .../payment_mollie/i18n/fa.po | 89 +++ .../payment_mollie/i18n/fi.po | 93 +++ .../payment_mollie/i18n/fr.po | 95 +++ .../payment_mollie/i18n/he.po | 89 +++ .../payment_mollie/i18n/hi.po | 89 +++ .../payment_mollie/i18n/hr.po | 89 +++ .../payment_mollie/i18n/hu.po | 93 +++ .../payment_mollie/i18n/id.po | 94 +++ .../payment_mollie/i18n/it.po | 96 +++ .../payment_mollie/i18n/ja.po | 93 +++ .../payment_mollie/i18n/ko.po | 93 +++ .../payment_mollie/i18n/ku.po | 89 +++ .../payment_mollie/i18n/lt.po | 89 +++ .../payment_mollie/i18n/mn.po | 89 +++ .../payment_mollie/i18n/my.po | 89 +++ .../payment_mollie/i18n/nb.po | 93 +++ .../payment_mollie/i18n/nl.po | 95 +++ .../payment_mollie/i18n/payment_mollie.pot | 81 +++ .../payment_mollie/i18n/pl.po | 94 +++ .../payment_mollie/i18n/pt.po | 96 +++ .../payment_mollie/i18n/pt_BR.po | 96 +++ .../payment_mollie/i18n/ro.po | 89 +++ .../payment_mollie/i18n/ru.po | 102 +++ .../payment_mollie/i18n/sl.po | 94 +++ .../payment_mollie/i18n/sr@latin.po | 89 +++ .../payment_mollie/i18n/sv.po | 95 +++ .../payment_mollie/i18n/th.po | 93 +++ .../payment_mollie/i18n/tr.po | 93 +++ .../payment_mollie/i18n/uk.po | 89 +++ .../payment_mollie/i18n/vi.po | 97 +++ .../payment_mollie/i18n/zh_CN.po | 93 +++ .../payment_mollie/i18n/zh_TW.po | 101 +++ .../payment_mollie/models/__init__.py | 4 + .../payment_mollie/models/payment_provider.py | 76 ++ .../models/payment_transaction.py | 131 ++++ .../static/description/icon.png | Bin 0 -> 792 bytes .../static/description/icon.svg | 1 + .../payment_mollie/tests/__init__.py | 4 + .../payment_mollie/tests/common.py | 21 + .../payment_mollie/tests/test_mollie.py | 40 ++ .../views/payment_mollie_templates.xml | 13 + .../views/payment_provider_views.xml | 17 + .../payment_nuvei/README.md | 43 ++ .../payment_nuvei/__init__.py | 14 + .../payment_nuvei/__manifest__.py | 20 + .../payment_nuvei/const.py | 67 ++ .../payment_nuvei/controllers/__init__.py | 3 + .../payment_nuvei/controllers/main.py | 91 +++ .../payment_nuvei/data/neutralize.sql | 5 + .../data/payment_provider_data.xml | 9 + .../payment_nuvei/i18n/ar.po | 131 ++++ .../payment_nuvei/i18n/az.po | 126 ++++ .../payment_nuvei/i18n/bg.po | 126 ++++ .../payment_nuvei/i18n/ca.po | 133 ++++ .../payment_nuvei/i18n/cs.po | 130 ++++ .../payment_nuvei/i18n/da.po | 130 ++++ .../payment_nuvei/i18n/de.po | 134 ++++ .../payment_nuvei/i18n/el.po | 130 ++++ .../payment_nuvei/i18n/es.po | 135 ++++ .../payment_nuvei/i18n/es_419.po | 134 ++++ .../payment_nuvei/i18n/et.po | 126 ++++ .../payment_nuvei/i18n/fa.po | 126 ++++ .../payment_nuvei/i18n/fi.po | 130 ++++ .../payment_nuvei/i18n/fr.po | 134 ++++ .../payment_nuvei/i18n/he.po | 126 ++++ .../payment_nuvei/i18n/hi.po | 126 ++++ .../payment_nuvei/i18n/hr.po | 126 ++++ .../payment_nuvei/i18n/hu.po | 130 ++++ .../payment_nuvei/i18n/id.po | 132 ++++ .../payment_nuvei/i18n/it.po | 134 ++++ .../payment_nuvei/i18n/ja.po | 130 ++++ .../payment_nuvei/i18n/ko.po | 130 ++++ .../payment_nuvei/i18n/ku.po | 126 ++++ .../payment_nuvei/i18n/lt.po | 126 ++++ .../payment_nuvei/i18n/mn.po | 126 ++++ .../payment_nuvei/i18n/my.po | 126 ++++ .../payment_nuvei/i18n/nb.po | 130 ++++ .../payment_nuvei/i18n/nl.po | 134 ++++ .../payment_nuvei/i18n/payment_nuvei.pot | 126 ++++ .../payment_nuvei/i18n/pl.po | 131 ++++ .../payment_nuvei/i18n/pt.po | 133 ++++ .../payment_nuvei/i18n/pt_BR.po | 133 ++++ .../payment_nuvei/i18n/ro.po | 126 ++++ .../payment_nuvei/i18n/ru.po | 133 ++++ .../payment_nuvei/i18n/sl.po | 131 ++++ .../payment_nuvei/i18n/sr@latin.po | 126 ++++ .../payment_nuvei/i18n/sv.po | 132 ++++ .../payment_nuvei/i18n/th.po | 131 ++++ .../payment_nuvei/i18n/tr.po | 130 ++++ .../payment_nuvei/i18n/uk.po | 126 ++++ .../payment_nuvei/i18n/vi.po | 133 ++++ .../payment_nuvei/i18n/zh_CN.po | 130 ++++ .../payment_nuvei/i18n/zh_TW.po | 138 ++++ .../payment_nuvei/models/__init__.py | 4 + .../payment_nuvei/models/payment_provider.py | 82 +++ .../models/payment_transaction.py | 171 +++++ .../payment_nuvei/static/description/icon.png | Bin 0 -> 1949 bytes .../payment_nuvei/static/description/icon.svg | 1 + .../payment_nuvei/tests/__init__.py | 6 + .../payment_nuvei/tests/common.py | 35 + .../tests/test_payment_provider.py | 48 ++ .../tests/test_payment_transaction.py | 168 +++++ .../tests/test_processing_flows.py | 90 +++ .../views/payment_nuvei_templates.xml | 13 + .../views/payment_provider_views.xml | 32 + .../payment_paymob/README.md | 31 + .../payment_paymob/__init__.py | 14 + .../payment_paymob/__manifest__.py | 21 + .../payment_paymob/const.py | 72 ++ .../payment_paymob/controllers/__init__.py | 3 + .../payment_paymob/controllers/main.py | 129 ++++ .../payment_paymob/data/neutralize.sql | 6 + .../data/payment_provider_data.xml | 9 + .../payment_paymob/i18n/ar.po | 176 +++++ .../payment_paymob/i18n/az.po | 176 +++++ .../payment_paymob/i18n/bg.po | 176 +++++ .../payment_paymob/i18n/ca.po | 176 +++++ .../payment_paymob/i18n/cs.po | 176 +++++ .../payment_paymob/i18n/da.po | 176 +++++ .../payment_paymob/i18n/de.po | 188 +++++ .../payment_paymob/i18n/el.po | 176 +++++ .../payment_paymob/i18n/es.po | 176 +++++ .../payment_paymob/i18n/es_419.po | 183 +++++ .../payment_paymob/i18n/et.po | 176 +++++ .../payment_paymob/i18n/fa.po | 176 +++++ .../payment_paymob/i18n/fi.po | 176 +++++ .../payment_paymob/i18n/fr.po | 176 +++++ .../payment_paymob/i18n/he.po | 176 +++++ .../payment_paymob/i18n/hi.po | 176 +++++ .../payment_paymob/i18n/hr.po | 176 +++++ .../payment_paymob/i18n/hu.po | 176 +++++ .../payment_paymob/i18n/id.po | 176 +++++ .../payment_paymob/i18n/it.po | 176 +++++ .../payment_paymob/i18n/ja.po | 176 +++++ .../payment_paymob/i18n/ko.po | 180 +++++ .../payment_paymob/i18n/ku.po | 176 +++++ .../payment_paymob/i18n/lt.po | 176 +++++ .../payment_paymob/i18n/mn.po | 176 +++++ .../payment_paymob/i18n/my.po | 176 +++++ .../payment_paymob/i18n/nb.po | 176 +++++ .../payment_paymob/i18n/nl.po | 176 +++++ .../payment_paymob/i18n/payment_paymob.pot | 176 +++++ .../payment_paymob/i18n/pl.po | 176 +++++ .../payment_paymob/i18n/pt.po | 176 +++++ .../payment_paymob/i18n/pt_BR.po | 185 +++++ .../payment_paymob/i18n/ro.po | 176 +++++ .../payment_paymob/i18n/ru.po | 176 +++++ .../payment_paymob/i18n/sl.po | 176 +++++ .../payment_paymob/i18n/sr@latin.po | 176 +++++ .../payment_paymob/i18n/sv.po | 176 +++++ .../payment_paymob/i18n/th.po | 176 +++++ .../payment_paymob/i18n/tr.po | 176 +++++ .../payment_paymob/i18n/uk.po | 176 +++++ .../payment_paymob/i18n/vi.po | 176 +++++ .../payment_paymob/i18n/zh_CN.po | 176 +++++ .../payment_paymob/i18n/zh_TW.po | 176 +++++ .../payment_paymob/models/__init__.py | 4 + .../payment_paymob/models/payment_provider.py | 270 +++++++ .../models/payment_transaction.py | 151 ++++ .../static/description/icon.png | Bin 0 -> 1620 bytes .../static/description/icon.svg | 10 + .../payment_paymob/tests/__init__.py | 4 + .../payment_paymob/tests/common.py | 83 +++ .../payment_paymob/tests/test_paymob.py | 63 ++ .../views/payment_paymob_templates.xml | 13 + .../views/payment_provider_views.xml | 57 ++ .../payment_paypal/README.md | 42 ++ .../payment_paypal/__init__.py | 14 + .../payment_paypal/__manifest__.py | 27 + .../payment_paypal/const.py | 67 ++ .../payment_paypal/controllers/__init__.py | 3 + .../payment_paypal/controllers/main.py | 133 ++++ .../payment_paypal/data/neutralize.sql | 5 + .../data/payment_provider_data.xml | 8 + .../payment_paypal/i18n/af.po | 140 ++++ .../payment_paypal/i18n/am.po | 140 ++++ .../payment_paypal/i18n/ar.po | 197 ++++++ .../payment_paypal/i18n/az.po | 177 +++++ .../payment_paypal/i18n/bg.po | 177 +++++ .../payment_paypal/i18n/bs.po | 143 ++++ .../payment_paypal/i18n/ca.po | 191 +++++ .../payment_paypal/i18n/cs.po | 188 +++++ .../payment_paypal/i18n/da.po | 195 +++++ .../payment_paypal/i18n/de.po | 197 ++++++ .../payment_paypal/i18n/el.po | 193 +++++ .../payment_paypal/i18n/es.po | 202 ++++++ .../payment_paypal/i18n/es_419.po | 184 +++++ .../payment_paypal/i18n/es_CL.po | 140 ++++ .../payment_paypal/i18n/et.po | 146 ++++ .../payment_paypal/i18n/eu.po | 140 ++++ .../payment_paypal/i18n/fa.po | 181 +++++ .../payment_paypal/i18n/fi.po | 193 +++++ .../payment_paypal/i18n/fo.po | 140 ++++ .../payment_paypal/i18n/fr.po | 224 ++++++ .../payment_paypal/i18n/fr_CA.po | 140 ++++ .../payment_paypal/i18n/gl.po | 140 ++++ .../payment_paypal/i18n/gu.po | 140 ++++ .../payment_paypal/i18n/he.po | 187 +++++ .../payment_paypal/i18n/hi.po | 177 +++++ .../payment_paypal/i18n/hr.po | 194 +++++ .../payment_paypal/i18n/hu.po | 194 +++++ .../payment_paypal/i18n/id.po | 190 +++++ .../payment_paypal/i18n/is.po | 144 ++++ .../payment_paypal/i18n/it.po | 225 ++++++ .../payment_paypal/i18n/ja.po | 195 +++++ .../payment_paypal/i18n/ka.po | 140 ++++ .../payment_paypal/i18n/kab.po | 140 ++++ .../payment_paypal/i18n/km.po | 143 ++++ .../payment_paypal/i18n/ko.po | 190 +++++ .../payment_paypal/i18n/ku.po | 177 +++++ .../payment_paypal/i18n/lb.po | 140 ++++ .../payment_paypal/i18n/lo.po | 140 ++++ .../payment_paypal/i18n/lt.po | 197 ++++++ .../payment_paypal/i18n/lv.po | 140 ++++ .../payment_paypal/i18n/mk.po | 140 ++++ .../payment_paypal/i18n/mn.po | 191 +++++ .../payment_paypal/i18n/my.po | 177 +++++ .../payment_paypal/i18n/nb.po | 190 +++++ .../payment_paypal/i18n/nl.po | 216 ++++++ .../payment_paypal/i18n/payment_paypal.pot | 177 +++++ .../payment_paypal/i18n/pl.po | 197 ++++++ .../payment_paypal/i18n/pt.po | 183 +++++ .../payment_paypal/i18n/pt_BR.po | 198 ++++++ .../payment_paypal/i18n/ro.po | 178 +++++ .../payment_paypal/i18n/ru.po | 204 ++++++ .../payment_paypal/i18n/sk.po | 146 ++++ .../payment_paypal/i18n/sl.po | 182 +++++ .../payment_paypal/i18n/sq.po | 140 ++++ .../payment_paypal/i18n/sr@latin.po | 178 +++++ .../payment_paypal/i18n/sv.po | 186 +++++ .../payment_paypal/i18n/th.po | 186 +++++ .../payment_paypal/i18n/tr.po | 198 ++++++ .../payment_paypal/i18n/uk.po | 229 ++++++ .../payment_paypal/i18n/vi.po | 190 +++++ .../payment_paypal/i18n/zh_CN.po | 228 ++++++ .../payment_paypal/i18n/zh_TW.po | 193 +++++ .../payment_paypal/models/__init__.py | 4 + .../payment_paypal/models/payment_provider.py | 195 +++++ .../models/payment_transaction.py | 165 +++++ .../static/description/icon.png | Bin 0 -> 932 bytes .../static/description/icon.svg | 1 + .../static/src/interactions/payment_button.js | 76 ++ .../static/src/interactions/payment_form.js | 237 +++++++ .../payment_paypal/tests/__init__.py | 4 + .../payment_paypal/tests/common.py | 61 ++ .../payment_paypal/tests/test_paypal.py | 151 ++++ .../payment_paypal/utils.py | 58 ++ .../views/payment_form_templates.xml | 29 + .../views/payment_provider_views.xml | 48 ++ .../views/payment_transaction_views.xml | 18 + .../payment_razorpay/README.md | 49 ++ .../payment_razorpay/__init__.py | 14 + .../payment_razorpay/__manifest__.py | 26 + .../payment_razorpay/const.py | 158 +++++ .../payment_razorpay/controllers/__init__.py | 4 + .../payment_razorpay/controllers/main.py | 113 +++ .../controllers/onboarding.py | 85 +++ .../payment_razorpay/data/neutralize.sql | 10 + .../data/payment_provider_data.xml | 9 + .../payment_razorpay/i18n/ar.po | 187 +++++ .../payment_razorpay/i18n/az.po | 179 +++++ .../payment_razorpay/i18n/bg.po | 179 +++++ .../payment_razorpay/i18n/ca.po | 185 +++++ .../payment_razorpay/i18n/cs.po | 183 +++++ .../payment_razorpay/i18n/da.po | 183 +++++ .../payment_razorpay/i18n/de.po | 191 +++++ .../payment_razorpay/i18n/el.po | 183 +++++ .../payment_razorpay/i18n/es.po | 190 +++++ .../payment_razorpay/i18n/es_419.po | 187 +++++ .../payment_razorpay/i18n/et.po | 283 ++++++++ .../payment_razorpay/i18n/fa.po | 179 +++++ .../payment_razorpay/i18n/fi.po | 186 +++++ .../payment_razorpay/i18n/fr.po | 189 +++++ .../payment_razorpay/i18n/he.po | 179 +++++ .../payment_razorpay/i18n/hi.po | 179 +++++ .../payment_razorpay/i18n/hr.po | 179 +++++ .../payment_razorpay/i18n/hu.po | 183 +++++ .../payment_razorpay/i18n/id.po | 187 +++++ .../payment_razorpay/i18n/it.po | 190 +++++ .../payment_razorpay/i18n/ja.po | 184 +++++ .../payment_razorpay/i18n/ko.po | 184 +++++ .../payment_razorpay/i18n/ku.po | 179 +++++ .../payment_razorpay/i18n/lt.po | 179 +++++ .../payment_razorpay/i18n/mn.po | 179 +++++ .../payment_razorpay/i18n/my.po | 179 +++++ .../payment_razorpay/i18n/nb.po | 183 +++++ .../payment_razorpay/i18n/nl.po | 191 +++++ .../i18n/payment_razorpay.pot | 283 ++++++++ .../payment_razorpay/i18n/pl.po | 184 +++++ .../payment_razorpay/i18n/pt.po | 188 +++++ .../payment_razorpay/i18n/pt_BR.po | 188 +++++ .../payment_razorpay/i18n/ro.po | 179 +++++ .../payment_razorpay/i18n/ru.po | 318 +++++++++ .../payment_razorpay/i18n/sl.po | 184 +++++ .../payment_razorpay/i18n/sr@latin.po | 179 +++++ .../payment_razorpay/i18n/sv.po | 188 +++++ .../payment_razorpay/i18n/th.po | 185 +++++ .../payment_razorpay/i18n/tr.po | 183 +++++ .../payment_razorpay/i18n/uk.po | 179 +++++ .../payment_razorpay/i18n/vi.po | 189 +++++ .../payment_razorpay/i18n/zh_CN.po | 183 +++++ .../payment_razorpay/i18n/zh_TW.po | 324 +++++++++ .../payment_razorpay/models/__init__.py | 5 + .../models/payment_provider.py | 313 ++++++++ .../payment_razorpay/models/payment_token.py | 50 ++ .../models/payment_transaction.py | 469 ++++++++++++ .../static/description/icon.png | Bin 0 -> 976 bytes .../static/description/icon.svg | 1 + .../static/src/interactions/payment_form.js | 85 +++ .../payment_razorpay/tests/__init__.py | 6 + .../payment_razorpay/tests/common.py | 67 ++ .../tests/test_payment_provider.py | 31 + .../tests/test_payment_transaction.py | 163 +++++ .../tests/test_processing_flows.py | 83 +++ .../views/payment_provider_views.xml | 95 +++ .../views/payment_razorpay_templates.xml | 28 + .../payment_redsys/README.md | 33 + .../payment_redsys/__init__.py | 13 + .../payment_redsys/__manifest__.py | 20 + .../payment_redsys/const.py | 70 ++ .../payment_redsys/controllers/__init__.py | 3 + .../payment_redsys/controllers/main.py | 76 ++ .../payment_redsys/data/neutralize.sql | 5 + .../data/payment_provider_data.xml | 9 + .../payment_redsys/i18n/ar.po | 97 +++ .../payment_redsys/i18n/az.po | 97 +++ .../payment_redsys/i18n/bg.po | 97 +++ .../payment_redsys/i18n/ca.po | 103 +++ .../payment_redsys/i18n/cs.po | 97 +++ .../payment_redsys/i18n/da.po | 97 +++ .../payment_redsys/i18n/de.po | 97 +++ .../payment_redsys/i18n/el.po | 97 +++ .../payment_redsys/i18n/es.po | 97 +++ .../payment_redsys/i18n/es_419.po | 102 +++ .../payment_redsys/i18n/et.po | 97 +++ .../payment_redsys/i18n/fa.po | 97 +++ .../payment_redsys/i18n/fi.po | 97 +++ .../payment_redsys/i18n/fr.po | 97 +++ .../payment_redsys/i18n/he.po | 97 +++ .../payment_redsys/i18n/hi.po | 97 +++ .../payment_redsys/i18n/hr.po | 97 +++ .../payment_redsys/i18n/hu.po | 97 +++ .../payment_redsys/i18n/id.po | 97 +++ .../payment_redsys/i18n/it.po | 97 +++ .../payment_redsys/i18n/ja.po | 97 +++ .../payment_redsys/i18n/ko.po | 101 +++ .../payment_redsys/i18n/ku.po | 97 +++ .../payment_redsys/i18n/lt.po | 97 +++ .../payment_redsys/i18n/mn.po | 97 +++ .../payment_redsys/i18n/my.po | 97 +++ .../payment_redsys/i18n/nb.po | 97 +++ .../payment_redsys/i18n/nl.po | 97 +++ .../payment_redsys/i18n/payment_redsys.pot | 97 +++ .../payment_redsys/i18n/pl.po | 97 +++ .../payment_redsys/i18n/pt.po | 97 +++ .../payment_redsys/i18n/pt_BR.po | 103 +++ .../payment_redsys/i18n/ro.po | 97 +++ .../payment_redsys/i18n/ru.po | 97 +++ .../payment_redsys/i18n/sl.po | 97 +++ .../payment_redsys/i18n/sr@latin.po | 97 +++ .../payment_redsys/i18n/sv.po | 97 +++ .../payment_redsys/i18n/th.po | 97 +++ .../payment_redsys/i18n/tr.po | 97 +++ .../payment_redsys/i18n/uk.po | 97 +++ .../payment_redsys/i18n/vi.po | 97 +++ .../payment_redsys/i18n/zh_CN.po | 97 +++ .../payment_redsys/i18n/zh_TW.po | 97 +++ .../payment_redsys/models/__init__.py | 4 + .../payment_redsys/models/payment_provider.py | 78 ++ .../models/payment_transaction.py | 163 +++++ .../static/description/icon.png | Bin 0 -> 57980 bytes .../static/description/icon.svg | 33 + .../payment_redsys/tests/__init__.py | 5 + .../payment_redsys/tests/common.py | 33 + .../tests/test_payment_transaction.py | 60 ++ .../tests/test_processing_flows.py | 91 +++ .../views/payment_provider_views.xml | 32 + .../views/payment_redsys_templates.xml | 12 + .../payment_stripe/README.md | 75 ++ .../payment_stripe/__init__.py | 14 + .../payment_stripe/__manifest__.py | 28 + .../payment_stripe/const.py | 152 ++++ .../payment_stripe/controllers/__init__.py | 4 + .../payment_stripe/controllers/main.py | 240 +++++++ .../payment_stripe/controllers/onboarding.py | 40 ++ .../payment_stripe/data/neutralize.sql | 5 + .../data/payment_provider_data.xml | 12 + .../payment_stripe/i18n/ar.po | 276 ++++++++ .../payment_stripe/i18n/az.po | 251 +++++++ .../payment_stripe/i18n/bg.po | 289 ++++++++ .../payment_stripe/i18n/bs.po | 201 ++++++ .../payment_stripe/i18n/ca.po | 276 ++++++++ .../payment_stripe/i18n/cs.po | 267 +++++++ .../payment_stripe/i18n/da.po | 268 +++++++ .../payment_stripe/i18n/de.po | 280 ++++++++ .../payment_stripe/i18n/el.po | 264 +++++++ .../payment_stripe/i18n/es.po | 276 ++++++++ .../payment_stripe/i18n/es_419.po | 307 ++++++++ .../payment_stripe/i18n/et.po | 203 ++++++ .../payment_stripe/i18n/fa.po | 261 +++++++ .../payment_stripe/i18n/fi.po | 279 ++++++++ .../payment_stripe/i18n/fr.po | 277 ++++++++ .../payment_stripe/i18n/gu.po | 199 ++++++ .../payment_stripe/i18n/he.po | 264 +++++++ .../payment_stripe/i18n/hi.po | 289 ++++++++ .../payment_stripe/i18n/hr.po | 265 +++++++ .../payment_stripe/i18n/hu.po | 265 +++++++ .../payment_stripe/i18n/id.po | 275 +++++++ .../payment_stripe/i18n/is.po | 202 ++++++ .../payment_stripe/i18n/it.po | 279 ++++++++ .../payment_stripe/i18n/ja.po | 272 +++++++ .../payment_stripe/i18n/km.po | 200 ++++++ .../payment_stripe/i18n/ko.po | 269 +++++++ .../payment_stripe/i18n/ku.po | 289 ++++++++ .../payment_stripe/i18n/lb.po | 196 +++++ .../payment_stripe/i18n/lt.po | 271 +++++++ .../payment_stripe/i18n/lv.po | 196 +++++ .../payment_stripe/i18n/mn.po | 262 +++++++ .../payment_stripe/i18n/my.po | 289 ++++++++ .../payment_stripe/i18n/nb.po | 264 +++++++ .../payment_stripe/i18n/nl.po | 280 ++++++++ .../payment_stripe/i18n/payment_stripe.pot | 251 +++++++ .../payment_stripe/i18n/pl.po | 273 +++++++ .../payment_stripe/i18n/pt.po | 265 +++++++ .../payment_stripe/i18n/pt_BR.po | 280 ++++++++ .../payment_stripe/i18n/ro.po | 252 +++++++ .../payment_stripe/i18n/ru.po | 308 ++++++++ .../payment_stripe/i18n/sk.po | 203 ++++++ .../payment_stripe/i18n/sl.po | 258 +++++++ .../payment_stripe/i18n/sr@latin.po | 255 +++++++ .../payment_stripe/i18n/sv.po | 280 ++++++++ .../payment_stripe/i18n/th.po | 272 +++++++ .../payment_stripe/i18n/tr.po | 275 +++++++ .../payment_stripe/i18n/uk.po | 268 +++++++ .../payment_stripe/i18n/vi.po | 279 ++++++++ .../payment_stripe/i18n/zh_CN.po | 266 +++++++ .../payment_stripe/i18n/zh_TW.po | 295 ++++++++ .../payment_stripe/models/__init__.py | 5 + .../payment_stripe/models/payment_provider.py | 511 +++++++++++++ .../payment_stripe/models/payment_token.py | 50 ++ .../models/payment_transaction.py | 433 ++++++++++++ .../static/description/icon.png | Bin 0 -> 942 bytes .../static/description/icon.svg | 1 + ...le-developer-merchantid-domain-association | 1 + .../src/interactions/express_checkout.js | 231 ++++++ .../static/src/interactions/payment_form.js | 196 +++++ .../static/src/js/stripe_options.js | 18 + .../src/scss/payment_stripe_templates.scss | 4 + .../payment_stripe/tests/__init__.py | 5 + .../payment_stripe/tests/common.py | 99 +++ .../payment_stripe/tests/test_refund_flows.py | 49 ++ .../payment_stripe/tests/test_stripe.py | 202 ++++++ .../payment_stripe/utils.py | 78 ++ .../views/payment_provider_views.xml | 63 ++ .../views/payment_stripe_templates.xml | 31 + .../views/payment_templates.xml | 28 + .../payment_worldline/README.md | 44 ++ .../payment_worldline/__init__.py | 14 + .../payment_worldline/__manifest__.py | 25 + .../payment_worldline/const.py | 77 ++ .../payment_worldline/controllers/__init__.py | 3 + .../payment_worldline/controllers/main.py | 98 +++ .../payment_worldline/data/neutralize.sql | 7 + .../data/payment_provider_data.xml | 10 + .../payment_worldline/i18n/ar.po | 152 ++++ .../payment_worldline/i18n/az.po | 147 ++++ .../payment_worldline/i18n/bg.po | 147 ++++ .../payment_worldline/i18n/ca.po | 151 ++++ .../payment_worldline/i18n/cs.po | 151 ++++ .../payment_worldline/i18n/da.po | 151 ++++ .../payment_worldline/i18n/de.po | 153 ++++ .../payment_worldline/i18n/el.po | 151 ++++ .../payment_worldline/i18n/es.po | 153 ++++ .../payment_worldline/i18n/es_419.po | 153 ++++ .../payment_worldline/i18n/et.po | 129 ++++ .../payment_worldline/i18n/fa.po | 147 ++++ .../payment_worldline/i18n/fi.po | 153 ++++ .../payment_worldline/i18n/fr.po | 153 ++++ .../payment_worldline/i18n/he.po | 147 ++++ .../payment_worldline/i18n/hi.po | 147 ++++ .../payment_worldline/i18n/hr.po | 147 ++++ .../payment_worldline/i18n/hu.po | 151 ++++ .../payment_worldline/i18n/id.po | 153 ++++ .../payment_worldline/i18n/it.po | 153 ++++ .../payment_worldline/i18n/ja.po | 151 ++++ .../payment_worldline/i18n/ko.po | 151 ++++ .../payment_worldline/i18n/ku.po | 147 ++++ .../payment_worldline/i18n/lt.po | 147 ++++ .../payment_worldline/i18n/mn.po | 147 ++++ .../payment_worldline/i18n/my.po | 147 ++++ .../payment_worldline/i18n/nb.po | 151 ++++ .../payment_worldline/i18n/nl.po | 152 ++++ .../i18n/payment_worldline.pot | 129 ++++ .../payment_worldline/i18n/pl.po | 152 ++++ .../payment_worldline/i18n/pt.po | 153 ++++ .../payment_worldline/i18n/pt_BR.po | 153 ++++ .../payment_worldline/i18n/ro.po | 147 ++++ .../payment_worldline/i18n/ru.po | 152 ++++ .../payment_worldline/i18n/sl.po | 152 ++++ .../payment_worldline/i18n/sr@latin.po | 147 ++++ .../payment_worldline/i18n/sv.po | 151 ++++ .../payment_worldline/i18n/th.po | 151 ++++ .../payment_worldline/i18n/tr.po | 151 ++++ .../payment_worldline/i18n/uk.po | 147 ++++ .../payment_worldline/i18n/vi.po | 153 ++++ .../payment_worldline/i18n/zh_CN.po | 151 ++++ .../payment_worldline/i18n/zh_TW.po | 151 ++++ .../payment_worldline/models/__init__.py | 4 + .../models/payment_provider.py | 142 ++++ .../models/payment_transaction.py | 333 +++++++++ .../static/description/icon.png | Bin 0 -> 1149 bytes .../static/description/icon.svg | 1 + .../static/src/interactions/payment_form.js | 25 + .../payment_worldline/tests/__init__.py | 4 + .../payment_worldline/tests/common.py | 155 ++++ .../payment_worldline/tests/test_worldline.py | 157 ++++ .../views/payment_provider_views.xml | 43 ++ .../views/payment_worldline_templates.xml | 8 + .../payment_xendit/README.md | 46 ++ .../payment_xendit/__init__.py | 14 + .../payment_xendit/__manifest__.py | 26 + .../payment_xendit/const.py | 45 ++ .../payment_xendit/controllers/__init__.py | 3 + .../payment_xendit/controllers/main.py | 80 +++ .../payment_xendit/data/neutralize.sql | 3 + .../data/payment_provider_data.xml | 10 + .../payment_xendit/i18n/ar.po | 202 ++++++ .../payment_xendit/i18n/az.po | 195 +++++ .../payment_xendit/i18n/bg.po | 195 +++++ .../payment_xendit/i18n/ca.po | 201 ++++++ .../payment_xendit/i18n/cs.po | 199 ++++++ .../payment_xendit/i18n/da.po | 199 ++++++ .../payment_xendit/i18n/de.po | 203 ++++++ .../payment_xendit/i18n/el.po | 199 ++++++ .../payment_xendit/i18n/es.po | 202 ++++++ .../payment_xendit/i18n/es_419.po | 201 ++++++ .../payment_xendit/i18n/et.po | 175 +++++ .../payment_xendit/i18n/fa.po | 195 +++++ .../payment_xendit/i18n/fi.po | 201 ++++++ .../payment_xendit/i18n/fr.po | 203 ++++++ .../payment_xendit/i18n/he.po | 195 +++++ .../payment_xendit/i18n/hi.po | 195 +++++ .../payment_xendit/i18n/hr.po | 195 +++++ .../payment_xendit/i18n/hu.po | 199 ++++++ .../payment_xendit/i18n/id.po | 202 ++++++ .../payment_xendit/i18n/it.po | 203 ++++++ .../payment_xendit/i18n/ja.po | 199 ++++++ .../payment_xendit/i18n/ko.po | 199 ++++++ .../payment_xendit/i18n/ku.po | 195 +++++ .../payment_xendit/i18n/lt.po | 195 +++++ .../payment_xendit/i18n/mn.po | 195 +++++ .../payment_xendit/i18n/my.po | 195 +++++ .../payment_xendit/i18n/nb.po | 199 ++++++ .../payment_xendit/i18n/nl.po | 203 ++++++ .../payment_xendit/i18n/payment_xendit.pot | 175 +++++ .../payment_xendit/i18n/pl.po | 200 ++++++ .../payment_xendit/i18n/pt.po | 203 ++++++ .../payment_xendit/i18n/pt_BR.po | 203 ++++++ .../payment_xendit/i18n/ro.po | 195 +++++ .../payment_xendit/i18n/ru.po | 207 ++++++ .../payment_xendit/i18n/sl.po | 200 ++++++ .../payment_xendit/i18n/sr@latin.po | 195 +++++ .../payment_xendit/i18n/sv.po | 203 ++++++ .../payment_xendit/i18n/th.po | 199 ++++++ .../payment_xendit/i18n/tr.po | 195 +++++ .../payment_xendit/i18n/uk.po | 195 +++++ .../payment_xendit/i18n/vi.po | 203 ++++++ .../payment_xendit/i18n/zh_CN.po | 199 ++++++ .../payment_xendit/i18n/zh_TW.po | 199 ++++++ .../payment_xendit/models/__init__.py | 4 + .../payment_xendit/models/payment_provider.py | 102 +++ .../models/payment_transaction.py | 222 ++++++ .../static/description/icon.png | Bin 0 -> 3296 bytes .../static/description/icon.svg | 1 + .../static/src/interactions/payment_form.js | 254 +++++++ .../static/src/js/auth_service.js | 12 + .../payment_xendit/static/src/js/auth_ui.js | 29 + .../payment_xendit/tests/__init__.py | 6 + .../payment_xendit/tests/common.py | 63 ++ .../tests/test_payment_provider.py | 16 + .../tests/test_payment_transaction.py | 157 ++++ .../tests/test_processing_flows.py | 96 +++ .../views/payment_provider_views.xml | 33 + .../views/payment_xendit_templates.xml | 111 +++ 1472 files changed, 194608 insertions(+) create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/__init__.py create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/iot_base.pot create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/static/src/@types/services.d.ts create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/static/src/device_controller.js create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/static/src/network_utils/http.js create mode 100644 odoo-bringout-oca-ocb-iot_base/iot_base/static/src/network_utils/longpolling.js create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/.gitignore create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/__init__.py create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/__manifest__.py create mode 100755 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_image.sh create mode 100755 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_utils/download_requirements.sh create mode 100755 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_utils/methods.sh create mode 100755 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_utils/partition_image.sh create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_utils/sparse-checkout create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/aiortc-1.4.0-py3-none-any.whl create mode 100755 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/led_manager.sh create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/odoo.conf create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/packages.txt create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/requirements.txt create mode 100755 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/setup_ramdisks.sh create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/cups/cups-files.conf create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/cups/cupsd.conf create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/default/hostapd create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/default/ifplugd create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/dnsmasq.conf create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/fstab create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/hostapd/hostapd.conf create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/nginx/conf.d/access_point.conf create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/nginx/conf.d/iot.conf create mode 100755 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/rc.local create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/ssl/certs/nginx-cert.crt create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/ssl/private/nginx-cert.key create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/home/odoo/.config/labwc/autostart create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/home/odoo/.config/labwc/iot-bg.png create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/home/odoo/.config/labwc/rc.xml create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/var/www/html/502.html create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/NetworkManager/conf.d/90-dns-none.conf create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/default/keyboard create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/default/locale create mode 100755 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/init_image.sh create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/logrotate.conf create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/logrotate.d/odoo create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/resolv.conf create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/labwc.service create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/odoo-led-manager.service create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/odoo-ngrok.service create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/odoo.service create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/ramdisks.service create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/udev/rules.d/99-usb.rules create mode 100644 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/udev/rules.d/99-z-input.rules create mode 100755 odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/home/pi/.vimrc create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/__init__.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/browser.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/cli/genproxytoken.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/connection_manager.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/controllers/driver.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/controllers/homepage.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/controllers/proxy.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/driver.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/event_manager.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/exception_logger.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/http.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/interface.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/display_driver_L.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/keyboard_usb_driver_L.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/l10n_eg_drivers.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/l10n_ke_edi_serial_driver.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/printer_driver_L.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/printer_driver_W.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/printer_driver_base.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/serial_base_driver.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/serial_scale_driver.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/display_interface_L.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/printer_interface_L.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/printer_interface_W.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/serial_interface.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/usb_interface_L.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/main.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/server_logger.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/img/background-light.svg create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/img/favicon.png create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/Homepage.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/FooterButtons.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/IconButton.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/LoadingFullScreen.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/SingleData.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/BootstrapDialog.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/CredentialDialog.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/DeviceDialog.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/HandlerDialog.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/RemoteDebugDialog.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/ServerDialog.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/SixDialog.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/TimeDialog.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/UpdateDialog.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/WifiDialog.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/css/homepage.css create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/css/logs.css create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/css/status_display.css create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/hooks/useStore.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/logs.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/main.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/status.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/store.js create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/__init__.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/certificate.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/helpers.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/route.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/system.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/upgrade.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/wifi.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/views/index.html create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/views/logs.html create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/views/status_display.html create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/webrtc_client.py create mode 100644 odoo-bringout-oca-ocb-iot_drivers/iot_drivers/websocket_client.py create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/README.md create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/const.py create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/controllers/main.py create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/data/neutralize.sql create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/af.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/am.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/bs.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/es_CL.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/eu.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fo.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fr_CA.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/gl.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/gu.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/is.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ka.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/kab.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/km.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/lb.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/lo.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/lv.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/mk.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ne.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/payment_adyen.pot create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sk.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sq.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/models/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/models/payment_token.py create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/static/src/interactions/payment_form.js create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/tests/test_adyen.py create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/utils.py create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/views/payment_adyen_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/views/payment_form_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/wizards/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/wizards/payment_capture_wizard.py create mode 100644 odoo-bringout-oca-ocb-payment_adyen/payment_adyen/wizards/payment_capture_wizard_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/README.md create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/const.py create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/controllers/main.py create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/data/neutralize.sql create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/payment_aps.pot create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/models/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/tests/test_payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/tests/test_processing_flows.py create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/utils.py create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/views/payment_aps_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_aps/payment_aps/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/README.md create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/const.py create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/controllers/main.py create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/data/neutralize.sql create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/payment_asiapay.pot create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/models/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/tests/test_payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/tests/test_payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/tests/test_processing_flows.py create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/views/payment_asiapay_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_asiapay/payment_asiapay/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/README.md create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/const.py create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/controllers/main.py create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/data/neutralize.sql create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/af.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/am.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/bs.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/es_CL.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/eu.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/fo.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/fr_CA.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/gl.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/gu.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/is.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/ka.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/kab.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/km.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/lb.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/lo.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/lv.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/mk.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/ne.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/payment_authorize.pot create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/sk.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/sq.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/models/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/models/authorize_request.py create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/models/payment_token.py create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/static/src/interactions/payment_form.js create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/static/src/scss/payment_authorize.scss create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/tests/test_authorize.py create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/tests/test_refund_flows.py create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/views/payment_authorize_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_authorize/payment_authorize/views/payment_token_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/README.md create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/const.py create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/controllers/main.py create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/data/neutralize.sql create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/af.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/am.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/bs.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/es_CL.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/eu.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/fo.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/fr_CA.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/gl.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/gu.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/is.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/ka.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/kab.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/km.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/lb.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/lo.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/lv.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/mk.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/ne.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/payment_buckaroo.pot create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/sk.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/sq.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/models/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/tests/test_buckaroo.py create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/views/payment_buckaroo_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_buckaroo/payment_buckaroo/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/README.md create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/const.py create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/controllers/main.py create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/data/payment_method_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/payment_demo.pot create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/models/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/models/payment_token.py create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/static/img/demo.png create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/static/src/interactions/express_checkout.js create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/static/src/interactions/payment_demo_mixin.js create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/static/src/interactions/payment_form.js create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/tests/test_payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/tests/test_processing_flows.py create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/views/payment_demo_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/views/payment_token_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_demo/payment_demo/views/payment_transaction_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/README.md create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/const.py create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/controllers/main.py create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/data/neutralize.sql create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/payment_dpo.pot create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/models/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/tests/test_payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/tests/test_processing_flows.py create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/views/payment_dpo_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_dpo/payment_dpo/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/README.md create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/const.py create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/controllers/main.py create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/data/neutralize.sql create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/payment_flutterwave.pot create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/models/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/models/payment_token.py create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/static/src/interactions/payment_form.js create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/tests/test_payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/tests/test_payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/tests/test_processing_flows.py create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/views/payment_flutterwave_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_flutterwave/payment_flutterwave/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/README.md create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/const.py create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/controllers/main.py create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/data/neutralize.sql create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/payment_iyzico.pot create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/models/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/tests/test_payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/tests/test_payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/tests/test_processing_flows.py create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/views/payment_iyzico_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_iyzico/payment_iyzico/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/README.md create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/const.py create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/controllers/onboarding.py create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/controllers/payment.py create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/data/neutralize.sql create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/payment_mercado_pago.pot create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/models/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/models/payment_token.py create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/static/src/interactions/payment_form.js create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/tests/test_payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/tests/test_payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/tests/test_processing_flows.py create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/views/payment_form_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/views/payment_mercado_pago_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_mercado_pago/payment_mercado_pago/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/README.md create mode 100755 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/__init__.py create mode 100755 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/const.py create mode 100755 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/controllers/__init__.py create mode 100755 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/controllers/main.py create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/data/neutralize.sql create mode 100755 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/payment_mollie.pot create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/i18n/zh_TW.po create mode 100755 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/models/__init__.py create mode 100755 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/tests/test_mollie.py create mode 100644 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/views/payment_mollie_templates.xml create mode 100755 odoo-bringout-oca-ocb-payment_mollie/payment_mollie/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/README.md create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/const.py create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/controllers/main.py create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/data/neutralize.sql create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/payment_nuvei.pot create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/models/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/tests/test_payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/tests/test_payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/tests/test_processing_flows.py create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/views/payment_nuvei_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_nuvei/payment_nuvei/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/README.md create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/const.py create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/controllers/main.py create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/data/neutralize.sql create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/payment_paymob.pot create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/models/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/tests/test_paymob.py create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/views/payment_paymob_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_paymob/payment_paymob/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/README.md create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/const.py create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/controllers/main.py create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/data/neutralize.sql create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/af.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/am.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/bs.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/es_CL.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/eu.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/fo.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/fr_CA.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/gl.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/gu.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/is.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/ka.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/kab.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/km.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/lb.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/lo.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/lv.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/mk.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/payment_paypal.pot create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/sk.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/sq.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/models/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/static/src/interactions/payment_button.js create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/static/src/interactions/payment_form.js create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/tests/test_paypal.py create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/utils.py create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/views/payment_form_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_paypal/payment_paypal/views/payment_transaction_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/README.md create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/const.py create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/controllers/main.py create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/controllers/onboarding.py create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/data/neutralize.sql create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/payment_razorpay.pot create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/models/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/models/payment_token.py create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/static/src/interactions/payment_form.js create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/tests/test_payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/tests/test_payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/tests/test_processing_flows.py create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_razorpay/payment_razorpay/views/payment_razorpay_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/README.md create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/const.py create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/controllers/main.py create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/data/neutralize.sql create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/payment_redsys.pot create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/models/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/tests/test_payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/tests/test_processing_flows.py create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_redsys/payment_redsys/views/payment_redsys_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/README.md create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/const.py create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/controllers/main.py create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/controllers/onboarding.py create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/data/neutralize.sql create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/bs.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/gu.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/is.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/km.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/lb.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/lv.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/payment_stripe.pot create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/sk.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/models/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/models/payment_token.py create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/static/files/apple-developer-merchantid-domain-association create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/static/src/interactions/express_checkout.js create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/static/src/interactions/payment_form.js create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/static/src/js/stripe_options.js create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/static/src/scss/payment_stripe_templates.scss create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/tests/test_refund_flows.py create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/tests/test_stripe.py create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/utils.py create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/views/payment_stripe_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_stripe/payment_stripe/views/payment_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/README.md create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/const.py create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/controllers/main.py create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/data/neutralize.sql create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/payment_worldline.pot create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/models/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/static/src/interactions/payment_form.js create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/tests/test_worldline.py create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_worldline/payment_worldline/views/payment_worldline_templates.xml create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/README.md create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/__manifest__.py create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/const.py create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/controllers/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/controllers/main.py create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/data/neutralize.sql create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/data/payment_provider_data.xml create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ar.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/az.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/bg.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ca.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/cs.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/da.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/de.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/el.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/es.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/es_419.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/et.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/fa.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/fi.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/fr.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/he.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/hi.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/hr.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/hu.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/id.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/it.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ja.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ko.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ku.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/lt.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/mn.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/my.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/nb.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/nl.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/payment_xendit.pot create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/pl.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/pt.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/pt_BR.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ro.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ru.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/sl.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/sr@latin.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/sv.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/th.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/tr.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/uk.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/vi.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/zh_CN.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/zh_TW.po create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/models/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/models/payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/models/payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/description/icon.png create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/description/icon.svg create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/src/interactions/payment_form.js create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/src/js/auth_service.js create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/src/js/auth_ui.js create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/tests/__init__.py create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/tests/common.py create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/tests/test_payment_provider.py create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/tests/test_payment_transaction.py create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/tests/test_processing_flows.py create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/views/payment_provider_views.xml create mode 100644 odoo-bringout-oca-ocb-payment_xendit/payment_xendit/views/payment_xendit_templates.xml diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/__init__.py b/odoo-bringout-oca-ocb-iot_base/iot_base/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/__manifest__.py b/odoo-bringout-oca-ocb-iot_base/iot_base/__manifest__.py new file mode 100644 index 00000000..65020ce0 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/__manifest__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + + +{ + 'name': 'IoT Base', + 'version': '1.0', + 'category': 'Hidden', + 'description': """ +Base tools required by all IoT related modules. +=============================================== +""", + 'depends': ['web'], + 'installable': True, + 'author': 'Odoo S.A.', + 'license': 'LGPL-3', + 'assets': { + 'web.assets_backend': [ + 'iot_base/static/src/network_utils/*', + 'iot_base/static/src/device_controller.js', + ], + }, +} diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ar.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ar.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ar.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/az.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/az.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/az.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/bg.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/bg.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/bg.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ca.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ca.po new file mode 100644 index 00000000..1569dc49 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ca.po @@ -0,0 +1,32 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +# "Noemi Pla Garcia (nopl)" , 2025. +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-24 19:23+0000\n" +"Last-Translator: \"Noemi Pla Garcia (nopl)\" \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.12.2\n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "Ha fallat la connexió a la IoT Box" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/cs.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/cs.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/cs.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/da.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/da.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/da.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/de.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/de.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/de.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/el.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/el.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/el.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/es.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/es.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/es.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/es_419.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/es_419.po new file mode 100644 index 00000000..a8e8c2b2 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/es_419.po @@ -0,0 +1,32 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +# "Patricia Gutiérrez (pagc)" , 2025. +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-18 19:00+0000\n" +"Last-Translator: \"Patricia Gutiérrez (pagc)\" \n" +"Language-Team: Spanish (Latin America) \n" +"Language: es_419\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.12.2\n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "Falló la conexión a la caja IoT" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "No fue posible contactar a la caja IoT en %s" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/et.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/et.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/et.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/fa.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/fa.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/fa.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/fi.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/fi.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/fi.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/fr.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/fr.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/fr.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/he.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/he.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/he.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/hi.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/hi.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/hi.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/hr.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/hr.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/hr.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/hu.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/hu.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/hu.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/id.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/id.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/id.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/iot_base.pot b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/iot_base.pot new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/iot_base.pot @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/it.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/it.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/it.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ja.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ja.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ja.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ko.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ko.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ko.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ku.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ku.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ku.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/lt.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/lt.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/lt.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/mn.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/mn.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/mn.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/my.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/my.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/my.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/nb.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/nb.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/nb.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/nl.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/nl.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/nl.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/pl.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/pl.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/pl.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/pt.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/pt.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/pt.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/pt_BR.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/pt_BR.po new file mode 100644 index 00000000..bc0c7325 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/pt_BR.po @@ -0,0 +1,32 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +# "Maitê Dietze (madi)" , 2025. +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-24 19:23+0000\n" +"Last-Translator: \"Maitê Dietze (madi)\" \n" +"Language-Team: Portuguese (Brazil) \n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 5.12.2\n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "Conexão ao IoT Box falhou" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "Não foi possível contatar a IoT Box em %s" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ro.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ro.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ro.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ru.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ru.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/ru.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/sl.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/sl.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/sl.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/sr@latin.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/sr@latin.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/sr@latin.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/sv.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/sv.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/sv.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/th.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/th.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/th.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/tr.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/tr.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/tr.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/uk.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/uk.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/uk.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/vi.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/vi.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/vi.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/zh_CN.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/zh_CN.po new file mode 100644 index 00000000..ba6846c9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/zh_CN.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-11 13:57+0000\n" +"PO-Revision-Date: 2025-09-11 13:57+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/zh_TW.po b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/zh_TW.po new file mode 100644 index 00000000..a4ad3b2c --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/i18n/zh_TW.po @@ -0,0 +1,32 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * iot_base +# +# Translators: +# Wil Odoo, 2025 +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server saas~18.3\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-05-09 20:36+0000\n" +"PO-Revision-Date: 2025-05-17 15:02+0000\n" +"Last-Translator: Wil Odoo, 2025\n" +"Language-Team: Chinese (Taiwan) (https://app.transifex.com/odoo/teams/41243/zh_TW/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: zh_TW\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Connection to IoT Box failed" +msgstr "連接到IoT Box失敗" + +#. module: iot_base +#. odoo-javascript +#: code:addons/iot_base/static/src/network_utils/longpolling.js:0 +msgid "Failed to reach IoT Box at %s" +msgstr "" diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/static/src/@types/services.d.ts b/odoo-bringout-oca-ocb-iot_base/iot_base/static/src/@types/services.d.ts new file mode 100644 index 00000000..901e4898 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/static/src/@types/services.d.ts @@ -0,0 +1,7 @@ +declare module "services" { + import { iotLongpollingService } from "@iot_base/network_utils/longpolling"; + + export interface Services { + iot_longpolling: typeof iotLongpollingService + } +} diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/static/src/device_controller.js b/odoo-bringout-oca-ocb-iot_base/iot_base/static/src/device_controller.js new file mode 100644 index 00000000..6724abac --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/static/src/device_controller.js @@ -0,0 +1,40 @@ +import { uniqueId } from "@web/core/utils/functions"; + +/** + * Used to communicate to the iot devices. + */ +export class DeviceController { + /** + * @param {import("@iot_base/network_utils/longpolling").IoTLongpolling} iotLongpolling + * @param {{ iot_ip: string, identifier: string, iot_id: Object, manual_measurement: string }} deviceInfo - Representation of an iot device + */ + constructor(iotLongpolling, deviceInfo) { + this.id = uniqueId('listener-'); + this.iotIp = deviceInfo.iot_ip; + this.identifier = deviceInfo.identifier; + this.iotId = deviceInfo.iot_id?.id; // if class is instantiated without providing the full device record, iot_id will be undefined + this.manual_measurement = deviceInfo.manual_measurement; + this.iotLongpolling = iotLongpolling; + } + + /** + * Send an action to the device. + * @param data - action to send to the device + * @param fallback - if true, no notification will be displayed on fail + */ + action(data, fallback = false) { + return this.iotLongpolling.action(this.iotIp, this.identifier, data, fallback); + } + + /** + * Add a listener to the device. + * @param callback - function to call when the listener is triggered + * @param fallback - if true, no notification will be displayed on fail + */ + addListener(callback, fallback = true) { + return this.iotLongpolling.addListener(this.iotIp, [this.identifier], this.id, callback, fallback); + } + removeListener() { + return this.iotLongpolling.removeListener(this.iotIp, this.identifier, this.id); + } +} diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/static/src/network_utils/http.js b/odoo-bringout-oca-ocb-iot_base/iot_base/static/src/network_utils/http.js new file mode 100644 index 00000000..f0d70eda --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/static/src/network_utils/http.js @@ -0,0 +1,39 @@ +import { browser } from "@web/core/browser/browser"; + +/** + * Format the endpoint to send the request to + * Used to ensure the request is sent with the same protocol as the current page + * (e.g. if the current page is HTTPS, the request will be sent to the IoT Box using HTTPS) + * @param ip IP Address of the IoT Box + * @param route Route to send the request to + * @returns {string} The formatted endpoint + */ +export function formatEndpoint(ip, route) { + const url = new URL(window.location.href); + url.search = ""; + url.hostname = ip; + url.pathname = route; + if (url.port) url.port = "8069"; + return url.toString(); +} + +/** + * Send a POST request to the IoT Box + * @param ip IP Address of the IoT Box + * @param route Endpoint to send the request to + * @param params Parameters to send with the request (optional) + * @param timeout Time before the request times out (default: 6000ms) + * @param headers HTTP headers to send with the request (optional) + * @returns {Promise} + */ +export async function post(ip, route, params = {}, timeout = 6000, headers = {}) { + const endpoint = formatEndpoint(ip, route); + const response = await browser.fetch(endpoint, { + body: JSON.stringify({'params': params}), + method: "POST", + headers: {"Content-Type": "application/json", ...headers}, + signal: AbortSignal.timeout(timeout), + }); + + return response.json(); +} diff --git a/odoo-bringout-oca-ocb-iot_base/iot_base/static/src/network_utils/longpolling.js b/odoo-bringout-oca-ocb-iot_base/iot_base/static/src/network_utils/longpolling.js new file mode 100644 index 00000000..249c25f7 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_base/iot_base/static/src/network_utils/longpolling.js @@ -0,0 +1,229 @@ +import { registry } from '@web/core/registry'; +import { post } from '@iot_base/network_utils/http'; +import { uuid } from "@web/core/utils/strings"; +import { _t } from '@web/core/l10n/translation'; + +export class IoTLongpolling { + static serviceDependencies = ["notification", "orm"]; + actionRoute = '/iot_drivers/action'; + pollRoute = '/iot_drivers/event'; + + rpcDelay = 1500; + maxRpcDelay = 15000; + + _retries = 0; + _listeners = {}; + + constructor() { + this.setup(...arguments); + } + + /** + * Setup in addition to constructor to allow patching + */ + setup({ notification, orm }) { + this._session_id = uuid(); + this._delayedStartPolling(this.rpcDelay); + this.notification = notification; + this.orm = orm; + } + + /** + * Add a device_identifier to listeners[iot_ip] and restart polling + * + * @param {string} iot_ip + * @param {Array} devices list of devices + * @param {string} listener_id + * @param {boolean} fallback if true, no notification will be displayed on fail + * @param {Callback} callback + */ + async addListener(iot_ip, devices, listener_id, callback, fallback = true) { + if (!this._listeners[iot_ip]) { + this._listeners[iot_ip] = { + last_event: 0, + devices: {}, + session_id: this._session_id, + rpc: false, + }; + } + for (const device of devices) { + this._listeners[iot_ip].devices[device] = { + listener_id: listener_id, + device_identifier: device, + callback: callback, + }; + } + this.stopPolling(iot_ip); + this.startPolling(iot_ip, fallback); + } + + /** + * Stop listening to iot device with id `device_identifier` + * @param {string} iot_ip + * @param {string} device_identifier + * @param {string} listener_id + */ + removeListener(iot_ip, device_identifier, listener_id) { + const device = this._listeners[iot_ip].devices[device_identifier]; + if (device && device.listener_id === listener_id) { + delete this._listeners[iot_ip].devices[device_identifier]; + } + } + + /** + * Execute an action on device_identifier + * Action depends on the driver that supports the device + * + * @param {string} iot_ip + * @param {string} device_identifier + * @param {Object} data contains the information needed to perform an action on this device_identifier + * @param {boolean} fallback if true, no notification will be displayed on fail + * @param {string} route endpoint to call on the IoT Box (default: /iot_drivers/action) + */ + action(iot_ip, device_identifier, data, fallback = false, route = null) { + this.protocol = window.location.protocol; + const body = { + session_id: this._session_id, + device_identifier: device_identifier, + data, + }; + return this._rpcIoT(iot_ip, route || this.actionRoute, body, undefined, fallback); + } + + /** + * Start a long polling, i.e. it continually opens a long poll + * connection as long as it is not stopped (@see `stopPolling`) + * @param {string} iot_ip + * @param {boolean} fallback if true, no notification will be displayed on fail + */ + startPolling(iot_ip, fallback = true) { + if (iot_ip) { + if (!this._listeners[iot_ip].rpc) { + this._poll(iot_ip, fallback); + } + } else { + const self = this; + Object.keys(this._listeners).forEach((ip) => { + self.startPolling(ip); + }); + } + } + + /** + * Stops any started long polling + * + * Aborts a pending long-poll so that we immediately remove ourselves + * from listening on notifications on this channel. + */ + stopPolling(iot_ip) { + if (this._listeners[iot_ip].rpc) { + this._listeners[iot_ip].rpc.abort(); + this._listeners[iot_ip].rpc = false; + } + } + + _delayedStartPolling(delay) { + // ``fallback: true`` to avoid error notification on longpolling setup + setTimeout(() => this.startPolling(null, true), delay); + } + + /** + * Execute an RPC to the box + * Used to do both polling or action + * + * @param {string} iot_ip IP of the IoT Box + * @param {string} route endpoint to call on the IoT Box + * @param {Object} params information needed to perform an action or the listener for the polling + * @param {number} timeout time before the request times out (undefined to use default timeout from http.js) + * @param {boolean} fallback if true, no notification will be displayed on fail + * @param {Object} headers headers to send with the request (optional, allows patching) + */ + async _rpcIoT(iot_ip, route, params, timeout = undefined, fallback = false, headers = undefined) { + try { + const result = await post(iot_ip, route, params, timeout, headers); + + if (this._listeners[iot_ip] && route === this.pollRoute) { + this._listeners[iot_ip].rpc = result; + return this._listeners[iot_ip].rpc; + } else { + return result; + } + } catch { + if (!fallback) { + this._doWarnFail(iot_ip); + } + throw new Error("Longpolling action failed"); + } + } + + /** + * Make a poll request to an IoT Box + * + * @param {string} iot_ip + * @param {boolean} fallback if true, no notification will be displayed on fail + */ + _poll(iot_ip, fallback = true) { + const listener = this._listeners[iot_ip]; + + // The backend has a maximum cycle time of 50 seconds so give +10 seconds + this._rpcIoT(iot_ip, this.pollRoute, { listener: listener }, 60000, fallback).then( + (result) => { + this._retries = 0; + this._listeners[iot_ip].rpc = false; + const remainingDevices = Object.keys(this._listeners[iot_ip].devices || {}); + if (result.result) { + if (this._session_id === result.result.session_id) { + this._onSuccess(iot_ip, result.result); + } + } else if (remainingDevices.length > 0) { + this._poll(iot_ip); + } + }, + (e) => { + if (e.name === "TimeoutError") { + this._onError(); + } + } + ); + } + + _onSuccess(iot_ip, result) { + this._listeners[iot_ip].last_event = result.time; + + const devices = this._listeners[iot_ip].devices; + devices[result.device_identifier]?.callback(result); + + if (Object.keys(devices || {}).length > 0) { + this._poll(iot_ip); + } + this._retries = 0; + } + + _onError() { + this._retries++; + this._delayedStartPolling(Math.min(this.rpcDelay * this._retries, this.maxRpcDelay)); + } + + /** + * This method is needed in _poll. + * @param {string} url + */ + _doWarnFail(url) { + this.notification.add( + _t("Failed to reach IoT Box at %s", url), + { + title: _t("Connection to IoT Box failed"), + type: "danger", + } + ); + } +} + +export const iotLongpollingService = { + dependencies: IoTLongpolling.serviceDependencies, + start(_, deps) { + return new IoTLongpolling(deps); + }, +}; + +registry.category('services').add('iot_longpolling', iotLongpollingService); diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/.gitignore b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/.gitignore new file mode 100644 index 00000000..9821e546 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/.gitignore @@ -0,0 +1,3 @@ +root_mount/ +*.img +**/ngrok diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/__init__.py b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/__manifest__.py b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/__manifest__.py new file mode 100644 index 00000000..c2256395 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/__manifest__.py @@ -0,0 +1,9 @@ +{ + 'name': 'IoT Box Image Build Tools', + 'category': 'Hidden/Tools', + 'summary': 'Build tools for the IoT Box image', + 'description': "This module allows you to build an image for the IoT Box.", + 'installable': False, + 'author': 'Odoo S.A.', + 'license': 'LGPL-3', +} diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_image.sh b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_image.sh new file mode 100755 index 00000000..fd7fcd8d --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_image.sh @@ -0,0 +1,94 @@ +#!/usr/bin/env bash +set -o errexit +set -o nounset +set -o pipefail +# set -o xtrace + +__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +source ${__dir}/build_utils/methods.sh # Load useful functions + +ensure_root # Check if script is run as root, exit if not + +require_command losetup +require_command qemu-arm-static +require_command zerofree + +MOUNT_POINT="${__dir}/root_mount" +OVERWRITE_FILES_BEFORE_INIT_DIR="${__dir}/overwrite_before_init" +OVERWRITE_FILES_AFTER_INIT_DIR="${__dir}/overwrite_after_init" +BUILD_UTILS_DIR="${__dir}/build_utils" +VERSION_IOTBOX="$(date '+%y.%m')" + +if [[ "${1:-}" == "-c" || "${1:-}" == "--cleanup" ]]; then + echo "Cleaning up..." + umount -fv "${MOUNT_POINT}/boot/" > /dev/null 2>&1 || true + umount -lv "${MOUNT_POINT}" > /dev/null 2>&1 || true + rm -rfv "${MOUNT_POINT}" + rm -rf overwrite_before_init/usr + rm -rf overwrite_before_init/home/pi/odoo + rm -rfv iotbox.img + losetup -d /dev/loop0 > /dev/null 2>&1 || true + losetup -d /dev/loop1 > /dev/null 2>&1 || true + echo "Cleanup done." + exit 0 +fi + +# Download and extract Raspberry Pi OS, ngrok and clone Odoo repository +source ${BUILD_UTILS_DIR}/download_requirements.sh "${__dir}" + +# Clone the Raspberry Pi OS image into the IoT Box image. +rsync -avh --progress "${RASPIOS}" iotbox.img + +# Prepare the image for the IoT Box system: partition and format. +# source to share variables +source ${BUILD_UTILS_DIR}/partition_image.sh "iotbox.img" + +# Mount system partition and customize the active system +mkdir -pv "${MOUNT_POINT}" +mount -v "${LOOP_IOT_SYS}" "${MOUNT_POINT}" +mount -v "${LOOP_IOT_BOOT}" "${MOUNT_POINT}/boot/" + +QEMU_ARM_STATIC="/usr/bin/qemu-arm-static" +cp -v "${QEMU_ARM_STATIC}" "${MOUNT_POINT}/usr/bin/" + +# 'Overlay' the pre-init overwrite directory onto the mounted image filesystem. +cp -av "${OVERWRITE_FILES_BEFORE_INIT_DIR}"/* "${MOUNT_POINT}" + +# Reload network manager is mandatory in order to apply DNS configurations: +# it needs to be reloaded after copying the 'overwrite_before_init' files in the new image +# it needs to be performed in the classic filesystem, as 'systemctl' commands are not available in /root_bypass_ramdisks +sudo systemctl reload NetworkManager + +# generate a keypair for the IoT Box SSH Certificate Authority +mkdir -pv ./.ssh +echo "y" | ssh-keygen -t ed25519 -f "./.ssh/iotbox_ca_${VERSION_IOTBOX}" -N "" -C "Odoo SSH CA ${VERSION_IOTBOX}" +cp -v "./.ssh/iotbox_ca_${VERSION_IOTBOX}.pub" "${MOUNT_POINT}/etc/ssh/ca.pub" + +# Run initialization script inside /mount_point (the mounted path of the image) +chroot "${MOUNT_POINT}" /bin/bash -c "/etc/init_image.sh" + +# Copy IoT Box version info. +mkdir -pv "${MOUNT_POINT}/var/odoo/" +echo "${VERSION_IOTBOX}" > "${MOUNT_POINT}/var/odoo/iotbox_version" + +# 'Overlay' the post-init overwrite directory onto the mounted image filesystem. +cp -a "${OVERWRITE_FILES_AFTER_INIT_DIR}"/* "${MOUNT_POINT}" + +# Unmount partitions: zerofree needs partitions to be unmounted (or mounted as read-only) +umount -fv "${MOUNT_POINT}"/boot/ +umount -lv "${MOUNT_POINT}"/ + +echo "Running zerofree..." +zerofree -v "${LOOP_IOT_SYS}" || true + +sleep 10 + +# Final cleanup: unmount partitions and remove loop device mappings +rm -rf "${CLONE_DIR}" +rm -rf "${OVERWRITE_FILES_BEFORE_INIT_DIR}/usr" +rm -rfv "${MOUNT_POINT}" +losetup -d ${LOOP_IOT} + +echo "" +echo "Image build finished, you'll find the certificate authority keypair at './.ssh/iotbox_ca_${VERSION_IOTBOX}'" diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_utils/download_requirements.sh b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_utils/download_requirements.sh new file mode 100755 index 00000000..13ccb1f0 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_utils/download_requirements.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +set -o errexit +set -o nounset +set -o pipefail + +require_command git +require_command tar +require_command unxz +require_command unzip +require_command wget + +__dir=$1 + +# Ask user for branch/version and repository info +current_branch="$(git branch --show-current)" +read -p "Enter dev branch [${current_branch}]: " VERSION +VERSION=${VERSION:-$current_branch} + +current_remote=$(git config branch.$current_branch.remote) +current_repo="$(git remote get-url $current_remote | sed 's/.*github.com[\/:]//' | sed 's/\/odoo.git//')" +read -p "Enter repo [${current_repo}]: " REPO +REPO="https://github.com/${REPO:-$current_repo}/odoo.git" +echo "Using repo: ${REPO}" + +CLONE_DIR="${OVERWRITE_FILES_BEFORE_INIT_DIR}/home/pi/odoo" +if [ ! -d "$CLONE_DIR" ]; then + echo "Clone GitHub repo" + mkdir -pv "${CLONE_DIR}" + git clone -b ${VERSION} --no-local --no-checkout --depth=1 ${REPO} "${CLONE_DIR}" + cd "${CLONE_DIR}" + git config core.sparsecheckout true + tee -a .git/info/sparse-checkout < "${BUILD_UTILS_DIR}/sparse-checkout" > /dev/null + git read-tree -mu HEAD + git remote set-url origin "https://github.com/odoo/odoo.git" # ensure remote is the original repo +fi +cd "${__dir}" + +# Download and extract the Raspberry Pi OS image if not present. +if ! file_exists *raspios*.img ; then + wget "https://downloads.raspberrypi.com/raspios_lite_armhf/images/raspios_lite_armhf-2024-11-19/2024-11-19-raspios-bookworm-armhf-lite.img.xz" -O raspios.img.xz + unxz --verbose raspios.img.xz +fi +RASPIOS=$(echo *raspios*.img) + +# Download ngrok for ARM and place it in the overwrite directory. +USR_BIN="${OVERWRITE_FILES_BEFORE_INIT_DIR}/usr/bin/" +mkdir -pv "${USR_BIN}" +if ! file_exists "${USR_BIN}/ngrok" ; then + wget -O /tmp/ngrok.tgz 'https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-arm.tgz' + tar xvzf /tmp/ngrok.tgz -C "${USR_BIN}" --remove-files +fi diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_utils/methods.sh b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_utils/methods.sh new file mode 100755 index 00000000..7b1c598d --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_utils/methods.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -o errexit +set -o nounset +set -o pipefail + +ensure_root() { + if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root" + exit 1 + fi +} + +file_exists() { + [[ -f $1 ]]; +} + +require_command() { + type "$1" &> /dev/null || { + echo "Command $1 is missing. Install it (e.g. with 'apt-get install $1'). Aborting." >&2; + exit 1; + } +} diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_utils/partition_image.sh b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_utils/partition_image.sh new file mode 100755 index 00000000..b7d87590 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_utils/partition_image.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +set -o errexit +set -o nounset +set -o pipefail + +ensure_root # Check if script is run as root, exit if not + +require_command fdisk +require_command losetup +require_command parted +require_command e2fsck +require_command resize2fs +require_command e2label + +IOTBOX=$1 + +# Enlarge the image (zero-pad). Sector size is 512 bytes (checked with: sudo fdisk -l raspios.img). +# Note that we can dd using bigger sector size to speed up the process, but we need to be careful with the amount of sectors. +# +# We want to add 2.75GiB to the system partition to have enough space to install programs: +# x (MiB) * 1024 * 1024 / 512 = y (sectors) <=> x (GiB) * 2048 = y (sectors) +# e.g. (2.75 * 1024) MiB * 2048 = 5.5M (sectors) +echo "Enlarging the image..." +SYSTEM_INCREASE_MiB=2816 # 2.75GiB * 1024 = 2816MiB, using MiB to avoid floating numbers +SYSTEM_INCREASE_AMOUNT_SECTORS=$((SYSTEM_INCREASE_MiB * 2048)) # sectors +dd if=/dev/zero of="./${IOTBOX}" bs=512 count=${SYSTEM_INCREASE_AMOUNT_SECTORS} status=progress conv=notrunc oflag=append + +# Map partitions from the IoT Box image to loop devices (/dev/loop1pX). +LOOP_IOT=$(losetup -Pf --show ${IOTBOX}) +LOOP_IOT_BOOT="${LOOP_IOT}p1)" # /dev/loop1p1 +LOOP_IOT_SYS="${LOOP_IOT}p2" # /dev/loop1p2 +echo "Loop devices for ${IOTBOX}:" +echo " Boot: ${LOOP_IOT_BOOT}" +echo " System: ${LOOP_IOT_SYS}" + +# Resize the system partition to make it bigger: +# We take the last sector of the raspbian image, and add the amount of sectors of the increase (gives us the end sector). +SYSTEM_END_SECTOR=$(fdisk -l ${IOTBOX} | grep "${IOTBOX}2" | awk '{print $3}') +NEW_END_SECTOR_SYSTEM=$((SYSTEM_END_SECTOR + SYSTEM_INCREASE_AMOUNT_SECTORS - 1)) +parted -s ${LOOP_IOT} resizepart 2 "${NEW_END_SECTOR_SYSTEM}s" + +# We need to remap the whole image to resize the filesystem taking changes into account. +losetup -d ${LOOP_IOT} +LOOP_IOT=$(losetup -Pf --show ${IOTBOX}) +LOOP_IOT_BOOT="${LOOP_IOT}p1" # /dev/loop1p1 +LOOP_IOT_SYS="${LOOP_IOT}p2" # /dev/loop1p2 + +# Format and resize system partition filesystem. +e2fsck -fvy ${LOOP_IOT_SYS} +resize2fs ${LOOP_IOT_SYS} + +# Rename the system partition (optional but cool). +e2label ${LOOP_IOT_SYS} iotboxfs diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_utils/sparse-checkout b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_utils/sparse-checkout new file mode 100644 index 00000000..25fe5834 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/build_utils/sparse-checkout @@ -0,0 +1,9 @@ +addons/web +addons/iot_base +addons/iot_box_image/configuration +addons/iot_drivers +addons/hw_drivers +addons/hw_posbox_homepage +addons/point_of_sale/tools/posbox/configuration +odoo/ +odoo-bin diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/aiortc-1.4.0-py3-none-any.whl b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/aiortc-1.4.0-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..d8cccf577e25c8b48be0f07733cce7fd3f5307cf GIT binary patch literal 84454 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
UYr9g?nEq7!@ZnW-O|l$6?;kw)NzZ(@~~#G8X+* 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 literal 0 HcmV?d00001 diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/led_manager.sh b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/led_manager.sh new file mode 100755 index 00000000..b34c6651 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/led_manager.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +STATUS_UPDATE_DELAY_SECONDS=10 + +GREEN_LED="/sys/class/leds/ACT/trigger" +RED_LED="/sys/class/leds/PWR/trigger" + +IS_PI5=false +if grep -q "Raspberry Pi 5" /proc/device-tree/model 2>/dev/null; then + IS_PI5=true +fi + +led_off() { + if $IS_PI5 && [ "$1" == "$GREEN_LED" ]; then + echo "default-on" > "$1" + else + echo "none" > "$1" + fi +} + +led_constant() { + if $IS_PI5 && [ "$1" == "$GREEN_LED" ]; then + echo "none" > "$1" + else + echo "default-on" > "$1" + fi +} + +led_blink() { + echo "heartbeat" > "$1" +} + +# Disable both LEDs initially +led_off "$GREEN_LED" +led_off "$RED_LED" + +while true; do + sleep $STATUS_UPDATE_DELAY_SECONDS + if ! ping -q -c 1 -W 2 1.1.1.1 >/dev/null; then + # No network: blink red LED, (green stays off) + led_blink "$RED_LED" + led_off "$GREEN_LED" + continue + fi + + if ! systemctl is-active --quiet odoo.service; then + # Odoo service is not running: Red ON, Green OFF + led_constant "$RED_LED" + led_off "$GREEN_LED" + continue + fi + + if grep -q "remote_server" /home/pi/odoo.conf 2>/dev/null; then + # Paired with database: Green ON, Red OFF + led_constant "$GREEN_LED" + led_off "$RED_LED" + else + # Not paired: blink green LED (red stays off) + led_blink "$GREEN_LED" + led_off "$RED_LED" + fi +done diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/odoo.conf b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/odoo.conf new file mode 100644 index 00000000..369ea747 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/odoo.conf @@ -0,0 +1,11 @@ +[options] +data_dir = /var/run/odoo +log_handler = :INFO,werkzeug:WARNING +log_level = info +pidfile = /var/run/odoo/odoo.pid +limit_time_cpu = 600 +limit_time_real = 1200 +max_cron_threads = 0 +server_wide_modules=iot_drivers,web +list_db = False +http_interface = 0.0.0.0 diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/packages.txt b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/packages.txt new file mode 100644 index 00000000..7e5664dc --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/packages.txt @@ -0,0 +1,64 @@ +arp-scan +chromium-browser +console-data +cups +cups-ipp-utils +dbus +dnsmasq +fswebcam +git +hostapd +iw +kpartx +labwc +localepurge +mtr +nginx-full +printer-driver-all +python3 +python3-aioice +python3-crc32c +python3-cryptography +python3-cups +python3-babel +python3-dateutil +python3-dbus +python3-docutils +python3-evdev +python3-jinja2 +python3-libcamera +python3-netifaces +python3-num2words +python3-openssl +python3-passlib +python3-pil +python3-pip +python3-polib +python3-psutil +python3-psycopg2 +python3-pyee +python3-pylibsrtp +python3-pykcs11 +python3-pypdf2 +python3-pyudev +python3-qrcode +python3-reportlab +python3-requests +python3-rjsmin +python3-schedule +python3-screeninfo +python3-serial +python3-urllib3 +python3-usb +python3-vobject +python3-werkzeug +python3-zeep +python3-zeroconf +rsync +screen +seatd +swaybg +vim +wlr-randr +wtype +xdotool diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/requirements.txt b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/requirements.txt new file mode 100644 index 00000000..a03cde33 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/requirements.txt @@ -0,0 +1,20 @@ +# The following requirements are needed only on Raspberry Pi IoT: +gatt; sys_platform == "linux" and "rpi" in platform_release +/home/pi/odoo/addons/iot_box_image/configuration/aiortc-1.4.0-py3-none-any.whl; sys_platform == "linux" and "rpi" in platform_release + +# The following requirements are needed only on Windows Virtual IoT: +aiortc==1.4.0; sys_platform == "win32" +ghostscript==0.7; sys_platform == "win32" +decorator; sys_platform == "win32" + +# The following requirements are needed on every platforms, but are installed +# via apt-get on the Raspberry Pi: +PyKCS11==1.5.16; sys_platform == "win32" +schedule==1.2.1; sys_platform == "win32" + +# The following requirements are needed on every platforms: +python-escpos==3.1 +websocket-client==1.6.3 + +# The following requirements are needed only on Test IoT server: +./addons/iot_box_image/configuration/aiortc-1.4.0-py3-none-any.whl; sys_platform == "linux" and "rpi" not in platform_release diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/setup_ramdisks.sh b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/setup_ramdisks.sh new file mode 100755 index 00000000..c3404588 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/configuration/setup_ramdisks.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +set -o errexit +set -o nounset +set -o pipefail +# set -o xtrace + +create_ramdisk () { + ORIGINAL="${1}" + RAMDISK="${ORIGINAL}_ram" + SIZE="${2}" + echo "Creating ramdisk for ${1} of size ${SIZE}..." + + mount -t tmpfs -o size="${SIZE}" tmpfs "${RAMDISK}" + rsync -a --exclude="swap" --exclude="apt" --exclude="dpkg" --exclude=".mozilla" "${ORIGINAL}/" "${RAMDISK}/" + mount --bind "${RAMDISK}" "${ORIGINAL}" +} + +echo "Creating ramdisks..." +# Note: As of 2025 we are using 2 Gb ram rpi4 as basic IoT Boxes. +# The 2 Gb limit applies here +create_ramdisk "/var" "512M" +create_ramdisk "/etc" "64M" +create_ramdisk "/tmp" "1G" # big size necessary for chromium kiosk usage + +# bind mount / so that we can get to the real /var and /etc +mount --bind / /root_bypass_ramdisks + +# allow to cups server to save configuration file of printers +mount --bind /root_bypass_ramdisks/etc/cups /root_bypass_ramdisks/etc/cups diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/cups/cups-files.conf b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/cups/cups-files.conf new file mode 100644 index 00000000..31864e16 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/cups/cups-files.conf @@ -0,0 +1,93 @@ +# +# File/directory/user/group configuration file for the CUPS scheduler. +# See "man cups-files.conf" for a complete description of this file. +# + +# List of events that are considered fatal errors for the scheduler... +#FatalErrors config + +# Do we call fsync() after writing configuration or status files? +#SyncOnClose Yes + +# Default user and group for filters/backends/helper programs; this cannot be +# any user or group that resolves to ID 0 for security reasons... +#User lp +#Group lp + +# Administrator user group, used to match @SYSTEM in cupsd.conf policy rules... +# This cannot contain the Group value for security reasons... +SystemGroup lpadmin pi + + +# User that is substituted for unauthenticated (remote) root accesses... +#RemoteRoot remroot + +# Do we allow file: device URIs other than to /dev/null? +#FileDevice No + +# Permissions for configuration and log files... +#ConfigFilePerm 0640 +#LogFilePerm 00640 + +# Location of the file logging all access to the scheduler; may be the name +# "syslog". If not an absolute path, the value of ServerRoot is used as the +# root directory. Also see the "AccessLogLevel" directive in cupsd.conf. +AccessLog /var/log/cups/access_log + +# Location of cache files used by the scheduler... +#CacheDir /var/cache/cups + +# Location of data files used by the scheduler... +#DataDir /usr/share/cups + +# Location of the static web content served by the scheduler... +#DocumentRoot /usr/share/cups/doc-root + +# Location of the file logging all messages produced by the scheduler and any +# helper programs; may be the name "syslog". If not an absolute path, the value +# of ServerRoot is used as the root directory. Also see the "LogLevel" +# directive in cupsd.conf. +ErrorLog /var/log/cups/error_log + +# Location of fonts used by older print filters... +#FontPath /usr/share/cups/fonts + +# Location of LPD configuration +#LPDConfigFile + +# Location of the file logging all pages printed by the scheduler and any +# helper programs; may be the name "syslog". If not an absolute path, the value +# of ServerRoot is used as the root directory. Also see the "PageLogFormat" +# directive in cupsd.conf. +PageLog /var/log/cups/page_log + +# Location of the file listing all of the local printers... +#Printcap /run/cups/printcap + +# Format of the Printcap file... +#PrintcapFormat bsd +#PrintcapFormat plist +#PrintcapFormat solaris + +# Location of all spool files... +#RequestRoot /var/spool/cups + +# Location of helper programs... +#ServerBin /usr/lib/cups + +# SSL/TLS keychain for the scheduler... +#ServerKeychain ssl + +# Location of other configuration files... +ServerRoot /root_bypass_ramdisks/etc/cups + +# Location of Samba configuration file... +#SMBConfigFile + +# Location of scheduler state files... +#StateDir /run/cups + +# Location of scheduler/helper temporary files. This directory is emptied on +# scheduler startup and cannot be one of the standard (public) temporary +# directory locations for security reasons... +#TempDir /var/spool/cups/tmp diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/cups/cupsd.conf b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/cups/cupsd.conf new file mode 100644 index 00000000..14ca7120 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/cups/cupsd.conf @@ -0,0 +1,186 @@ +# +# Configuration file for the CUPS scheduler. See "man cupsd.conf" for a +# complete description of this file. +# + +# Log general information in error_log - change "warn" to "debug" +# for troubleshooting... +LogLevel warn +PageLogFormat + +# Deactivate CUPS' internal logrotating, as we provide a better one, especially +# LogLevel debug2 gets usable now +MaxLogSize 0 + +# Only listen for connections from the local machine. +Listen 0.0.0.0:631 +Listen /run/cups/cups.sock + +# Show shared printers on the local network. +Browsing On +BrowseLocalProtocols dnssd + +# Local printers are not shared by default +DefaultShared No + +# Default authentication type, when authentication is required... +DefaultAuthType Basic + +# Web interface setting... +WebInterface Yes + +# Default paper size depends on the printer +DefaultPaperSize None + +# Restrict access to the server... + + Order allow,deny + Allow all + + +# Restrict access to the admin pages... + + Order allow,deny + Allow all + + +# Restrict access to configuration files... + + Order allow,deny + Allow all + + +# Restrict access to log files... + + Order allow,deny + Allow all + + +# Set the default printer/job policies... + + # Job/subscription privacy... + JobPrivateAccess default + JobPrivateValues default + SubscriptionPrivateAccess default + SubscriptionPrivateValues default + + # Job-related operations must be done by the owner or an administrator... + + Order allow,deny + Allow all + + + + Order allow,deny + Allow all + + + # All administration operations require an administrator to authenticate... + + Order allow,deny + Allow all + + + # All printer operations require a printer operator to authenticate... + + Order allow,deny + Allow all + + + # Only the owner or an administrator can cancel or authenticate a job... + + Order allow,deny + Allow all + + + + Order allow,deny + Allow all + + + +# Set the authenticated printer/job policies... + + # Job/subscription privacy... + JobPrivateAccess default + JobPrivateValues default + SubscriptionPrivateAccess default + SubscriptionPrivateValues default + + # Job-related operations must be done by the owner or an administrator... + + Order allow,deny + Allow all + + + + Order allow,deny + Allow all + + + # All administration operations require an administrator to authenticate... + + Order allow,deny + Allow all + + + # All printer operations require a printer operator to authenticate... + + Order allow,deny + Allow all + + + # Only the owner or an administrator can cancel or authenticate a job... + + Order allow,deny + Allow all + + + + Order allow,deny + Allow all + + + +# Set the kerberized printer/job policies... + + # Job/subscription privacy... + JobPrivateAccess default + JobPrivateValues default + SubscriptionPrivateAccess default + SubscriptionPrivateValues default + + # Job-related operations must be done by the owner or an administrator... + + Order allow,deny + Allow all + + + + Order allow,deny + Allow all + + + # All administration operations require an administrator to authenticate... + + Order allow,deny + Allow all + + + # All printer operations require a printer operator to authenticate... + + Order allow,deny + Allow all + + + # Only the owner or an administrator can cancel or authenticate a job... + + Order allow,deny + Allow all + + + + Order allow,deny + Allow all + + \ No newline at end of file diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/default/hostapd b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/default/hostapd new file mode 100644 index 00000000..7e97ae99 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/default/hostapd @@ -0,0 +1,20 @@ +# Defaults for hostapd initscript +# +# See /usr/share/doc/hostapd/README.Debian for information about alternative +# methods of managing hostapd. +# +# Uncomment and set DAEMON_CONF to the absolute path of a hostapd configuration +# file and hostapd will be started during system boot. An example configuration +# file can be found at /usr/share/doc/hostapd/examples/hostapd.conf.gz +# +DAEMON_CONF="/etc/hostapd/hostapd.conf" + +# Additional daemon options to be appended to hostapd command:- +# -d show more debug messages (-dd for even more) +# -K include key data in debug messages +# -t include timestamps in some debug messages +# +# Note that -B (daemon mode) and -P (pidfile) options are automatically +# configured by the init.d script and must not be added to DAEMON_OPTS. +# +DAEMON_OPTS="-d" diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/default/ifplugd b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/default/ifplugd new file mode 100644 index 00000000..cf433197 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/default/ifplugd @@ -0,0 +1,17 @@ +# This file may be changed either manually or by running dpkg-reconfigure. +# +# N.B.: dpkg-reconfigure deletes everything from this file except for +# the assignments to variables INTERFACES, HOTPLUG_INTERFACES, ARGS and +# SUSPEND_ACTION. When run it uses the current values of those variables +# as their default values, thus preserving the administrator's changes. +# +# This file is sourced by both the init script /etc/init.d/ifplugd and +# the udev script /lib/udev/ifplugd.agent to give default values. +# The init script starts ifplugd for all interfaces listed in +# INTERFACES, and the udev script starts ifplugd for all interfaces +# listed in HOTPLUG_INTERFACES. The special value all starts one +# ifplugd for all interfaces being present. +INTERFACES="eth0" # auto +HOTPLUG_INTERFACES="eth0" # all +ARGS="-q -f -u0 -d10 -w -I" +SUSPEND_ACTION="stop" diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/dnsmasq.conf b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/dnsmasq.conf new file mode 100644 index 00000000..3d0d0531 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/dnsmasq.conf @@ -0,0 +1,669 @@ +# Configuration file for dnsmasq. +# +# Format is one option per line, legal options are the same +# as the long options legal on the command line. See +# "/usr/sbin/dnsmasq --help" or "man 8 dnsmasq" for details. + +# Listen on this specific port instead of the standard DNS port +# (53). Setting this to zero completely disables DNS function, +# leaving only DHCP and/or TFTP. +#port=5353 + +# The following two options make you a better netizen, since they +# tell dnsmasq to filter out queries which the public DNS cannot +# answer, and which load the servers (especially the root servers) +# unnecessarily. If you have a dial-on-demand link they also stop +# these requests from bringing up the link unnecessarily. + +# Never forward plain names (without a dot or domain part) +#domain-needed +# Never forward addresses in the non-routed address spaces. +bogus-priv + +# Uncomment these to enable DNSSEC validation and caching: +# (Requires dnsmasq to be built with DNSSEC option.) +#conf-file=%%PREFIX%%/share/dnsmasq/trust-anchors.conf +#dnssec + +# Replies which are not DNSSEC signed may be legitimate, because the domain +# is unsigned, or may be forgeries. Setting this option tells dnsmasq to +# check that an unsigned reply is OK, by finding a secure proof that a DS +# record somewhere between the root and the domain does not exist. +# The cost of setting this is that even queries in unsigned domains will need +# one or more extra DNS queries to verify. +#dnssec-check-unsigned + +# Uncomment this to filter useless windows-originated DNS requests +# which can trigger dial-on-demand links needlessly. +# Note that (amongst other things) this blocks all SRV requests, +# so don't use it if you use eg Kerberos, SIP, XMMP or Google-talk. +# This option only affects forwarding, SRV records originating for +# dnsmasq (via srv-host= lines) are not suppressed by it. +#filterwin2k + +# Change this line if you want dns to get its upstream servers from +# somewhere other that /etc/resolv.conf +#resolv-file= + +# By default, dnsmasq will send queries to any of the upstream +# servers it knows about and tries to favour servers to are known +# to be up. Uncommenting this forces dnsmasq to try each query +# with each server strictly in the order they appear in +# /etc/resolv.conf +#strict-order + +# If you don't want dnsmasq to read /etc/resolv.conf or any other +# file, getting its servers from this file instead (see below), then +# uncomment this. +#no-resolv + +# If you don't want dnsmasq to poll /etc/resolv.conf or other resolv +# files for changes and re-read them then uncomment this. +#no-poll + +# Add other name servers here, with domain specs if they are for +# non-public domains. +server=/localnet/10.11.12.1 + +# Example of routing PTR queries to nameservers: this will send all +# address->name queries for 192.168.3/24 to nameserver 10.1.2.3 +#server=/3.168.192.in-addr.arpa/10.1.2.3 + +# Add local-only domains here, queries in these domains are answered +# from /etc/hosts or DHCP only. +local=/localnet/ + +# Add domains which you want to force to an IP address here. +# The example below send any host in double-click.net to a local +# web-server. +#address=/double-click.net/127.0.0.1 +address=/#/10.11.12.1 + +# --address (and --server) work with IPv6 addresses too. +#address=/www.thekelleys.org.uk/fe80::20d:60ff:fe36:f83 + +# Add the IPs of all queries to yahoo.com, google.com, and their +# subdomains to the vpn and search ipsets: +#ipset=/yahoo.com/google.com/vpn,search + +# You can control how dnsmasq talks to a server: this forces +# queries to 10.1.2.3 to be routed via eth1 +# server=10.1.2.3@eth1 + +# and this sets the source (ie local) address used to talk to +# 10.1.2.3 to 192.168.1.1 port 55 (there must be a interface with that +# IP on the machine, obviously). +# server=10.1.2.3@192.168.1.1#55 + +# If you want dnsmasq to change uid and gid to something other +# than the default, edit the following lines. +#user= +#group= + +# If you want dnsmasq to listen for DHCP and DNS requests only on +# specified interfaces (and the loopback) give the name of the +# interface (eg eth0) here. +# Repeat the line for more than one interface. +interface=wlan0 +# Or you can specify which interface _not_ to listen on +#except-interface= +# Or which to listen on by address (remember to include 127.0.0.1 if +# you use this.) +#listen-address= +# If you want dnsmasq to provide only DNS service on an interface, +# configure it as shown above, and then use the following line to +# disable DHCP and TFTP on it. +#no-dhcp-interface= + +# On systems which support it, dnsmasq binds the wildcard address, +# even when it is listening on only some interfaces. It then discards +# requests that it shouldn't reply to. This has the advantage of +# working even when interfaces come and go and change address. If you +# want dnsmasq to really bind only the interfaces it is listening on, +# uncomment this option. About the only time you may need this is when +# running another nameserver on the same machine. +#bind-interfaces + +# If you don't want dnsmasq to read /etc/hosts, uncomment the +# following line. +#no-hosts +# or if you want it to read another file, as well as /etc/hosts, use +# this. +#addn-hosts=/etc/banner_add_hosts + +# Set this (and domain: see below) if you want to have a domain +# automatically added to simple names in a hosts-file. +#expand-hosts + +# Set the domain for dnsmasq. this is optional, but if it is set, it +# does the following things. +# 1) Allows DHCP hosts to have fully qualified domain names, as long +# as the domain part matches this setting. +# 2) Sets the "domain" DHCP option thereby potentially setting the +# domain of all systems configured by DHCP +# 3) Provides the domain part for "expand-hosts" +#domain=thekelleys.org.uk + +# Set a different domain for a particular subnet +#domain=wireless.thekelleys.org.uk,192.168.2.0/24 + +# Same idea, but range rather then subnet +#domain=reserved.thekelleys.org.uk,192.68.3.100,192.168.3.200 + +# Uncomment this to enable the integrated DHCP server, you need +# to supply the range of addresses available for lease and optionally +# a lease time. If you have more than one network, you will need to +# repeat this for each network on which you want to supply DHCP +# service. +domain=localnet +dhcp-range=10.11.12.2,10.11.12.254 + +# This is an example of a DHCP range where the netmask is given. This +# is needed for networks we reach the dnsmasq DHCP server via a relay +# agent. If you don't know what a DHCP relay agent is, you probably +# don't need to worry about this. +#dhcp-range=192.168.0.50,192.168.0.150,255.255.255.0,12h + +# This is an example of a DHCP range which sets a tag, so that +# some DHCP options may be set only for this network. +#dhcp-range=set:red,192.168.0.50,192.168.0.150 + +# Use this DHCP range only when the tag "green" is set. +#dhcp-range=tag:green,192.168.0.50,192.168.0.150,12h + +# Specify a subnet which can't be used for dynamic address allocation, +# is available for hosts with matching --dhcp-host lines. Note that +# dhcp-host declarations will be ignored unless there is a dhcp-range +# of some type for the subnet in question. +# In this case the netmask is implied (it comes from the network +# configuration on the machine running dnsmasq) it is possible to give +# an explicit netmask instead. +#dhcp-range=192.168.0.0,static + +# Enable DHCPv6. Note that the prefix-length does not need to be specified +# and defaults to 64 if missing/ +#dhcp-range=1234::2, 1234::500, 64, 12h + +# Do Router Advertisements, BUT NOT DHCP for this subnet. +#dhcp-range=1234::, ra-only + +# Do Router Advertisements, BUT NOT DHCP for this subnet, also try and +# add names to the DNS for the IPv6 address of SLAAC-configured dual-stack +# hosts. Use the DHCPv4 lease to derive the name, network segment and +# MAC address and assume that the host will also have an +# IPv6 address calculated using the SLAAC algorithm. +#dhcp-range=1234::, ra-names + +# Do Router Advertisements, BUT NOT DHCP for this subnet. +# Set the lifetime to 46 hours. (Note: minimum lifetime is 2 hours.) +#dhcp-range=1234::, ra-only, 48h + +# Do DHCP and Router Advertisements for this subnet. Set the A bit in the RA +# so that clients can use SLAAC addresses as well as DHCP ones. +#dhcp-range=1234::2, 1234::500, slaac + +# Do Router Advertisements and stateless DHCP for this subnet. Clients will +# not get addresses from DHCP, but they will get other configuration information. +# They will use SLAAC for addresses. +#dhcp-range=1234::, ra-stateless + +# Do stateless DHCP, SLAAC, and generate DNS names for SLAAC addresses +# from DHCPv4 leases. +#dhcp-range=1234::, ra-stateless, ra-names + +# Do router advertisements for all subnets where we're doing DHCPv6 +# Unless overridden by ra-stateless, ra-names, et al, the router +# advertisements will have the M and O bits set, so that the clients +# get addresses and configuration from DHCPv6, and the A bit reset, so the +# clients don't use SLAAC addresses. +#enable-ra + +# Supply parameters for specified hosts using DHCP. There are lots +# of valid alternatives, so we will give examples of each. Note that +# IP addresses DO NOT have to be in the range given above, they just +# need to be on the same network. The order of the parameters in these +# do not matter, it's permissible to give name, address and MAC in any +# order. + +# Always allocate the host with Ethernet address 11:22:33:44:55:66 +# The IP address 192.168.0.60 +#dhcp-host=11:22:33:44:55:66,192.168.0.60 + +# Always set the name of the host with hardware address +# 11:22:33:44:55:66 to be "fred" +#dhcp-host=11:22:33:44:55:66,fred + +# Always give the host with Ethernet address 11:22:33:44:55:66 +# the name fred and IP address 192.168.0.60 and lease time 45 minutes +#dhcp-host=11:22:33:44:55:66,fred,192.168.0.60,45m + +# Give a host with Ethernet address 11:22:33:44:55:66 or +# 12:34:56:78:90:12 the IP address 192.168.0.60. Dnsmasq will assume +# that these two Ethernet interfaces will never be in use at the same +# time, and give the IP address to the second, even if it is already +# in use by the first. Useful for laptops with wired and wireless +# addresses. +#dhcp-host=11:22:33:44:55:66,12:34:56:78:90:12,192.168.0.60 + +# Give the machine which says its name is "bert" IP address +# 192.168.0.70 and an infinite lease +#dhcp-host=bert,192.168.0.70,infinite + +# Always give the host with client identifier 01:02:02:04 +# the IP address 192.168.0.60 +#dhcp-host=id:01:02:02:04,192.168.0.60 + +# Always give the InfiniBand interface with hardware address +# 80:00:00:48:fe:80:00:00:00:00:00:00:f4:52:14:03:00:28:05:81 the +# ip address 192.168.0.61. The client id is derived from the prefix +# ff:00:00:00:00:00:02:00:00:02:c9:00 and the last 8 pairs of +# hex digits of the hardware address. +#dhcp-host=id:ff:00:00:00:00:00:02:00:00:02:c9:00:f4:52:14:03:00:28:05:81,192.168.0.61 + +# Always give the host with client identifier "marjorie" +# the IP address 192.168.0.60 +#dhcp-host=id:marjorie,192.168.0.60 + +# Enable the address given for "judge" in /etc/hosts +# to be given to a machine presenting the name "judge" when +# it asks for a DHCP lease. +#dhcp-host=judge + +# Never offer DHCP service to a machine whose Ethernet +# address is 11:22:33:44:55:66 +#dhcp-host=11:22:33:44:55:66,ignore + +# Ignore any client-id presented by the machine with Ethernet +# address 11:22:33:44:55:66. This is useful to prevent a machine +# being treated differently when running under different OS's or +# between PXE boot and OS boot. +#dhcp-host=11:22:33:44:55:66,id:* + +# Send extra options which are tagged as "red" to +# the machine with Ethernet address 11:22:33:44:55:66 +#dhcp-host=11:22:33:44:55:66,set:red + +# Send extra options which are tagged as "red" to +# any machine with Ethernet address starting 11:22:33: +#dhcp-host=11:22:33:*:*:*,set:red + +# Give a fixed IPv6 address and name to client with +# DUID 00:01:00:01:16:d2:83:fc:92:d4:19:e2:d8:b2 +# Note the MAC addresses CANNOT be used to identify DHCPv6 clients. +# Note also the they [] around the IPv6 address are obligatory. +#dhcp-host=id:00:01:00:01:16:d2:83:fc:92:d4:19:e2:d8:b2, fred, [1234::5] + +# Ignore any clients which are not specified in dhcp-host lines +# or /etc/ethers. Equivalent to ISC "deny unknown-clients". +# This relies on the special "known" tag which is set when +# a host is matched. +#dhcp-ignore=tag:!known + +# Send extra options which are tagged as "red" to any machine whose +# DHCP vendorclass string includes the substring "Linux" +#dhcp-vendorclass=set:red,Linux + +# Send extra options which are tagged as "red" to any machine one +# of whose DHCP userclass strings includes the substring "accounts" +#dhcp-userclass=set:red,accounts + +# Send extra options which are tagged as "red" to any machine whose +# MAC address matches the pattern. +#dhcp-mac=set:red,00:60:8C:*:*:* + +# If this line is uncommented, dnsmasq will read /etc/ethers and act +# on the ethernet-address/IP pairs found there just as if they had +# been given as --dhcp-host options. Useful if you keep +# MAC-address/host mappings there for other purposes. +#read-ethers + +# Send options to hosts which ask for a DHCP lease. +# See RFC 2132 for details of available options. +# Common options can be given to dnsmasq by name: +# run "dnsmasq --help dhcp" to get a list. +# Note that all the common settings, such as netmask and +# broadcast address, DNS server and default route, are given +# sane defaults by dnsmasq. You very likely will not need +# any dhcp-options. If you use Windows clients and Samba, there +# are some options which are recommended, they are detailed at the +# end of this section. + +# Override the default route supplied by dnsmasq, which assumes the +# router is the same machine as the one running dnsmasq. +#dhcp-option=3,1.2.3.4 +dhcp-option=3,10.11.12.1 +dhcp-option=6,10.11.12.1 + +# Do the same thing, but using the option name +#dhcp-option=option:router,1.2.3.4 + +# Override the default route supplied by dnsmasq and send no default +# route at all. Note that this only works for the options sent by +# default (1, 3, 6, 12, 28) the same line will send a zero-length option +# for all other option numbers. +#dhcp-option=3 + +# Set the NTP time server addresses to 192.168.0.4 and 10.10.0.5 +#dhcp-option=option:ntp-server,192.168.0.4,10.10.0.5 + +# Send DHCPv6 option. Note [] around IPv6 addresses. +#dhcp-option=option6:dns-server,[1234::77],[1234::88] + +# Send DHCPv6 option for namservers as the machine running +# dnsmasq and another. +#dhcp-option=option6:dns-server,[::],[1234::88] + +# Ask client to poll for option changes every six hours. (RFC4242) +#dhcp-option=option6:information-refresh-time,6h + +# Set option 58 client renewal time (T1). Defaults to half of the +# lease time if not specified. (RFC2132) +#dhcp-option=option:T1:1m + +# Set option 59 rebinding time (T2). Defaults to 7/8 of the +# lease time if not specified. (RFC2132) +#dhcp-option=option:T2:2m + +# Set the NTP time server address to be the same machine as +# is running dnsmasq +#dhcp-option=42,0.0.0.0 + +# Set the NIS domain name to "welly" +#dhcp-option=40,welly + +# Set the default time-to-live to 50 +#dhcp-option=23,50 + +# Set the "all subnets are local" flag +#dhcp-option=27,1 + +# Send the etherboot magic flag and then etherboot options (a string). +#dhcp-option=128,e4:45:74:68:00:00 +#dhcp-option=129,NIC=eepro100 + +# Specify an option which will only be sent to the "red" network +# (see dhcp-range for the declaration of the "red" network) +# Note that the tag: part must precede the option: part. +#dhcp-option = tag:red, option:ntp-server, 192.168.1.1 + +# The following DHCP options set up dnsmasq in the same way as is specified +# for the ISC dhcpcd in +# http://www.samba.org/samba/ftp/docs/textdocs/DHCP-Server-Configuration.txt +# adapted for a typical dnsmasq installation where the host running +# dnsmasq is also the host running samba. +# you may want to uncomment some or all of them if you use +# Windows clients and Samba. +#dhcp-option=19,0 # option ip-forwarding off +#dhcp-option=44,0.0.0.0 # set netbios-over-TCP/IP nameserver(s) aka WINS server(s) +#dhcp-option=45,0.0.0.0 # netbios datagram distribution server +#dhcp-option=46,8 # netbios node type + +# Send an empty WPAD option. This may be REQUIRED to get windows 7 to behave. +#dhcp-option=252,"\n" + +# Send RFC-3397 DNS domain search DHCP option. WARNING: Your DHCP client +# probably doesn't support this...... +#dhcp-option=option:domain-search,eng.apple.com,marketing.apple.com + +# Send RFC-3442 classless static routes (note the netmask encoding) +#dhcp-option=121,192.168.1.0/24,1.2.3.4,10.0.0.0/8,5.6.7.8 + +# Send vendor-class specific options encapsulated in DHCP option 43. +# The meaning of the options is defined by the vendor-class so +# options are sent only when the client supplied vendor class +# matches the class given here. (A substring match is OK, so "MSFT" +# matches "MSFT" and "MSFT 5.0"). This example sets the +# mtftp address to 0.0.0.0 for PXEClients. +#dhcp-option=vendor:PXEClient,1,0.0.0.0 + +# Send microsoft-specific option to tell windows to release the DHCP lease +# when it shuts down. Note the "i" flag, to tell dnsmasq to send the +# value as a four-byte integer - that's what microsoft wants. See +# http://technet2.microsoft.com/WindowsServer/en/library/a70f1bb7-d2d4-49f0-96d6-4b7414ecfaae1033.mspx?mfr=true +#dhcp-option=vendor:MSFT,2,1i + +# Send the Encapsulated-vendor-class ID needed by some configurations of +# Etherboot to allow is to recognise the DHCP server. +#dhcp-option=vendor:Etherboot,60,"Etherboot" + +# Send options to PXELinux. Note that we need to send the options even +# though they don't appear in the parameter request list, so we need +# to use dhcp-option-force here. +# See http://syslinux.zytor.com/pxe.php#special for details. +# Magic number - needed before anything else is recognised +#dhcp-option-force=208,f1:00:74:7e +# Configuration file name +#dhcp-option-force=209,configs/common +# Path prefix +#dhcp-option-force=210,/tftpboot/pxelinux/files/ +# Reboot time. (Note 'i' to send 32-bit value) +#dhcp-option-force=211,30i + +# Set the boot filename for netboot/PXE. You will only need +# this is you want to boot machines over the network and you will need +# a TFTP server; either dnsmasq's built in TFTP server or an +# external one. (See below for how to enable the TFTP server.) +#dhcp-boot=pxelinux.0 + +# The same as above, but use custom tftp-server instead machine running dnsmasq +#dhcp-boot=pxelinux,server.name,192.168.1.100 + +# Boot for Etherboot gPXE. The idea is to send two different +# filenames, the first loads gPXE, and the second tells gPXE what to +# load. The dhcp-match sets the gpxe tag for requests from gPXE. +#dhcp-match=set:gpxe,175 # gPXE sends a 175 option. +#dhcp-boot=tag:!gpxe,undionly.kpxe +#dhcp-boot=mybootimage + +# Encapsulated options for Etherboot gPXE. All the options are +# encapsulated within option 175 +#dhcp-option=encap:175, 1, 5b # priority code +#dhcp-option=encap:175, 176, 1b # no-proxydhcp +#dhcp-option=encap:175, 177, string # bus-id +#dhcp-option=encap:175, 189, 1b # BIOS drive code +#dhcp-option=encap:175, 190, user # iSCSI username +#dhcp-option=encap:175, 191, pass # iSCSI password + +# Test for the architecture of a netboot client. PXE clients are +# supposed to send their architecture as option 93. (See RFC 4578) +#dhcp-match=peecees, option:client-arch, 0 #x86-32 +#dhcp-match=itanics, option:client-arch, 2 #IA64 +#dhcp-match=hammers, option:client-arch, 6 #x86-64 +#dhcp-match=mactels, option:client-arch, 7 #EFI x86-64 + +# Do real PXE, rather than just booting a single file, this is an +# alternative to dhcp-boot. +#pxe-prompt="What system shall I netboot?" +# or with timeout before first available action is taken: +#pxe-prompt="Press F8 for menu.", 60 + +# Available boot services. for PXE. +#pxe-service=x86PC, "Boot from local disk" + +# Loads /pxelinux.0 from dnsmasq TFTP server. +#pxe-service=x86PC, "Install Linux", pxelinux + +# Loads /pxelinux.0 from TFTP server at 1.2.3.4. +# Beware this fails on old PXE ROMS. +#pxe-service=x86PC, "Install Linux", pxelinux, 1.2.3.4 + +# Use bootserver on network, found my multicast or broadcast. +#pxe-service=x86PC, "Install windows from RIS server", 1 + +# Use bootserver at a known IP address. +#pxe-service=x86PC, "Install windows from RIS server", 1, 1.2.3.4 + +# If you have multicast-FTP available, +# information for that can be passed in a similar way using options 1 +# to 5. See page 19 of +# http://download.intel.com/design/archives/wfm/downloads/pxespec.pdf + + +# Enable dnsmasq's built-in TFTP server +#enable-tftp + +# Set the root directory for files available via FTP. +#tftp-root=/var/ftpd + +# Do not abort if the tftp-root is unavailable +#tftp-no-fail + +# Make the TFTP server more secure: with this set, only files owned by +# the user dnsmasq is running as will be send over the net. +#tftp-secure + +# This option stops dnsmasq from negotiating a larger blocksize for TFTP +# transfers. It will slow things down, but may rescue some broken TFTP +# clients. +#tftp-no-blocksize + +# Set the boot file name only when the "red" tag is set. +#dhcp-boot=tag:red,pxelinux.red-net + +# An example of dhcp-boot with an external TFTP server: the name and IP +# address of the server are given after the filename. +# Can fail with old PXE ROMS. Overridden by --pxe-service. +#dhcp-boot=/var/ftpd/pxelinux.0,boothost,192.168.0.3 + +# If there are multiple external tftp servers having a same name +# (using /etc/hosts) then that name can be specified as the +# tftp_servername (the third option to dhcp-boot) and in that +# case dnsmasq resolves this name and returns the resultant IP +# addresses in round robin fashion. This facility can be used to +# load balance the tftp load among a set of servers. +#dhcp-boot=/var/ftpd/pxelinux.0,boothost,tftp_server_name + +# Set the limit on DHCP leases, the default is 150 +#dhcp-lease-max=150 + +# The DHCP server needs somewhere on disk to keep its lease database. +# This defaults to a sane location, but if you want to change it, use +# the line below. +#dhcp-leasefile=/var/lib/misc/dnsmasq.leases + +# Set the DHCP server to authoritative mode. In this mode it will barge in +# and take over the lease for any client which broadcasts on the network, +# whether it has a record of the lease or not. This avoids long timeouts +# when a machine wakes up on a new network. DO NOT enable this if there's +# the slightest chance that you might end up accidentally configuring a DHCP +# server for your campus/company accidentally. The ISC server uses +# the same option, and this URL provides more information: +# http://www.isc.org/files/auth.html +dhcp-authoritative + +# Run an executable when a DHCP lease is created or destroyed. +# The arguments sent to the script are "add" or "del", +# then the MAC address, the IP address and finally the hostname +# if there is one. +#dhcp-script=/bin/echo + +# Set the cachesize here. +#cache-size=150 + +# If you want to disable negative caching, uncomment this. +#no-negcache + +# Normally responses which come from /etc/hosts and the DHCP lease +# file have Time-To-Live set as zero, which conventionally means +# do not cache further. If you are happy to trade lower load on the +# server for potentially stale date, you can set a time-to-live (in +# seconds) here. +#local-ttl= + +# If you want dnsmasq to detect attempts by Verisign to send queries +# to unregistered .com and .net hosts to its sitefinder service and +# have dnsmasq instead return the correct NXDOMAIN response, uncomment +# this line. You can add similar lines to do the same for other +# registries which have implemented wildcard A records. +#bogus-nxdomain=64.94.110.11 + +# If you want to fix up DNS results from upstream servers, use the +# alias option. This only works for IPv4. +# This alias makes a result of 1.2.3.4 appear as 5.6.7.8 +#alias=1.2.3.4,5.6.7.8 +# and this maps 1.2.3.x to 5.6.7.x +#alias=1.2.3.0,5.6.7.0,255.255.255.0 +# and this maps 192.168.0.10->192.168.0.40 to 10.0.0.10->10.0.0.40 +#alias=192.168.0.10-192.168.0.40,10.0.0.0,255.255.255.0 + +# Change these lines if you want dnsmasq to serve MX records. + +# Return an MX record named "maildomain.com" with target +# servermachine.com and preference 50 +#mx-host=maildomain.com,servermachine.com,50 + +# Set the default target for MX records created using the localmx option. +#mx-target=servermachine.com + +# Return an MX record pointing to the mx-target for all local +# machines. +#localmx + +# Return an MX record pointing to itself for all local machines. +#selfmx + +# Change the following lines if you want dnsmasq to serve SRV +# records. These are useful if you want to serve ldap requests for +# Active Directory and other windows-originated DNS requests. +# See RFC 2782. +# You may add multiple srv-host lines. +# The fields are ,,,, +# If the domain part if missing from the name (so that is just has the +# service and protocol sections) then the domain given by the domain= +# config option is used. (Note that expand-hosts does not need to be +# set for this to work.) + +# A SRV record sending LDAP for the example.com domain to +# ldapserver.example.com port 389 +#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389 + +# A SRV record sending LDAP for the example.com domain to +# ldapserver.example.com port 389 (using domain=) +#srv-host=_ldap._tcp,ldapserver.example.com,389 + +# Two SRV records for LDAP, each with different priorities +#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,1 +#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,2 + +# A SRV record indicating that there is no LDAP server for the domain +# example.com +#srv-host=_ldap._tcp.example.com + +# The following line shows how to make dnsmasq serve an arbitrary PTR +# record. This is useful for DNS-SD. (Note that the +# domain-name expansion done for SRV records _does_not +# occur for PTR records.) +#ptr-record=_http._tcp.dns-sd-services,"New Employee Page._http._tcp.dns-sd-services" + +# Change the following lines to enable dnsmasq to serve TXT records. +# These are used for things like SPF and zeroconf. (Note that the +# domain-name expansion done for SRV records _does_not +# occur for TXT records.) + +#Example SPF. +#txt-record=example.com,"v=spf1 a -all" + +#Example zeroconf +#txt-record=_http._tcp.example.com,name=value,paper=A4 + +# Provide an alias for a "local" DNS name. Note that this _only_ works +# for targets which are names from DHCP or /etc/hosts. Give host +# "bert" another name, bertrand +#cname=bertand,bert + +# For debugging purposes, log each DNS query as it passes through +# dnsmasq. +#log-queries + +# Log lots of extra information about DHCP transactions. +#log-dhcp + +# Include another lot of configuration options. +#conf-file=/etc/dnsmasq.more.conf +#conf-dir=/etc/dnsmasq.d + +# Include all the files in a directory except those ending in .bak +#conf-dir=/etc/dnsmasq.d,.bak + +# Include all files in a directory which end in .conf +#conf-dir=/etc/dnsmasq.d/,*.conf \ No newline at end of file diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/fstab b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/fstab new file mode 100644 index 00000000..f8537aa5 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/fstab @@ -0,0 +1,4 @@ +proc /proc proc defaults 0 0 +/dev/mmcblk0p1 /boot vfat defaults 0 2 +/dev/mmcblk0p2 / ext4 defaults,noatime 0 1 +# a swapfile is not a swap partition, so no using swapon|off from here on, use dphys-swapfile swap[on|off] for that diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/hostapd/hostapd.conf b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/hostapd/hostapd.conf new file mode 100644 index 00000000..953be3c8 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/hostapd/hostapd.conf @@ -0,0 +1,3 @@ +interface=wlan0 +ssid=IoTBox +channel=1 diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/nginx/conf.d/access_point.conf b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/nginx/conf.d/access_point.conf new file mode 100644 index 00000000..dbe91413 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/nginx/conf.d/access_point.conf @@ -0,0 +1,11 @@ +server { + # By listening specifically on the access point IP, this server block will only match + # requests when the access point is enabled. We mark it as the 'default_server' so that + # it takes priority over the regular config. + listen 10.11.12.1:80 default_server; + + location / { + # Redirect any URL to the homepage (triggers the 'sign-in' popup upon connecting to the IoT box) + return 301 $scheme://10.11.12.1:8069; + } +} diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/nginx/conf.d/iot.conf b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/nginx/conf.d/iot.conf new file mode 100644 index 00000000..3a6024f2 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/nginx/conf.d/iot.conf @@ -0,0 +1,39 @@ +server { + listen 80; + listen [::]:80; + listen 443 ssl http2; + listen [::]:443 ssl http2; + + ssl_certificate /etc/ssl/certs/nginx-cert.crt; + ssl_certificate_key /etc/ssl/private/nginx-cert.key; + + # Increase the allowed body size from 1MB to 10MB, this ensures + # large actions such as printing a PDF will always work. + client_max_body_size 10M; + + location / { + # Increase the request timeout from 1 minute to 10 minutes, + # this is required for the self-flashing feature. + proxy_read_timeout 600s; + proxy_pass http://127.0.0.1:8069; + } + + # If the iot_drivers module fails to start, the user will be sent to the + # database selector. Instead of this we will show them the 502 error page + # (IoT box is down) as it is more appropriate. + location /web/database/selector { + return 301 /502.html; + } + + error_page 502 /502.html; + location /502.html { + root /var/www/html; + } + + # Expose the /var/log/ folder directly via nginx, so that + # it remains accessible even if Odoo is failing to start. + location /odoo-logs { + alias /var/log/; + autoindex on; + } +} diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/rc.local b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/rc.local new file mode 100755 index 00000000..b59a265f --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/rc.local @@ -0,0 +1,46 @@ +#!/bin/sh -e +# +# rc.local +# +# This script is executed at the end of each multiuser runlevel. +# Make sure that the script will "exit 0" on success or any other +# value on error. +# +# In order to enable or disable this script just change the execution +# bits. +# +# By default this script does nothing. + +exec 1>/var/log/rc.local.log 2>&1 # send stdout and stderr from rc.local to a log file +set -x # display commands before execution + +# Ensure Wi-Fi radio is enabled +nmcli radio wifi on + +# Print the IP address +_IP=$(hostname -I) || true +if [ "$_IP" ]; then + printf "My IP address is %s\n" "$_IP" +fi + +mkdir -p /var/run/odoo +chown odoo:odoo /var/run/odoo + +# For compatibility between new IoT Box images and old Odoo code on it (it will not start Odoo on boot without this) +start_wifi=/home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/wireless_ap.sh +if [ -f $start_wifi ]; then + $start_wifi & +fi + +# Update current branch +cd /home/pi/odoo +localbranch=$(sudo -u odoo git symbolic-ref -q --short HEAD) +localremote=$(sudo -u odoo git config branch.$localbranch.remote) + +sudo -u odoo rm -f /home/pi/odoo/.git/shallow.lock +sudo -u odoo git remote set-url "${localremote}" "https://github.com/odoo/odoo.git" + +sudo -u odoo GIT_SSL_NO_VERIFY=1 git fetch "${localremote}" "${localbranch}" --depth=1 +sudo -u odoo git reset --hard FETCH_HEAD + +exit 0 diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/ssl/certs/nginx-cert.crt b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/ssl/certs/nginx-cert.crt new file mode 100644 index 00000000..6181845e --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/ssl/certs/nginx-cert.crt @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID4TCCAsmgAwIBAgIJAMCws64aK3IlMA0GCSqGSIb3DQEBCwUAMIGFMQswCQYD +VQQGEwJCRTEXMBUGA1UECAwOQnJhYmFudC1XYWxsb24xGTAXBgNVBAcMEEdyYW5k +LVJvc2nDg8KocmUxEDAOBgNVBAoMB09kb29Jb1QxDDAKBgNVBAsMA0lvVDEiMCAG +A1UEAwwZT2Rvb1RlbXBJb1RCb3hDZXJ0aWZpY2F0ZTAgFw0xODA5MjgxNjIzNDNa +GA8yMTE4MDkwNDE2MjM0M1owgYUxCzAJBgNVBAYTAkJFMRcwFQYDVQQIDA5CcmFi +YW50LVdhbGxvbjEZMBcGA1UEBwwQR3JhbmQtUm9zacODwqhyZTEQMA4GA1UECgwH +T2Rvb0lvVDEMMAoGA1UECwwDSW9UMSIwIAYDVQQDDBlPZG9vVGVtcElvVEJveENl +cnRpZmljYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq8O2dZJO +Pj9QJ2bIDthDNfDK4gm4jthIpwFpJFQmrWfZyQy2IiECnGwHlb8T2pZAw6LhyMbK +EPeaiyNAxztkJQavyW/tyRzWJiVI5/gPkWn3PFSWiJc7tpN2dgYlOzhEa209SJvC +qCS/ncraUt8o/KjW8F155mqYZ9qwD52tJyKjbtzIwG3KO5+ErcWGiMs77pGkimb1 +f9gNQ+JclGyVJ2WUhXeFU6C8hdz1JlsDqYabaZzS0ESvXhGhstcRUU/KzdNYe/7d +Xw4vmxyQvzbyJaj+T5ILCMkgU6OPeEfswEF1qXyEIdIXlD4pSMlGzQ3MDku564e1 +ebR51BwkfHwtewIDAQABo1AwTjAdBgNVHQ4EFgQU5Zyb7DuZFqb96okkP1yfDV2Q +Gv8wHwYDVR0jBBgwFoAU5Zyb7DuZFqb96okkP1yfDV2QGv8wDAYDVR0TBAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAQEALkon2ZHMBW9t+8oig/C5I+edCniSgs+2Loh9 +ufIG5G7KD8MuKjg55a9cCH1Ra5GSVZTj4krBPab21lN+8rb2mAeIEbIwyivx6dlP +2x9Xf3ifvdB4Lav7zSjX3TNB+1OxLCYtxlCLDPdIHgSX5bz00KRsRPQn2o/hSBtK +4BzZckiz7ZzUFZUQb1lzqccAPLMM28JCEgWFJPHRXQHIq6cMLNm/z6JlkGzNwl6m +vdVieTlZ9dwwwGvgMk3lmGUYUO8NUyEi5n2sY72xAs3+2Tep2T4VHn0i9CYOsA2A +k5/8BMbjf0ghkzhf2MkLBhIwHuaI6TKClvRtoRdTwceJhnkyPQ== +-----END CERTIFICATE----- diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/ssl/private/nginx-cert.key b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/ssl/private/nginx-cert.key new file mode 100644 index 00000000..b210484b --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/etc/ssl/private/nginx-cert.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCrw7Z1kk4+P1An +ZsgO2EM18MriCbiO2EinAWkkVCatZ9nJDLYiIQKcbAeVvxPalkDDouHIxsoQ95qL +I0DHO2QlBq/Jb+3JHNYmJUjn+A+Rafc8VJaIlzu2k3Z2BiU7OERrbT1Im8KoJL+d +ytpS3yj8qNbwXXnmaphn2rAPna0nIqNu3MjAbco7n4StxYaIyzvukaSKZvV/2A1D +4lyUbJUnZZSFd4VToLyF3PUmWwOphptpnNLQRK9eEaGy1xFRT8rN01h7/t1fDi+b +HJC/NvIlqP5PkgsIySBTo494R+zAQXWpfIQh0heUPilIyUbNDcwOS7nrh7V5tHnU +HCR8fC17AgMBAAECggEAeYkN/br8Kgdai8aqH/bd97jdlXsTX9+h6KmS3+W7SE+H +Rj78UMHSuyOlaku9nJlcUhFaeVpPeBn6/CCBoXdgsOI+V+Ye9oK09GDFaX2YZmf4 +THP938BCvDkzROesSG7T2r988XdlENyPyPLT8Hd+5OgCzikWK/eYx0Nx+Fq1Pk6W +U7TSap7YFlXlP7vAxogOng1eIXQfWLWnS4ZYQALLWYlJbSwvnA2caEqM68df9M1z +X974ZAVKYKftzc506s6Mrjaw0RBM/fXKUGAUsip5Aw/4QCzICqU71taolnwVl3dL +tHFib7HX55ge5N0IBYIKzjj496ceUegnLNSaYmnPQQKBgQDj+5qjsBXkPuS0FABS +yEHLf1xIrr2pVRnctlCmN7s/PIAL/depRBcRST2ZRQeek4LIgbDZ++nBSCPc2fMj +TrVYq/b7VK7aCs0uDuvJT2ScVm6QHkoc780XNoAo5QgwARksW53N7ysbXkG/YaSj +xDlcQ2dmjZNq1frEJBr3bXkMqQKBgQDA33dfm2khNJZFXOJIHxaxeilNBndowknF +lHMm1hWXvjh66dwS3hxhj03pqF+33xxP6BA6y32sn30dFBduw9kvN/2gCsxTMDNE +8/EncC31i1eEQH1vK/fe02nvR8SbI9NcyD53emsOWsZi/FevrHK+LudgopA/ddMk +fbPN0rn7gwKBgGz9pQEqNl0G4Eli4oCw8ht6SMEKoOtqHtIQat/79s2Ve9W/xjFK +twhxjjxO7wSVmsmGjui3cRoRBewYWg+AGlxI4etnoavlzA9/3KNCDGRdQcAuatoI +nnDBgmWKkO56J/G33upLs70Cw8XdxVrxfUaphq5Vcqt5nsfURvwQ3vT5AoGAJ4qo +8pTuDLy3Qik0ywx0npYo+X2l5XhPn447vW6Oprl84tYnJEcdEnNKyeiXFx9Ksqcl +DKjDbyyTfe6sjyzfzepwuOr90OBE4pIQksFQ6tJScu61yKD/BFPbmA7io9vIbXEw +PVZ/tEWv/oM1hvKX453CGfG6GQiS7RxITJ4zOvkCgYEAgaMK2j02vmWHuDWvCsJC +XS8PMuVsc3cqwyhqyal4s9XGMHqsbeura3OI/LObg7inoSlSyD3Eax0MdlbwywmE +Qq8FzCgw9gNu3BQPZgfKSfc/zvdAjlaVtLhW6ztoK1kWgmcnRXr5YNorNK99HHTL +a4T40G2WVNTtlTOarEvYrP0= +-----END PRIVATE KEY----- diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/home/odoo/.config/labwc/autostart b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/home/odoo/.config/labwc/autostart new file mode 100644 index 00000000..c8e7bd42 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/home/odoo/.config/labwc/autostart @@ -0,0 +1,2 @@ +swaybg -i ~/.config/labwc/iot-bg.png -m fit >/dev/null 2>&1 & +wtype -M alt -M logo h -m alt -m logo diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/home/odoo/.config/labwc/iot-bg.png b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/home/odoo/.config/labwc/iot-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..9f5d7c232af0f484718820c21a783840d233b4ba GIT binary patch literal 29628 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 M)78&qol`;+00_@%kpKVy literal 0 HcmV?d00001 diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/home/odoo/.config/labwc/rc.xml b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/home/odoo/.config/labwc/rc.xml new file mode 100644 index 00000000..cc4eccea --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/home/odoo/.config/labwc/rc.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/var/www/html/502.html b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/var/www/html/502.html new file mode 100644 index 00000000..6bebf22f --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_after_init/var/www/html/502.html @@ -0,0 +1,95 @@ + + + + + IoT Box is down + + +
+
+

IoT Box is down

+ Download Odoo logs + Download Nginx logs +
+

(502 Bad Gateway)

+

The IoT Box received the request but was not able to handle it. You can try to refresh the page to see if the request can now be handled.

+

If the error persists for more than 5 minutes:

+
    +
  1. Force restart the IoT Box by unplugging the IoT power supply then plugging it in again
  2. +
  3. Re-flash the SD card of the IoT Box, see: + documentation +
  4. +
+
+ + + diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/NetworkManager/conf.d/90-dns-none.conf b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/NetworkManager/conf.d/90-dns-none.conf new file mode 100644 index 00000000..d435aba9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/NetworkManager/conf.d/90-dns-none.conf @@ -0,0 +1,2 @@ +[main] +dns=none diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/default/keyboard b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/default/keyboard new file mode 100644 index 00000000..2609b092 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/default/keyboard @@ -0,0 +1,10 @@ +# KEYBOARD CONFIGURATION FILE + +# Consult the keyboard(5) manual page. + +XKBMODEL="pc105" +XKBLAYOUT="us" +XKBVARIANT="" +XKBOPTIONS="" + +BACKSPACE="guess" \ No newline at end of file diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/default/locale b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/default/locale new file mode 100644 index 00000000..30237635 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/default/locale @@ -0,0 +1,3 @@ +LANG=en_US.UTF-8 +LANGUAGE=en_US:en +LC_ALL=en_US.UTF-8 diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/init_image.sh b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/init_image.sh new file mode 100755 index 00000000..3e77218a --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/init_image.sh @@ -0,0 +1,231 @@ +#!/usr/bin/env bash +set -o errexit +set -o nounset +set -o pipefail +# set -o xtrace + +__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +__file="${__dir}/$(basename "${BASH_SOURCE[0]}")" +__base="$(basename ${__file} .sh)" + +# Recommends: antiword, graphviz, ghostscript, python-gevent, poppler-utils +export DEBIAN_FRONTEND=noninteractive + +# single-user mode, appropriate for chroot environment +# explicitly setting the runlevel prevents warnings after installing packages +export RUNLEVEL=1 + +# Unset lang variables to prevent locale settings leaking from host +unset "${!LC_@}" +unset "${!LANG@}" + +# set locale to en_US +echo "set locale to en_US" +echo "en_US.UTF-8 UTF-8" > /etc/locale.gen +dpkg-reconfigure locales + +# Aliases +echo "alias ll='ls -al'" | tee -a ~/.bashrc /home/pi/.bashrc +echo "alias odoo='sudo systemctl stop odoo; sudo -u odoo /usr/bin/python3 /home/pi/odoo/odoo-bin --config /home/pi/odoo.conf'" | tee -a ~/.bashrc /home/pi/.bashrc +echo "alias odoo_logs='less -R +F /var/log/odoo/odoo-server.log'" | tee -a ~/.bashrc /home/pi/.bashrc +echo "alias odoo_conf='cat /home/pi/odoo.conf'" | tee -a ~/.bashrc /home/pi/.bashrc +echo "alias install='sudo chroot /root_bypass_ramdisks/'" | tee -a ~/.bashrc /home/pi/.bashrc +echo "alias blackbox='ls /dev/serial/by-path/'" | tee -a ~/.bashrc /home/pi/.bashrc +echo "alias nano='sudo -u odoo nano -l'" | tee -a /home/pi/.bashrc +echo "alias vim='sudo -u odoo vim -u /home/pi/.vimrc'" | tee -a /home/pi/.bashrc +echo "alias odoo_luxe='printf \" ______\n< Luxe >\n ------\n \\ ^__^\n \\ (oo)\\_______\n (__)\\ )\\/\\ \n ||----w |\n || ||\n\"'" | tee -a ~/.bashrc /home/pi/.bashrc +echo "alias odoo_start='sudo systemctl start odoo'" >> /home/pi/.bashrc +echo "alias odoo_stop='sudo systemctl stop odoo'" >> /home/pi/.bashrc +echo "alias odoo_restart='sudo systemctl restart odoo'" >> /home/pi/.bashrc +echo " +odoo_help() { + echo '-------------------------------' + echo ' Welcome to Odoo IoT Box tools' + echo '-------------------------------' + echo '' + echo 'odoo Starts/Restarts Odoo server manually (not through odoo.service)' + echo 'odoo_logs Displays Odoo server logs in real time' + echo 'odoo_conf Displays Odoo configuration file content' + echo 'install Bypasses ramdisks to allow package installation' + echo 'blackbox Lists all serial connected devices' + echo 'odoo_start Starts Odoo service' + echo 'odoo_stop Stops Odoo service' + echo 'odoo_restart Restarts Odoo service' + echo 'odoo_dev Resets Odoo on the specified branch from odoo-dev repository' + echo 'odoo_origin Resets Odoo on the specified branch from the odoo repository' + echo 'devtools Enables/Disables specific functions for development (more help with devtools help)' + echo '' + echo 'Odoo IoT online help: ' +} + +odoo_dev() { + if [ -z \"\$1\" ]; then + odoo_help + return + fi + pwd=\$(pwd) + cd /home/pi/odoo + sudo -u odoo git remote add dev https://github.com/odoo-dev/odoo.git + sudo -u odoo git fetch dev \$1 --depth=1 --prune + sudo -u odoo git reset --hard FETCH_HEAD + sudo -u odoo git branch -m \$1 + sudo chroot /root_bypass_ramdisks /bin/bash -c \"export DEBIAN_FRONTEND=noninteractive && xargs apt-get -y -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" install < /home/pi/odoo/addons/iot_box_image/configuration/packages.txt\" + sudo -u odoo pip3 install -r /home/pi/odoo/addons/iot_box_image/configuration/requirements.txt --break-system-package + cd \$pwd +} + +odoo_origin() { + if [ -z \"\$1\" ]; then + odoo_help + return + fi + pwd=\$(pwd) + cd /home/pi/odoo + sudo -u odoo git remote set-url origin https://github.com/odoo/odoo.git # ensure odoo repository + sudo -u odoo git fetch origin \$1 --depth=1 --prune + sudo -u odoo git reset --hard FETCH_HEAD + sudo -u odoo git branch -m \$1 + sudo chroot /root_bypass_ramdisks /bin/bash -c \"export DEBIAN_FRONTEND=noninteractive && xargs apt-get -y -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" install < /home/pi/odoo/addons/iot_box_image/configuration/packages.txt\" + sudo -u odoo pip3 install -r /home/pi/odoo/addons/iot_box_image/configuration/requirements.txt --break-system-package + cd \$pwd +} + +pip() { + if [[ -z \"\$1\" || -z \"\$2\" ]]; then + odoo_help + return 1 + fi + additional_arg=\"\" + if [ \"\$1\" == \"install\" ]; then + additional_arg=\"--user\" + fi + pip3 \"\$1\" \"\$2\" --break-system-package \$additional_arg +} + +devtools() { + help_message() { + echo 'Usage: devtools [action name]' + echo '' + echo 'Only provide an action name if you want to enable/disable a specific device action.' + echo 'If no action name is provided, all actions will be enabled/disabled.' + echo 'To enable/disable multiple actions, enclose them in quotes separated by commas.' + } + case \"\$1\" in + enable|disable) + case \"\$2\" in + general|actions|longpolling) + if ! grep -q '^\[devtools\]' /home/pi/odoo.conf; then + sudo -u odoo bash -c \"printf '\n[devtools]\n' >> /home/pi/odoo.conf\" + fi + if [ \"\$1\" == \"disable\" ]; then + value=\"\${3:-*}\" # Default to '*' if no action name is provided + devtools enable \"\$2\" # Remove action/general/longpolling from conf to avoid duplicate keys + sudo sed -i \"/^\[devtools\]/a\\\\\$2 = \$value\" /home/pi/odoo.conf + elif [ \"\$1\" == \"enable\" ]; then + sudo sed -i \"/\[devtools\]/,/\[/{/\$2 =/d}\" /home/pi/odoo.conf + fi + ;; + *) + help_message + return 1 + ;; + esac + ;; + *) + help_message + return 1 + ;; + esac +} +" | tee -a ~/.bashrc /home/pi/.bashrc + +# Change default hostname from 'raspberrypi' to 'iotbox' +echo iotbox | tee /etc/hostname +sed -i 's/\braspberrypi/iotbox/g' /etc/hosts + +apt-get update + +# At the first start it is necessary to configure a password +# This will be modified by a unique password on the first start of Odoo +password="$(openssl rand -base64 12)" +echo "pi:${password}" | chpasswd +echo TrustedUserCAKeys /etc/ssh/ca.pub >> /etc/ssh/sshd_config + +# Prevent Wi-Fi blocking +apt-get -y remove rfkill + +echo "Acquire::Retries "16";" > /etc/apt/apt.conf.d/99acquire-retries +# KEEP OWN CONFIG FILES DURING PACKAGE CONFIGURATION +# http://serverfault.com/questions/259226/automatically-keep-current-version-of-config-files-when-apt-get-install +xargs apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install < /home/pi/odoo/addons/iot_box_image/configuration/packages.txt +apt-get -y autoremove + +apt-get clean +localepurge +rm -rfv /usr/share/doc + +# Remove the default nginx website, we have our own config in /etc/nginx/conf.d/ +rm /etc/nginx/sites-enabled/default + +pip3 install -r /home/pi/odoo/addons/iot_box_image/configuration/requirements.txt --break-system-package + +# Create Odoo user for odoo service and disable password login +adduser --disabled-password --gecos "" --shell /usr/sbin/nologin odoo + +# odoo user doesn't need to type its password to run sudo commands +cp /etc/sudoers.d/010_pi-nopasswd /etc/sudoers.d/010_odoo-nopasswd +sed -i 's/pi/odoo/g' /etc/sudoers.d/010_odoo-nopasswd + +# copy the odoo.conf file to the overwrite directory +mv -v "/home/pi/odoo/addons/iot_box_image/configuration/odoo.conf" "/home/pi/" +chown odoo:odoo "/home/pi/odoo.conf" + +groupadd usbusers +usermod -a -G usbusers odoo +usermod -a -G video odoo +usermod -a -G render odoo +usermod -a -G lp odoo +usermod -a -G input odoo +usermod -a -G dialout odoo +usermod -a -G pi odoo +mkdir -v /var/log/odoo +chown odoo:odoo /var/log/odoo +chown odoo:odoo -R /home/pi/odoo/ + +# logrotate is very picky when it comes to file permissions +chown -R root:root /etc/logrotate.d/ +chmod -R 644 /etc/logrotate.d/ +chown root:root /etc/logrotate.conf +chmod 644 /etc/logrotate.conf + +update-rc.d -f hostapd remove +update-rc.d -f nginx remove +update-rc.d -f dnsmasq remove + +systemctl enable ramdisks.service +systemctl disable dphys-swapfile.service +systemctl enable ssh +systemctl set-default graphical.target +systemctl disable getty@tty1.service +systemctl disable systemd-timesyncd.service +systemctl unmask hostapd.service +systemctl disable hostapd.service +systemctl disable cups-browsed.service +systemctl enable labwc.service +systemctl enable odoo.service +systemctl enable odoo-led-manager.service +systemctl enable odoo-ngrok.service + +# create dirs for ramdisks +create_ramdisk_dir () { + mkdir -v "${1}_ram" +} + +create_ramdisk_dir "/var" +create_ramdisk_dir "/etc" +create_ramdisk_dir "/tmp" +mkdir -v /root_bypass_ramdisks + +echo "" +echo "--- DEFAULT PASSWORD: ${password} ---" +echo "" diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/logrotate.conf b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/logrotate.conf new file mode 100644 index 00000000..53bf9854 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/logrotate.conf @@ -0,0 +1,17 @@ +# see "man logrotate" for details +# rotate log files daily +daily + +# keep 3 days worth of backlogs +rotate 3 + +# create new (empty) log files after rotating old ones +create + +# uncomment this if you want your log files compressed +#compress + +# packages drop log rotation information into this directory +include /etc/logrotate.d + +# system-specific logs may be configured here diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/logrotate.d/odoo b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/logrotate.d/odoo new file mode 100644 index 00000000..b97543f4 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/logrotate.d/odoo @@ -0,0 +1,6 @@ +/var/log/odoo/*.log { + size 100M + copytruncate + missingok + notifempty +} diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/resolv.conf b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/resolv.conf new file mode 100644 index 00000000..b48f4bc2 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/resolv.conf @@ -0,0 +1,4 @@ +nameserver 1.1.1.1 +nameserver 1.0.0.1 +nameserver 8.8.8.8 +nameserver 8.8.4.4 diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/labwc.service b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/labwc.service new file mode 100644 index 00000000..c2d2b3de --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/labwc.service @@ -0,0 +1,16 @@ +[Unit] +Description=labwc wayland compositor +Documentation=man:labwc(1) +After=graphical.target systemd-user-sessions.service + +[Service] +User=odoo +ExecStart=/usr/bin/labwc +Environment="XDG_RUNTIME_DIR=/run/odoo" +Environment="XDG_CACHE_HOME=/run/odoo" +Environment="WLR_LIBINPUT_NO_DEVICES=1" +Restart=always +Type=simple + +[Install] +WantedBy=graphical.target diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/odoo-led-manager.service b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/odoo-led-manager.service new file mode 100644 index 00000000..8457f713 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/odoo-led-manager.service @@ -0,0 +1,12 @@ +[Unit] +Description=Odoo LED Status Indicator: makes LEDs blink based on Odoo status + +[Service] +Type=simple +User=root +ExecStart=/home/pi/odoo/addons/iot_box_image/configuration/led_manager.sh +Restart=on-failure +RestartSec=5s + +[Install] +WantedBy=multi-user.target diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/odoo-ngrok.service b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/odoo-ngrok.service new file mode 100644 index 00000000..3e211017 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/odoo-ngrok.service @@ -0,0 +1,14 @@ +[Unit] +Description=Odoo Service to ensure ngrok is running +After=network.target +StartLimitIntervalSec=0 + +[Service] +Type=simple +User=root +ExecStart=/usr/bin/ngrok tcp 22 --config /home/pi/ngrok.yml +Restart=on-failure +RestartSec=5s + +[Install] +WantedBy=multi-user.target diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/odoo.service b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/odoo.service new file mode 100644 index 00000000..4effe1eb --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/odoo.service @@ -0,0 +1,30 @@ +[Unit] +Description=Odoo IoT Box service +After=cups.socket network-online.target NetworkManager.service rc-local.service +Wants=network-online.target +StartLimitIntervalSec=0 + +[Service] +User=odoo +Group=odoo +Environment="LIBCAMERA_LOG_LEVELS=3" +Environment="XDG_RUNTIME_DIR=/run/odoo" +Environment="XDG_CACHE_HOME=/run/odoo" +Environment="ODOO_PY_COLORS=True" +ExecStartPre=sudo /bin/mkdir -p /run/odoo +ExecStartPre=sudo /bin/chown odoo:odoo /run/odoo +ExecStartPre=sudo timedatectl set-ntp true +ExecStart=/usr/bin/python3 /home/pi/odoo/odoo-bin --config /home/pi/odoo.conf +Restart=on-failure +RestartSec=10s +StandardOutput=null +StandardError=append:/var/log/odoo/odoo-server.log + +[Install] +WantedBy=multi-user.target + +# Tip: don't forget to 'systemctl disable' then re 'enable' service if you update the 'WantedBy' line +# reason is that 'enable' creates a symlink in /etc/systemd/system/multi-user.target.wants/ pointing to this file which does +# not get updated if you only 'systemctl daemon-reload' + +# Documentation: https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/ramdisks.service b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/ramdisks.service new file mode 100644 index 00000000..5d5695c4 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/systemd/system/ramdisks.service @@ -0,0 +1,12 @@ +[Unit] +Description=ramdisks +DefaultDependencies=no +After=sysinit.target local-fs.target +Before=basic.target + +[Service] +Type=oneshot +ExecStart=/home/pi/odoo/addons/iot_box_image/configuration/setup_ramdisks.sh + +[Install] +WantedBy=basic.target diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/udev/rules.d/99-usb.rules b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/udev/rules.d/99-usb.rules new file mode 100644 index 00000000..7a282a8e --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/udev/rules.d/99-usb.rules @@ -0,0 +1,2 @@ +SUBSYSTEM=="usb", GROUP="usbusers", MODE="0660" +SUBSYSTEMS=="usb", GROUP="usbusers", MODE="0660" \ No newline at end of file diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/udev/rules.d/99-z-input.rules b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/udev/rules.d/99-z-input.rules new file mode 100644 index 00000000..aab19f2d --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/etc/udev/rules.d/99-z-input.rules @@ -0,0 +1,2 @@ +SUBSYSTEM=="input", GROUP="input", MODE="0660" +KERNEL=="tty[0-9]*", GROUP="tty", MODE="0660" \ No newline at end of file diff --git a/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/home/pi/.vimrc b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/home/pi/.vimrc new file mode 100755 index 00000000..ac06ceb0 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_box_image/iot_box_image/overwrite_before_init/home/pi/.vimrc @@ -0,0 +1,31 @@ +filetype on +set all& +set autoindent +set backspace=2 +set nobackup +set nocompatible +set noerrorbells +set noexpandtab +set expandtab +set number +set hidden +set history=500 +set hlsearch +set ignorecase +set laststatus=2 +set modeline +set mouse=a +set ruler +set shiftwidth=4 +set scrolloff=5 +set showcmd +set showmode +set tabstop=4 +set textwidth=0 +set visualbell +set t_vb= +set wrap +set list +set listchars=tab:~.,trail:.,extends:>,precedes:< +set viminfo="NONE" +syntax on diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/__init__.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/__init__.py new file mode 100644 index 00000000..4be1b59a --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/__init__.py @@ -0,0 +1,43 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from functools import wraps +import requests +import logging + +from . import server_logger +from . import connection_manager +from . import controllers +from . import driver +from . import event_manager +from . import exception_logger +from . import http +from . import interface +from . import main +from . import tools +from . import websocket_client +from . import webrtc_client + +_logger = logging.getLogger(__name__) +_logger.warning("==== Starting Odoo ====") + +_get = requests.get +_post = requests.post + + +def set_default_options(func): + @wraps(func) + def wrapper(*args, **kwargs): + headers = kwargs.pop('headers', None) or {} + verify = kwargs.pop('verify', False) + headers['User-Agent'] = 'OdooIoTBox/1.0' + server_url = tools.helpers.get_odoo_server_url() + db_name = tools.helpers.get_conf('db_name') + if server_url and db_name and args[0].startswith(server_url) and '/web/login?db=' not in args[0]: + headers['X-Odoo-Database'] = db_name + return func(*args, headers=headers, verify=verify, **kwargs) + + return wrapper + + +requests.get = set_default_options(_get) +requests.post = set_default_options(_post) diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/__manifest__.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/__manifest__.py new file mode 100644 index 00000000..da707bcc --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/__manifest__.py @@ -0,0 +1,27 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +{ + 'name': 'Hardware Proxy', + 'category': 'Hidden', + 'sequence': 6, + 'summary': 'Connect the Web Client to Hardware Peripherals', + 'website': 'https://www.odoo.com/app/iot', + 'description': """ +Hardware Poxy +============= + +This module allows you to remotely use peripherals connected to this server. + +This modules only contains the enabling framework. The actual devices drivers +are found in other modules that must be installed separately. + +""", + 'assets': { + 'iot_drivers.assets': [ # dummy asset name to make sure it does not load outside of IoT homepage + 'iot_drivers/static/**/*', + ], + }, + 'installable': False, + 'author': 'Odoo S.A.', + 'license': 'LGPL-3', +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/browser.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/browser.py new file mode 100644 index 00000000..5df3c5fa --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/browser.py @@ -0,0 +1,128 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +import logging +import subprocess +from enum import Enum +from odoo.addons.iot_drivers.tools import helpers + + +_logger = logging.getLogger(__name__) + +CHROMIUM_ARGS = [ + '--incognito', + '--disable-infobars', + '--noerrdialogs', + '--no-first-run', + '--bwsi', # Use chromium without signing in + '--disable-extensions', # Disable extensions as they fill up /tmp + '--disk-cache-dir=/dev/null', # Disable disk cache + '--disk-cache-size=1', # Set disk cache size to 1 byte + '--log-level=3', # Reduce amount of logs +] + + +class BrowserState(Enum): + """Enum to represent the state of the browser""" + NORMAL = 'normal' + KIOSK = 'kiosk' + FULLSCREEN = 'fullscreen' + + +class Browser: + """Methods to interact with a browser""" + + def __init__(self, url, _x_screen, env): + """ + :param url: URL to open in the browser + :param _x_screen: X screen number + :param env: Environment variables (e.g. os.environ.copy()) + :param kiosk: Whether the browser should be in kiosk mode + """ + self.url = url + self.browser = 'chromium-browser' + self.browser_process_name = 'chromium' + self.state = BrowserState.NORMAL + self._x_screen = _x_screen + self._set_environment(env) + self.open_browser() + + def _set_environment(self, env): + """ + Set the environment variables for the browser + :param env: Environment variables (os.environ.copy()) + """ + self.env = env + self.env['DISPLAY'] = f':0.{self._x_screen}' + self.env['XAUTHORITY'] = '/run/lightdm/pi/xauthority' + for key in ['HOME', 'XDG_RUNTIME_DIR', 'XDG_CACHE_HOME']: + self.env[key] = '/tmp/' + self._x_screen + + def open_browser(self, url=None, state=BrowserState.FULLSCREEN): + """ + open the browser with the given URL, or reopen it if it is already open + :param url: URL to open in the browser + :param state: State of the browser (normal, kiosk, fullscreen) + """ + self.url = url or self.url + self.state = state + + # Reopen to take new url or additional args into account + self.close_browser() + + browser_args = list(CHROMIUM_ARGS) + + if state == BrowserState.KIOSK: + browser_args.extend(["--kiosk", "--touch-events"]) + elif state == BrowserState.FULLSCREEN: + browser_args.append("--start-fullscreen") + + subprocess.Popen( + [ + self.browser, + self.url, + *browser_args, + ], + env=self.env, + ) + + helpers.save_browser_state(url=self.url) + + def close_browser(self): + """close the browser""" + # Kill browser instance (can't `instance.pkill()` as we can't keep the instance after Odoo service restarts) + # We need to terminate it because Odoo will create a new instance each time it is restarted. + subprocess.run(['pkill', self.browser_process_name], check=False) + + def xdotool_keystroke(self, keystroke): + """ + Execute a keystroke using xdotool + :param keystroke: Keystroke to execute + """ + subprocess.run([ + 'xdotool', 'search', + '--sync', '--onlyvisible', + '--screen', self._x_screen, + '--class', self.browser_process_name, + 'key', keystroke, + ], check=False) + + def xdotool_type(self, text): + """ + Type text using xdotool + :param text: Text to type + """ + subprocess.run([ + 'xdotool', 'search', + '--sync', '--onlyvisible', + '--screen', self._x_screen, + '--class', self.browser_process_name, + 'type', text, + ], check=False) + + def refresh(self): + """Refresh the current tab""" + self.xdotool_keystroke('ctrl+r') + + def disable_kiosk_mode(self): + """Removes arguments to chromium-browser cli to open it without kiosk mode""" + if self.state == BrowserState.KIOSK: + self.open_browser(state=BrowserState.FULLSCREEN) diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/cli/genproxytoken.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/cli/genproxytoken.py new file mode 100644 index 00000000..07d51c7b --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/cli/genproxytoken.py @@ -0,0 +1,28 @@ +import secrets +import sys +import textwrap + +from passlib.hash import pbkdf2_sha512 + +from odoo.cli import Command +from odoo.tools import config + + +class GenProxyToken(Command): + """ Generate and (re)set proxy access token in config file """ + + def generate_token(self, length=16): + token = secrets.token_hex(int(length / 2)) + split_size = int(length / 4) + return '-'.join(textwrap.wrap(token, split_size)) + + def run(self, cmdargs): + self.parser.add_argument('-c', '--config', type=str, help="Specify an alternate config file") + self.parser.add_argument('--token-length', type=int, help="Token Length", default=16) + args, _ = self.parser.parse_known_args() + if args.config: + config.rcfile = args.config + token = self.generate_token(length=args.token_length) + config['proxy_access_token'] = pbkdf2_sha512.hash(token) + config.save() + sys.stdout.write(f'{token}\n') diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/connection_manager.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/connection_manager.py new file mode 100644 index 00000000..36a5563e --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/connection_manager.py @@ -0,0 +1,115 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import logging +import requests +from threading import Thread +import time + +from odoo.addons.iot_drivers.main import iot_devices, manager +from odoo.addons.iot_drivers.tools import helpers, upgrade, wifi +from odoo.addons.iot_drivers.tools.system import IS_RPI, IS_TEST + +_logger = logging.getLogger(__name__) + + +class ConnectionManager(Thread): + daemon = True + + def __init__(self): + super().__init__() + self.pairing_code = False + self.pairing_uuid = False + self.pairing_code_expired = False + self.new_database_url = False + + self.iot_box_registered = False + self.n_times_polled = -1 + + requests.packages.urllib3.disable_warnings() + + def _register_iot_box(self): + """ This method is called to register the IoT Box on odoo.com and get a pairing code""" + req = self._call_iot_proxy() + if all(key in req for key in ['pairing_code', 'pairing_uuid']): + self.pairing_code = req['pairing_code'] + self.pairing_uuid = req['pairing_uuid'] + if IS_RPI: + self._try_print_pairing_code() + self.iot_box_registered = True + + def _get_next_polling_interval(self): + # To avoid spamming odoo.com with requests we gradually space out the requests + # e.g If the pairing code is valid for 2 hours this would lead to max 329 requests + # Starting with 15 seconds and ending with 40s interval, staying under 20s for 50 min + self.n_times_polled += 1 + return 14 + 1.01 ** self.n_times_polled + + def run(self): + # Double loop is needed in case the IoT Box isn't initially connected to the internet + while True: + while self._should_poll_to_connect_database(): + if not self.iot_box_registered: + self._register_iot_box() + + self._poll_pairing_result() + time.sleep(self._get_next_polling_interval()) + time.sleep(5) + + def _should_poll_to_connect_database(self): + return ( + not helpers.get_odoo_server_url() and + helpers.get_ip() and + not (IS_RPI and wifi.is_access_point()) and + not self.pairing_code_expired + ) + + def _call_iot_proxy(self): + data = { + 'params': { + 'pairing_code': self.pairing_code, + 'pairing_uuid': self.pairing_uuid, + 'serial_number': helpers.get_identifier(), + } + } + + try: + req = requests.post( + 'https://iot-proxy.odoo.com/odoo-enterprise/iot/connect-box', + json=data, + timeout=5, + ) + req.raise_for_status() + if req.json().get('error') == 'expired': + self.pairing_code_expired = True + self.pairing_code = False + self.pairing_uuid = False + return req.json().get('result', {}) + except Exception: + _logger.exception('Could not reach iot-proxy.odoo.com') + return {} + + def _poll_pairing_result(self): + result = self._call_iot_proxy() + if all(key in result for key in ['url', 'token', 'db_uuid', 'enterprise_code']): + self._connect_to_server(result['url'], result['token'], result['db_uuid'], result['enterprise_code']) + + def _connect_to_server(self, url, token, db_uuid, enterprise_code): + self.new_database_url = url + # Save DB URL and token + helpers.save_conf_server(url, token, db_uuid, enterprise_code) + # Send already detected devices and IoT Box info to the database + manager._send_all_devices() + # Switch git branch before restarting, this avoids restarting twice + upgrade.check_git_branch() + # Restart to get a certificate, load the IoT handlers... + helpers.odoo_restart(2) + + def _try_print_pairing_code(self): + printers = [device for device in iot_devices.values() if device.device_type == 'printer' and device.connected_by_usb and device.device_subtype in ['receipt_printer', 'label_printer']] + for printer in printers: + printer.print_status() + + +connection_manager = ConnectionManager() +if not IS_TEST: + connection_manager.start() diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/controllers/__init__.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/controllers/__init__.py new file mode 100644 index 00000000..5a69ca74 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/controllers/__init__.py @@ -0,0 +1,5 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import driver +from . import proxy +from . import homepage diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/controllers/driver.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/controllers/driver.py new file mode 100644 index 00000000..3e58462d --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/controllers/driver.py @@ -0,0 +1,96 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from datetime import datetime +import logging +import os +from socket import gethostname +import time +from werkzeug.exceptions import InternalServerError +from zlib import adler32 + +from odoo import http, tools + +from odoo.addons.iot_drivers.event_manager import event_manager +from odoo.addons.iot_drivers.main import iot_devices +from odoo.addons.iot_drivers.tools import helpers, route + +_logger = logging.getLogger(__name__) + +DEVICE_TYPES = [ + "display", "printer", "scanner", "keyboard", "camera", "device", "payment", "scale", "fiscal_data_module" +] + + +class DriverController(http.Controller): + @helpers.toggleable + @route.iot_route('/iot_drivers/action', type='jsonrpc', cors='*', csrf=False) + def action(self, session_id, device_identifier, data): + """This route is called when we want to make an action with device (take picture, printing,...) + We specify in data from which session_id that action is called + And call the action of specific device + """ + # If device_identifier is a type of device, we take the first device of this type + # required for longpolling with community db + if device_identifier in DEVICE_TYPES: + device_identifier = next((d for d in iot_devices if iot_devices[d].device_type == device_identifier), None) + + iot_device = iot_devices.get(device_identifier) + + if not iot_device: + _logger.warning("IoT Device with identifier %s not found", device_identifier) + return False + + data['session_id'] = session_id # ensure session_id is in data as for websocket communication + _logger.debug("Calling action %s for device %s", data.get('action', ''), device_identifier) + iot_device.action(data) + return True + + @helpers.toggleable + @route.iot_route('/iot_drivers/event', type='jsonrpc', cors='*', csrf=False) + def event(self, listener): + """ + listener is a dict in witch there are a sessions_id and a dict of device_identifier to listen + """ + req = event_manager.add_request(listener) + # Search for previous events and remove events older than 5 seconds + oldest_time = time.time() - 5 + for event in list(event_manager.events): + if event['time'] < oldest_time: + del event_manager.events[0] + continue + if event['device_identifier'] in listener['devices'] and event['time'] > listener['last_event']: + event['session_id'] = req['session_id'] + _logger.debug("Event %s found for device %s ", event, event['device_identifier']) + return event + + # Wait for new event + if req['event'].wait(50): + req['event'].clear() + req['result']['session_id'] = req['session_id'] + return req['result'] + + @route.iot_route('/iot_drivers/download_logs', type='http', cors='*', csrf=False) + def download_logs(self): + """ + Downloads the log file + """ + log_path = tools.config['logfile'] or "/var/log/odoo/odoo-server.log" + try: + stat = os.stat(log_path) + except FileNotFoundError: + raise InternalServerError("Log file has not been found. Check your Log file configuration.") + check = adler32(log_path.encode()) + log_file_name = f"iot-odoo-{gethostname()}-{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.log" + # intentionally don't use Stream.from_path as the path used is not in the addons path + # for instance, for the iot-box it will be in /var/log/odoo + return http.Stream( + type='path', + path=log_path, + download_name=log_file_name, + etag=f'{int(stat.st_mtime)}-{stat.st_size}-{check}', + last_modified=stat.st_mtime, + size=stat.st_size, + mimetype='text/plain', + ).get_response( + mimetype='text/plain', as_attachment=True + ) diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/controllers/homepage.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/controllers/homepage.py new file mode 100644 index 00000000..68463421 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/controllers/homepage.py @@ -0,0 +1,486 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import json +import logging +import netifaces +import subprocess +import threading +import time + +from itertools import groupby +from pathlib import Path + +from odoo import http +from odoo.addons.iot_drivers.tools import certificate, helpers, route, upgrade, wifi +from odoo.addons.iot_drivers.tools.system import IOT_SYSTEM, IS_RPI +from odoo.addons.iot_drivers.main import iot_devices, unsupported_devices +from odoo.addons.iot_drivers.connection_manager import connection_manager +from odoo.tools.misc import file_path +from odoo.addons.iot_drivers.server_logger import ( + check_and_update_odoo_config_log_to_server_option, + get_odoo_config_log_to_server_option, + close_server_log_sender_handler, +) + +_logger = logging.getLogger(__name__) + +IOT_LOGGING_PREFIX = 'iot-logging-' +INTERFACE_PREFIX = 'interface-' +DRIVER_PREFIX = 'driver-' +AVAILABLE_LOG_LEVELS = ('debug', 'info', 'warning', 'error') +AVAILABLE_LOG_LEVELS_WITH_PARENT = AVAILABLE_LOG_LEVELS + ('parent',) + +CONTENT_SECURITY_POLICY = ( + "default-src 'none';" + "script-src 'self' 'unsafe-eval';" # OWL requires `unsafe-eval` to render templates + "connect-src 'self';" + "img-src 'self' data:;" # `data:` scheme required as Bootstrap uses it for embedded SVGs + "style-src 'self';" + "font-src 'self';" +) + + +class IotBoxOwlHomePage(http.Controller): + def __init__(self): + super().__init__() + self.updating = threading.Lock() + + @route.iot_route('/', type='http') + def index(self): + return http.Stream.from_path("iot_drivers/views/index.html").get_response(content_security_policy=CONTENT_SECURITY_POLICY) + + @route.iot_route('/logs', type='http') + def logs_page(self): + return http.Stream.from_path("iot_drivers/views/logs.html").get_response(content_security_policy=CONTENT_SECURITY_POLICY) + + @route.iot_route('/status', type='http') + def status_page(self): + return http.Stream.from_path("iot_drivers/views/status_display.html").get_response(content_security_policy=CONTENT_SECURITY_POLICY) + + # ---------------------------------------------------------- # + # GET methods # + # -> Always use json.dumps() to return a JSON response # + # ---------------------------------------------------------- # + @route.iot_route('/iot_drivers/restart_odoo_service', type='http', cors='*') + def odoo_service_restart(self): + helpers.odoo_restart(0) + return json.dumps({ + 'status': 'success', + 'message': 'Odoo service restarted', + }) + + @route.iot_route('/iot_drivers/iot_logs', type='http', cors='*') + def get_iot_logs(self): + logs_path = "/var/log/odoo/odoo-server.log" if IS_RPI else Path().absolute().parent.joinpath('odoo.log') + with open(logs_path, encoding="utf-8") as file: + return json.dumps({ + 'status': 'success', + 'logs': file.read(), + }) + + @route.iot_route('/iot_drivers/six_payment_terminal_clear', type='http', cors='*') + def clear_six_terminal(self): + helpers.update_conf({'six_payment_terminal': ''}) + return json.dumps({ + 'status': 'success', + 'message': 'Successfully cleared Six Payment Terminal', + }) + + @route.iot_route('/iot_drivers/clear_credential', type='http', cors='*') + def clear_credential(self): + helpers.update_conf({ + 'db_uuid': '', + 'enterprise_code': '', + }) + helpers.odoo_restart(0) + return json.dumps({ + 'status': 'success', + 'message': 'Successfully cleared credentials', + }) + + @route.iot_route('/iot_drivers/wifi_clear', type='http', cors='*', linux_only=True) + def clear_wifi_configuration(self): + helpers.update_conf({'wifi_ssid': '', 'wifi_password': ''}) + wifi.disconnect() + return json.dumps({ + 'status': 'success', + 'message': 'Successfully disconnected from wifi', + }) + + @route.iot_route('/iot_drivers/server_clear', type='http', cors='*') + def clear_server_configuration(self): + helpers.disconnect_from_server() + close_server_log_sender_handler() + return json.dumps({ + 'status': 'success', + 'message': 'Successfully disconnected from server', + }) + + @route.iot_route('/iot_drivers/ping', type='http', cors='*') + def ping(self): + return json.dumps({ + 'status': 'success', + 'message': 'pong', + }) + + @route.iot_route('/iot_drivers/data', type="http", cors='*') + def get_homepage_data(self): + network_interfaces = [] + if IS_RPI: + ssid = wifi.get_current() or wifi.get_access_point_ssid() + for iface_id in netifaces.interfaces(): + if iface_id == 'lo': + continue # Skip loopback interface (127.0.0.1) + + is_wifi = 'wlan' in iface_id + network_interfaces.extend([{ + 'id': iface_id, + 'is_wifi': is_wifi, + 'ssid': ssid if is_wifi else None, + 'ip': conf.get('addr', 'No Internet'), + } for conf in netifaces.ifaddresses(iface_id).get(netifaces.AF_INET, [])]) + + devices = [{ + 'name': device.device_name, + 'type': device.device_type, + 'identifier': device.device_identifier, + 'connection': device.device_connection, + } for device in iot_devices.values()] + devices += list(unsupported_devices.values()) + + def device_type_key(device): + return device['type'] + + grouped_devices = { + device_type: list(devices) + for device_type, devices in groupby(sorted(devices, key=device_type_key), device_type_key) + } + + six_terminal = helpers.get_conf('six_payment_terminal') or 'Not Configured' + network_qr_codes = wifi.generate_network_qr_codes() if IS_RPI else {} + odoo_server_url = helpers.get_odoo_server_url() or '' + odoo_uptime_seconds = time.monotonic() - helpers.odoo_start_time + system_uptime_seconds = time.monotonic() - helpers.system_start_time + + return json.dumps({ + 'db_uuid': helpers.get_conf('db_uuid'), + 'enterprise_code': helpers.get_conf('enterprise_code'), + 'ip': helpers.get_ip(), + 'identifier': helpers.get_identifier(), + 'mac_address': helpers.get_mac_address(), + 'devices': grouped_devices, + 'server_status': odoo_server_url, + 'pairing_code': connection_manager.pairing_code, + 'new_database_url': connection_manager.new_database_url, + 'pairing_code_expired': connection_manager.pairing_code_expired and not odoo_server_url, + 'six_terminal': six_terminal, + 'is_access_point_up': IS_RPI and wifi.is_access_point(), + 'network_interfaces': network_interfaces, + 'version': helpers.get_version(), + 'system': IOT_SYSTEM, + 'odoo_uptime_seconds': odoo_uptime_seconds, + 'system_uptime_seconds': system_uptime_seconds, + 'certificate_end_date': certificate.get_certificate_end_date(), + 'wifi_ssid': helpers.get_conf('wifi_ssid'), + 'qr_code_wifi': network_qr_codes.get('qr_wifi'), + 'qr_code_url': network_qr_codes.get('qr_url'), + }) + + @route.iot_route('/iot_drivers/wifi', type="http", cors='*', linux_only=True) + def get_available_wifi(self): + return json.dumps({ + 'currentWiFi': wifi.get_current(), + 'availableWiFi': wifi.get_available_ssids(), + }) + + @route.iot_route('/iot_drivers/version_info', type="http", cors='*', linux_only=True) + def get_version_info(self): + # Check branch name and last commit hash on IoT Box + current_commit = upgrade.git("rev-parse", "HEAD") + current_branch = upgrade.git("rev-parse", "--abbrev-ref", "HEAD") + if not current_commit or not current_branch: + return json.dumps({ + 'status': 'error', + 'message': 'Failed to retrieve current commit or branch', + }) + + last_available_commit = upgrade.git("ls-remote", "origin", current_branch) + if not last_available_commit: + _logger.error("Failed to retrieve last commit available for branch origin/%s", current_branch) + return json.dumps({ + 'status': 'error', + 'message': 'Failed to retrieve last commit available for branch origin/' + current_branch, + }) + last_available_commit = last_available_commit.split()[0].strip() + + return json.dumps({ + 'status': 'success', + # Checkout requires db to align with its version (=branch) + 'odooIsUpToDate': current_commit == last_available_commit or not bool(helpers.get_odoo_server_url()), + 'imageIsUpToDate': IS_RPI and not bool(helpers.check_image()), + 'currentCommitHash': current_commit, + }) + + @route.iot_route('/iot_drivers/log_levels', type="http", cors='*') + def log_levels(self): + drivers_list = helpers.get_handlers_files_to_load( + file_path('iot_drivers/iot_handlers/drivers')) + interfaces_list = helpers.get_handlers_files_to_load( + file_path('iot_drivers/iot_handlers/interfaces')) + return json.dumps({ + 'title': "Odoo's IoT Box - Handlers list", + 'breadcrumb': 'Handlers list', + 'drivers_list': drivers_list, + 'interfaces_list': interfaces_list, + 'server': helpers.get_odoo_server_url(), + 'is_log_to_server_activated': get_odoo_config_log_to_server_option(), + 'root_logger_log_level': self._get_logger_effective_level_str(logging.getLogger()), + 'odoo_current_log_level': self._get_logger_effective_level_str(logging.getLogger('odoo')), + 'recommended_log_level': 'warning', + 'available_log_levels': AVAILABLE_LOG_LEVELS, + 'drivers_logger_info': self._get_iot_handlers_logger(drivers_list, 'drivers'), + 'interfaces_logger_info': self._get_iot_handlers_logger(interfaces_list, 'interfaces'), + }) + + @route.iot_route('/iot_drivers/load_iot_handlers', type="http", cors='*') + def load_iot_handlers(self): + helpers.download_iot_handlers(False) + helpers.odoo_restart(0) + return json.dumps({ + 'status': 'success', + 'message': 'IoT Handlers loaded successfully', + }) + + @route.iot_route('/iot_drivers/is_ngrok_enabled', type="http", linux_only=True) + def is_ngrok_enabled(self): + return json.dumps({'enabled': helpers.is_ngrok_enabled()}) + + # ---------------------------------------------------------- # + # POST methods # + # -> Never use json.dumps() it will be done automatically # + # ---------------------------------------------------------- # + @route.iot_route('/iot_drivers/six_payment_terminal_add', type="jsonrpc", methods=['POST'], cors='*') + def add_six_terminal(self, terminal_id): + if terminal_id.isdigit(): + helpers.update_conf({'six_payment_terminal': terminal_id}) + else: + _logger.warning('Ignoring invalid Six TID: "%s". Only digits are allowed', terminal_id) + return self.clear_six_terminal() + return { + 'status': 'success', + 'message': 'Successfully saved Six Payment Terminal', + } + + @route.iot_route('/iot_drivers/save_credential', type="jsonrpc", methods=['POST'], cors='*') + def save_credential(self, db_uuid, enterprise_code): + helpers.update_conf({ + 'db_uuid': db_uuid, + 'enterprise_code': enterprise_code, + }) + helpers.odoo_restart(0) + return { + 'status': 'success', + 'message': 'Successfully saved credentials', + } + + @route.iot_route('/iot_drivers/update_wifi', type="jsonrpc", methods=['POST'], cors='*', linux_only=True) + def update_wifi(self, essid, password): + if wifi.reconnect(essid, password, force_update=True): + helpers.update_conf({'wifi_ssid': essid, 'wifi_password': password}) + + res_payload = { + 'status': 'success', + 'message': 'Connecting to ' + essid, + } + else: + res_payload = { + 'status': 'error', + 'message': 'Failed to connect to ' + essid, + } + + return res_payload + + @route.iot_route( + '/iot_drivers/generate_password', type="jsonrpc", methods=["POST"], cors='*', linux_only=True + ) + def generate_password(self): + return { + 'password': helpers.generate_password(), + } + + @route.iot_route('/iot_drivers/enable_ngrok', type="jsonrpc", methods=['POST'], linux_only=True) + def enable_remote_connection(self, auth_token): + return {'status': 'success' if helpers.toggle_remote_connection(auth_token) else 'failure'} + + @route.iot_route('/iot_drivers/disable_ngrok', type="jsonrpc", methods=['POST'], linux_only=True) + def disable_remote_connection(self): + return {'status': 'success' if helpers.toggle_remote_connection() else 'failure'} + + @route.iot_route('/iot_drivers/connect_to_server', type="jsonrpc", methods=['POST'], cors='*') + def connect_to_odoo_server(self, token): + if token: + try: + if len(token.split('|')) == 4: + # Old style token with pipe separators (pre v18 DB) + url, token, db_uuid, enterprise_code = token.split('|') + configuration = helpers.parse_url(url) + helpers.save_conf_server(configuration["url"], token, db_uuid, enterprise_code) + else: + # New token using query params (v18+ DB) + configuration = helpers.parse_url(token) + helpers.save_conf_server(**configuration) + except ValueError: + _logger.warning("Wrong server token: %s", token) + return { + 'status': 'failure', + 'message': 'Invalid URL provided.', + } + except (subprocess.CalledProcessError, OSError, Exception): + return { + 'status': 'failure', + 'message': 'Failed to write server configuration files on IoT. Please try again.', + } + + # 1 sec delay for IO operations (save_conf_server) + helpers.odoo_restart(1) + return { + 'status': 'success', + 'message': 'Successfully connected to db, IoT will restart to update the configuration.', + } + + @route.iot_route('/iot_drivers/log_levels_update', type="jsonrpc", methods=['POST'], cors='*') + def update_log_level(self, name, value): + if not name.startswith(IOT_LOGGING_PREFIX) and name != 'log-to-server': + return { + 'status': 'error', + 'message': 'Invalid logger name', + } + + if name == 'log-to-server': + check_and_update_odoo_config_log_to_server_option(value) + + name = name[len(IOT_LOGGING_PREFIX):] + if name == 'root': + self._update_logger_level('', value, AVAILABLE_LOG_LEVELS) + elif name == 'odoo': + self._update_logger_level('odoo', value, AVAILABLE_LOG_LEVELS) + self._update_logger_level('werkzeug', value if value != 'debug' else 'info', AVAILABLE_LOG_LEVELS) + elif name.startswith(INTERFACE_PREFIX): + logger_name = name[len(INTERFACE_PREFIX):] + self._update_logger_level(logger_name, value, AVAILABLE_LOG_LEVELS_WITH_PARENT, 'interfaces') + elif name.startswith(DRIVER_PREFIX): + logger_name = name[len(DRIVER_PREFIX):] + self._update_logger_level(logger_name, value, AVAILABLE_LOG_LEVELS_WITH_PARENT, 'drivers') + else: + _logger.warning('Unhandled iot logger: %s', name) + + return { + 'status': 'success', + 'message': 'Logger level updated', + } + + @route.iot_route('/iot_drivers/update_git_tree', type="jsonrpc", methods=['POST'], cors='*', linux_only=True) + def update_git_tree(self): + upgrade.check_git_branch() + return { + 'status': 'success', + 'message': 'Successfully updated the IoT Box', + } + + # ---------------------------------------------------------- # + # Utils # + # ---------------------------------------------------------- # + def _get_iot_handlers_logger(self, handlers_name, iot_handler_folder_name): + handlers_loggers_level = dict() + for handler_name in handlers_name: + handler_logger = self._get_iot_handler_logger(handler_name, iot_handler_folder_name) + if not handler_logger: + # Might happen if the file didn't define a logger (or not init yet) + handlers_loggers_level[handler_name] = False + _logger.debug('Unable to find logger for handler %s', handler_name) + continue + logger_parent = handler_logger.parent + handlers_loggers_level[handler_name] = { + 'level': self._get_logger_effective_level_str(handler_logger), + 'is_using_parent_level': handler_logger.level == logging.NOTSET, + 'parent_name': logger_parent.name, + 'parent_level': self._get_logger_effective_level_str(logger_parent), + } + return handlers_loggers_level + + def _update_logger_level(self, logger_name, new_level, available_log_levels, handler_folder=False): + """Update (if necessary) Odoo's configuration and logger to the given logger_name to the given level. + The responsibility of saving the config file is not managed here. + + :param logger_name: name of the logging logger to change level + :param new_level: new log level to set for this logger + :param available_log_levels: iterable of logs levels allowed (for initial check) + :param str handler_folder: optional string of the IoT handler folder name ('interfaces' or 'drivers') + """ + # We store the timestamp to reset the log level to warning after a week (7 days * 24 hours * 3600 seconds) + # This is to avoid sending polluted logs with debug messages to the db + conf = {'log_level_reset_timestamp': str(time.time() + 7 * 24 * 3600)} + + if new_level not in available_log_levels: + _logger.warning('Unknown level to set on logger %s: %s', logger_name, new_level) + return + + if handler_folder: + logger = self._get_iot_handler_logger(logger_name, handler_folder) + if not logger: + _logger.warning('Unable to change log level for logger %s as logger missing', logger_name) + return + logger_name = logger.name + + ODOO_TOOL_CONFIG_HANDLER_NAME = 'log_handler' + LOG_HANDLERS = (helpers.get_conf(ODOO_TOOL_CONFIG_HANDLER_NAME, section='options') or []).split(',') + LOGGER_PREFIX = logger_name + ':' + IS_NEW_LEVEL_PARENT = new_level == 'parent' + + if not IS_NEW_LEVEL_PARENT: + intended_to_find = LOGGER_PREFIX + new_level.upper() + if intended_to_find in LOG_HANDLERS: + # There is nothing to do, the entry is already inside + return + + # We remove every occurrence for the given logger + log_handlers_without_logger = [ + log_handler for log_handler in LOG_HANDLERS if not log_handler.startswith(LOGGER_PREFIX) + ] + + if IS_NEW_LEVEL_PARENT: + # We must check that there is no existing entries using this logger (whatever the level) + if len(log_handlers_without_logger) == len(LOG_HANDLERS): + return + + # We add if necessary new logger entry + # If it is "parent" it means we want it to inherit from the parent logger. + # In order to do this we have to make sure that no entries for the logger exists in the + # `log_handler` (which is the case at this point as long as we don't re-add an entry) + new_level_upper_case = new_level.upper() + if not IS_NEW_LEVEL_PARENT: + new_entry = LOGGER_PREFIX + new_level_upper_case + log_handlers_without_logger.append(new_entry) + _logger.debug('Adding to odoo config log_handler: %s', new_entry) + conf[ODOO_TOOL_CONFIG_HANDLER_NAME] = ','.join(log_handlers_without_logger) + + # Update the logger dynamically + real_new_level = logging.NOTSET if IS_NEW_LEVEL_PARENT else new_level_upper_case + _logger.debug('Change logger %s level to %s', logger_name, real_new_level) + logging.getLogger(logger_name).setLevel(real_new_level) + + helpers.update_conf(conf, section='options') + + def _get_logger_effective_level_str(self, logger): + return logging.getLevelName(logger.getEffectiveLevel()).lower() + + def _get_iot_handler_logger(self, handler_name, handler_folder_name): + """ + Get Odoo Iot logger given an IoT handler name + :param handler_name: name of the IoT handler + :param handler_folder_name: IoT handler folder name (interfaces or drivers) + :return: logger if any, False otherwise + """ + odoo_addon_handler_path = helpers.compute_iot_handlers_addon_name(handler_folder_name, handler_name) + return odoo_addon_handler_path in logging.Logger.manager.loggerDict and \ + logging.getLogger(odoo_addon_handler_path) diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/controllers/proxy.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/controllers/proxy.py new file mode 100644 index 00000000..a60ddf84 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/controllers/proxy.py @@ -0,0 +1,19 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import http +from odoo.addons.iot_drivers.tools import route + +proxy_drivers = {} + + +class ProxyController(http.Controller): + @route.iot_route('/hw_proxy/hello', type='http', cors='*') + def hello(self): + return "ping" + + @route.iot_route('/hw_proxy/status_json', type='jsonrpc', cors='*') + def status_json(self): + return { + driver: instance.get_status() + for driver, instance in proxy_drivers.items() + } diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/driver.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/driver.py new file mode 100644 index 00000000..31a1282d --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/driver.py @@ -0,0 +1,81 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +import logging +from threading import Thread, Event + +from odoo.addons.iot_drivers.main import drivers, iot_devices +from odoo.addons.iot_drivers.event_manager import event_manager +from odoo.addons.iot_drivers.tools.helpers import toggleable +from odoo.tools.lru import LRU + +_logger = logging.getLogger(__name__) + + +class Driver(Thread): + """Hook to register the driver into the drivers list""" + connection_type = '' + daemon = True + priority = 0 + + def __init__(self, identifier, device): + super().__init__() + self.dev = device + self.device_identifier = identifier + self.device_name = '' + self.device_connection = '' + self.device_type = '' + self.device_manufacturer = '' + self.data = {'value': '', 'result': ''} # TODO: deprecate "value"? + self._actions = {} + self._stopped = Event() + self._recent_action_ids = LRU(256) + + def __init_subclass__(cls): + super().__init_subclass__() + if cls not in drivers: + drivers.append(cls) + + @classmethod + def supported(cls, device): + """ + On specific driver override this method to check if device is supported or not + return True or False + """ + return False + + @toggleable + def action(self, data): + """Helper function that calls a specific action method on the device. + + :param dict data: the action method name and the parameters to be passed to it + :return: the result of the action method + """ + if self._check_if_action_is_duplicate(data.get('action_unique_id')): + return + + action = data.get('action', '') + session_id = data.get('session_id') + if session_id: + self.data["owner"] = session_id + try: + response = {'status': 'success', 'result': self._actions[action](data), 'action_args': {**data}} + except Exception as e: + _logger.exception("Error while executing action %s with params %s", action, data) + response = {'status': 'error', 'result': str(e), 'action_args': {**data}} + + # Make response available to /event route or websocket + # printers handle their own events (low on paper, etc.) + if self.device_type != "printer": + event_manager.device_changed(self, response) + + def _check_if_action_is_duplicate(self, action_unique_id): + if not action_unique_id: + return False + if action_unique_id in self._recent_action_ids: + _logger.warning("Duplicate action %s received, ignoring", action_unique_id) + return True + self._recent_action_ids[action_unique_id] = action_unique_id + return False + + def disconnect(self): + self._stopped.set() + del iot_devices[self.device_identifier] diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/event_manager.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/event_manager.py new file mode 100644 index 00000000..53b70e25 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/event_manager.py @@ -0,0 +1,84 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from threading import Event +import time + +from odoo.http import request +from odoo.addons.iot_drivers.tools import helpers +from odoo.addons.iot_drivers.webrtc_client import webrtc_client +from odoo.addons.iot_drivers.websocket_client import send_to_controller + + +class EventManager: + def __init__(self): + self.events = [] + self.sessions = {} + + def _delete_expired_sessions(self, ttl=70): + """Clear sessions that are no longer called. + + :param int ttl: time a session can stay unused before being deleted + """ + self.sessions = { + session: self.sessions[session] + for session in self.sessions + if self.sessions[session]['time_request'] + ttl < time.time() + } + + def add_request(self, listener): + """Create a new session for the listener. + :param dict listener: listener id and devices + :return: the session created + """ + session_id = listener['session_id'] + session = { + 'session_id': session_id, + 'devices': listener['devices'], + 'event': Event(), + 'result': {}, + 'time_request': time.time(), + } + self._delete_expired_sessions() + + self.sessions[session_id] = session + return session + + def device_changed(self, device, data=None): + """Register a new event. + + If ``data`` is provided, it means that the caller is the action method, + it will be used as the event data (instead of the one provided by the request). + + :param Driver device: actual device class + :param dict data: data returned by the device (optional) + """ + data = data or (request.params.get('data', {}) if request else {}) + + # Make notification available to longpolling event route + event = { + **device.data, + 'device_identifier': device.device_identifier, + 'time': time.time(), + **data, + } + send_to_controller({ + **event, + 'session_id': data.get('action_args', {}).get('session_id', ''), + 'iot_box_identifier': helpers.get_identifier(), + **data, + }) + webrtc_client.send(event) + self.events.append(event) + for session in self.sessions: + session_devices = self.sessions[session]['devices'] + if ( + any(d in [device.device_identifier, device.device_type] for d in session_devices) + and not self.sessions[session]['event'].is_set() + ): + if device.device_type in session_devices: + event['device_identifier'] = device.device_type # allow device type as identifier (longpolling) + self.sessions[session]['result'] = event + self.sessions[session]['event'].set() + + +event_manager = EventManager() diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/exception_logger.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/exception_logger.py new file mode 100644 index 00000000..2356d876 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/exception_logger.py @@ -0,0 +1,38 @@ + +from io import StringIO + +import logging +import sys + +from odoo.addons.iot_drivers.tools.system import IS_TEST + +_logger = logging.getLogger(__name__) + + +class ExceptionLogger: + """ + Redirect any unhandled python exception to the logger to keep track of them in the log file. + """ + def __init__(self): + self._buffer = StringIO() + + def write(self, message): + self._buffer.write(message) + if message.endswith('\n'): + self._flush_buffer() + + def _flush_buffer(self): + self._buffer.seek(0) + _logger.error(self._buffer.getvalue().rstrip('\n')) + self._buffer = StringIO() # Reset the buffer + + def flush(self): + if self._buffer.tell() > 0: + self._flush_buffer() + + def close(self): + self.flush() + + +if not IS_TEST: + sys.stderr = ExceptionLogger() diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/http.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/http.py new file mode 100644 index 00000000..875f895b --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/http.py @@ -0,0 +1,41 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import collections +import odoo.http + +from odoo.http import JsonRPCDispatcher, serialize_exception +from odoo.addons.iot_drivers.tools.system import IS_TEST +from werkzeug.exceptions import Forbidden + + +class JsonRPCDispatcherPatch(JsonRPCDispatcher): + def handle_error(self, exc: Exception) -> collections.abc.Callable: + """Monkey patch the handle_error method to add HTTP 403 Forbidden + error handling. + + :param exc: the exception that occurred. + :returns: a WSGI application + """ + error = { + 'code': 200, # this code is the JSON-RPC level code, it is + # distinct from the HTTP status code. This + # code is ignored and the value 200 (while + # misleading) is totally arbitrary. + 'message': "Odoo Server Error", + 'data': serialize_exception(exc), + } + if isinstance(exc, Forbidden): + error['code'] = 403 + error['message'] = "403: Forbidden" + error['data'] = {"message": error['data']["message"]} # only keep the message, not the traceback + + return self._response(error=error) + + +if not IS_TEST: + # Test IoT system is expected to handle Odoo database unlike "real" IoT systems. + + def db_list(force=False, host=None): + return [] + + odoo.http.db_list = db_list diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/interface.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/interface.py new file mode 100644 index 00000000..f293dba0 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/interface.py @@ -0,0 +1,91 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import logging +from threading import Thread +import time + +from odoo.addons.iot_drivers.main import drivers, interfaces, iot_devices, unsupported_devices + +_logger = logging.getLogger(__name__) + + +class Interface(Thread): + _loop_delay = 3 # Delay (in seconds) between calls to get_devices or 0 if it should be called only once + connection_type = '' + allow_unsupported = False + daemon = True + + def __init__(self): + super().__init__() + self._detected_devices = set() + self.drivers = sorted([d for d in drivers if d.connection_type == self.connection_type], key=lambda d: d.priority, reverse=True) + + def __init_subclass__(cls): + super().__init_subclass__() + interfaces[cls.__name__] = cls + + def run(self): + while self.connection_type and self.drivers: + self.update_iot_devices(self.get_devices()) + if not self._loop_delay: + break + time.sleep(self._loop_delay) + + def add_device(self, identifier, device): + if identifier in iot_devices: + return + supported_driver = next( + (driver for driver in self.drivers if driver.supported(device)), + None + ) + if supported_driver: + _logger.info('Device %s is now connected', identifier) + if identifier in unsupported_devices: + del unsupported_devices[identifier] + d = supported_driver(identifier, device) + iot_devices[identifier] = d + # Start the thread after creating the iot_devices entry so the + # thread can assume the iot_devices entry will exist while it's + # running, at least until the `disconnect` above gets triggered + # when `removed` is not empty. + d.start() + elif self.allow_unsupported and identifier not in unsupported_devices: + _logger.info('Unsupported device %s is now connected', identifier) + unsupported_devices[identifier] = { + 'name': f'Unknown device ({self.connection_type})', + 'identifier': identifier, + 'type': 'unsupported', + 'connection': 'direct' if self.connection_type == 'usb' else self.connection_type, + } + + def remove_device(self, identifier): + if identifier in iot_devices: + iot_devices[identifier].disconnect() + _logger.info('Device %s is now disconnected', identifier) + elif self.allow_unsupported and identifier in unsupported_devices: + del unsupported_devices[identifier] + _logger.info('Unsupported device %s is now disconnected', identifier) + + def update_iot_devices(self, devices=None): + if devices is None: + devices = {} + + added = devices.keys() - self._detected_devices + removed = self._detected_devices - devices.keys() + unsupported = {device for device in unsupported_devices if device in devices} + self._detected_devices = set(devices.keys()) + + for identifier in removed: + self.remove_device(identifier) + + for identifier in added | unsupported: + self.add_device(identifier, devices[identifier]) + + def get_devices(self): + raise NotImplementedError() + + def start(self): + try: + super().start() + except Exception: + _logger.exception("Interface %s could not be started", str(self)) diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/display_driver_L.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/display_driver_L.py new file mode 100644 index 00000000..6d064660 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/display_driver_L.py @@ -0,0 +1,150 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import json +import logging +import os +import requests +import subprocess +import time +import werkzeug + +from odoo import http +from odoo.addons.iot_drivers.browser import Browser, BrowserState +from odoo.addons.iot_drivers.driver import Driver +from odoo.addons.iot_drivers.main import iot_devices +from odoo.addons.iot_drivers.tools import helpers, route +from odoo.addons.iot_drivers.tools.helpers import Orientation + +_logger = logging.getLogger(__name__) + + +class DisplayDriver(Driver): + connection_type = 'display' + + def __init__(self, identifier, device): + super().__init__(identifier, device) + self.device_type = 'display' + self.device_connection = 'hdmi' + self.device_name = device['name'] + self.owner = False + self.customer_display_data = {} + + saved_url, self.orientation = helpers.load_browser_state() + self._x_screen = device.get('x_screen', '0') + self.url = saved_url or self.get_url_from_db() or 'http://localhost:8069/status/' + self.browser = Browser(self.url, self._x_screen, os.environ.copy()) + self.set_orientation(self.orientation) + + self._actions.update({ + 'update_url': self._action_update_url, + 'display_refresh': self._action_display_refresh, + 'open_kiosk': self._action_open_kiosk, + 'rotate_screen': self._action_rotate_screen, + 'open': self._action_open_customer_display, + 'close': self._action_close_customer_display, + 'set': self._action_set_customer_display, + }) + + @classmethod + def supported(cls, device): + return True # All devices with connection_type == 'display' are supported + + @classmethod + def get_default_display(cls): + displays = list(filter(lambda d: iot_devices[d].device_type == 'display', iot_devices)) + return len(displays) and iot_devices[displays[0]] + + def run(self): + while not self._stopped.is_set() and "pos_customer_display" not in self.url: + time.sleep(60) + if self.url != 'http://localhost:8069/status/' and self.browser.state != BrowserState.KIOSK: + # Refresh the page every minute + self.browser.refresh() + + def update_url(self, url=None): + self.url = ( + url + or helpers.load_browser_state()[0] + or 'http://localhost:8069/status/' + ) + + browser_state = BrowserState.KIOSK if "/pos-self/" in self.url else BrowserState.FULLSCREEN + self.browser.open_browser(self.url, browser_state) + + @helpers.require_db + def get_url_from_db(self, server_url=None): + """Get the display URL provided by the connected database. + + :param server_url: The URL of the connected database (provided by decorator). + :return: URL to display or None. + """ + try: + response = requests.get(f"{server_url}/iot/box/{helpers.get_identifier()}/display_url", timeout=5) + response.raise_for_status() + data = json.loads(response.content.decode()) + return data.get(self.device_identifier) + except requests.exceptions.RequestException: + _logger.exception("Failed to get display URL from server") + except json.decoder.JSONDecodeError: + return response.content.decode('utf8') + + def _action_update_url(self, data): + helpers.save_browser_state(url=data.get('url')) + self.update_url(data.get('url')) + + def _action_display_refresh(self, data): + self.browser.refresh() + + def _action_open_kiosk(self, data): + origin = helpers.get_odoo_server_url() + self.update_url(f"{origin}/pos-self/{data.get('pos_id')}?access_token={data.get('access_token')}") + self.set_orientation(Orientation.RIGHT) + + def _action_rotate_screen(self, data): + orientation = data.get('orientation', 'NORMAL').upper() + self.set_orientation(Orientation[orientation]) + + def _action_open_customer_display(self, data): + if not data.get('pos_id') or not data.get('access_token'): + return + + origin = helpers.get_odoo_server_url() or http.request.httprequest.origin + self.update_url(f"{origin}/pos_customer_display/{data['pos_id']}/{data['access_token']}") + + def _action_close_customer_display(self, data): + helpers.update_conf({"browser_url": "", "screen_orientation": ""}) + self.browser.disable_kiosk_mode() + self.update_url() + + def _action_set_customer_display(self, data): + if not data.get('data'): + return + + self.data['customer_display_data'] = data['data'] + + def set_orientation(self, orientation=Orientation.NORMAL): + if type(orientation) is not Orientation: + raise TypeError("orientation must be of type Orientation") + + subprocess.run(['wlr-randr', '--output', self.device_identifier, '--transform', orientation.value], check=True) + # Update touchscreen mapping to this display + subprocess.run( + ['sed', '-i', f's/HDMI-A-[12]/{self.device_identifier}/', '/home/odoo/.config/labwc/rc.xml'], + check=False, + ) + # Tell labwc to reload its configuration + subprocess.run(['pkill', '-HUP', 'labwc'], check=False) + helpers.save_browser_state(orientation=orientation) + + +class DisplayController(http.Controller): + @route.iot_route('/hw_proxy/customer_facing_display', type='jsonrpc', cors='*') + def customer_facing_display(self): + display = self.ensure_display() + return display.data.get('customer_display_data', {}) + + def ensure_display(self): + display: DisplayDriver = DisplayDriver.get_default_display() + if not display: + raise werkzeug.exceptions.ServiceUnavailable(description="No display connected") + return display diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/keyboard_usb_driver_L.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/keyboard_usb_driver_L.py new file mode 100644 index 00000000..04918070 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/keyboard_usb_driver_L.py @@ -0,0 +1,382 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import ctypes +import evdev +import json +import logging +from lxml import etree +import os +from queue import Queue, Empty +import re +import requests +import subprocess +from threading import Lock +import time +from usb import util + +from odoo import http +from odoo.addons.iot_drivers.controllers.proxy import proxy_drivers +from odoo.addons.iot_drivers.driver import Driver +from odoo.addons.iot_drivers.event_manager import event_manager +from odoo.addons.iot_drivers.main import iot_devices +from odoo.addons.iot_drivers.tools import helpers, route + +_logger = logging.getLogger(__name__) +xlib = ctypes.cdll.LoadLibrary('libX11.so.6') + + +class KeyboardUSBDriver(Driver): + # The list of devices can be found in /proc/bus/input/devices + # or "ls -l /dev/input/by-path" + # Note: the user running "evdev" commands must be inside the "input" group + # Each device's input will correspond to a file in /dev/input/event* + # The exact file can be found by looking at the "Handlers" line in /proc/bus/input/devices + # Example: "H: Handlers=sysrq kbd leds event0" -> The file used is /dev/input/event0 + # If you read the file "/dev/input/event0" you will get the input from the device in real time + # One usb device can have multiple associated event files (like a foot pedal which has 3 event files) + + connection_type = 'usb' + keyboard_layout_groups = [] + available_layouts = [] + input_devices = [] + + def __init__(self, identifier, device): + if not hasattr(KeyboardUSBDriver, 'display'): + os.environ['XAUTHORITY'] = "/run/lightdm/pi/xauthority" + KeyboardUSBDriver.display = xlib.XOpenDisplay(bytes(":0.0", "utf-8")) + + super().__init__(identifier, device) + self.device_connection = 'direct' + self.device_name = self._set_name() + + self._actions.update({ + 'update_layout': self._update_layout, + 'update_is_scanner': self._save_is_scanner, + '': self._action_default, + }) + + # from https://github.com/xkbcommon/libxkbcommon/blob/master/test/evdev-scancodes.h + self._scancode_to_modifier = { + 42: 'left_shift', + 54: 'right_shift', + 58: 'caps_lock', + 69: 'num_lock', + 100: 'alt_gr', # right alt + } + self._tracked_modifiers = {modifier: False for modifier in self._scancode_to_modifier.values()} + + if not KeyboardUSBDriver.available_layouts: + KeyboardUSBDriver.load_layouts_list() + KeyboardUSBDriver.send_layouts_list() + + for evdev_device in [evdev.InputDevice(path) for path in evdev.list_devices()]: + if (device.idVendor == evdev_device.info.vendor) and (device.idProduct == evdev_device.info.product): + self.input_devices.append(evdev_device) + + self._set_device_type('scanner') if self._is_scanner() else self._set_device_type() + + @classmethod + def supported(cls, device): + for cfg in device: + for itf in cfg: + if itf.bInterfaceClass == 3 and itf.bInterfaceProtocol != 2: + device.interface_protocol = itf.bInterfaceProtocol + return True + return False + + @classmethod + def get_status(self): + """Allows `hw_proxy.Proxy` to retrieve the status of the scanners""" + status = 'connected' if any(iot_devices[d].device_type == "scanner" for d in iot_devices) else 'disconnected' + return {'status': status, 'messages': ''} + + @classmethod + @helpers.require_db + def send_layouts_list(cls, server_url=None): + try: + response = requests.post( + server_url + '/iot/keyboard_layouts', + data={'available_layouts': json.dumps(cls.available_layouts)}, timeout=5 + ) + response.raise_for_status() + except requests.exceptions.RequestException: + _logger.exception('Could not reach configured server to send available layouts') + + @classmethod + def load_layouts_list(cls): + tree = etree.parse("/usr/share/X11/xkb/rules/base.xml", etree.XMLParser(ns_clean=True, recover=True)) + layouts = tree.xpath("//layout") + for layout in layouts: + layout_name = layout.xpath("./configItem/name")[0].text + layout_description = layout.xpath("./configItem/description")[0].text + KeyboardUSBDriver.available_layouts.append({ + 'name': layout_description, + 'layout': layout_name, + }) + for variant in layout.xpath("./variantList/variant"): + variant_name = variant.xpath("./configItem/name")[0].text + variant_description = variant.xpath("./configItem/description")[0].text + KeyboardUSBDriver.available_layouts.append({ + 'name': variant_description, + 'layout': layout_name, + 'variant': variant_name, + }) + + def _set_name(self): + try: + manufacturer = util.get_string(self.dev, self.dev.iManufacturer) + product = util.get_string(self.dev, self.dev.iProduct) + if manufacturer and product: + return re.sub(r"[^\w \-+/*&]", '', "%s - %s" % (manufacturer, product)) + except ValueError as e: + _logger.warning(e) + return 'Unknown input device' + + def run(self): + try: + for device in self.input_devices: + for event in device.read_loop(): + if self._stopped.is_set(): + break + if event.type == evdev.ecodes.EV_KEY: + data = evdev.categorize(event) + + modifier_name = self._scancode_to_modifier.get(data.scancode) + if modifier_name: + if modifier_name in ('caps_lock', 'num_lock'): + if data.keystate == 1: + self._tracked_modifiers[modifier_name] = not self._tracked_modifiers[modifier_name] + else: + self._tracked_modifiers[modifier_name] = bool(data.keystate) # 1 for keydown, 0 for keyup + elif data.keystate == 1: + self.key_input(data.scancode) + + except Exception as err: # noqa: BLE001 + _logger.warning(err) + + def _change_keyboard_layout(self, new_layout): + """Change the layout of the current device to what is specified in + new_layout. + + Args: + new_layout (dict): A dict containing two keys: + - layout (str): The layout code + - variant (str): An optional key to represent the variant of the + selected layout + """ + if hasattr(self, 'keyboard_layout'): + KeyboardUSBDriver.keyboard_layout_groups.remove(self.keyboard_layout) + + if new_layout: + self.keyboard_layout = new_layout.get('layout') or 'us' + if new_layout.get('variant'): + self.keyboard_layout += "(%s)" % new_layout['variant'] + else: + self.keyboard_layout = 'us' + + KeyboardUSBDriver.keyboard_layout_groups.append(self.keyboard_layout) + subprocess.call(["setxkbmap", "-display", ":0.0", ",".join(KeyboardUSBDriver.keyboard_layout_groups)]) + + # Close then re-open display to refresh the mapping + xlib.XCloseDisplay(KeyboardUSBDriver.display) + KeyboardUSBDriver.display = xlib.XOpenDisplay(bytes(":0.0", "utf-8")) + + def save_layout(self, layout): + """Save the layout to a file on the box to read it when restarting it. + We need that in order to keep the selected layout after a reboot. + + Args: + new_layout (dict): A dict containing two keys: + - layout (str): The layout code + - variant (str): An optional key to represent the variant of the + selected layout + """ + file_path = helpers.path_file('odoo-keyboard-layouts.conf') + if file_path.exists(): + data = json.loads(file_path.read_text()) + else: + data = {} + data[self.device_identifier] = layout + helpers.write_file('odoo-keyboard-layouts.conf', json.dumps(data)) + + def load_layout(self): + """Read the layout from the saved filed and set it as current layout. + If no file or no layout is found we use 'us' by default. + """ + file_path = helpers.path_file('odoo-keyboard-layouts.conf') + if file_path.exists(): + data = json.loads(file_path.read_text()) + layout = data.get(self.device_identifier, {'layout': 'us'}) + else: + layout = {'layout': 'us'} + self._change_keyboard_layout(layout) + + def _action_default(self, data): + self.data['value'] = '' + + def _is_scanner(self): + """Read the device type from the saved filed and set it as current type. + If no file or no device type is found we try to detect it automatically. + """ + device_name = self.device_name.lower() + scanner_name = ['barcode', 'scanner', 'reader'] + is_scanner = any(x in device_name for x in scanner_name) or self.dev.interface_protocol == '0' + + file_path = helpers.path_file('odoo-keyboard-is-scanner.conf') + if file_path.exists(): + data = json.loads(file_path.read_text()) + is_scanner = data.get(self.device_identifier, {}).get('is_scanner', is_scanner) + return is_scanner + + def _keyboard_input(self, scancode): + """Deal with a keyboard input. Send the character corresponding to the + pressed key represented by its scancode to the connected Odoo instance. + + Args: + scancode (int): The scancode of the pressed key. + """ + self.data['value'] = self._scancode_to_char(scancode) + if self.data['value']: + event_manager.device_changed(self) + + def _barcode_scanner_input(self, scancode): + """Deal with a barcode scanner input. Add the new character scanned to + the current barcode or complete the barcode if "Return" is pressed. + When a barcode is completed, two tasks are performed: + - Send a device_changed update to the event manager to notify the + listeners that the value has changed (used in Enterprise). + - Add the barcode to the list barcodes that are being queried in + Community. + + Args: + scancode (int): The scancode of the pressed key. + """ + if scancode == 28: # Return + self.data['value'] = self._current_barcode + event_manager.device_changed(self) + self._barcodes.put((time.time(), self._current_barcode)) + self._current_barcode = '' + else: + self._current_barcode += self._scancode_to_char(scancode) + + def _save_is_scanner(self, data): + """Save the type of device. + We need that in order to keep the selected type of device after a reboot. + """ + is_scanner = {'is_scanner': data.get('is_scanner')} + file_path = helpers.path_file('odoo-keyboard-is-scanner.conf') + if file_path.exists(): + data = json.loads(file_path.read_text()) + else: + data = {} + data[self.device_identifier] = is_scanner + helpers.write_file('odoo-keyboard-is-scanner.conf', json.dumps(data)) + self._set_device_type('scanner') if is_scanner.get('is_scanner') else self._set_device_type() + + def _update_layout(self, data): + layout = { + 'layout': data.get('layout'), + 'variant': data.get('variant'), + } + self._change_keyboard_layout(layout) + self.save_layout(layout) + + def _set_device_type(self, device_type='keyboard'): + """Modify the device type between 'keyboard' and 'scanner' + + Args: + type (string): Type wanted to switch + """ + if device_type == 'scanner': + self.device_type = 'scanner' + self.key_input = self._barcode_scanner_input + self._barcodes = Queue() + self._current_barcode = '' + for device in self.input_devices: + device.grab() + self.read_barcode_lock = Lock() + else: + self.device_type = 'keyboard' + self.key_input = self._keyboard_input + self.load_layout() + + def _scancode_to_char(self, scancode): + """Translate a received scancode to a character depending on the + selected keyboard layout and the current state of the keyboard's + modifiers. + + Args: + scancode (int): The scancode of the pressed key, to be translated to + a character + + Returns: + str: The translated scancode. + """ + # Scancode -> Keysym : Depends on the keyboard layout + group = KeyboardUSBDriver.keyboard_layout_groups.index(self.keyboard_layout) + modifiers = self._get_active_modifiers(scancode) + keysym = ctypes.c_int(xlib.XkbKeycodeToKeysym(KeyboardUSBDriver.display, scancode + 8, group, modifiers)) + + # Translate Keysym to a character + key_pressed = ctypes.create_string_buffer(5) + xlib.XkbTranslateKeySym(KeyboardUSBDriver.display, ctypes.byref(keysym), 0, ctypes.byref(key_pressed), 5, ctypes.byref(ctypes.c_int())) + if key_pressed.value: + return key_pressed.value.decode('utf-8') + return '' + + def _get_active_modifiers(self, scancode): + """Get the state of currently active modifiers. + + Args: + scancode (int): The scancode of the key being translated + + Returns: + int: The current state of the modifiers: + 0 -- Lowercase + 1 -- Highercase or (NumLock + key pressed on keypad) + 2 -- AltGr + 3 -- Highercase + AltGr + """ + modifiers = 0 + uppercase = (self._tracked_modifiers['right_shift'] or self._tracked_modifiers['left_shift']) ^ self._tracked_modifiers['caps_lock'] + if uppercase or (scancode in [71, 72, 73, 75, 76, 77, 79, 80, 81, 82, 83] and self._tracked_modifiers['num_lock']): + modifiers += 1 + + if self._tracked_modifiers['alt_gr']: + modifiers += 2 + + return modifiers + + def read_next_barcode(self): + """Get the value of the last barcode that was scanned but not sent yet + and not older than 5 seconds. This function is used in Community, when + we don't have access to the IoTLongpolling. + + Returns: + str: The next barcode to be read or an empty string. + """ + + # Previous query still running, stop it by sending a fake barcode + if self.read_barcode_lock.locked(): + self._barcodes.put((time.time(), "")) + + with self.read_barcode_lock: + try: + timestamp, barcode = self._barcodes.get(True, 55) + if timestamp > time.time() - 5: + return barcode + except Empty: + return '' + + +proxy_drivers['scanner'] = KeyboardUSBDriver + + +class KeyboardUSBController(http.Controller): + @route.iot_route('/hw_proxy/scanner', type='jsonrpc', cors='*') + def get_barcode(self): + scanners = [iot_devices[d] for d in iot_devices if iot_devices[d].device_type == "scanner"] + if scanners: + return scanners[0].read_next_barcode() + time.sleep(5) + return None diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/l10n_eg_drivers.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/l10n_eg_drivers.py new file mode 100644 index 00000000..b79d7da7 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/l10n_eg_drivers.py @@ -0,0 +1,134 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +import base64 +import json +import logging +import PyKCS11 + +from passlib.context import CryptContext + +from odoo import http +from odoo.tools.config import config +from odoo.addons.iot_drivers.tools import route +from odoo.addons.iot_drivers.tools.system import IOT_SYSTEM, IS_RPI, IS_WINDOWS + +_logger = logging.getLogger(__name__) + +crypt_context = CryptContext(schemes=['pbkdf2_sha512']) + + +class EtaUsbController(http.Controller): + + def _is_access_token_valid(self, access_token): + stored_hash = config.get('proxy_access_token') + if not stored_hash: + # empty password/hash => authentication forbidden + return False + return crypt_context.verify(access_token, stored_hash) + + @route.iot_route('/hw_l10n_eg_eta/certificate', type='http', cors='*', csrf=False, methods=['POST']) + def eta_certificate(self, pin, access_token): + """Gets the certificate from the token and returns it to the main odoo instance so that we can prepare the + cades-bes object on the main odoo instance rather than this middleware + + :param pin: pin of the token + :param access_token: token shared with the main odoo instance + :return: json object with the certificate + """ + if not self._is_access_token_valid(access_token): + return self._get_error_template('unauthorized') + session, error = self._get_session(pin) + if error: + return error + try: + cert = session.findObjects([(PyKCS11.CKA_CLASS, PyKCS11.CKO_CERTIFICATE)])[0] + cert_bytes = bytes(session.getAttributeValue(cert, [PyKCS11.CKA_VALUE])[0]) + payload = { + 'certificate': base64.b64encode(cert_bytes).decode() + } + return json.dumps(payload) + except Exception as ex: + _logger.exception('Error while getting ETA certificate') + return self._get_error_template(str(ex)) + finally: + session.logout() + session.closeSession() + + @route.iot_route('/hw_l10n_eg_eta/sign', type='http', cors='*', csrf=False, methods=['POST']) + def eta_sign(self, pin, access_token, invoices): + """Check if the access_token is valid and sign the invoices accessing the usb key with the pin. + + :param pin: pin of the token + :param access_token: token shared with the main odoo instance + :param invoices: dictionary of invoices. Keys are invoices ids, value are the base64 encoded binaries to sign + :return: json object with the signed invoices + """ + if not self._is_access_token_valid(access_token): + return self._get_error_template('unauthorized') + session, error = self._get_session(pin) + if error: + return error + try: + cert = session.findObjects([(PyKCS11.CKA_CLASS, PyKCS11.CKO_CERTIFICATE)])[0] + cert_id = session.getAttributeValue(cert, [PyKCS11.CKA_ID])[0] + priv_key = session.findObjects([(PyKCS11.CKA_CLASS, PyKCS11.CKO_PRIVATE_KEY), (PyKCS11.CKA_ID, cert_id)])[0] + + invoice_dict = dict() + invoices = json.loads(invoices) + for invoice, eta_inv in invoices.items(): + to_sign = base64.b64decode(eta_inv) + signed_data = session.sign(priv_key, to_sign, PyKCS11.Mechanism(PyKCS11.CKM_SHA256_RSA_PKCS)) + invoice_dict[invoice] = base64.b64encode(bytes(signed_data)).decode() + + payload = { + 'invoices': json.dumps(invoice_dict), + } + return json.dumps(payload) + except Exception as ex: + _logger.exception('Error while signing invoices') + return self._get_error_template(str(ex)) + finally: + session.logout() + session.closeSession() + + def _get_session(self, pin): + session = False + + lib, error = self.get_crypto_lib() + if error: + return session, error + + try: + pkcs11 = PyKCS11.PyKCS11Lib() + pkcs11.load(pkcs11dll_filename=lib) + except PyKCS11.PyKCS11Error: + return session, self._get_error_template('missing_dll') + + slots = pkcs11.getSlotList(tokenPresent=True) + if not slots: + return session, self._get_error_template('no_drive') + if len(slots) > 1: + return session, self._get_error_template('multiple_drive') + + try: + session = pkcs11.openSession(slots[0], PyKCS11.CKF_SERIAL_SESSION | PyKCS11.CKF_RW_SESSION) + session.login(pin) + except Exception as ex: # noqa: BLE001 + error = self._get_error_template(str(ex)) + return session, error + + def get_crypto_lib(self): + error = lib = False + if IOT_SYSTEM == 'Darwin': + lib = '/Library/OpenSC/lib/onepin-opensc-pkcs11.so' + elif IS_RPI: + lib = '/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so' + elif IS_WINDOWS: + lib = 'C:/Windows/System32/eps2003csp11.dll' + else: + error = self._get_error_template('unsupported_system') + return lib, error + + def _get_error_template(self, error_str): + return json.dumps({ + 'error': error_str, + }) diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/l10n_ke_edi_serial_driver.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/l10n_ke_edi_serial_driver.py new file mode 100644 index 00000000..c311a11c --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/l10n_ke_edi_serial_driver.py @@ -0,0 +1,253 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import logging +import serial +import time +import struct +import json +from functools import reduce + +from odoo import http +from odoo.addons.iot_drivers.iot_handlers.drivers.serial_base_driver import SerialDriver, SerialProtocol, serial_connection +from odoo.addons.iot_drivers.main import iot_devices +from odoo.addons.iot_drivers.tools import route + +_logger = logging.getLogger(__name__) + +TremolG03Protocol = SerialProtocol( + name='Tremol G03', + baudrate=115200, + bytesize=serial.EIGHTBITS, + stopbits=serial.STOPBITS_ONE, + parity=serial.PARITY_NONE, + timeout=4, + writeTimeout=0.2, + measureRegexp=None, + statusRegexp=None, + commandTerminator=b'', + commandDelay=0.2, + measureDelay=3, + newMeasureDelay=0.2, + measureCommand=b'', + emptyAnswerValid=False, +) + +STX = 0x02 +ETX = 0x0A +ACK = 0x06 +NACK = 0x15 + +# Dictionary defining the output size of expected from various commands +COMMAND_OUTPUT_SIZE = { + 0x30: 7, + 0x31: 7, + 0x38: 157, + 0x39: 155, + 0x60: 40, + 0x68: 23, +} + +FD_ERRORS = { + 0x30: 'OK', + 0x32: 'Registers overflow', + 0x33: 'Clock failure or incorrect date & time', + 0x34: 'Opened fiscal receipt', + 0x39: 'Incorrect password', + 0x3b: '24 hours block - missing Z report', + 0x3d: 'Interrupt power supply in fiscal receipt (one time until status is read)', + 0x3e: 'Overflow EJ', + 0x3f: 'Insufficient conditions', +} + +COMMAND_ERRORS = { + 0x30: 'OK', + 0x31: 'Invalid command', + 0x32: 'Illegal command', + 0x33: 'Z daily report is not zero', + 0x34: 'Syntax error', + 0x35: 'Input registers orverflow', + 0x36: 'Zero input registers', + 0x37: 'Unavailable transaction for correction', + 0x38: 'Insufficient amount on hand', +} + + +class TremolG03Driver(SerialDriver): + """Driver for the Kenyan Tremol G03 fiscal device.""" + + _protocol = TremolG03Protocol + + def __init__(self, identifier, device): + super().__init__(identifier, device) + self.device_type = 'fiscal_data_module' + self.message_number = 0 + + @classmethod + def get_default_device(cls): + fiscal_devices = list(filter(lambda d: iot_devices[d].device_type == 'fiscal_data_module', iot_devices)) + return len(fiscal_devices) and iot_devices[fiscal_devices[0]] + + @classmethod + def supported(cls, device): + """Checks whether the device, which port info is passed as argument, is supported by the driver. + + :param device: path to the device + :type device: str + :return: whether the device is supported by the driver + :rtype: bool + """ + protocol = cls._protocol + try: + protocol = cls._protocol + with serial_connection(device['identifier'], protocol) as connection: + connection.write(b'\x09') + time.sleep(protocol.commandDelay) + response = connection.read(1) + if response == b'\x40': + return True + + except serial.serialutil.SerialTimeoutException: + pass + except Exception: + _logger.exception('Error while probing %s with protocol %s', device, protocol.name) + + # ---------------- + # HELPERS + # ---------------- + + @staticmethod + def generate_checksum(message): + """ Generate the checksum bytes for the bytes provided. + + :param message: bytes representing the part of the message from which the checksum is calculated + :returns: two checksum bytes calculated from the message + + This checksum is calculated as: + 1) XOR of all bytes of the bytes + 2) Conversion of the one XOR byte into the two bytes of the checksum by + adding 30h to each half-byte of the XOR + + eg. to_check = \x12\x23\x34\x45\x56 + XOR of all bytes in to_check = \x16 + checksum generated as \x16 -> \x31 \x36 + """ + xor = reduce(lambda a, b: a ^ b, message) + return bytes([(xor >> 4) + 0x30, (xor & 0xf) + 0x30]) + + # ---------------- + # COMMUNICATION + # ---------------- + + def send(self, msgs): + """ Send and receive messages to/from the fiscal device over serial connection + + Generate the wrapped message from the msgs and send them to the device. + The wrapping contains the (starting byte) (length byte) + and (message number byte) at the start and two (checksum + bytes), and the line-feed byte at the end. + :param msgs: A list of byte strings representing the and + components of the serial message. + :return: A list of the responses (if any) from the device. If the + response is an ack, it wont be part of this list. + """ + + with self._device_lock: + replies = [] + for msg in msgs: + self.message_number += 1 + core_message = struct.pack('BB%ds' % (len(msg)), len(msg) + 34, self.message_number + 32, msg) + request = struct.pack('B%ds2sB' % (len(core_message)), STX, core_message, self.generate_checksum(core_message), ETX) + time.sleep(self._protocol.commandDelay) + self._connection.write(request) + _logger.debug('Debug send request: %s', request) + # If we know the expected output size, we can set the read + # buffer to match the size of the output. + output_size = COMMAND_OUTPUT_SIZE.get(msg[0]) + if output_size: + try: + response = self._connection.read(output_size) + except serial.serialutil.SerialTimeoutException: + _logger.exception('Timeout error while reading response to command %s', msg) + self.data['status'] = "Device timeout error" + else: + time.sleep(self._protocol.measureDelay) + response = self._connection.read_all() + _logger.debug('Debug send response: %s', response) + if not response: + self.data['status'] = "No response" + _logger.error("Sent request: %s,\n Received no response", request) + self.abort_post() + break + if response[0] == ACK: + # In the case where either byte is not 0x30, there has been an error + if response[2] != 0x30 or response[3] != 0x30: + self.data['status'] = response[2:4].decode('cp1251') + _logger.error( + "Sent request: %s,\n Received fiscal device error: %s \n Received command error: %s", + request, FD_ERRORS.get(response[2], 'Unknown fiscal device error'), + COMMAND_ERRORS.get(response[3], 'Unknown command error'), + ) + self.abort_post() + break + replies.append('') + elif response[0] == NACK: + self.data['status'] = "Received NACK" + _logger.error("Sent request: %s,\n Received NACK \x15", request) + self.abort_post() + break + elif response[0] == 0x02: + self.data['status'] = "ok" + size = response[1] - 35 + reply = response[4:4 + size] + replies.append(reply.decode('cp1251')) + return {'replies': replies, 'status': self.data['status']} + + def abort_post(self): + """ Cancel the posting of the invoice + + In the event of an error, it is better to try to cancel the posting of + the invoice, since the state of the invoice on the device will remain + open otherwise, blocking further invoices being sent. + """ + self.message_number += 1 + abort = struct.pack('BBB', 35, self.message_number + 32, 0x39) + request = struct.pack('B3s2sB', STX, abort, self.generate_checksum(abort), ETX) + self._connection.write(request) + _logger.debug('Debug abort_post request: %s', request) + response = self._connection.read(COMMAND_OUTPUT_SIZE[0x39]) + _logger.debug('Debug abort_post response: %s', response) + if response and response[0] == 0x02: + self.data['status'] += "\n The invoice was successfully cancelled" + _logger.info("Invoice successfully cancelled") + else: + self.data['status'] += "\n The invoice could not be cancelled." + _logger.error("Failed to cancel invoice, received response: %s", response) + + +class TremolG03Controller(http.Controller): + + @route.iot_route('/hw_proxy/l10n_ke_cu_send', type='http', cors='*', csrf=False, methods=['POST']) + def l10n_ke_cu_send(self, messages, company_vat): + """ Posts the messages sent to this endpoint to the fiscal device connected to the server + + :param messages: The messages (consisting of and ) to + send to the fiscal device. + :returns: Dictionary containing a list of the responses from + fiscal device and status of the fiscal device. + """ + device = TremolG03Driver.get_default_device() + if device: + # First run the command to get the fiscal device numbers + device_numbers = device.send([b'\x60']) + # If the vat doesn't match, abort + if device_numbers['status'] != 'ok': + return device_numbers + serial_number, device_vat, _dummy = device_numbers['replies'][0].split(';') + if device_vat != company_vat: + return json.dumps({'status': 'The company vat number does not match that of the device'}) + messages = json.loads(messages) + device.message_number = 0 + resp = json.dumps({**device.send([msg.encode('cp1251') for msg in messages]), 'serial_number': serial_number}) + return resp + else: + return json.dumps({'status': 'The fiscal device is not connected to the proxy server'}) diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/printer_driver_L.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/printer_driver_L.py new file mode 100644 index 00000000..f838a41e --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/printer_driver_L.py @@ -0,0 +1,273 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from base64 import b64decode +from cups import IPPError, IPP_JOB_COMPLETED, IPP_JOB_PROCESSING, IPP_JOB_PENDING, CUPS_FORMAT_AUTO +from escpos import printer +from escpos.escpos import EscposIO +import escpos.exceptions +import logging +import netifaces as ni +import time + +from odoo import http +from odoo.addons.iot_drivers.connection_manager import connection_manager +from odoo.addons.iot_drivers.controllers.proxy import proxy_drivers +from odoo.addons.iot_drivers.iot_handlers.drivers.printer_driver_base import PrinterDriverBase +from odoo.addons.iot_drivers.iot_handlers.interfaces.printer_interface_L import conn, cups_lock +from odoo.addons.iot_drivers.main import iot_devices +from odoo.addons.iot_drivers.tools import helpers, wifi, route + +_logger = logging.getLogger(__name__) + + +class PrinterDriver(PrinterDriverBase): + + def __init__(self, identifier, device): + super().__init__(identifier, device) + self.device_connection = device['device-class'].lower() + self.receipt_protocol = 'star' if 'STR_T' in device['device-id'] else 'escpos' + self.connected_by_usb = self.device_connection == 'direct' + self.device_name = device['device-make-and-model'] + self.ip = device.get('ip') + + if any(cmd in device['device-id'] for cmd in ['CMD:STAR;', 'CMD:ESC/POS;']): + self.device_subtype = "receipt_printer" + elif any(cmd in device['device-id'] for cmd in ['COMMAND SET:ZPL;', 'CMD:ESCLABEL;']): + self.device_subtype = "label_printer" + else: + self.device_subtype = "office_printer" + + if self.device_subtype == "receipt_printer" and self.receipt_protocol == 'escpos': + self._init_escpos(device) + + self.print_status() + + def _init_escpos(self, device): + if device.get('usb_product'): + def usb_matcher(usb_device): + return ( + usb_device.manufacturer and usb_device.manufacturer.lower() == device['usb_manufacturer'] and + usb_device.product == device['usb_product'] and + usb_device.serial_number == device['usb_serial_number'] + ) + + self.escpos_device = printer.Usb(usb_args={"custom_match": usb_matcher}) + elif device.get('ip'): + self.escpos_device = printer.Network(device['ip'], timeout=5) + else: + return + try: + self.escpos_device.open() + self.escpos_device.set_with_default(align='center') + self.escpos_device.close() + except escpos.exceptions.Error as e: + _logger.info("%s - Could not initialize escpos class: %s", self.device_name, e) + self.escpos_device = None + + @classmethod + def supported(cls, device): + return True + + def disconnect(self): + self.send_status('disconnected', 'Printer was disconnected') + super().disconnect() + + def print_raw(self, data): + """Print raw data to the printer + + :param data: The data to print + """ + if not self.check_printer_status(): + return + + try: + with cups_lock: + job_id = conn.createJob(self.device_identifier, 'Odoo print job', {'document-format': CUPS_FORMAT_AUTO}) + conn.startDocument(self.device_identifier, job_id, 'Odoo print job', CUPS_FORMAT_AUTO, 1) + conn.writeRequestData(data, len(data)) + conn.finishDocument(self.device_identifier) + self.job_ids.append(job_id) + except IPPError: + _logger.exception("Printing failed") + self.send_status(status='error', message='ERROR_FAILED') + + @classmethod + def format_star(cls, im): + width = int((im.width + 7) / 8) + + raster_init = b'\x1b\x2a\x72\x41' + raster_page_length = b'\x1b\x2a\x72\x50\x30\x00' + raster_send = b'\x62' + raster_close = b'\x1b\x2a\x72\x42' + + raster_data = b'' + dots = im.tobytes() + while len(dots): + raster_data += raster_send + width.to_bytes(2, 'little') + dots[:width] + dots = dots[width:] + + return raster_init + raster_page_length + raster_data + raster_close + + @classmethod + def _get_iot_status(cls): + identifier = helpers.get_identifier() + mac_address = helpers.get_mac_address() + pairing_code = connection_manager.pairing_code + ssid = wifi.get_access_point_ssid() if wifi.is_access_point() else wifi.get_current() + + ips = [] + for iface_id in ni.interfaces(): + iface_obj = ni.ifaddresses(iface_id) + ifconfigs = iface_obj.get(ni.AF_INET, []) + for conf in ifconfigs: + if 'addr' in conf and conf['addr'] not in ['127.0.0.1', '10.11.12.1']: + ips.append(conf['addr']) + + return {"identifier": identifier, "mac_address": mac_address, "pairing_code": pairing_code, "ssid": ssid, "ips": ips} + + def print_status(self, data=None): + """Prints the status ticket of the IoT Box on the current printer. + + :param data: If not None, it means that it has been called from the action route, meaning + that no matter the connection type, the printer should print the status ticket. + """ + if not self.connected_by_usb and not data: + return + if self.device_subtype == "receipt_printer": + self.print_status_receipt() + elif self.device_subtype == "label_printer": + self.print_status_zpl() + else: + title, body = self._printer_status_content() + self.print_raw(title + b'\r\n' + body.decode().replace('\n', '\r\n').encode()) + + def print_status_receipt(self): + """Prints the status ticket of the IoT Box on the current printer.""" + title, body = self._printer_status_content() + + commands = self.RECEIPT_PRINTER_COMMANDS[self.receipt_protocol] + if self.escpos_device: + try: + with EscposIO(self.escpos_device) as dev: + dev.printer.set(align='center', double_height=True, double_width=True) + dev.printer.textln(title.decode()) + dev.printer.set_with_default(align='center', double_height=False, double_width=False) + dev.writelines(body.decode()) + dev.printer.qr(f"http://{helpers.get_ip()}", size=6) + return + except (escpos.exceptions.Error, OSError, AssertionError): + _logger.warning("Failed to print QR status receipt, falling back to simple receipt") + + title = commands['title'] % title + self.print_raw(commands['center'] + title + b'\n' + body + commands['cut']) + + def print_status_zpl(self): + iot_status = self._get_iot_status() + + title = "IoT Box Connected" if helpers.get_odoo_server_url() else "IoT Box Status" + command = f"^XA^CI28 ^FT35,40 ^A0N,30 ^FD{title}^FS" + p = 85 + if iot_status["pairing_code"]: + command += f"^FT35,{p} ^A0N,25 ^FDGo to the IoT app, click \"Connect\",^FS" + p += 35 + command += f"^FT35,{p} ^A0N,25 ^FDPairing code: {iot_status['pairing_code']}^FS" + p += 35 + if iot_status["ssid"]: + command += f"^FT35,{p} ^A0N,25 ^FDWi-Fi: {iot_status['ssid']}^FS" + p += 35 + if iot_status["identifier"]: + command += f"^FT35,{p} ^A0N,25 ^FDIdentifier: {iot_status['identifier']}^FS" + p += 35 + if iot_status["ips"]: + command += f"^FT35,{p} ^A0N,25 ^FDIP: {', '.join(iot_status['ips'])}^FS" + p += 35 + command += "^XZ" + + self.print_raw(command.encode()) + + def _printer_status_content(self): + """Formats the status information of the IoT Box into a title and a body. + + :return: The title and the body of the status ticket + :rtype: tuple of bytes + """ + + wlan = identifier = homepage = pairing_code = mac_address = "" + iot_status = self._get_iot_status() + + if iot_status["pairing_code"]: + pairing_code = ( + '\nOdoo not connected\n' + 'Go to the IoT app, click "Connect",\n' + 'Pairing Code: %s\n' % iot_status["pairing_code"] + ) + + if iot_status['ssid']: + wlan = '\nWireless network:\n%s\n' % iot_status["ssid"] + + ips = iot_status["ips"] + if len(ips) == 0: + ip = ( + "\nERROR: Could not connect to LAN\n\nPlease check that the IoT Box is correc-\ntly connected with a " + "network cable,\n that the LAN is setup with DHCP, and\nthat network addresses are available" + ) + elif len(ips) == 1: + ip = '\nIoT Box IP Address:\n%s\n' % ips[0] + else: + ip = '\nIoT Box IP Addresses:\n%s\n' % '\n'.join(ips) + + if len(ips) >= 1: + identifier = '\nIdentifier:\n%s\n' % iot_status["identifier"] + mac_address = '\nMac Address:\n%s\n' % iot_status["mac_address"] + homepage = '\nIoT Box Homepage:\nhttp://%s:8069\n' % ips[0] + + title = b'IoT Box Connected' if helpers.get_odoo_server_url() else b'IoT Box Status' + body = pairing_code + wlan + identifier + mac_address + ip + homepage + + return title, body.encode() + + def _action_default(self, data): + _logger.debug("_action_default called for printer %s", self.device_name) + self.print_raw(b64decode(data['document'])) + return {'print_id': data['print_id']} if 'print_id' in data else {} + + def _cancel_job_with_error(self, job_id, error_message): + self.job_ids.remove(job_id) + conn.cancelJob(job_id) + self.send_status(status='error', message=error_message) + + def _check_job_status(self, job_id): + try: + with cups_lock: + job = conn.getJobAttributes(job_id, requested_attributes=['job-state', 'job-state-reasons', 'job-printer-state-message', 'time-at-creation']) + _logger.debug("job details for job id #%d: %s", job_id, job) + job_state = job['job-state'] + if job_state == IPP_JOB_COMPLETED: + self.job_ids.remove(job_id) + self.send_status(status='success') + # Generic timeout, e.g. USB printer has been unplugged + elif job['time-at-creation'] + self.job_timeout_seconds < time.time(): + self._cancel_job_with_error(job_id, 'ERROR_TIMEOUT') + # Cannot reach network printer + elif job_state == IPP_JOB_PROCESSING and 'printer is unreachable' in job.get('job-printer-state-message', ''): + self._cancel_job_with_error(job_id, 'ERROR_UNREACHABLE') + # Any other failure state + elif job_state not in [IPP_JOB_PROCESSING, IPP_JOB_PENDING]: + self._cancel_job_with_error(job_id, 'ERROR_UNKNOWN') + except IPPError: + _logger.exception('IPP error occurred while fetching CUPS jobs') + self.job_ids.remove(job_id) + + +class PrinterController(http.Controller): + + @route.iot_route('/hw_proxy/default_printer_action', type='jsonrpc', cors='*') + def default_printer_action(self, data): + printer = next((d for d in iot_devices if iot_devices[d].device_type == 'printer' and iot_devices[d].device_connection == 'direct'), None) + if printer: + iot_devices[printer].action(data) + return True + return False + + +proxy_drivers['printer'] = PrinterDriver diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/printer_driver_W.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/printer_driver_W.py new file mode 100644 index 00000000..466c9f59 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/printer_driver_W.py @@ -0,0 +1,161 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import logging +from base64 import b64decode +from datetime import datetime, timezone +from escpos import printer +import escpos.exceptions +import io +import win32print +import pywintypes +import ghostscript + +from odoo.addons.iot_drivers.controllers.proxy import proxy_drivers +from odoo.addons.iot_drivers.iot_handlers.drivers.printer_driver_base import PrinterDriverBase +from odoo.addons.iot_drivers.tools import helpers +from odoo.tools.mimetypes import guess_mimetype +from odoo.addons.iot_drivers.iot_handlers.interfaces.printer_interface_W import win32print_lock + +_logger = logging.getLogger(__name__) + + +class PrinterDriver(PrinterDriverBase): + + def __init__(self, identifier, device): + super().__init__(identifier, device) + self.device_connection = self._compute_device_connection(device) + self.device_name = device.get('identifier') + self.printer_handle = device.get('printer_handle') + + self.receipt_protocol = 'escpos' + if any(cmd in device['identifier'] for cmd in ['STAR', 'Receipt']): + self.device_subtype = "receipt_printer" + elif "ZPL" in device['identifier']: + self.device_subtype = "label_printer" + else: + self.device_subtype = "office_printer" + + if self.device_subtype == "receipt_printer" and self.receipt_protocol == 'escpos': + self._init_escpos(device) + + def _init_escpos(self, device): + if self.device_connection != 'network': + return + + self.escpos_device = printer.Network(device['port'], timeout=5) + try: + self.escpos_device.open() + self.escpos_device.close() + except escpos.exceptions.Error: + _logger.exception("Could not initialize escpos class") + self.escpos_device = None + + @classmethod + def supported(cls, device): + return True + + @staticmethod + def _compute_device_connection(device): + return 'direct' if device['port'].startswith(('USB', 'TMUSB', 'COM', 'LPT')) else 'network' + + def disconnect(self): + self.send_status('disconnected', 'Printer was disconnected') + super().disconnect() + + def print_raw(self, data): + if not self.check_printer_status(): + return + + with win32print_lock: + job_id = win32print.StartDocPrinter(self.printer_handle, 1, ('', None, "RAW")) + win32print.StartPagePrinter(self.printer_handle) + win32print.WritePrinter(self.printer_handle, data) + win32print.EndPagePrinter(self.printer_handle) + win32print.EndDocPrinter(self.printer_handle) + self.job_ids.append(job_id) + + def print_report(self, data): + with win32print_lock: + helpers.write_file('document.pdf', data, 'wb') + file_name = helpers.path_file('document.pdf') + printer = self.device_name + + args = [ + "-dPrinted", "-dBATCH", "-dNOPAUSE", "-dNOPROMPT", + "-q", + "-sDEVICE#mswinpr2", + f'-sOutputFile#%printer%{printer}', + f'{file_name}' + ] + + _logger.debug("Printing report with ghostscript using %s", args) + stderr_buf = io.BytesIO() + stdout_buf = io.BytesIO() + stdout_log_level = logging.DEBUG + try: + ghostscript.Ghostscript(*args, stdout=stdout_buf, stderr=stderr_buf) + self.send_status(status='success') + except Exception: + _logger.exception("Error while printing report, ghostscript args: %s, error buffer: %s", args, stderr_buf.getvalue()) + stdout_log_level = logging.ERROR # some stdout value might contains relevant error information + self.send_status(status='error', message='ERROR_FAILED') + raise + finally: + _logger.log(stdout_log_level, "Ghostscript stdout: %s", stdout_buf.getvalue()) + + def _action_default(self, data): + _logger.debug("_action_default called for printer %s", self.device_name) + + document = b64decode(data['document']) + mimetype = guess_mimetype(document) + if mimetype == 'application/pdf': + self.print_report(document) + else: + self.print_raw(document) + _logger.debug("_action_default finished with mimetype %s for printer %s", mimetype, self.device_name) + return {'print_id': data['print_id']} if 'print_id' in data else {} + + def print_status(self, _data=None): + """Prints the status ticket of the IoT Box on the current printer. + + :param _data: dict provided by the action route + """ + if self.device_subtype == "receipt_printer": + commands = self.RECEIPT_PRINTER_COMMANDS[self.receipt_protocol] + self.print_raw(commands['center'] + (commands['title'] % b'IoT Box Test Receipt') + commands['cut']) + elif self.device_type == "label_printer": + self.print_raw("^XA^CI28 ^FT35,40 ^A0N,30 ^FDIoT Box Test Label^FS^XZ".encode()) # noqa: UP012 + else: + self.print_raw("IoT Box Test Page".encode()) # noqa: UP012 + + def _cancel_job_with_error(self, job_id, error_message): + self.job_ids.remove(job_id) + win32print.SetJob(self.printer_handle, job_id, 0, None, win32print.JOB_CONTROL_DELETE) + self.send_status(status='error', message=error_message) + + def _check_job_status(self, job_id): + try: + job = win32print.GetJob(self.printer_handle, job_id, win32print.JOB_INFO_1) + elapsed_time = datetime.now(timezone.utc) - job['Submitted'] + _logger.debug('job details for job id #%d: %s', job_id, job) + if job['Status'] & win32print.JOB_STATUS_PRINTED: + self.job_ids.remove(job_id) + self.send_status(status='success') + # Print timeout, e.g. network printer is disconnected + if elapsed_time.seconds > self.job_timeout_seconds: + self._cancel_job_with_error(job_id, 'ERROR_TIMEOUT') + # Generic error, e.g. USB printer is not connected + elif job['Status'] & win32print.JOB_STATUS_ERROR: + self._cancel_job_with_error(job_id, 'ERROR_UNKNOWN') + except pywintypes.error as error: + # GetJob returns error 87 (incorrect parameter) if the print job doesn't exist. + # Windows deletes print jobs on completion, so this actually means the print + # was succcessful. + if error.winerror == 87: + self.send_status(status='success') + else: + _logger.exception('Win32 error occurred while querying print job') + self.job_ids.remove(job_id) + + +proxy_drivers['printer'] = PrinterDriver diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/printer_driver_base.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/printer_driver_base.py new file mode 100644 index 00000000..648d148a --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/printer_driver_base.py @@ -0,0 +1,277 @@ +from abc import ABC, abstractmethod +from base64 import b64decode +from escpos.escpos import EscposIO +import escpos.printer +import escpos.exceptions +import io +import logging +from PIL import Image, ImageOps +import re +import time + +from odoo.addons.iot_drivers.driver import Driver +from odoo.addons.iot_drivers.main import iot_devices +from odoo.addons.iot_drivers.event_manager import event_manager + +_logger = logging.getLogger(__name__) + + +def _read_escpos_with_retry(self): + """Replaces the python-escpos read function to perform repeated reads. + + This is necessary due to an issue when using USB, where it takes several + reads to get the answer of the command that has just been sent. + """ + assert self.device + + for attempt in range(5): + if result := self.device.read(self.in_ep, 16): + return result + + time.sleep(0.05) + _logger.debug("Read attempt %s failed", attempt) + + +# Monkeypatch the USB printer read method with our retrying version +escpos.printer.Usb._read = _read_escpos_with_retry + + +class PrinterDriverBase(Driver, ABC): + connection_type = 'printer' + job_timeout_seconds = 30 + + RECEIPT_PRINTER_COMMANDS = { + 'star': { + 'center': b'\x1b\x1d\x61\x01', # ESC GS a n + 'cut': b'\x1b\x64\x02', # ESC d n + 'title': b'\x1b\x69\x01\x01%s\x1b\x69\x00\x00', # ESC i n1 n2 + 'drawers': [b'\x07', b'\x1a'] # BEL & SUB + }, + 'escpos': { + 'center': b'\x1b\x61\x01', # ESC a n + 'cut': b'\x1d\x56\x41\n', # GS V m + 'title': b'\x1b\x21\x30%s\x1b\x21\x00', # ESC ! n + 'drawers': [b'\x1b\x3d\x01', b'\x1b\x70\x00\x19\x19', b'\x1b\x70\x01\x19\x19'] # ESC = n then ESC p m t1 t2 + } + } + + def __init__(self, identifier, device): + super().__init__(identifier, device) + + self.device_type = 'printer' + self.job_ids = [] + self.escpos_device = None + + self._actions.update({ + 'cashbox': self.open_cashbox, + 'print_receipt': self.print_receipt, + 'status': self.print_status, + '': self._action_default, + }) + + @classmethod + def get_status(cls): + status = 'connected' if any( + iot_devices[d].device_type == "printer" + and iot_devices[d].device_connection == 'direct' + for d in iot_devices + ) else 'disconnected' + return {'status': status, 'messages': ''} + + def send_status(self, status, message=None): + """Sends a status update event for the printer. + + :param str status: The value of the status + :param str message: A comprehensive message describing the status + """ + self.data['status'] = status + self.data['message'] = message + event_manager.device_changed(self, {'session_id': self.data.get('owner')}) + + def print_receipt(self, data): + _logger.debug("print_receipt called for printer %s", self.device_name) + + receipt = b64decode(data['receipt']) + im = Image.open(io.BytesIO(receipt)) + + # Convert to greyscale then to black and white + im = im.convert("L") + im = ImageOps.invert(im) + im = im.convert("1") + + print_command = getattr(self, 'format_%s' % self.receipt_protocol)(im) + self.print_raw(print_command) + + @classmethod + def format_escpos_bit_image_raster(cls, im): + """ prints with the `GS v 0`-command """ + width = int((im.width + 7) / 8) + + raster_send = b'\x1d\x76\x30\x00' + max_slice_height = 255 + + raster_data = b'' + dots = im.tobytes() + while len(dots): + im_slice = dots[:width * max_slice_height] + slice_height = int(len(im_slice) / width) + raster_data += raster_send + width.to_bytes(2, 'little') + slice_height.to_bytes(2, 'little') + im_slice + dots = dots[width * max_slice_height:] + + return raster_data + cls.RECEIPT_PRINTER_COMMANDS['escpos']['cut'] + + @classmethod + def extract_columns_from_picture(cls, im, line_height): + # Code inspired from python esc pos library: + # https://github.com/python-escpos/python-escpos/blob/4a0f5855ef118a2009b843a3a106874701d8eddf/src/escpos/image.py#L73-L89 + width_pixels, height_pixels = im.size + for left in range(0, width_pixels, line_height): + box = (left, 0, left + line_height, height_pixels) + im_chunk = im.transform((line_height, height_pixels), Image.EXTENT, box) + yield im_chunk.tobytes() + + def format_escpos_bit_image_column( + self, im, high_density_vertical=True, high_density_horizontal=True, size_scale=100 + ): + """Prints with the `ESC *`-command + reference: https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=88 + + :param im: PIL image + :param high_density_vertical: high density in vertical direction + :param high_density_horizontal: high density in horizontal direction + :param size_scale: picture scale in percentage, + e.g: 50 -> half the size (horizontally and vertically) + """ + size_scale_ratio = size_scale / 100 + size_scale_width = int(im.width * size_scale_ratio) + size_scale_height = int(im.height * size_scale_ratio) + im = im.resize((size_scale_width, size_scale_height)) + # escpos ESC * command print column per column + # (instead of usual row by row). + # So we transpose the picture to ease the calculations + im = im.transpose(Image.ROTATE_270).transpose(Image.FLIP_LEFT_RIGHT) + + # Most of the code here is inspired from python escpos library + # https://github.com/python-escpos/python-escpos/blob/4a0f5855ef118a2009b843a3a106874701d8eddf/src/escpos/escpos.py#L237C9-L251 + ESC = b'\x1b' + density_byte = (1 if high_density_horizontal else 0) + \ + (32 if high_density_vertical else 0) + nL = im.height & 0xFF + nH = (im.height >> 8) & 0xFF + HEADER = ESC + b'*' + bytes([density_byte, nL, nH]) + + raster_data = ESC + b'3\x10' # Adjust line-feed size + line_height = 24 if high_density_vertical else 8 + for column in self.extract_columns_from_picture(im, line_height): + raster_data += HEADER + column + b'\n' + raster_data += ESC + b'2' # Reset line-feed size + return raster_data + self.RECEIPT_PRINTER_COMMANDS['escpos']['cut'] + + def format_escpos(self, im): + # Epson support different command to print pictures. + # We use by default "GS v 0", but it is incompatible with certain + # printer models (like TM-U2x0) + # As we are pretty limited in the information that we have, we will + # use the printer name to parse some configuration value + # Printer name examples: + # EpsonTMM30 + # -> Print using raster mode + # TM-U220__IMC_LDV_LDH_SCALE70__ + # -> Print using column bit image mode (without vertical and + # horizontal density and a scale of 70%) + + # Default image printing mode + image_mode = 'raster' + + options_str = self.device_name.split('__') + option_str = "" + if len(options_str) > 2: + option_str = options_str[1].upper() + if option_str.startswith('IMC'): + image_mode = 'column' + + if image_mode == 'raster': + return self.format_escpos_bit_image_raster(im) + + # Default printing mode parameters + high_density_vertical = True + high_density_horizontal = True + scale = 100 + + # Parse the printer name to get the needed parameters + # The separator need to not be filtered by `get_identifier` + options = option_str.split('_') + for option in options: + if option == 'LDV': + high_density_vertical = False + elif option == 'LDH': + high_density_horizontal = False + elif option.startswith('SCALE'): + scale_value_str = re.search(r'\d+$', option) + if scale_value_str is not None: + scale = int(scale_value_str.group()) + else: + raise ValueError("Missing printer SCALE parameter integer value in option: " + option) + + return self.format_escpos_bit_image_column(im, high_density_vertical, high_density_horizontal, scale) + + def open_cashbox(self, data): + """Sends a signal to the current printer to open the connected cashbox.""" + _logger.debug("open_cashbox called for printer %s", self.device_name) + + commands = self.RECEIPT_PRINTER_COMMANDS[self.receipt_protocol] + for drawer in commands['drawers']: + self.print_raw(drawer) + + def check_printer_status(self): + if not self.escpos_device: + return True + try: + with EscposIO(self.escpos_device, autocut=False) as esc: + esc.printer.open() + if not esc.printer.is_online(): + self.send_status(status='error', message='ERROR_OFFLINE') + return False + paper_status = esc.printer.paper_status() + if paper_status == 0: + self.send_status(status='error', message='ERROR_NO_PAPER') + return False + elif paper_status == 1: + self.send_status(status='warning', message='WARNING_LOW_PAPER') + except (escpos.exceptions.Error, OSError, AssertionError): + self.escpos_device = None + _logger.warning("Failed to query ESC/POS status") + + return True + + def run(self): + while True: + # We monitor ongoing jobs by polling them every second. + # Ideally we would receive events instead of polling, but unfortunately CUPS + # events do not trigger with all printers, and win32print has no event mechanism. + for job_id in self.job_ids: + self._check_job_status(job_id) + time.sleep(1) + + @abstractmethod + def print_raw(self, data): + """Sends the raw data to the printer. + + :param data: The data to send to the printer + """ + pass + + @abstractmethod + def print_status(self, data): + """Method called to test a printer, printing a status page.""" + pass + + @abstractmethod + def _action_default(self, data): + """Action called when no action name is provided in the action data.""" + pass + + @abstractmethod + def _check_job_status(self, job_id): + """Method called to poll the status of a print job.""" + pass diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/serial_base_driver.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/serial_base_driver.py new file mode 100644 index 00000000..fea69a39 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/serial_base_driver.py @@ -0,0 +1,161 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from typing import NamedTuple +from contextlib import contextmanager +import logging +import serial +from threading import Lock +import time +import traceback + +from odoo.addons.iot_drivers.event_manager import event_manager +from odoo.addons.iot_drivers.driver import Driver + +_logger = logging.getLogger(__name__) + + +class SerialProtocol(NamedTuple): + name: any + baudrate: any + bytesize: any + stopbits: any + parity: any + timeout: any + writeTimeout: any + measureRegexp: any + statusRegexp: any + commandTerminator: any + commandDelay: any + measureDelay: any + newMeasureDelay: any + measureCommand: any + emptyAnswerValid: any + + +@contextmanager +def serial_connection(path, protocol, is_probing=False): + """Opens a serial connection to a device and closes it automatically after use. + + :param path: path to the device + :type path: string + :param protocol: an object containing the serial protocol to connect to a device + :type protocol: namedtuple + :param is_probing: a flag thet if set to `True` makes the timeouts longer, defaults to False + :type is_probing: bool, optional + """ + + PROBING_TIMEOUT = 1 + port_config = { + 'baudrate': protocol.baudrate, + 'bytesize': protocol.bytesize, + 'stopbits': protocol.stopbits, + 'parity': protocol.parity, + 'timeout': PROBING_TIMEOUT if is_probing else protocol.timeout, # longer timeouts for probing + 'writeTimeout': PROBING_TIMEOUT if is_probing else protocol.writeTimeout # longer timeouts for probing + } + connection = serial.Serial(path, **port_config) + yield connection + connection.close() + + +class SerialDriver(Driver): + """Abstract base class for serial drivers.""" + + _protocol = None + connection_type = 'serial' + + STATUS_CONNECTED = 'connected' + STATUS_ERROR = 'error' + STATUS_CONNECTING = 'connecting' + STATUS_DISCONNECTED = 'disconnected' + + def __init__(self, identifier, device): + """ Attributes initialization method for `SerialDriver`. + + :param device: path to the device + :type device: str + """ + + super().__init__(identifier, device) + self._actions.update({ + 'get_status': self._push_status, + }) + self.device_connection = 'serial' + self._device_lock = Lock() + self._status = {'status': self.STATUS_CONNECTING, 'message_title': '', 'message_body': ''} + self._set_name() + + def _get_raw_response(connection): + pass + + def _push_status(self): + """Updates the current status and pushes it to the frontend.""" + + self.data['status'] = self._status + + def _set_name(self): + """Tries to build the device's name based on its type and protocol name but falls back on a default name if that doesn't work.""" + + try: + name = ('%s serial %s' % (self._protocol.name, self.device_type)).title() + except Exception: # noqa: BLE001 + name = 'Unknown Serial Device' + self.device_name = name + + def _take_measure(self): + pass + + def _do_action(self, data): + """Helper function that calls a specific action method on the device. + + :param data: the `_actions` key mapped to the action method we want to call + :type data: string + """ + + with self._device_lock: + try: + self._actions[data['action']](data) + time.sleep(self._protocol.commandDelay) + except Exception: + msg = f'An error occurred while performing action "{data}" on "{self.device_name}"' + _logger.exception(msg) + self._status = {'status': self.STATUS_ERROR, 'message_title': msg, 'message_body': traceback.format_exc()} + self._push_status() + self._status = {'status': self.STATUS_CONNECTED, 'message_title': '', 'message_body': ''} + self.data['status'] = self._status + + def action(self, data): + """Establish a connection with the device if needed and have it perform a specific action. + + :param data: the `_actions` key mapped to the action method we want to call + :type data: string + """ + self.data["owner"] = data.get('session_id') + self.data["action_args"] = {**data} + + if self._connection and self._connection.isOpen(): + self._do_action(data) + else: + with serial_connection(self.device_identifier, self._protocol) as connection: + self._connection = connection + self._do_action(data) + event_manager.device_changed(self, data) # Make response available to /event route or websocket + + def run(self): + """Continuously gets new measures from the device.""" + + try: + with serial_connection(self.device_identifier, self._protocol) as connection: + self._connection = connection + self._status['status'] = self.STATUS_CONNECTED + self._push_status() + while not self._stopped.is_set(): + self._take_measure() + time.sleep(self._protocol.newMeasureDelay) + self._status['status'] = self.STATUS_DISCONNECTED + self._push_status() + except Exception: + msg = 'Error while reading %s' % self.device_name + _logger.exception(msg) + self._status = {'status': self.STATUS_ERROR, 'message_title': msg, 'message_body': traceback.format_exc()} + self._push_status() diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/serial_scale_driver.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/serial_scale_driver.py new file mode 100644 index 00000000..3f103d28 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/drivers/serial_scale_driver.py @@ -0,0 +1,218 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import logging +import re +import serial +import threading +import time + +from odoo import http +from odoo.addons.iot_drivers.controllers.proxy import proxy_drivers +from odoo.addons.iot_drivers.event_manager import event_manager +from odoo.addons.iot_drivers.iot_handlers.drivers.serial_base_driver import SerialDriver, SerialProtocol, serial_connection + + +_logger = logging.getLogger(__name__) + +# Only needed to expose scale via hw_proxy (used by Community edition) +ACTIVE_SCALE = None +new_weight_event = threading.Event() + +# 8217 Mettler-Toledo (Weight-only) Protocol, as described in the scale's Service Manual. +# e.g. here: https://www.manualslib.com/manual/861274/Mettler-Toledo-Viva.html?page=51#manual +# Our recommended scale, the Mettler-Toledo "Ariva-S", supports this protocol on +# both the USB and RS232 ports, it can be configured in the setup menu as protocol option 3. +# We use the default serial protocol settings, the scale's settings can be configured in the +# scale's menu anyway. +Toledo8217Protocol = SerialProtocol( + name='Toledo 8217', + baudrate=9600, + bytesize=serial.SEVENBITS, + stopbits=serial.STOPBITS_ONE, + parity=serial.PARITY_EVEN, + timeout=1, + writeTimeout=1, + measureRegexp=b"\x02\\s*([0-9.]+)N?\\r", + statusRegexp=b"\x02\\s*\\?([^\x00])\\r", + commandDelay=0.2, + measureDelay=0.5, + newMeasureDelay=0.2, + commandTerminator=b'', + measureCommand=b'W', + emptyAnswerValid=False, +) + + +# HW Proxy is used by Community edition +class ScaleReadHardwareProxy(http.Controller): + @http.route('/hw_proxy/scale_read', type='jsonrpc', auth='none', cors='*') + def scale_read(self): + if ACTIVE_SCALE: + return {'weight': ACTIVE_SCALE._scale_read_hw_proxy()} + return None + + +class ScaleDriver(SerialDriver): + """Abstract base class for scale drivers.""" + last_sent_value = None + + def __init__(self, identifier, device): + super().__init__(identifier, device) + self.device_type = 'scale' + self._set_actions() + self._is_reading = True + + # The HW Proxy can only expose one scale, + # only the last scale connected is kept + global ACTIVE_SCALE # noqa: PLW0603 + ACTIVE_SCALE = self + proxy_drivers['scale'] = ACTIVE_SCALE + + # Used by the HW Proxy in Community edition + def get_status(self): + """Allows `hw_proxy.Proxy` to retrieve the status of the scales""" + + status = self._status + return {'status': status['status'], 'messages': [status['message_title']]} + + def _set_actions(self): + """Initializes `self._actions`, a map of action keys sent by the frontend to backend action methods.""" + + self._actions.update({ + 'read_once': self._read_once_action, + 'start_reading': self._start_reading_action, + 'stop_reading': self._stop_reading_action, + }) + + def _start_reading_action(self, data): + """Starts asking for the scale value.""" + self._is_reading = True + + def _stop_reading_action(self, data): + """Stops asking for the scale value.""" + self._is_reading = False + + def _read_once_action(self, data): + """Reads the scale current weight value and pushes it to the frontend.""" + + self._read_weight() + self.last_sent_value = self.data['result'] + + @staticmethod + def _get_raw_response(connection): + """Gets raw bytes containing the updated value of the device. + + :param connection: a connection to the device's serial port + :type connection: pyserial.Serial + :return: the raw response to a weight request + :rtype: str + """ + + answer = [] + while True: + char = connection.read(1) + if not char: + break + else: + answer.append(bytes(char)) + return b''.join(answer) + + def _read_weight(self): + """Asks for a new weight from the scale, checks if it is valid and, if it is, makes it the current value.""" + + protocol = self._protocol + self._connection.write(protocol.measureCommand + protocol.commandTerminator) + answer = self._get_raw_response(self._connection) + match = re.search(self._protocol.measureRegexp, answer) + if match: + self.data = { + 'result': float(match.group(1)), + 'status': self._status + } + else: + self._read_status(answer) + + # Ensures compatibility with Community edition + def _scale_read_hw_proxy(self): + """Used when the iot app is not installed""" + with self._device_lock: + self._read_weight() + return self.data['result'] + + def _take_measure(self): + """Reads the device's weight value, and pushes that value to the frontend.""" + + with self._device_lock: + self._read_weight() + if self.data['result'] != self.last_sent_value or self._status['status'] == self.STATUS_ERROR: + self.last_sent_value = self.data['result'] + event_manager.device_changed(self) + + +class Toledo8217Driver(ScaleDriver): + """Driver for the Toldedo 8217 serial scale.""" + _protocol = Toledo8217Protocol + + def __init__(self, identifier, device): + super().__init__(identifier, device) + self.device_manufacturer = 'Toledo' + + @classmethod + def supported(cls, device): + """Checks whether the device, which port info is passed as argument, is supported by the driver. + + :param device: path to the device + :type device: str + :return: whether the device is supported by the driver + :rtype: bool + """ + + protocol = cls._protocol + + try: + with serial_connection(device['identifier'], protocol, is_probing=True) as connection: + connection.reset_input_buffer() + + connection.write(b'Ehello' + protocol.commandTerminator) + time.sleep(protocol.commandDelay) + answer = connection.read(8) + if answer == b'\x02E\rhello': + connection.write(b'F' + protocol.commandTerminator) + connection.reset_input_buffer() + return True + except serial.serialutil.SerialTimeoutException: + pass + except Exception: + _logger.exception('Error while probing %s with protocol %s', device, protocol.name) + return False + + def _read_status(self, answer): + """ + Status byte in form of an ascii character (Ex: 'D') is sent if scale is in motion, or is net/gross weight is negative or over capacity. + Convert the status byte to a binary string, and check its bits to see if there is an error. + LSB is the last char so the binary string is read in reverse and the first char is a parity bit, so we ignore it. + :param answer: scale answer (Example: b'\x02?D\r') + :type answer: bytestring + """ + status_char_error_bits = ( + 'Scale in motion', # 0 + 'Over capacity', # 1 + 'Under zero', # 2 + 'Outside zero capture range', # 3 + 'Center of zero', # 4 + 'Net weight', # 5 + 'Bad Command from host', # 6 + ) + + status_match = self._protocol.statusRegexp and re.search(self._protocol.statusRegexp, answer) + if status_match: + status_char = status_match.group(1).decode() # Example: b'D' extracted from b'\x02?D\r' + binary_status_char = format(ord(status_char), '08b') # Example: '00001101' + for index, bit in enumerate(binary_status_char[1:][::-1]): # Read the bits in reverse order (LSB is at the last char) + ignore the first "parity" bit + if int(bit): + _logger.debug("Scale error: %s. Status string: %s. Scale answer: %s.", status_char_error_bits[index], binary_status_char, answer) + self.data = { + 'result': 0, + 'status': self._status, + } + break diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/display_interface_L.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/display_interface_L.py new file mode 100644 index 00000000..51d78bcf --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/display_interface_L.py @@ -0,0 +1,39 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import logging +import re +import subprocess + +from odoo.addons.iot_drivers.interface import Interface + +_logger = logging.getLogger(__name__) + + +class DisplayInterface(Interface): + _loop_delay = 3 + connection_type = 'display' + + def get_devices(self): + randr_result = subprocess.run(['wlr-randr'], capture_output=True, text=True, check=False) + if randr_result.returncode != 0: + return {} + displays = re.findall(r"\((HDMI-A-\d)\)", randr_result.stdout) + return { + monitor: self._add_device(monitor, x_screen) + for x_screen, monitor in enumerate(displays) + } + + @classmethod + def _add_device(cls, display_identifier, x_screen): + """Creates a display_device dict. + + :param display_identifier: the identifier of the display + :param x_screen: the x screen number + :return: the display device dict + """ + + return { + 'identifier': display_identifier, + 'name': 'Display - ' + display_identifier, + 'x_screen': str(x_screen), + } diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/printer_interface_L.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/printer_interface_L.py new file mode 100644 index 00000000..15709d18 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/printer_interface_L.py @@ -0,0 +1,245 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from cups import Connection as CupsConnection, IPPError +from itertools import groupby +from threading import Lock +from urllib.parse import urlsplit, parse_qs, unquote +from zeroconf import ( + IPVersion, + ServiceBrowser, + ServiceStateChange, + Zeroconf, +) +import logging +import pyudev +import re +import time + +from odoo.addons.iot_drivers.interface import Interface +from odoo.addons.iot_drivers.main import iot_devices + +_logger = logging.getLogger(__name__) + +conn = CupsConnection() +PPDs = conn.getPPDs() +cups_lock = Lock() # We can only make one call to Cups at a time + + +class PrinterInterface(Interface): + connection_type = 'printer' + _loop_delay = 20 # Default delay between calls to get_devices + + def __init__(self): + super().__init__() + self.start_time = time.time() + + def get_devices(self): + discovered_devices = {} + with cups_lock: + printers = conn.getPrinters() + devices = conn.getDevices() + + # get and adjust configuration of printers already added in cups + for printer_name, printer in printers.items(): + path = printer.get('device-uri') + if path and printer_name != self.get_identifier(path): + device_class = 'direct' if 'usb' in path else 'network' + printer.update({ + 'already-configured': True, + 'device-class': device_class, + 'device-make-and-model': printer_name, # give name set in Cups + 'device-id': '', + }) + devices.update({printer_name: printer}) + + # filter devices (both added and not added in cups) to show as detected by the IoT Box + for path, device in devices.items(): + identifier, device = self.process_device(path, device) + + url_is_supported = any(protocol in device["url"] for protocol in ['dnssd', 'lpd', 'socket']) + model_is_valid = device["device-make-and-model"] != "Unknown" + printer_is_usb = "direct" in device["device-class"] + + if (url_is_supported and model_is_valid) or printer_is_usb: + discovered_devices.update({identifier: device}) + + if not device.get("already-configured"): + self.set_up_printer_in_cups(device) + + # Let get_devices be called again every 20 seconds (get_devices of PrinterInterface + # takes between 4 and 15 seconds) but increase the delay to 2 minutes if it has been + # running for more than 1 hour + if self.start_time and time.time() - self.start_time > 3600: + self._loop_delay = 120 + self.start_time = None # Reset start_time to avoid changing the loop delay again + + return self.deduplicate_printers(discovered_devices) + + def process_device(self, path, device): + identifier = self.get_identifier(path) + device.update({ + 'identifier': identifier, + 'url': path, + }) + if device['device-class'] == 'direct': + device.update(self.get_usb_info(path)) + elif device['device-class'] == 'network': + device['ip'] = self.get_ip(path) + + return identifier, device + + def get_identifier(self, path): + """ + Necessary because the path is not always a valid Cups identifier, + as it may contain characters typically found in URLs or paths. + + - Removes characters: ':', '/', '.', '\', and space. + - Removes the exact strings: "uuid=" and "serial=". + + Example 1: + Input: "ipp://printers/printer1:1234/abcd" + Output: "ippprintersprinter11234abcd" + + Example 2: + Input: "uuid=1234-5678-90ab-cdef" + Output: "1234-5678-90ab-cdef + """ + return re.sub(r'[:\/\.\\ ]|(uuid=)|(serial=)', '', path) + + def get_ip(self, device_path): + hostname = urlsplit(device_path).hostname + + if hostname and hostname.endswith(".local"): + zeroconf_name = unquote(hostname.lower()) + "." + if zeroconf_name in self.printer_ip_map: + return self.printer_ip_map[zeroconf_name] + + return hostname + + @staticmethod + def get_usb_info(device_path): + parsed_url = urlsplit(device_path) + parsed_query = parse_qs(parsed_url.query) + manufacturer = parsed_url.hostname + product = parsed_url.path.removeprefix("/") + serial = parsed_query["serial"][0] if "serial" in parsed_query else None + + if manufacturer and product and serial: + return { + "usb_manufacturer": manufacturer, + "usb_product": product, + "usb_serial_number": serial, + } + else: + return {} + + @staticmethod + def deduplicate_printers(discovered_printers): + result = [] + sorted_printers = sorted(discovered_printers.values(), key=lambda printer: str(printer.get('ip'))) + + for ip, printers_with_same_ip in groupby(sorted_printers, lambda printer: printer.get('ip')): + already_registered_identifier = next(( + identifier for identifier, device in iot_devices.items() + if device.device_type == 'printer' and ip and ip == device.ip + ), None) + if already_registered_identifier: + result.append({'identifier': already_registered_identifier}) + continue + + printers_with_same_ip = sorted(printers_with_same_ip, key=lambda printer: printer['identifier']) + if ip is None or len(printers_with_same_ip) == 1: + result += printers_with_same_ip + continue + + chosen_printer = next(( + printer for printer in printers_with_same_ip + if 'CMD:' in printer['device-id'] or 'ZPL' in printer['device-id'] + ), None) + if not chosen_printer: + chosen_printer = printers_with_same_ip[0] + result.append(chosen_printer) + + return {printer['identifier']: printer for printer in result} + + def monitor_for_printers(self): + context = pyudev.Context() + monitor = pyudev.Monitor.from_netlink(context) + monitor.filter_by('usb') + + def on_device_change(udev_device): + if udev_device.action != 'add' or udev_device.driver != 'usblp': + return + + try: + device_id = udev_device.attributes.asstring('ieee1284_id') + manufacturer = udev_device.parent.attributes.asstring('manufacturer') + product = udev_device.parent.attributes.asstring('product') + serial = udev_device.parent.attributes.asstring('serial') + except KeyError as err: + _logger.warning("Could not hotplug printer, field '%s' is not present", err.args[0]) + return + + path = f"usb://{manufacturer}/{product}?serial={serial}" + iot_device = { + 'device-class': 'direct', + 'device-make-and-model': f'{manufacturer} {product}', + 'device-id': device_id, + } + identifier, iot_device = self.process_device(path, iot_device) + self.add_device(identifier, iot_device) + + observer = pyudev.MonitorObserver(monitor, callback=on_device_change) + observer.start() + + def start_zeroconf_listener(self): + self.printer_ip_map = {} + service_types = [ + "_printer._tcp.local.", + "_pdl-datastream._tcp.local.", + "_ipp._tcp.local.", + "_ipps._tcp.local.", + ] + + def on_service_change(zeroconf, service_type, name, state_change): + if state_change is not ServiceStateChange.Added: + return + info = zeroconf.get_service_info(service_type, name) + if info and info.addresses: + address = info.parsed_addresses(IPVersion.V4Only)[0] + self.printer_ip_map[name.lower()] = address + + zeroconf = Zeroconf(ip_version=IPVersion.V4Only) + self.zeroconf_browser = ServiceBrowser(zeroconf, service_types, handlers=[on_service_change]) + + @staticmethod + def set_up_printer_in_cups(device): + """Configure detected printer in cups: ppd files, name, info, groups, ... + + :param dict device: printer device to configure in cups (detected but not added) + """ + fallback_model = device.get('device-make-and-model', "") + model = next(( + device_id.split(":")[1] for device_id in device.get('device-id', "").split(";") + if any(key in device_id for key in ['MDL', 'MODEL']) + ), fallback_model) + model = re.sub(r"[\(].*?[\)]", "", model).strip() + + ppdname_argument = next(({"ppdname": ppd} for ppd in PPDs if model and model in PPDs[ppd]['ppd-product']), {}) + + try: + with cups_lock: + conn.addPrinter(name=device['identifier'], device=device['url'], **ppdname_argument) + conn.setPrinterInfo(device['identifier'], device['device-make-and-model']) + conn.enablePrinter(device['identifier']) + conn.acceptJobs(device['identifier']) + conn.setPrinterUsersAllowed(device['identifier'], ['all']) + conn.addPrinterOptionDefault(device['identifier'], "usb-no-reattach", "true") + conn.addPrinterOptionDefault(device['identifier'], "usb-unidir", "true") + except IPPError: + _logger.exception("Failed to add printer '%s'", device['identifier']) + + def start(self): + super().start() + self.start_zeroconf_listener() + self.monitor_for_printers() diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/printer_interface_W.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/printer_interface_W.py new file mode 100644 index 00000000..59ffeb4d --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/printer_interface_W.py @@ -0,0 +1,46 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import logging +from threading import Lock +import win32print + +from odoo.addons.iot_drivers.interface import Interface + +_logger = logging.getLogger(__name__) + +win32print_lock = Lock() # Calling win32print in parallel can cause failed prints + + +class PrinterInterface(Interface): + _loop_delay = 30 + connection_type = 'printer' + + def get_devices(self): + printer_devices = {} + with win32print_lock: + printers = win32print.EnumPrinters(win32print.PRINTER_ENUM_LOCAL) + + for printer in printers: + identifier = printer[2] + handle_printer = win32print.OpenPrinter(identifier) + # The value "2" is the level of detail we want to get from the printer, see: + # https://learn.microsoft.com/en-us/windows/win32/printdocs/getprinter#parameters + printer_details = win32print.GetPrinter(handle_printer, 2) + printer_port = None + if printer_details: + # see: https://learn.microsoft.com/en-us/windows/win32/printdocs/printer-info-2#members + printer_port = printer_details.get('pPortName') + if printer_port is None: + _logger.warning('Printer "%s" has no port name. Used dummy port', identifier) + printer_port = 'IOT_DUMMY_PORT' + + if printer_port == "PORTPROMPT:": + # discard virtual printers (like "Microsoft Print to PDF") as they will trigger dialog boxes prompt + continue + + printer_devices[identifier] = { + 'identifier': identifier, + 'printer_handle': handle_printer, + 'port': printer_port, + } + return printer_devices diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/serial_interface.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/serial_interface.py new file mode 100644 index 00000000..7ce886a1 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/serial_interface.py @@ -0,0 +1,20 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from serial.tools.list_ports import comports + +from odoo.addons.iot_drivers.tools.system import IS_WINDOWS +from odoo.addons.iot_drivers.interface import Interface + + +class SerialInterface(Interface): + connection_type = 'serial' + allow_unsupported = True + + def get_devices(self): + serial_devices = { + port.device: {'identifier': port.device} + for port in comports() + if IS_WINDOWS or port.subsystem != 'amba' + # RPI 5 uses ttyAMA10 as a console serial port for system messages: odoo interprets it as scale -> avoid it + } + return serial_devices diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/usb_interface_L.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/usb_interface_L.py new file mode 100644 index 00000000..e23ef809 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/iot_handlers/interfaces/usb_interface_L.py @@ -0,0 +1,48 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from usb import core + +from odoo.addons.iot_drivers.interface import Interface + + +class USBInterface(Interface): + connection_type = 'usb' + allow_unsupported = True + + @staticmethod + def usb_matcher(dev): + # USB Class codes documentation: https://www.usb.org/defined-class-codes + # Ignore USB hubs (9) and printers (7) + if dev.bDeviceClass in [7, 9]: + return False + # If the device has generic base class (0) check its interface descriptor + elif dev.bDeviceClass == 0: + for conf in dev: + for interface in conf: + if interface.bInterfaceClass == 7: # 7 = printer + return False + + # Ignore serial adapters + try: + return dev.product != "USB2.0-Ser!" + except ValueError: + return True + + def get_devices(self): + """ + USB devices are identified by a combination of their `idVendor` and + `idProduct`. We can't be sure this combination in unique per equipment. + To still allow connecting multiple similar equipments, we complete the + identifier by a counter. The drawbacks are we can't be sure the equipments + will get the same identifiers after a reboot or a disconnect/reconnect. + """ + usb_devices = {} + devs = core.find(find_all=True, custom_match=self.usb_matcher) + cpt = 2 + for dev in devs: + identifier = "usb_%04x:%04x" % (dev.idVendor, dev.idProduct) + if identifier in usb_devices: + identifier += '_%s' % cpt + cpt += 1 + usb_devices[identifier] = dev + return usb_devices diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/main.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/main.py new file mode 100644 index 00000000..0aa2223b --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/main.py @@ -0,0 +1,181 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +import logging +import requests +import schedule +import subprocess +from threading import Thread +import time + +from odoo.addons.iot_drivers.tools import certificate, helpers, upgrade, wifi +from odoo.addons.iot_drivers.tools.system import IS_RPI +from odoo.addons.iot_drivers.websocket_client import WebsocketClient + +if IS_RPI: + from dbus.mainloop.glib import DBusGMainLoop + DBusGMainLoop(set_as_default=True) # Must be started from main thread + +_logger = logging.getLogger(__name__) + +drivers = [] +interfaces = {} +iot_devices = {} +unsupported_devices = {} + + +class Manager(Thread): + daemon = True + ws_channel = "" + + def __init__(self): + super().__init__() + self.identifier = helpers.get_identifier() + self.domain = self._get_domain() + self.version = helpers.get_version(detailed_version=True) + self.previous_iot_devices = {} + self.previous_unsupported_devices = {} + + def _get_domain(self): + """ + Get the iot box domain based on the IP address and subject. + """ + subject = helpers.get_conf('subject') + ip_addr = helpers.get_ip() + if subject and ip_addr: + return ip_addr.replace('.', '-') + subject.strip('*') + return ip_addr or '127.0.0.1' + + def _get_changes_to_send(self): + """ + Check if the IoT Box information has changed since the last time it was sent. + Returns True if any tracked property has changed. + """ + changed = False + + current_devices = set(iot_devices.keys()) | set(unsupported_devices.keys()) + previous_devices = set(self.previous_iot_devices.keys()) | set(self.previous_unsupported_devices.keys()) + if current_devices != previous_devices: + self.previous_iot_devices = iot_devices.copy() + self.previous_unsupported_devices = unsupported_devices.copy() + changed = True + + # IP address change + new_domain = self._get_domain() + if self.domain != new_domain: + self.domain = new_domain + changed = True + # Version change + new_version = helpers.get_version(detailed_version=True) + if self.version != new_version: + self.version = new_version + changed = True + + return changed + + @helpers.require_db + def _send_all_devices(self, server_url=None): + """This method send IoT Box and devices information to Odoo database + + As the server can be down or not started yet (in case of local testing), + we retry to send the data several times with a delay between each attempt. + + :param server_url: URL of the Odoo server (provided by decorator). + """ + iot_box = { + 'identifier': self.identifier, + 'ip': self.domain, + 'token': helpers.get_token(), + 'version': self.version, + } + devices_list = {} + for device in self.previous_iot_devices.values(): + identifier = device.device_identifier + devices_list[identifier] = { + 'name': device.device_name, + 'type': device.device_type, + 'manufacturer': device.device_manufacturer, + 'connection': device.device_connection, + 'subtype': device.device_subtype if device.device_type == 'printer' else '', + } + devices_list.update(self.previous_unsupported_devices) + + delay = .5 + max_retries = 5 + for attempt in range(1, max_retries + 1): + try: + response = requests.post( + server_url + "/iot/setup", + json={'params': {'iot_box': iot_box, 'devices': devices_list}}, + timeout=5, + ) + response.raise_for_status() + data = response.json() + self.ws_channel = data.get('result', '') + break # Success, exit the retry loop + except requests.exceptions.RequestException: + if attempt < max_retries: + _logger.warning( + 'Could not reach configured server to send all IoT devices, retrying in %s seconds (%d/%d attempts)', + delay, attempt, max_retries, exc_info=True + ) + time.sleep(delay) + else: + _logger.exception('Could not reach configured server to send all IoT devices after %d attempts.', max_retries) + except ValueError: + _logger.exception('Could not load JSON data: Received data is not valid JSON.\nContent:\n%s', response.content) + break + + def run(self): + """Thread that will load interfaces and drivers and contact the odoo server + with the updates. It will also reconnect to the Wi-Fi if the connection is lost. + """ + if IS_RPI: + # ensure that the root filesystem is writable retro compatibility (TODO: remove this in 19.0) + subprocess.run(["sudo", "mount", "-o", "remount,rw", "/"], check=False) + subprocess.run(["sudo", "mount", "-o", "remount,rw", "/root_bypass_ramdisks/"], check=False) + + wifi.reconnect(helpers.get_conf('wifi_ssid'), helpers.get_conf('wifi_password')) + + helpers.start_nginx_server() + _logger.info("IoT Box Image version: %s", helpers.get_version(detailed_version=True)) + upgrade.check_git_branch() + + if IS_RPI and helpers.get_odoo_server_url(): + helpers.generate_password() + + certificate.ensure_validity() + + # We first add the IoT Box to the connected DB because IoT handlers cannot be downloaded if + # the identifier of the Box is not found in the DB. So add the Box to the DB. + self._send_all_devices() + helpers.download_iot_handlers() + helpers.load_iot_handlers() + + for interface in interfaces.values(): + interface().start() + + # Set scheduled actions + schedule.every().day.at("00:00").do(certificate.ensure_validity) + schedule.every().day.at("00:00").do(helpers.reset_log_level) + + # Set up the websocket connection + ws_client = WebsocketClient(self.ws_channel) + if ws_client: + ws_client.start() + + # Check every 3 seconds if the list of connected devices has changed and send the updated + # list to the connected DB. + while 1: + try: + if self._get_changes_to_send(): + self._send_all_devices() + if IS_RPI and helpers.get_ip() != '10.11.12.1': + wifi.reconnect(helpers.get_conf('wifi_ssid'), helpers.get_conf('wifi_password')) + time.sleep(3) + schedule.run_pending() + except Exception: + # No matter what goes wrong, the Manager loop needs to keep running + _logger.exception("Manager loop unexpected error") + + +manager = Manager() +manager.start() diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/server_logger.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/server_logger.py new file mode 100644 index 00000000..43de43df --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/server_logger.py @@ -0,0 +1,171 @@ +import logging +import queue +import requests +import threading +import time + +from odoo.addons.iot_drivers.tools import helpers +from odoo.addons.iot_drivers.tools.system import IS_TEST +from odoo.netsvc import ColoredFormatter + +_logger = logging.getLogger(__name__) + +IOT_LOG_TO_SERVER_CONFIG_NAME = 'iot_log_to_server' # config name in odoo.conf + + +class AsyncHTTPHandler(logging.Handler): + """ + Custom logging handler which send IoT logs using asynchronous requests. + To avoid spamming the server, we send logs by batch each X seconds + """ + _MAX_QUEUE_SIZE = 1000 + """Maximum queue size. If a log record is received but the queue if full it will be discarded""" + _MAX_BATCH_SIZE = 50 + """Maximum number of sent logs batched at once. Used to avoid too heavy request. Log records still in the queue will + be handle in future flushes""" + _FLUSH_INTERVAL = 0.5 + """How much seconds it will sleep before checking for new logs to send""" + _REQUEST_TIMEOUT = 0.5 + """Amount of seconds to wait per log to send before timeout""" + _DELAY_BEFORE_NO_SERVER_LOG = 5 * 60 # 5 minutes + """Minimum delay in seconds before we log a server disconnection. + Used in order to avoid the IoT log file to have a log recorded each _FLUSH_INTERVAL (as this value is very small)""" + + def __init__(self, odoo_server_url, active): + """ + :param odoo_server_url: Odoo Server URL + """ + super().__init__() + self._odoo_server_url = odoo_server_url + self._db_name = helpers.get_conf('db_name') or '' + self._log_queue = queue.Queue(self._MAX_QUEUE_SIZE) + self._flush_thread = None + self._active = None + self._next_disconnection_time = None + self.toggle_active(active) + + def toggle_active(self, is_active): + """ + Switch it on or off the handler (depending on the IoT setting) without the need to close/reset it + """ + self._active = is_active + if self._active and self._odoo_server_url: + # Start the thread to periodically flush logs + self._flush_thread = threading.Thread(target=self._periodic_flush, name="ThreadServerLogSender", daemon=True) + self._flush_thread.start() + else: + self._flush_thread and self._flush_thread.join() # let a last flush + + def _periodic_flush(self): + odoo_session = requests.Session() + while self._odoo_server_url and self._active: # allow to exit the loop on thread.join + time.sleep(self._FLUSH_INTERVAL) + self._flush_logs(odoo_session) + + def _flush_logs(self, odoo_session): + def convert_to_byte(s): + return bytes(s, encoding="utf-8") + b'\n' + + def convert_server_line(log_level, line_formatted): + return convert_to_byte(f"{log_level},{line_formatted}") + + def empty_queue(): + yield convert_to_byte(f"identifier {helpers.get_identifier()}") + for _ in range(self._MAX_BATCH_SIZE): + # Use a limit to avoid having too heavy requests & infinite loop of the queue receiving new entries + try: + log_record = self._log_queue.get_nowait() + yield convert_server_line(log_record.levelno, self.format(log_record)) + except queue.Empty: + break + + # Report to the server if the queue is close from saturation + if queue_size >= .8 * self._MAX_QUEUE_SIZE: + log_message = "The IoT {} queue is saturating: {}/{} ({:.2f}%)".format( # noqa: UP032 + self.__class__.__name__, queue_size, self._MAX_QUEUE_SIZE, + 100 * queue_size / self._MAX_QUEUE_SIZE) + _logger.warning(log_message) # As we don't log our own logs, this will be part of the IoT logs + # In order to report this to the server (on the current batch) we will append it manually + yield convert_server_line(logging.WARNING, log_message) + + queue_size = self._log_queue.qsize() # This is an approximate value + + if not self._odoo_server_url or queue_size == 0: + return + try: + odoo_session.post( + self._odoo_server_url + '/iot/log', + data=empty_queue(), + headers={'X-Odoo-Database': self._db_name}, + timeout=self._REQUEST_TIMEOUT + ).raise_for_status() + self._next_disconnection_time = None + except (requests.exceptions.ConnectTimeout, requests.exceptions.ConnectionError) as request_errors: + now = time.time() + if not self._next_disconnection_time or now >= self._next_disconnection_time: + _logger.info("Connection with the server to send the logs failed. It is likely down: %s", request_errors) + self._next_disconnection_time = now + self._DELAY_BEFORE_NO_SERVER_LOG + except Exception as _: + _logger.exception('Unexpected error happened while sending logs to server') + + def emit(self, record): + # This is important that this method is as fast as possible. + # The log calls will be waiting for this function to finish + if not self._active: + return + try: # noqa: SIM105 + self._log_queue.put_nowait(record) + except queue.Full: + pass + + def close(self): + self.toggle_active(False) + super().close() + + +def close_server_log_sender_handler(): + _server_log_sender_handler.close() + + +def get_odoo_config_log_to_server_option(): + # Enabled by default if not in test mode + return not IS_TEST and (helpers.get_conf(IOT_LOG_TO_SERVER_CONFIG_NAME, section='options') or True) + + +def check_and_update_odoo_config_log_to_server_option(new_state): + """ + :return: wherever the config file need to be updated or not + """ + if get_odoo_config_log_to_server_option() != new_state: + helpers.update_conf({IOT_LOG_TO_SERVER_CONFIG_NAME, new_state}, section='options') + _server_log_sender_handler.toggle_active(new_state) + return True + return False + + +def _server_log_sender_handler_filter(log_record): + def _filter_my_logs(): + """Filter out our own logs (to avoid infinite loop)""" + return log_record.name == __name__ + + def _filter_frequent_irrelevant_calls(): + """Filter out this frequent irrelevant HTTP calls, to avoid spamming the server with useless logs""" + return ( + log_record.name == 'werkzeug' + and log_record.args + and len(log_record.args) > 0 + and str(log_record.args[0]).startswith('GET /hw_proxy/hello ') + ) + + return not (_filter_my_logs() or _filter_frequent_irrelevant_calls()) + + +# The server URL is set once at initlialisation as the IoT will always restart if the URL is changed +# The only other possible case is when the server URL value is "Cleared", +# in this case we force close the log handler (as it does not make sense anymore) +_server_log_sender_handler = AsyncHTTPHandler(helpers.get_odoo_server_url(), get_odoo_config_log_to_server_option()) +if not IS_TEST: + _server_log_sender_handler.setFormatter(ColoredFormatter('%(asctime)s %(pid)s %(levelname)s %(dbname)s %(name)s: %(message)s %(perf_info)s')) + _server_log_sender_handler.addFilter(_server_log_sender_handler_filter) + # Set it in the 'root' logger, on which every logger (including odoo) is a child + logging.getLogger().addHandler(_server_log_sender_handler) diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/img/background-light.svg b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/img/background-light.svg new file mode 100644 index 00000000..aa437a11 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/img/background-light.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/img/favicon.png b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/img/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..dfcf7b02ee888a14a6e86a389c524c3781e93b0c GIT binary patch literal 2036 zcmeAS@N?(olHy`uVBq!ia0y~yU`PRB4mJh`hJr^^Ll_tsI14-?iy0WiR6&^0Gf3qF z0|NtNage(c!@6@aFBupZSkfJR9T^xl_H+M9WMyDr@APzW45?szJLi6WaH!0I{m<{b z+a}9=TC9F{K!9-aqcu|ZeQvOQdeAKNpFz?l^Fo7KR?Wq?Ctc*PthlIt^ACH2c+Z9l zvp(>M`lxiRadu?cCMI!v*S+e#`|s}_Yugrk`}gL@zfZoay1s7v-shL!TRyMb|6Qyh zQKAhMrR6FsG%eX|HFZ|ANXZRJ)~v}v8zMb+w96ebpTo2;_?&&##C5wE7jk#^Pd9Pk z4EKuao2C@z$7@yGVEor(6+2z zL52(Lxh$tnKCHG=5&a|LV*Y&ggfskBYkjiC8>D&?M7DS_wn)sJer-kk#K$WIUiF#X zm>TtdqtsY%Q3d- z7yZ|&OiZ}CBn!2dsVeF$vdcSSqWYxsP0p^vW_%kuj%B#|I6H;)2s$4y=@t7>>3S>P zL@6y)ac}bH-yhOA-t9YhEBhGZlMh*&H_dX|QT>Vi&9O~4df%=T)!lS!u88Qe+&M{- z_nLEW_2*V^`hMfiKdFBG!-0Z2R~J3qCZK*_<%{EkjY=8E3?KhFH}maB=P&KbPgcsG zwr*AAV-gmN%B+4cU3{{o85gH#hRag4Sm%2GvzjH zGQA<@kQ(=RQ^EY!*H1^~}I|CUvG6vo~LEIQ?nc(uFdfvEMyB z%3PfT&R9Atw{+b*hua;;oqKo{fdssu`f0m4c60A z1^x%$sa|8#viP+71(hqdvHKP{%{FXhbv^lawn|CaRs-$mH_O8Ag_=H_HPLCJ!`nO}!oqH$FOl|Ltx)tt`ijpH4hJ_A1$%SJLHf`nAbL z$w3FFcE4IDp*^dyDBWaR&YtydTdquWTw~>1@#@8!1rv@nPW>JzZd!ShZJAjpTg_V0 zHp_lKctLJKv=M(5Cs}eeW)q)LwmS=X(TyQO)W%qB!J#X23UCZn*7RaUM zWQVdnw2S>2X(+n=%;Oyk(+@cJtUR3{@;`FN(WBfRTqjrBe9>6Jd-s8=)8Ugpe4cN+ zG-3DYReMj$SF5xtEqr`vy}<5@b_hWo9$niNe)p7u&Dt$0 zc5{y@R~d5nDsA|9wv$!x(5&_aD{cNroLM|a?8tXr#Qlo;e)9|C?JS>D zK`t|%FZ!q}?%VY-hV7yEM2n9v&nnIdyna@s+()N_Ls{w7#w$}JHJ0Do-`MnU=lAQp z&BuR)ZC$V0x=3l_`6{!3->!2rKKimfe4Q!sf2z~vYe!bDdC$Bpd_vDnpZ}*MXRbHm zxbJTfHRV&{n@jRah0j>FC_h!7*M4f5dhK*amLj$rzpnf996LYvpWce=pBZE8)|7ug zn;$R1I-m1Njpv<-f@{CX6{M-XWlhcbxR+h2nd6J_>{q|7l8-R(D;#ypU=BDoCHLUA zpuGHq&z~I5Yb=vJEGr|xxtT*yok!9|qqb_*``KF(Up!V?G&8AJGWxa{^U^!gtQ<2g zu-#nY#Tm>d_-c)MR?wkojxALu1>RbiHuO1s6}*4==Y~{)h4F{CDlGk@W7fI;`ieD& zJa7BiiErak5(>ASR+K+oC%aC8MRUr=vr%C}>A}05|L(h|s#N}@=KZ(zd>IR}pVzu` z2P_Uhe(#G(?Yn6mvEn=qyehjVDL>GkIK^?t-djh+^XA&t>?l6%EwOhI|DN_;D<5Vj z=kMbcRGH+|G4r!~k)226l#SP~_pFsx(r)<>;q@d{V4|4QnhBdkqvp44Y2{gz`%2iB zIi8Og!>R9XyH6HpNWTkr2%R-WDTVD5s;&+{^`Pty95^Sel$?MJrL3zK(kpGAW;RxX%wf-|wU mKKIR983Uff=xE~O_(c9?tqPM@hchrRFnGH9xvX { + await this.loadInitialData(); + }); + + setInterval(() => { + this.loadInitialData(); + }, 10000); + } + + get numDevices() { + return Object.values(this.state.data.devices) + .map((devices) => devices.length) + .reduce((a, b) => a + b, 0); + } + + get networkStatus() { + if ( + !this.store.isLinux || + this.state.data.network_interfaces.some((netInterface) => !netInterface.is_wifi) + ) { + return "Ethernet"; + } + const wifiInterface = this.state.data.network_interfaces.find( + (netInterface) => netInterface.ssid + ); + if (wifiInterface) { + return this.state.data.is_access_point_up + ? 'No internet connection - click on "Configure"' + : `Wi-Fi: ${wifiInterface.ssid}`; + } + return "Not Connected"; + } + + async loadInitialData() { + try { + const data = await this.store.rpc({ + url: "/iot_drivers/data", + }); + + if (data.system === "Linux") { + this.store.isLinux = true; + } + + this.state.data = data; + this.store.base = data; + this.state.loading = false; + this.store.update = new Date().getTime(); + } catch { + console.warn("Error while fetching data"); + } + } + + async restartOdooService() { + try { + await this.store.rpc({ + url: "/iot_drivers/restart_odoo_service", + }); + + this.state.waitRestart = true; + } catch { + console.warn("Error while restarting Odoo Service"); + } + } + + toggleAdvanced() { + this.store.advanced = !this.store.advanced; + localStorage.setItem("showAdvanced", this.store.advanced); + } + + static template = xml` + + + + Restarting IoT Box, please wait... + + + +
+
+
+ + +
+
+

IoT Box

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+
+ Loading... +
+
+
+ `; +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/FooterButtons.js b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/FooterButtons.js new file mode 100644 index 00000000..76cdeedc --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/FooterButtons.js @@ -0,0 +1,39 @@ +/* global owl */ + +import useStore from "../hooks/useStore.js"; +import { CredentialDialog } from "./dialog/CredentialDialog.js"; +import { HandlerDialog } from "./dialog/HandlerDialog.js"; +import { RemoteDebugDialog } from "./dialog/RemoteDebugDialog.js"; +import { TimeDialog } from "./dialog/TimeDialog.js"; + +const { Component, xml } = owl; + +export class FooterButtons extends Component { + static props = {}; + static components = { + RemoteDebugDialog, + HandlerDialog, + CredentialDialog, + TimeDialog, + }; + + setup() { + this.store = useStore(); + } + + static template = xml` + + `; +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/IconButton.js b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/IconButton.js new file mode 100644 index 00000000..d9525c5c --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/IconButton.js @@ -0,0 +1,22 @@ +/* global owl */ + +import useStore from "../hooks/useStore.js"; + +const { Component, xml } = owl; + +export class IconButton extends Component { + static props = { + onClick: Function, + icon: String, + }; + + setup() { + this.store = useStore(); + } + + static template = xml` +
+ +
+ `; +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/LoadingFullScreen.js b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/LoadingFullScreen.js new file mode 100644 index 00000000..37fdf0e6 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/LoadingFullScreen.js @@ -0,0 +1,41 @@ +/* global owl */ + +import useStore from "../hooks/useStore.js"; + +const { Component, xml, onMounted } = owl; + +export class LoadingFullScreen extends Component { + static props = { + slots: Object, + }; + + setup() { + this.store = useStore(); + + // We delay the RPC verification for 10 seconds to be sure that the Odoo service + // was already restarted + onMounted(() => { + setTimeout(() => { + setInterval(async () => { + try { + await this.store.rpc({ + url: "/iot_drivers/ping", + }); + window.location.reload(); + } catch { + console.warn("Odoo service is probably rebooting."); + } + }, 750); + }, 10000); + }); + } + + static template = xml` +
+
+ Loading... +
+ +
+ `; +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/SingleData.js b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/SingleData.js new file mode 100644 index 00000000..97b1ee78 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/SingleData.js @@ -0,0 +1,48 @@ +/* global owl */ + +const { Component, xml } = owl; + +export class SingleData extends Component { + static props = { + name: String, + value: String, + icon: { type: String, optional: true }, + style: { type: String, optional: true }, + slots: { type: Object, optional: true }, + btnName: { type: String, optional: true }, + btnAction: { type: Function, optional: true }, + }; + static defaultProps = { + style: "primary", + }; + + get valueIsURL() { + const expression = + /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[\w]*))?)/; + + const regex = new RegExp(expression); + if (this.props.value?.match(regex)) { + return true; + } else { + return false; + } + } + + static template = xml` +
+
+
+
+ + +
+

+ +

+
+
+ +
+ `; +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/BootstrapDialog.js b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/BootstrapDialog.js new file mode 100644 index 00000000..10fd85f9 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/BootstrapDialog.js @@ -0,0 +1,63 @@ +/* global owl */ + +const { Component, xml, useEffect, useRef } = owl; + +export class BootstrapDialog extends Component { + static props = { + identifier: String, + slots: Object, + btnName: { type: String, optional: true }, + isLarge: { type: Boolean, optional: true }, + onOpen: { type: Function, optional: true }, + onClose: { type: Function, optional: true }, + }; + + setup() { + this.dialog = useRef("dialog"); + + useEffect( + () => { + if (!this.dialog || !this.dialog.el) { + return; + } + + if (this.props.onOpen) { + this.dialog.el.addEventListener("show.bs.modal", this.props.onOpen); + } + + if (this.props.onClose) { + this.dialog.el.addEventListener("hide.bs.modal", this.props.onClose); + } + + return () => { + this.dialog.el.removeEventListener("show.bs.modal", this.props.onOpen); + this.dialog.el.removeEventListener("hide.bs.modal", this.props.onClose); + }; + }, + () => [this.dialog] + ); + } + + static template = xml` + + + + + + + + `; +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/DeviceDialog.js b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/DeviceDialog.js new file mode 100644 index 00000000..0f059c57 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/DeviceDialog.js @@ -0,0 +1,90 @@ +/* global owl */ + +import useStore from "../../hooks/useStore.js"; +import { BootstrapDialog } from "./BootstrapDialog.js"; + +const { Component, xml } = owl; + +export const DEVICE_ICONS = { + camera: "fa-camera", + device: "fa-plug", + display: "fa-desktop", + fiscal_data_module: "fa-dollar", + keyboard: "fa-keyboard-o", + payment: "fa-credit-card", + printer: "fa-print", + scale: "fa-balance-scale", + scanner: "fa-barcode", + unsupported: "fa-question", +}; + +export const CONNECTION_ICONS = { + hdmi: "fa-desktop", + direct: "fa-usb", + serial: "fa-usb", + network: "fa-sitemap", + bluetooth: "fa-bluetooth", +}; + +export class DeviceDialog extends Component { + static props = {}; + static components = { BootstrapDialog }; + + setup() { + this.store = useStore(); + this.icons = DEVICE_ICONS; + this.connectionIcons = CONNECTION_ICONS; + } + + formatDeviceType(deviceType, numDevices) { + const formattedDeviceType = + deviceType[0].toUpperCase() + deviceType.replaceAll("_", " ").slice(1); + return numDevices === 1 || deviceType === "unsupported" + ? formattedDeviceType + : `${formattedDeviceType}s`; + } + + get devices() { + return this.store.base.devices; + } + + static template = xml` + + + + Devices list + + + +
+
+

+ +

+
+
+
+ + + + + +
+
+
+
+
+
+ + + +
+
+ `; +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/HandlerDialog.js b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/HandlerDialog.js new file mode 100644 index 00000000..63acb4ea --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/HandlerDialog.js @@ -0,0 +1,154 @@ +/* global owl */ + +import useStore from "../../hooks/useStore.js"; +import { BootstrapDialog } from "./BootstrapDialog.js"; +import { LoadingFullScreen } from "../LoadingFullScreen.js"; + +const { Component, xml, useState } = owl; + +export class HandlerDialog extends Component { + static props = {}; + static components = { BootstrapDialog, LoadingFullScreen }; + + setup() { + this.store = useStore(); + this.state = useState({ + initialization: true, + waitRestart: false, + loading: false, + handlerData: {}, + globalLogger: {}, + }); + } + + onClose() { + this.state.initialization = []; + this.state.handlerData = {}; + } + + async getHandlerData() { + try { + const data = await this.store.rpc({ + url: "/iot_drivers/log_levels", + }); + this.state.handlerData = data; + this.state.globalLogger = { + "iot-logging-root": data.root_logger_log_level, + "iot-logging-odoo": data.odoo_current_log_level, + }; + this.state.initialization = false; + } catch { + console.warn("Error while fetching data"); + } + } + + async onChange(name, value) { + try { + await this.store.rpc({ + url: "/iot_drivers/log_levels_update", + method: "POST", + params: { + name: name, + value: value, + }, + }); + } catch { + console.warn("Error while saving data"); + } + } + + static template = xml` + + + + Processing your request, please wait... + + + + + + Handler logging + + +
+
+ Loading... +
+

Currently scanning for initialized drivers and interfaces...

+
+ +
+
Global logs level
+
+ + +
+
+
+
+
+
Interfaces logs level
+
+
+
+
+
Drivers logs level
+
+
+
+
+
+ + + +
+
+ `; +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/RemoteDebugDialog.js b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/RemoteDebugDialog.js new file mode 100644 index 00000000..fb623d1e --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/RemoteDebugDialog.js @@ -0,0 +1,139 @@ +/* global owl */ + +import useStore from "../../hooks/useStore.js"; +import { LoadingFullScreen } from "../LoadingFullScreen.js"; +import { BootstrapDialog } from "./BootstrapDialog.js"; + +const { Component, xml, onWillStart, useState } = owl; + +export class RemoteDebugDialog extends Component { + static props = {}; + static components = { BootstrapDialog, LoadingFullScreen }; + + setup() { + this.store = useStore(); + this.state = useState({ + password: "", + loading: false, + ngrok: false, + ngrokToken: "", + loadingNgrok: false, + }); + + onWillStart(async () => { + await this.isNgrokEnabled(); + }); + } + + async isNgrokEnabled() { + try { + const data = await this.store.rpc({ url: "/iot_drivers/is_ngrok_enabled" }); + this.state.ngrok = data.enabled; + if (!this.state.ngrok) { + this.state.ngrokToken = ""; + } + } catch { + console.warn("Error while fetching data"); + } + } + + async generatePassword() { + try { + this.state.loading = true; + + const data = await this.store.rpc({ + url: "/iot_drivers/generate_password", + method: "POST", + }); + + this.state.password = data.password; + this.state.loading = false; + } catch { + console.warn("Error while fetching data"); + } + } + + async enableNgrok() { + if (!this.state.ngrokToken) { + return; + } + this.state.loadingNgrok = true; + try { + await this.store.rpc({ + url: "/iot_drivers/enable_ngrok", + method: "POST", + params: { + auth_token: this.state.ngrokToken, + }, + }); + // Wait 2 seconds to let odoo-ngrok service start + await new Promise((resolve) => setTimeout(resolve, 2000)); + await this.isNgrokEnabled(); + } catch { + console.warn("Error while enabling remote debugging"); + } + this.state.loadingNgrok = false; + } + + async disableNgrok() { + this.state.loadingNgrok = true; + try { + await this.store.rpc({ + url: "/iot_drivers/disable_ngrok", + method: "POST", + }); + // Wait 2 seconds to let odoo-ngrok service stop + await new Promise((resolve) => setTimeout(resolve, 2000)); + await this.isNgrokEnabled(); + } catch { + console.warn("Error while disabling remote debugging"); + } + this.state.loadingNgrok = false; + } + + static template = xml` + + + + Remote Debugging + + + + +
+ + +
+ +
+ + + + +
+
+ `; +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/ServerDialog.js b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/ServerDialog.js new file mode 100644 index 00000000..6edb6d72 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/ServerDialog.js @@ -0,0 +1,90 @@ +/* global owl */ + +import useStore from "../../hooks/useStore.js"; +import { BootstrapDialog } from "./BootstrapDialog.js"; +import { LoadingFullScreen } from "../LoadingFullScreen.js"; + +const { Component, xml, useState } = owl; + +export class ServerDialog extends Component { + static props = {}; + static components = { BootstrapDialog, LoadingFullScreen }; + + setup() { + this.store = useStore(); + this.state = useState({ waitRestart: false, loading: false, error: null }); + this.form = useState({ token: "" }); + } + + async connectToServer() { + this.state.loading = true; + this.state.error = null; + try { + const data = await this.store.rpc({ + url: "/iot_drivers/connect_to_server", + method: "POST", + params: this.form, + }); + + if (data.status === "success") { + this.state.waitRestart = true; + } else { + this.state.error = data.message; + } + } catch { + console.warn("Error while fetching data"); + } + this.state.loading = false; + } + + async clearConfiguration() { + this.state.waitRestart = true; + try { + await this.store.rpc({ + url: "/iot_drivers/server_clear", + }); + } catch { + console.warn("Error while clearing configuration"); + } + } + + static template = xml` + + + + Updating Odoo Server information, please wait... + + + + + + Configure Odoo Database + + + +
+
+ +
+
+

+ Your current database is:
+ +

+
+
+
+ + + + + +
+
+ `; +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/SixDialog.js b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/SixDialog.js new file mode 100644 index 00000000..ab005d7d --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/SixDialog.js @@ -0,0 +1,83 @@ +/* global owl */ + +import useStore from "../../hooks/useStore.js"; +import { BootstrapDialog } from "./BootstrapDialog.js"; +import { LoadingFullScreen } from "../LoadingFullScreen.js"; + +const { Component, xml, useState, toRaw } = owl; + +export class SixDialog extends Component { + static props = {}; + static components = { BootstrapDialog, LoadingFullScreen }; + + setup() { + this.store = toRaw(useStore()); + this.state = useState({ waitRestart: false }); + this.form = useState({ terminal_id: this.store.base.six_terminal }); + } + + async configureSix() { + try { + if (!this.form.terminal_id) { + return; + } + + const data = await this.store.rpc({ + url: "/iot_drivers/six_payment_terminal_add", + method: "POST", + params: this.form, + }); + + if (data.status === "success") { + this.state.waitRestart = true; + } + } catch { + console.warn("Error while fetching data"); + } + } + + async disconnectSix() { + try { + const data = await this.store.rpc({ + url: "/iot_drivers/six_payment_terminal_clear", + }); + + if (data.status === "success") { + this.state.waitRestart = true; + } + } catch { + console.warn("Error while clearing configuration"); + } + } + + static template = xml` + + + + Your IoT Box is currently processing your request. Please wait. + + + + + + Configure a Six Terminal + + + +
+
+ +
+
+
+ + + + + +
+
+ `; +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/TimeDialog.js b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/TimeDialog.js new file mode 100644 index 00000000..860a8eef --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/TimeDialog.js @@ -0,0 +1,74 @@ +/* global owl */ + +import useStore from "../../hooks/useStore.js"; +import { BootstrapDialog } from "./BootstrapDialog.js"; + +const { Component, useState, xml } = owl; + +export class TimeDialog extends Component { + static props = {}; + static components = { BootstrapDialog }; + + setup() { + this.store = useStore(); + this.state = useState({ + odooUptimeSeconds: this.store.base.odoo_uptime_seconds, + systemUptimeSeconds: this.store.base.system_uptime_seconds, + }); + setInterval(() => { + this.state.odooUptimeSeconds += 1; + this.state.systemUptimeSeconds += 1; + }, 1000); + } + + startDateFromSeconds(uptimeInSeconds) { + const currentTimeMs = new Date().getTime(); + const odooUptimeMs = uptimeInSeconds * 1000; + return new Date(currentTimeMs - odooUptimeMs).toUTCString(); + } + + secondsToHumanReadable(periodInSeconds) { + const SECONDS_PER_HOUR = 3600; + const SECONDS_PER_DAY = SECONDS_PER_HOUR * 24; + const days = Math.floor(periodInSeconds / SECONDS_PER_DAY); + periodInSeconds = periodInSeconds % SECONDS_PER_DAY; + const hours = Math.floor(periodInSeconds / SECONDS_PER_HOUR); + periodInSeconds = periodInSeconds % SECONDS_PER_HOUR; + const minutes = Math.floor(periodInSeconds / 60); + const seconds = Math.floor(periodInSeconds % 60); + + const formatAmount = (amount, name) => `${amount} ${name}${amount === 1 ? "" : "s"}`; + const timeParts = [ + formatAmount(days, "day"), + formatAmount(hours, "hour"), + formatAmount(minutes, "minute"), + formatAmount(seconds, "second"), + ]; + return timeParts.join(", "); + } + + static template = xml` + + + IoT Box Uptime + + +
+
+
Odoo Service
+
Running for
+
Started at
+
+
+
Operating System
+
Running for
+
Started at
+
+
+
+ + + +
+ `; +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/UpdateDialog.js b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/UpdateDialog.js new file mode 100644 index 00000000..8a43fc6f --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/UpdateDialog.js @@ -0,0 +1,157 @@ +/* global owl */ + +import useStore from "../../hooks/useStore.js"; +import { BootstrapDialog } from "./BootstrapDialog.js"; +import { LoadingFullScreen } from "../LoadingFullScreen.js"; + +const { Component, xml, useState } = owl; + +export class UpdateDialog extends Component { + static props = {}; + static components = { BootstrapDialog, LoadingFullScreen }; + + setup() { + this.store = useStore(); + this.state = useState({ + initialization: true, + loading: false, + waitRestart: false, + odooIsUpToDate: false, + imageIsUpToDate: false, + currentCommitHash: "", + }); + } + + onClose() { + this.state.initialization = []; + } + + async getVersionInfo() { + try { + const data = await this.store.rpc({ + url: "/iot_drivers/version_info", + }); + + if (data.status === "error") { + console.error(data.message); + return; + } + + this.state.odooIsUpToDate = data.odooIsUpToDate; + this.state.imageIsUpToDate = data.imageIsUpToDate; + this.state.currentCommitHash = data.currentCommitHash; + this.state.initialization = false; + } catch { + console.warn("Error while fetching version info"); + } + } + + async updateGitTree() { + this.state.waitRestart = true; + try { + const data = await this.store.rpc({ + url: "/iot_drivers/update_git_tree", + method: "POST", + }); + + if (data.status === "error") { + this.state.waitRestart = false; + console.error(data.message); + } + } catch { + console.warn("Error while updating IoT Box."); + } + } + + async forceUpdateIotHandlers() { + this.state.waitRestart = true; + try { + await this.store.rpc({ + url: "/iot_drivers/load_iot_handlers", + }); + } catch { + console.warn("Error while downloading handlers from db."); + } + } + + get everythingIsUpToDate() { + return this.state.odooIsUpToDate && this.state.imageIsUpToDate; + } + + static template = xml` + + + + Updating your device, please wait... + + + + + + + + +
+
+ Loading... +
+

Currently fetching update data...

+
+ +
+
Operating System Update
+
+ Operating system is up to date +
+
+ A new version of the operating system is available, see: + + Flashing the SD Card on IoT Box + +
+ +
+ +
+
IoT Box Update
+
+ IoT Box is up to date. +
+
+ A new version of the IoT Box is available + +
+
+ Current: + + + +
+
+ +
Drivers Update
+
+ +
+
+ + + + + + `; +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/WifiDialog.js b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/WifiDialog.js new file mode 100644 index 00000000..399a0bc1 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/components/dialog/WifiDialog.js @@ -0,0 +1,178 @@ +/* global owl */ + +import useStore from "../../hooks/useStore.js"; +import { BootstrapDialog } from "./BootstrapDialog.js"; +import { LoadingFullScreen } from "../LoadingFullScreen.js"; + +const { Component, xml, useState } = owl; + +export class WifiDialog extends Component { + static props = {}; + static components = { BootstrapDialog, LoadingFullScreen }; + + setup() { + this.store = useStore(); + this.state = useState({ + scanning: true, + waitRestart: false, + status: "", + availableWiFi: [], + isPasswordVisible: false, + }); + this.form = useState({ + essid: "", + password: "", + }); + } + + onClose() { + this.state.availableWiFi = []; + this.state.scanning = true; + this.form.essid = ""; + this.form.password = ""; + } + + isCurrentlyConnectedToWifi() { + return ( + !this.store.base.is_access_point_up && + this.store.base.network_interfaces.some((netInterface) => netInterface.is_wifi) + ); + } + + isCurrentlyConnectedToEthernet() { + return this.store.base.network_interfaces.some((netInterface) => !netInterface.is_wifi); + } + + async getWiFiNetworks() { + try { + const data = await this.store.rpc({ + url: "/iot_drivers/wifi", + }); + this.form.essid = data.currentWiFi || "Select Network..."; + this.state.availableWiFi = data.availableWiFi; + + this.state.scanning = false; + } catch { + console.warn("Error while fetching data"); + } + } + + async connectToWiFi() { + if (!this.form.essid || !this.form.password) { + return; + } + + this.state.waitRestart = true; + const responsePromise = this.store.rpc({ + url: "/iot_drivers/update_wifi", + method: "POST", + params: this.form, + }); + if (this.isCurrentlyConnectedToEthernet()) { + const data = await responsePromise; + if (data.status !== "success") { + this.state.waitRestart = false; + } + } else { + // The IoT box is no longer reachable, so we can't await the response. + this.state.status = "connecting"; + this.state.waitRestart = false; + } + } + + async clearConfiguration() { + try { + this.state.waitRestart = true; + const responsePromise = this.store.rpc({ + url: "/iot_drivers/wifi_clear", + }); + if (this.isCurrentlyConnectedToEthernet()) { + const data = await responsePromise; + if (data.status !== "success") { + this.state.waitRestart = false; + } + } else { + // The IoT box is no longer reachable, so we can't await the response. + this.state.status = "disconnecting"; + this.state.waitRestart = false; + } + } catch { + console.warn("Error while clearing configuration"); + } + } + + togglePasswordVisibility() { + this.state.isPasswordVisible = !this.state.isPasswordVisible; + } + + static template = xml` + + + + Updating Wi-Fi configuration, please wait... + + + +
+
+ + The IoT Box will now attempt to connect to . The next step is to find your pairing code: +
    +
  • You will need a screen or a compatible USB printer connected.
  • +
  • In a few seconds, the pairing code should display on your screen and/or print from your printer.
  • +
  • Once you have the pairing code, you can enter it on the IoT app in your database to pair your IoT Box.
  • +
+ In the event that the pairing code does not appear, it may be because the IoT Box failed to connect to the Wi-Fi network. + In this case you will need to reconnect to the Wi-Fi hotspot and try again. +
+ + The IoT Box Wi-Fi configuration has been cleared. You will need to connect to the IoT Box hotspot or connect an ethernet cable. + +
+
+ + + + Configure Wi-Fi + + +
+
+ Loading... +
+

Currently scanning for available networks...

+
+ + +
+
+ +
+ +
+ + +
+
+
+ + + + + +
+
+ `; +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/css/homepage.css b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/css/homepage.css new file mode 100644 index 00000000..d0939581 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/css/homepage.css @@ -0,0 +1,97 @@ +:root { + --odoo-purple: #714B67 +} + +.color-primary { + color: var(--odoo-purple); +} + +.btn { + transition: none !important; + font-weight: 500; +} + +.btn.btn-primary { + background-color: var(--odoo-purple) !important; + border-color: var(--odoo-purple) !important; +} + +.btn.btn-primary:hover { + background-color: #52374B !important; + border-color: #52374B !important; +} + +.btn.btn-secondary { + color: #374151 !important; + background-color: #E7E9ED !important; + border-color: #E7E9ED !important; +} + +.btn.btn-secondary:hover { + color: #1F2937 !important; + background-color: #D8DADD !important; + border-color: #D8DADD !important; +} + +.alert.alert-secondary { + color: #017E84 !important; + background-color: #017E8425 !important; + border-color: #017E8480 !important; +} + +.odoo-bg-primary, .bg-primary, .form-check-input:checked, .nav-pills .nav-link.active { + background-color: var(--odoo-purple) !important; + border-color: var(--odoo-purple) !important; +} + +.odoo-bg-secondary, .bg-secondary { + background-color: #017E84 !important; +} + +.odoo-pill { + width: 7px !important; + height: 50px; +} + +.cursor-pointer { + cursor: pointer; +} + +.one-line { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.link-primary { + color: var(--odoo-purple) !important; + font-size: 12px; +} + +.always-on-top { + z-index: 9999; +} + +.background { + background-color: #F1F1F1; + height: 100vh; +} + +.icon-button { + width: 25px; + height: 25px; + font-size: 12px; +} + +.handler-loading { + min-height: 300px; +} + +.main-container { + max-width: 600px; +} + +.dialog-body { + max-height: 70vh; + min-height: 40vh; +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/css/logs.css b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/css/logs.css new file mode 100644 index 00000000..a49dfb70 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/css/logs.css @@ -0,0 +1,5 @@ +body { + width: 100%; + background-color: black; + color: white; +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/css/status_display.css b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/css/status_display.css new file mode 100644 index 00000000..a7e94725 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/css/status_display.css @@ -0,0 +1,55 @@ +html { + height: 100%; +} +body { + cursor: none; + background: url('/iot_drivers/static/img/background-light.svg') no-repeat center center fixed; + background-size: cover; + height: 100vh; +} +.qr-code-box { + position: absolute; + left: 20px; + bottom: 20px; +} +.qr-code { + display: flex; + justify-content: center; + align-items: center; +} +.qr-code img { + width: 150px; /* Ensure wifi and url QR code images appear as same size */ + height: 150px; + object-fit: contain; +} +.status-display-boxes { + position: absolute; + right: 20px; + bottom: 20px; +} +.status-display-box { + padding: 10px 20px; + background: rgba(255, 255, 255, 0.17); + border: 1px solid rgba(255, 255, 255, 0.06); + box-shadow: 0 0 5px 0 rgba(60, 60, 60, 0.4); + border-radius: 8px; + width: 500px; + margin-top: 20px; + backdrop-filter: blur(5px); +} +.table { + --bs-table-bg: none; +} +.odoo-logo { + width: 150px; +} +.iotbox-name { + font-size: 25px; +} +.device-type { + text-transform: capitalize; +} + +ul { + padding-left: 18px; +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/hooks/useStore.js b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/hooks/useStore.js new file mode 100644 index 00000000..2e7ff17b --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/hooks/useStore.js @@ -0,0 +1,8 @@ +/* global owl */ + +const { useState, useEnv } = owl; + +export default function useStore() { + const env = useEnv(); + return useState(env.store); +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/logs.js b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/logs.js new file mode 100644 index 00000000..a76ed637 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/logs.js @@ -0,0 +1,18 @@ +async function getLogs() { + try { + const result = await fetch("/iot_drivers/iot_logs"); + if (!result.ok) { + console.warn(`IoT box returned an error (${result.status} ${result.statusText})`); + return; + } + const data = await result.json(); + document.getElementById("logs").innerText = data.logs; + document.getElementById("logs").scrollTop = document.getElementById("logs").scrollHeight; + } catch (error) { + console.warn(`IoT box is unreachable: ${error}`); + } +} + +document.addEventListener("DOMContentLoaded", function () { + setInterval(getLogs, 1000); +}); diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/main.js b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/main.js new file mode 100644 index 00000000..8e91759f --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/main.js @@ -0,0 +1,17 @@ +/* global owl */ + +import { Homepage } from "./Homepage.js"; +import Store from "./store.js"; + +const { mount, reactive } = owl; + +function createStore() { + return reactive(new Store()); +} + +mount(Homepage, document.body, { + env: { + store: createStore(), + }, + dev: new URLSearchParams(window.location.search).has("debug"), +}); diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/status.js b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/status.js new file mode 100644 index 00000000..c5598910 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/status.js @@ -0,0 +1,178 @@ +/* global owl */ +import { DEVICE_ICONS } from "./components/dialog/DeviceDialog.js"; + +const { Component, mount, xml, useState } = owl; + +const STATUS_POLL_DELAY_MS = 5000; + +class StatusPage extends Component { + static props = {}; + + setup() { + this.state = useState({ data: {}, loading: true }); + this.icons = DEVICE_ICONS; + + this.loadInitialData(); + } + + async loadInitialData() { + try { + const response = await fetch("/iot_drivers/data"); + this.state.data = await response.json(); + this.state.loading = false; + } catch { + console.warn("Error while fetching data"); + } + setTimeout(() => this.loadInitialData(), STATUS_POLL_DELAY_MS); + } + + get accessPointSsid() { + return this.state.data.network_interfaces.filter((i) => i.is_wifi)[0]?.ssid; + } + + static template = xml` + +
+ +
+
+
+ Loading... +
+ + Connecting to , please wait + +
+
+ +
+
+
+

IoT Box Configuration

+
+ +
+

+ 1. Connect to + + + + + + + the IoT Box network +
+
+

+ QR Code Wi-FI +
+

+

+ 2. Open the IoT Box setup page +
+
+

+ QR Code Homepage +
+

+
+ +
+

Scan this QR code with your smartphone to connect to the IoT box's Wi-Fi hotspot:

+
+ QR Code Access Point +
+
+
+

Once you are connected to the Wi-Fi hotspot, you can scan this QR code to access the IoT box Wi-Fi configuration page:

+
+ QR Code Wifi Config +
+
+
+
+
+
+
+
+
+

Pairing Code

+
+ +

+

+ Enter this code in the IoT app in your Odoo database to pair the IoT Box. +

+ +

+ The pairing code has expired. Please restart your IoT Box to generate a new one. +

+

+
+

No Internet Connection

+
+

+ Please connect your IoT Box to internet via an ethernet cable or connect to Wi-FI network
+
+ to configure a Wi-Fi connection on the IoT Box +

+
+
+

Status display

+ +
General
+ + + + + + + + + + + + +
Identifier +
Mac Address +
Database +
+ +
Internet Connection
+ + + + + + +
+
+
+
Devices
+ + + + + + + +
+ + + +
    +
  • + +
  • +
  • ...
  • +
+
+
+
+
+
+
+ `; +} + +mount(StatusPage, document.body); diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/store.js b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/store.js new file mode 100644 index 00000000..35e58b7b --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/static/src/app/store.js @@ -0,0 +1,34 @@ +export default class Store { + constructor() { + this.setup(); + } + setup() { + this.url = ""; + this.base = {}; + this.update = 0; + this.isLinux = false; + this.advanced = false; + } + + async rpc({ url, method = "GET", params = {} }) { + if (method === "POST") { + const response = await fetch(url, { + method, + headers: { + "Content-Type": "application/json; charset=utf-8", + }, + body: JSON.stringify({ + params, + }), + }); + + const data = await response.json(); + return data.result; + } else if (method === "GET") { + const response = await fetch(url); + return await response.json(); + } + + return false; + } +} diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/__init__.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/__init__.py new file mode 100644 index 00000000..12c7fe43 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/__init__.py @@ -0,0 +1,5 @@ +from . import system +from . import helpers +from . import wifi +from . import route +from . import upgrade diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/certificate.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/certificate.py new file mode 100644 index 00000000..4fd19cc3 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/certificate.py @@ -0,0 +1,143 @@ +import datetime +import logging +import requests +from cryptography import x509 +from cryptography.x509.oid import NameOID +from pathlib import Path + +from odoo.addons.iot_drivers.tools.helpers import ( + get_conf, + get_identifier, + get_path_nginx, + odoo_restart, + require_db, + start_nginx_server, + update_conf, +) +from odoo.addons.iot_drivers.tools.system import IS_RPI, IS_TEST, IS_WINDOWS + +_logger = logging.getLogger(__name__) + + +@require_db +def ensure_validity(): + """Ensure that the certificate is up to date + Load a new if the current one is not valid or if there is none. + + This method also sends the certificate end date to the database. + """ + inform_database(get_certificate_end_date() or download_odoo_certificate()) + + +def get_certificate_end_date(): + """Check if the certificate is up to date and valid + + :return: End date of the certificate if it is valid, None otherwise + :rtype: str + """ + base_path = [get_path_nginx(), 'conf'] if IS_WINDOWS else ['/etc/ssl/certs'] + path = Path(*base_path, 'nginx-cert.crt') + if not path.exists(): + return None + + try: + cert = x509.load_pem_x509_certificate(path.read_bytes()) + except ValueError: + _logger.exception("Unable to read certificate file.") + return None + + common_name = next( + (name_attribute.value for name_attribute in cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME)), '' + ) + + cert_end_date = cert.not_valid_after + if ( + common_name == 'OdooTempIoTBoxCertificate' + or datetime.datetime.now() > cert_end_date - datetime.timedelta(days=10) + ): + _logger.debug("SSL certificate '%s' must be updated.", common_name) + return None + + _logger.debug("SSL certificate '%s' is valid until %s", common_name, cert_end_date) + return str(cert_end_date) + + +def download_odoo_certificate(retry=0): + """Send a request to Odoo with customer db_uuid and enterprise_code + to get a true certificate + """ + if IS_TEST: + _logger.info("Skipping certificate download in test mode.") + return None + db_uuid = get_conf('db_uuid') + enterprise_code = get_conf('enterprise_code') + if not db_uuid: + return None + try: + response = requests.post( + 'https://www.odoo.com/odoo-enterprise/iot/x509', + json={'params': {'db_uuid': db_uuid, 'enterprise_code': enterprise_code}}, + timeout=95, # let's encrypt library timeout + ) + response.raise_for_status() + response_body = response.json() + except (requests.exceptions.RequestException, ValueError) as e: + _logger.warning("An error occurred while trying to reach odoo.com to get a new certificate: %s", e) + if retry < 5: + return download_odoo_certificate(retry=retry + 1) + return _logger.exception("Maximum attempt to download the odoo.com certificate reached") + + server_error = response_body.get('error') + if server_error: + _logger.error("Server error received from odoo.com while trying to get the certificate: %s", server_error) + return None + + result = response_body.get('result', {}) + certificate_error = result.get('error') + if certificate_error: + _logger.warning("Error received from odoo.com while trying to get the certificate: %s", certificate_error) + return None + + update_conf({'subject': result['subject_cn']}) + + certificate = result['x509_pem'] + private_key = result['private_key_pem'] + if not certificate or not private_key: # ensure not empty strings + _logger.error("The certificate received from odoo.com is not valid.") + return None + + if IS_RPI: + Path('/etc/ssl/certs/nginx-cert.crt').write_text(certificate, encoding='utf-8') + Path('/root_bypass_ramdisks/etc/ssl/certs/nginx-cert.crt').write_text(certificate, encoding='utf-8') + Path('/etc/ssl/private/nginx-cert.key').write_text(private_key, encoding='utf-8') + Path('/root_bypass_ramdisks/etc/ssl/private/nginx-cert.key').write_text(private_key, encoding='utf-8') + start_nginx_server() + return str(x509.load_pem_x509_certificate(certificate.encode()).not_valid_after) + else: + Path(get_path_nginx(), 'conf', 'nginx-cert.crt').write_text(certificate, encoding='utf-8') + Path(get_path_nginx(), 'conf', 'nginx-cert.key').write_text(private_key, encoding='utf-8') + odoo_restart(3) + return None + + +@require_db +def inform_database(ssl_certificate_end_date, server_url=None): + """Inform the database about the certificate end date. + + If end date is ``None``, we avoid sending a useless request. + + :param str ssl_certificate_end_date: End date of the SSL certificate + :param str server_url: URL of the Odoo server (provided by decorator). + """ + if not ssl_certificate_end_date: + return + + try: + response = requests.post( + server_url + "/iot/box/update_certificate_status", + json={'params': {'identifier': get_identifier(), 'ssl_certificate_end_date': ssl_certificate_end_date}}, + timeout=5, + ) + response.raise_for_status() + except requests.exceptions.RequestException: + _logger.exception("Could not reach configured server to inform about the certificate status") diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/helpers.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/helpers.py new file mode 100644 index 00000000..5f0a91d2 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/helpers.py @@ -0,0 +1,642 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import configparser +from enum import Enum +from functools import cache, wraps +from importlib import util +import inspect +import io +import logging +import netifaces +from pathlib import Path +import re +import requests +import secrets +import subprocess +import socket +from urllib.parse import parse_qs +import urllib3.util +import sys +from threading import Thread, Lock +import time +import zipfile +from werkzeug.exceptions import Locked + +from odoo import http, release, service +from odoo.addons.iot_drivers.tools.system import IOT_CHAR, IOT_RPI_CHAR, IOT_WINDOWS_CHAR, IS_RPI, IS_TEST, IS_WINDOWS +from odoo.tools.func import reset_cached_properties +from odoo.tools.misc import file_path + +lock = Lock() +_logger = logging.getLogger(__name__) + +if IS_RPI: + import crypt + + +class Orientation(Enum): + """xrandr/wlr-randr screen orientation for kiosk mode""" + NORMAL = 'normal' + INVERTED = '180' + LEFT = '90' + RIGHT = '270' + + +class IoTRestart(Thread): + """ + Thread to restart odoo server in IoT Box when we must return a answer before + """ + def __init__(self, delay): + Thread.__init__(self) + self.delay = delay + + def run(self): + time.sleep(self.delay) + service.server.restart() + + +def toggleable(function): + """Decorate a function to enable or disable it based on the value + of the associated configuration parameter. + """ + fname = f"" + + @wraps(function) + def devtools_wrapper(*args, **kwargs): + if args and args[0].__class__.__name__ == 'DriverController': + if get_conf('longpolling', section='devtools'): + _logger.warning("Refusing call to %s: longpolling is disabled by devtools", fname) + raise Locked("Longpolling disabled by devtools") # raise to make the http request fail + elif function.__name__ == 'action': + action = args[1].get('action', 'default') # first argument is self (containing Driver instance), second is 'data' + disabled_actions = (get_conf('actions', section='devtools') or '').split(',') + if action in disabled_actions or '*' in disabled_actions: + _logger.warning("Ignoring call to %s: '%s' action is disabled by devtools", fname, action) + return None + elif get_conf('general', section='devtools'): + _logger.warning("Ignoring call to %s: method is disabled by devtools", fname) + return None + + return function(*args, **kwargs) + return devtools_wrapper + + +def require_db(function): + """Decorator to check if the IoT Box is connected to the internet + and to a database before executing the function. + This decorator injects the ``server_url`` parameter if the function has it. + """ + @wraps(function) + def wrapper(*args, **kwargs): + fname = f"" + server_url = get_odoo_server_url() + iot_box_ip = get_ip() + if not iot_box_ip or iot_box_ip == "10.11.12.1" or not server_url: + _logger.info('Ignoring the function %s without a connected database', fname) + return + + arg_name = 'server_url' + if arg_name in inspect.signature(function).parameters: + _logger.debug('Adding server_url param to %s', fname) + kwargs[arg_name] = server_url + + return function(*args, **kwargs) + return wrapper + + +if IS_WINDOWS: + def start_nginx_server(): + path_nginx = get_path_nginx() + if path_nginx: + _logger.info('Start Nginx server: %s\\nginx.exe', path_nginx) + subprocess.Popen([str(path_nginx / 'nginx.exe')], cwd=str(path_nginx)) +elif IS_RPI: + def start_nginx_server(): + subprocess.check_call(["sudo", "service", "nginx", "restart"]) +else: + def start_nginx_server(): + pass + + +def check_image(): + """Check if the current image of IoT Box is up to date + + :return: dict containing major and minor versions of the latest image available + :rtype: dict + """ + try: + response = requests.get('https://nightly.odoo.com/master/iotbox/SHA1SUMS.txt', timeout=5) + response.raise_for_status() + data = response.content.decode() + except requests.exceptions.HTTPError: + _logger.exception('Could not reach the server to get the latest image version') + return False + + check_file = {} + value_actual = '' + for line in data.split('\n'): + if line: + value, name = line.split(' ') + check_file.update({value: name}) + if name == 'iotbox-latest.zip': + value_latest = value + elif name == get_img_name(): + value_actual = value + if value_actual == value_latest: # pylint: disable=E0601 + return False + version = check_file.get(value_latest, 'Error').replace('iotboxv', '').replace('.zip', '').split('_') + return {'major': version[0], 'minor': version[1]} + + +def save_conf_server(url, token, db_uuid, enterprise_code, db_name=None): + """ + Save server configurations in odoo.conf + :param url: The URL of the server + :param token: The token to authenticate the server + :param db_uuid: The database UUID + :param enterprise_code: The enterprise code + :param db_name: The database name + """ + update_conf({ + 'remote_server': url, + 'token': token, + 'db_uuid': db_uuid, + 'enterprise_code': enterprise_code, + 'db_name': db_name, + }) + get_odoo_server_url.cache_clear() + + +def generate_password(): + """ + Generate an unique code to secure raspberry pi + """ + alphabet = 'abcdefghijkmnpqrstuvwxyz23456789' + password = ''.join(secrets.choice(alphabet) for i in range(12)) + try: + shadow_password = crypt.crypt(password, crypt.mksalt()) + subprocess.run(('sudo', 'usermod', '-p', shadow_password, 'pi'), check=True) + subprocess.run(('sudo', 'cp', '/etc/shadow', '/root_bypass_ramdisks/etc/shadow'), check=True) + return password + except subprocess.CalledProcessError as e: + _logger.exception("Failed to generate password: %s", e.output) + return 'Error: Check IoT log' + + +def get_img_name(): + major, minor = get_version()[1:].split('.') + return 'iotboxv%s_%s.zip' % (major, minor) + + +def get_ip(): + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + try: + s.connect(('8.8.8.8', 1)) # Google DNS + return s.getsockname()[0] + except OSError as e: + _logger.warning("Could not get local IP address: %s", e) + return None + finally: + s.close() + + +@cache +def get_identifier(): + if IS_RPI: + return read_file_first_line('/sys/firmware/devicetree/base/serial-number').strip("\x00") + elif IS_TEST: + return 'test_identifier' + + # On windows, get motherboard's uuid (serial number isn't reliable as it's not always present) + command = ['powershell', '-Command', "(Get-CimInstance Win32_ComputerSystemProduct).UUID"] + p = subprocess.run(command, stdout=subprocess.PIPE, check=False) + identifier = get_conf('generated_identifier') # Fallback identifier if windows does not return mb UUID + if p.returncode == 0 and p.stdout.decode().strip(): + return p.stdout.decode().strip() + + _logger.error("Failed to get Windows IoT serial number, defaulting to a random identifier") + if not identifier: + identifier = secrets.token_hex() + update_conf({'generated_identifier': identifier}) + + return identifier + + +def get_mac_address(): + interfaces = netifaces.interfaces() + for interface in interfaces: + if netifaces.ifaddresses(interface).get(netifaces.AF_INET): + addr = netifaces.ifaddresses(interface).get(netifaces.AF_LINK)[0]['addr'] + if addr != '00:00:00:00:00:00': + return addr + + +def get_path_nginx(): + return path_file('nginx') + + +@cache +def get_odoo_server_url(): + """Get the URL of the linked Odoo database. + + :return: The URL of the linked Odoo database. + :rtype: str or None + """ + return get_conf('remote_server') + + +def get_token(): + """:return: The token to authenticate the server""" + return get_conf('token') + + +def get_commit_hash(): + return subprocess.run( + ['git', '--work-tree=/home/pi/odoo/', '--git-dir=/home/pi/odoo/.git', 'rev-parse', '--short', 'HEAD'], + stdout=subprocess.PIPE, + check=True, + ).stdout.decode('ascii').strip() + + +@cache +def get_version(detailed_version=False): + if IS_RPI: + image_version = read_file_first_line('/var/odoo/iotbox_version') + elif IS_WINDOWS: + # updated manually when big changes are made to the windows virtual IoT + image_version = '23.11' + elif IS_TEST: + image_version = 'test' + + version = IOT_CHAR + image_version + if detailed_version: + # Note: on windows IoT, the `release.version` finish with the build date + version += f"-{release.version}" + if IS_RPI: + version += f'#{get_commit_hash()}' + + return version + + +def delete_iot_handlers(): + """Delete all drivers, interfaces and libs if any. + This is needed to avoid conflicts with the newly downloaded drivers. + """ + try: + iot_handlers = Path(file_path('iot_drivers/iot_handlers')) + filenames = [ + f"odoo/addons/iot_drivers/iot_handlers/{file.relative_to(iot_handlers)}" + for file in iot_handlers.glob('**/*') + if file.is_file() + ] + unlink_file(*filenames) + _logger.info("Deleted old IoT handlers") + except OSError: + _logger.exception('Failed to delete old IoT handlers') + + +@toggleable +@require_db +def download_iot_handlers(auto=True, server_url=None): + """Get the drivers from the configured Odoo server. + If drivers did not change on the server, download + will be skipped. + + :param auto: If True, the download will depend on the parameter set in the database + :param server_url: The URL of the connected Odoo database (provided by decorator). + """ + etag = get_conf('iot_handlers_etag') + try: + response = requests.post( + server_url + '/iot/get_handlers', + data={'identifier': get_identifier(), 'auto': auto}, + timeout=8, + headers={'If-None-Match': etag} if etag else None, + ) + response.raise_for_status() + except requests.exceptions.RequestException: + _logger.exception('Could not reach configured server to download IoT handlers') + return + + data = response.content + if response.status_code == 304 or not data: + _logger.info('No new IoT handler to download') + return + + try: + update_conf({'iot_handlers_etag': response.headers['ETag'].strip('"')}) + except KeyError: + _logger.exception('No ETag in the response headers') + + try: + zip_file = zipfile.ZipFile(io.BytesIO(data)) + except zipfile.BadZipFile: + _logger.exception('Bad IoT handlers response received: not a zip file') + return + + delete_iot_handlers() + path = path_file('odoo', 'addons', 'iot_drivers', 'iot_handlers') + zip_file.extractall(path) + + +def compute_iot_handlers_addon_name(handler_kind, handler_file_name): + return "odoo.addons.iot_drivers.iot_handlers.{handler_kind}.{handler_name}".\ + format(handler_kind=handler_kind, handler_name=handler_file_name.removesuffix('.py')) + + +def load_iot_handlers(): + """ + This method loads local files: 'odoo/addons/iot_drivers/iot_handlers/drivers' and + 'odoo/addons/iot_drivers/iot_handlers/interfaces' + And execute these python drivers and interfaces + """ + for directory in ['interfaces', 'drivers']: + path = file_path(f'iot_drivers/iot_handlers/{directory}') + filesList = get_handlers_files_to_load(path) + for file in filesList: + spec = util.spec_from_file_location(compute_iot_handlers_addon_name(directory, file), str(Path(path).joinpath(file))) + if spec: + module = util.module_from_spec(spec) + try: + spec.loader.exec_module(module) + except Exception: + _logger.exception('Unable to load handler file: %s', file) + reset_cached_properties(http.root) + + +def get_handlers_files_to_load(handler_path): + """ + Get all handler files that an IoT system should load in a list. + - Rpi IoT boxes load file without suffixe and _L + - Windows IoT load file without suffixes and _W + :param handler_path: The path to the directory containing the files (either drivers or interfaces) + :return: files corresponding to the current IoT system + :rtype list: + """ + if IS_RPI: + return [x.name for x in Path(handler_path).glob(f'*[!{IOT_WINDOWS_CHAR}].*')] + elif IS_WINDOWS: + return [x.name for x in Path(handler_path).glob(f'*[!{IOT_RPI_CHAR}].*')] + return [] + + +def odoo_restart(delay=0): + """ + Restart Odoo service + :param delay: Delay in seconds before restarting the service (Default: 0) + """ + IR = IoTRestart(delay) + IR.start() + + +def path_file(*args): + """Return the path to the file from IoT Box root or Windows Odoo + server folder + + :return: The path to the file + """ + return Path(sys.path[0]).parent.joinpath(*args) + + +def read_file_first_line(filename): + path = path_file(filename) + if path.exists(): + with path.open('r') as f: + return f.readline().strip('\n') + + +def unlink_file(*filenames): + for filename in filenames: + path = path_file(filename) + if path.exists(): + path.unlink() + + +def write_file(filename, text, mode='w'): + """This function writes 'text' to 'filename' file + + :param filename: The name of the file to write to + :param text: The text to write to the file + :param mode: The mode to open the file in (Default: 'w') + """ + path = path_file(filename) + with open(path, mode) as f: + f.write(text) + + +def download_from_url(download_url, path_to_filename): + """ + This function downloads from its 'download_url' argument and + saves the result in 'path_to_filename' file + The 'path_to_filename' needs to be a valid path + file name + (Example: 'C:\\Program Files\\Odoo\\downloaded_file.zip') + """ + try: + request_response = requests.get(download_url, timeout=60) + request_response.raise_for_status() + write_file(path_to_filename, request_response.content, 'wb') + _logger.info('Downloaded %s from %s', path_to_filename, download_url) + except requests.exceptions.RequestException: + _logger.exception('Failed to download from %s', download_url) + + +def unzip_file(path_to_filename, path_to_extract): + """ + This function unzips 'path_to_filename' argument to + the path specified by 'path_to_extract' argument + and deletes the originally used .zip file + Example: unzip_file('C:\\Program Files\\Odoo\\downloaded_file.zip', 'C:\\Program Files\\Odoo\\new_folder')) + Will extract all the contents of 'downloaded_file.zip' to the 'new_folder' location) + """ + try: + path = path_file(path_to_filename) + with zipfile.ZipFile(path) as zip_file: + zip_file.extractall(path_file(path_to_extract)) + Path(path).unlink() + _logger.info('Unzipped %s to %s', path_to_filename, path_to_extract) + except Exception: + _logger.exception('Failed to unzip %s', path_to_filename) + + +def update_conf(values, section='iot.box'): + """Update odoo.conf with the given key and value. + + :param dict values: key-value pairs to update the config with. + :param str section: The section to update the key-value pairs in (Default: iot.box). + """ + _logger.debug("Updating odoo.conf with values: %s", values) + conf = get_conf() + + if not conf.has_section(section): + _logger.debug("Creating new section '%s' in odoo.conf", section) + conf.add_section(section) + + for key, value in values.items(): + conf.set(section, key, value) if value else conf.remove_option(section, key) + + with open(path_file("odoo.conf"), "w", encoding='utf-8') as f: + conf.write(f) + + +def get_conf(key=None, section='iot.box'): + """Get the value of the given key from odoo.conf, or the full config if no key is provided. + + :param key: The key to get the value of. + :param section: The section to get the key from (Default: iot.box). + :return: The value of the key provided or None if it doesn't exist, or full conf object if no key is provided. + """ + conf = configparser.RawConfigParser() + conf.read(path_file("odoo.conf")) + + return conf.get(section, key, fallback=None) if key else conf # Return the key's value or the configparser object + + +def disconnect_from_server(): + """Disconnect the IoT Box from the server""" + update_conf({ + 'remote_server': '', + 'token': '', + 'db_uuid': '', + 'db_name': '', + 'enterprise_code': '', + 'screen_orientation': '', + 'browser_url': '', + 'iot_handlers_etag': '', + 'last_websocket_message_id': '', + }) + odoo_restart() + + +def save_browser_state(url=None, orientation=None): + """Save the browser state to the file + + :param url: The URL the browser is on (if None, the URL is not saved) + :param orientation: The orientation of the screen (if None, the orientation is not saved) + """ + to_update = { + "browser_url": url, + "screen_orientation": orientation.name.lower() if orientation else None, + } + # Only update the values that are not None + update_conf({k: v for k, v in to_update.items() if v is not None}) + + +def load_browser_state(): + """Load the browser state from the file + + :return: The URL the browser is on and the orientation of the screen (default to NORMAL) + """ + url = get_conf('browser_url') + orientation = get_conf('screen_orientation') or Orientation.NORMAL.name + return url, Orientation[orientation.upper()] + + +def url_is_valid(url): + """Checks whether the provided url is a valid one or not + + :param url: the URL to check + :return: True if the URL is valid and False otherwise + :rtype: bool + """ + try: + result = urllib3.util.parse_url(url.strip()) + return all([result.scheme in ["http", "https"], result.netloc, result.host != 'localhost']) + except urllib3.exceptions.LocationParseError: + return False + + +def parse_url(url): + """Parses URL params and returns them as a dictionary starting by the url. + Does not allow multiple params with the same name (e.g. ?a=1&a=2 will return the same as ?a=1) + + :param url: the URL to parse + :return: the dictionary containing the URL and params + :rtype: dict + """ + if not url_is_valid(url): + raise ValueError("Invalid URL provided.") + + url = urllib3.util.parse_url(url.strip()) + search_params = { + key: value[0] + for key, value in parse_qs(url.query, keep_blank_values=True).items() + } + return { + "url": f"{url.scheme}://{url.netloc}", + **search_params, + } + + +def reset_log_level(): + """Reset the log level to the default one if the reset timestamp is reached + This timestamp is set by the log controller in `iot_drivers/homepage.py` when the log level is changed + """ + log_level_reset_timestamp = get_conf('log_level_reset_timestamp') + if log_level_reset_timestamp and float(log_level_reset_timestamp) <= time.time(): + _logger.info("Resetting log level to default.") + update_conf({ + 'log_level_reset_timestamp': '', + 'log_handler': ':INFO,werkzeug:WARNING', + 'log_level': 'info', + }) + + +def _get_system_uptime(): + if not IS_RPI: + return 0 + uptime_string = read_file_first_line("/proc/uptime") + return float(uptime_string.split(" ")[0]) + + +def _get_raspberry_pi_model(): + """Returns the Raspberry Pi model number (e.g. 4) as an integer + Returns 0 if the model can't be determined, or -1 if called on Windows + + :rtype: int + """ + if not IS_RPI: + return -1 + with open('/proc/device-tree/model', encoding='utf-8') as model_file: + match = re.search(r'Pi (\d)', model_file.read()) + return int(match[1]) if match else 0 + + +raspberry_pi_model = _get_raspberry_pi_model() +odoo_start_time = time.monotonic() +system_start_time = odoo_start_time - _get_system_uptime() + + +def is_ngrok_enabled(): + """Check if a ngrok tunnel is active on the IoT Box""" + try: + response = requests.get("http://localhost:4040/api/tunnels", timeout=5) + response.raise_for_status() + response.json() + return True + except (requests.exceptions.RequestException, ValueError): + # if the request fails or the response is not valid JSON, + # it means ngrok is not enabled or not running + _logger.debug("Ngrok isn't running.", exc_info=True) + return False + + +def toggle_remote_connection(token=""): + """Enable/disable remote connection to the IoT Box using ngrok. + If the token is provided, it will set up ngrok with the + given authtoken, else it will disable the ngrok service. + + :param str token: The ngrok authtoken to use for the connection""" + _logger.info("Toggling remote connection with token: %s...", token[:5] if token else "") + p = subprocess.run( + ['sudo', 'ngrok', 'config', 'add-authtoken', token, '--config', '/home/pi/ngrok.yml'], + check=False, + ) + if p.returncode == 0: + subprocess.run( + ['sudo', 'systemctl', 'restart' if token else "stop", 'odoo-ngrok.service'], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + check=False, + ) + return True + return False diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/route.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/route.py new file mode 100644 index 00000000..e02cb78c --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/route.py @@ -0,0 +1,31 @@ +import logging + +from odoo.addons.iot_drivers.tools.system import IS_RPI +from odoo import http + +_logger = logging.getLogger(__name__) + + +def iot_route(route=None, linux_only=False, **kwargs): + """A wrapper for the http.route function that sets useful defaults for IoT: + - ``auth = 'none'`` + - ``save_session = False`` + + Both auth and sessions are useless on IoT since we have no DB and no users. + + :param route: The route to be decorated. + :param linux_only: If ``True``, the route will be forbidden for virtual IoT Boxes. + """ + if 'auth' not in kwargs: + kwargs['auth'] = 'none' + if 'save_session' not in kwargs: + kwargs['save_session'] = False + + http_decorator = http.route(route, **kwargs) + + def decorator(endpoint): + if linux_only and not IS_RPI: + return None # Remove the route if not Linux (will return 404) + return http_decorator(endpoint) + + return decorator diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/system.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/system.py new file mode 100644 index 00000000..50a95fb5 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/system.py @@ -0,0 +1,28 @@ +"""Operating system-related utilities for the IoT""" + +from platform import system, release + +IOT_SYSTEM = system() + +IOT_RPI_CHAR, IOT_WINDOWS_CHAR, IOT_TEST_CHAR = "L", "W", "T" + +IS_WINDOWS = IOT_SYSTEM[0] == IOT_WINDOWS_CHAR +IS_RPI = 'rpi' in release() +IS_TEST = not IS_RPI and not IS_WINDOWS +"""IoT system "Test" correspond to any non-Raspberry Pi nor windows system. +Expected to be Linux or macOS used locally for development purposes.""" + +IOT_CHAR = IOT_RPI_CHAR if IS_RPI else IOT_WINDOWS_CHAR if IS_WINDOWS else IOT_TEST_CHAR +"""IoT system character used in the identifier and version. +- 'L' for Raspberry Pi +- 'W' for Windows +- 'T' for Test (non-Raspberry Pi nor Windows)""" + +if IS_RPI: + def rpi_only(function): + """Decorator to check if the system is raspberry pi before running the function.""" + return function +else: + def rpi_only(_): + """No-op decorator for non raspberry pi systems.""" + return lambda *args, **kwargs: None diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/upgrade.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/upgrade.py new file mode 100644 index 00000000..45ce6a04 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/upgrade.py @@ -0,0 +1,204 @@ +"""Module to manage odoo code upgrades using git""" + +import logging +import requests +import subprocess +from odoo.addons.iot_drivers.tools.helpers import ( + odoo_restart, + path_file, + require_db, + toggleable, + unlink_file, +) +from odoo.addons.iot_drivers.tools.system import rpi_only, IS_RPI, IS_TEST + +_logger = logging.getLogger(__name__) + + +def git(*args): + """Run a git command with the given arguments, taking system + into account. + + :param args: list of arguments to pass to git + """ + git_executable = 'git' if IS_RPI else path_file('git', 'cmd', 'git.exe') + command = [git_executable, f'--work-tree={path_file("odoo")}', f'--git-dir={path_file("odoo", ".git")}', *args] + + p = subprocess.run(command, stdout=subprocess.PIPE, text=True, check=False) + if p.returncode == 0: + return p.stdout.strip() + return None + + +def pip(*args): + """Run a pip command with the given arguments, taking system + into account. + + :param args: list of arguments to pass to pip + """ + python_executable = [] if IS_RPI else [path_file('python', 'python.exe'), '-m'] + command = [*python_executable, 'pip', *args] + + if IS_RPI and args[0] == 'install': + command.append('--user') + command.append('--break-system-package') + + p = subprocess.run(command, stdout=subprocess.PIPE, check=False) + return p.returncode + + +def get_db_branch(server_url): + """Get the current branch of the database. + + :param server_url: The URL of the connected Odoo database. + :return: the current branch of the database + """ + try: + response = requests.post(server_url + "/web/webclient/version_info", json={}, timeout=5) + response.raise_for_status() + except requests.exceptions.HTTPError: + _logger.exception('Could not reach configured server to get the Odoo version') + return None + try: + return response.json()['result']['server_serie'].replace('~', '-') + except ValueError: + _logger.exception('Could not load JSON data: Received data is not valid JSON.\nContent:\n%s', response.content) + return None + + +@toggleable +@require_db +def check_git_branch(server_url=None): + """Check if the local branch is the same as the connected Odoo DB and + checkout to match it if needed. + + :param server_url: The URL of the connected Odoo database (provided by decorator). + """ + if IS_TEST: + return + db_branch = get_db_branch(server_url) + if not db_branch: + _logger.warning("Could not get the database branch, skipping git checkout") + return + + try: + if not git('ls-remote', 'origin', db_branch): + db_branch = 'master' + + local_branch = git('symbolic-ref', '-q', '--short', 'HEAD') + _logger.info("IoT Box git branch: %s / Associated Odoo db's git branch: %s", local_branch, db_branch) + + if db_branch != local_branch: + # Repository updates + unlink_file("odoo/.git/shallow.lock") # In case of previous crash/power-off, clean old lockfile + checkout(db_branch) + update_requirements() + + # System updates + update_packages() + + # Miscellaneous updates (version migrations) + misc_migration_updates() + _logger.warning("Update completed, restarting...") + odoo_restart() + except Exception: + _logger.exception('An error occurred while trying to update the code with git') + + +def _ensure_production_remote(local_remote): + """Ensure that the remote repository is the production one + (https://github.com/odoo/odoo.git). + + :param local_remote: The name of the remote repository. + """ + production_remote = "https://github.com/odoo/odoo.git" + if git('remote', 'get-url', local_remote) != production_remote: + _logger.info("Setting remote repository to production: %s", production_remote) + git('remote', 'set-url', local_remote, production_remote) + + +def checkout(branch, remote=None): + """Checkout to the given branch of the given git remote. + + :param branch: The name of the branch to check out. + :param remote: The name of the local git remote to use (usually ``origin`` but computed if not provided). + """ + _logger.info("Preparing local repository for checkout") + git('branch', '-m', branch) # Rename the current branch to the target branch name + + remote = remote or git('config', f'branch.{branch}.remote') or 'origin' + _ensure_production_remote(remote) + + _logger.warning("Checking out %s/%s", remote, branch) + git('remote', 'set-branches', remote, branch) + git('fetch', remote, branch, '--depth=1', '--prune') # refs/remotes to avoid 'unknown revision' + git('reset', 'FETCH_HEAD', '--hard') + + _logger.info("Cleaning the working directory") + git('clean', '-dfx') + + +def update_requirements(): + """Update the Python requirements of the IoT Box, installing the ones + listed in the requirements.txt file. + """ + requirements_file = path_file('odoo', 'addons', 'iot_box_image', 'configuration', 'requirements.txt') + if not requirements_file.exists(): + _logger.info("No requirements file found, not updating.") + return + + _logger.info("Updating pip requirements") + pip('install', '-r', requirements_file) + + +@rpi_only +def update_packages(): + """Update apt packages on the IoT Box, installing the ones listed in + the packages.txt file. + Requires ``writable`` context manager. + """ + packages_file = path_file('odoo', 'addons', 'iot_box_image', 'configuration', 'packages.txt') + if not packages_file.exists(): + _logger.info("No packages file found, not updating.") + return + + # update and install packages in the foreground + commands = ( + "export DEBIAN_FRONTEND=noninteractive && " + "mount -t proc proc /proc && " + "apt-get update && " + f"xargs apt-get -y -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold' install < {packages_file}" + ) + _logger.warning("Updating apt packages") + if subprocess.run( + f'sudo chroot /root_bypass_ramdisks /bin/bash -c "{commands}"', shell=True, check=False + ).returncode != 0: + _logger.error("An error occurred while trying to update the packages") + return + + # upgrade and remove packages in the background + background_cmd = 'chroot /root_bypass_ramdisks /bin/bash -c "apt-get upgrade -y && apt-get -y autoremove"' + subprocess.Popen(["sudo", "bash", "-c", background_cmd], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + + +@rpi_only +def misc_migration_updates(): + """Run miscellaneous updates after the code update.""" + _logger.warning("Running version migration updates") + if path_file('odoo', 'addons', 'point_of_sale').exists(): + # TODO: remove this when v18.0 is deprecated (point_of_sale/tools/posbox/ -> iot_box_image/) + ramdisks_service = "/root_bypass_ramdisks/etc/systemd/system/ramdisks.service" + subprocess.run( + ['sudo', 'sed', '-i', 's|iot_box_image|point_of_sale/tools/posbox|g', ramdisks_service], check=False + ) + + # TODO: Remove this code when v16 is deprecated + with open('/home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/odoo.conf', 'r+', encoding='utf-8') as f: + if "server_wide_modules" not in f.read(): + f.write("server_wide_modules=hw_drivers,hw_posbox_homepage,web\n") + + if path_file('odoo', 'addons', 'hw_drivers').exists(): + # TODO: remove this when v18.4 is deprecated (hw_drivers/,hw_posbox_homepage/ -> iot_drivers/) + subprocess.run( + ['sed', '-i', 's|iot_drivers|hw_drivers,hw_posbox_homepage|g', '/home/pi/odoo.conf'], check=False + ) diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/wifi.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/wifi.py new file mode 100644 index 00000000..e6765344 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/tools/wifi.py @@ -0,0 +1,327 @@ +"""Module to manage Wi-Fi connections and access point mode using +NetworkManager and ``nmcli`` tool. +""" + +import base64 +from io import BytesIO +import logging +import qrcode +import re +import secrets +import subprocess +import time +from pathlib import Path +from functools import cache + +from .helpers import get_ip, get_identifier, get_conf + +_logger = logging.getLogger(__name__) + +START = True +STOP = False + + +def _nmcli(args, sudo=False): + """Run nmcli command with given arguments and return the output. + + :param args: Arguments to pass to nmcli + :param sudo: Run the command with sudo privileges + :return: Output of the command + :rtype: str + """ + command = ['nmcli', '-t', *args] + if sudo: + command = ['sudo', *command] + + p = subprocess.run(command, stdout=subprocess.PIPE, check=False) + if p.returncode == 0: + return p.stdout.decode().strip() + return None + + +def _scan_network(): + """Scan for connected/available networks and return the SSID. + + :return: list of found SSIDs with a flag indicating whether it's the connected network + :rtype: list[tuple[bool, str]] + """ + ssids = _nmcli(['-f', 'ACTIVE,SSID', 'dev', 'wifi'], sudo=True) + ssids_dict = { + ssid.split(':')[-1]: ssid.startswith('yes:') + for ssid in sorted(ssids.splitlines()) + if ssid + } if ssids else {} + _logger.debug("Found networks: %s", ssids_dict) + + return [(status, ssid) for ssid, status in ssids_dict.items()] + + +def _reload_network_manager(): + """Reload the NetworkManager service. + Can be useful when ``nmcli`` doesn't respond correctly (e.g. can't fetch available + networks properly). + + :return: True if the service is reloaded successfully + :rtype: bool + """ + if subprocess.run(['sudo', 'systemctl', 'reload', 'NetworkManager'], check=False).returncode == 0: + return True + else: + _logger.error('Failed to reload NetworkManager service') + return False + + +def get_current(): + """Get the SSID of the currently connected network, or None if it is not connected + + :return: The connected network's SSID, or None + :rtype: str | None + """ + nmcli_output = _nmcli(['-f', 'GENERAL.CONNECTION,GENERAL.STATE', 'dev', 'show', 'wlan0']) + if not nmcli_output: + return None + + ssid_match = re.match(r'GENERAL\.CONNECTION:(\S+)\n', nmcli_output) + if not ssid_match: + return None + + return ssid_match[1] if '(connected)' in nmcli_output else None + + +def get_available_ssids(): + """Get the SSIDs of the available networks. May reload NetworkManager service + if the list doesn't contain all the available networks. + + :return: List of available SSIDs + :rtype: list[str] + """ + ssids = _scan_network() + + # If the list contains only the connected network, reload network manager and rescan + if len(ssids) == 1 and is_current(ssids[0][1]) and _reload_network_manager(): + ssids = _scan_network() + + return [ssid for (_, ssid) in ssids] + + +def is_current(ssid): + """Check if the given SSID is the one connected.""" + return ssid == get_current() + + +def disconnect(): + """Disconnects from the current network. + + :return: True if disconnected successfully + """ + ssid = get_current() + + if not ssid: + return True + + _logger.info('Disconnecting from network %s', ssid) + _nmcli(['con', 'down', ssid], sudo=True) + + if not get_ip(): + toggle_access_point(START) + return not is_current(ssid) + + +def _connect(ssid, password): + """Disables access point mode and connects to the given + network using the provided password. + + :param str ssid: SSID of the network to connect to + :param str password: Password of the network to connect to + :return: True if connected successfully + """ + if ssid not in get_available_ssids() or not toggle_access_point(STOP): + return False + + _logger.info('Connecting to network %s', ssid) + _nmcli(['device', 'wifi', 'connect', ssid, 'password', password], sudo=True) + + if not _validate_configuration(ssid): + _logger.warning('Failed to make network configuration persistent for %s', ssid) + + return is_current(ssid) + + +def reconnect(ssid=None, password=None, force_update=False): + """Reconnect to the given network. If a connection to the network already exists, + we can reconnect to it without providing the password (e.g. after a reboot). + If no SSID is provided, we will try to reconnect to the last connected network. + + :param str ssid: SSID of the network to reconnect to (optional) + :param str password: Password of the network to reconnect to (optional) + :param bool force_update: Force connection, even if internet is already available through ethernet + :return: True if reconnected successfully + """ + if not force_update: + timer = time.time() + 10 # Required on boot: wait 10 sec (see: https://github.com/odoo/odoo/pull/187862) + while time.time() < timer: + if get_ip(): + if is_access_point(): + toggle_access_point(STOP) + return True + time.sleep(.5) + + if not ssid: + return toggle_access_point(START) + + should_start_access_point_on_failure = is_access_point() or not get_ip() + + # Try to re-enable an existing connection, or set up a new persistent one + if toggle_access_point(STOP) and not _nmcli(['con', 'up', ssid], sudo=True): + _connect(ssid, password) + + connected_successfully = is_current(ssid) + if not connected_successfully and should_start_access_point_on_failure: + toggle_access_point(START) + + return connected_successfully + + +def _validate_configuration(ssid): + """For security reasons, everything that is saved in the root filesystem + on IoT Boxes is lost after reboot. This method saves the network + configuration file in the right filesystem (``/root_bypass_ramdisks``). + + Although it is not mandatory to connect to the Wi-Fi, this method is required + for the network to be reconnected automatically after a reboot. + + :param str ssid: SSID of the network to validate + :return: True if the configuration file is saved successfully + :rtype: bool + """ + source_path = Path(f'/etc/NetworkManager/system-connections/{ssid}.nmconnection') + if not source_path.exists(): + return False + + destination_path = Path('/root_bypass_ramdisks') / source_path.relative_to('/') + + # Copy the configuration file to the root filesystem + if subprocess.run(['sudo', 'cp', source_path, destination_path], check=False).returncode == 0: + return True + else: + _logger.error('Failed to apply the network configuration to /root_bypass_ramdisks.') + return False + + +# -------------------------- # +# Access Point Configuration # +# -------------------------- # + +@cache +def get_access_point_ssid(): + """Generate a unique SSID for the access point. + Uses the identifier of the device or a random token if the + identifier was not found. + + :return: Generated SSID + :rtype: str + """ + return "IoTBox-" + get_identifier() or secrets.token_hex(8) + + +def _configure_access_point(on=True): + """Update the ``hostapd`` configuration file with the given SSID. + This method also adds/deletes a static IP address to the ``wlan0`` interface, + mandatory to allow people to connect to the access point. + + :param bool on: Start or stop the access point + :return: True if the configuration is successful + """ + ssid = get_access_point_ssid() + + if on: + _logger.info("Starting access point with SSID %s", ssid) + with open('/etc/hostapd/hostapd.conf', 'w', encoding='utf-8') as f: + f.write(f"interface=wlan0\nssid={ssid}\nchannel=1\n") + mode = 'add' if on else 'del' + return ( + subprocess.run( + ['sudo', 'ip', 'address', mode, '10.11.12.1/24', 'dev', 'wlan0'], check=False, stderr=subprocess.DEVNULL + ).returncode == 0 + or not on # Don't fail if stopping access point: IP address might not exist + ) + + +def toggle_access_point(state=START): + """Start or stop an access point. + + :param bool state: Start or stop the access point + :return: True if the operation on the access point is successful + :rtype: bool + """ + if not _configure_access_point(state): + return False + + mode = 'start' if state else 'stop' + _logger.info("%sing access point.", mode.capitalize()) + if subprocess.run(['sudo', 'systemctl', mode, 'hostapd'], check=False).returncode == 0: + return True + else: + _logger.error("Failed to %s access point.", mode) + return False + + +def is_access_point(): + """Check if the device is currently in access point mode. + + :return: True if the device is in access point mode + :rtype: bool + """ + return subprocess.run( + ['systemctl', 'is-active', 'hostapd'], stdout=subprocess.DEVNULL, check=False + ).returncode == 0 + + +@cache +def generate_qr_code_image(qr_code_data): + """Generate a QR code based on data argument and return it in base64 image format + Cached to avoir regenerating the same QR code multiple times + + :param str qr_code_data: Data to encode in the QR code + :return: The QR code image in base64 format ready to be used in json format + """ + qr_code = qrcode.QRCode( + version=1, + error_correction=qrcode.constants.ERROR_CORRECT_L, + box_size=6, + border=0, + ) + qr_code.add_data(qr_code_data) + + qr_code.make(fit=True) + img = qr_code.make_image(fill_color="black", back_color="transparent") + buffered = BytesIO() + img.save(buffered, format="PNG") + img_base64 = base64.b64encode(buffered.getvalue()).decode() + return f"data:image/png;base64,{img_base64}" + + +def generate_network_qr_codes(): + """Generate a QR codes for the IoT Box network and its homepage + and return them in base64 image format in a dictionary + + :return: A dictionary containing the QR codes in base64 format + :rtype: dict + """ + qr_code_images = { + 'qr_wifi': None, + 'qr_url': generate_qr_code_image(f'http://{get_ip()}'), + } + + # Generate QR codes which can be used to connect to the IoT Box Wi-Fi network + if not is_access_point(): + wifi_ssid = get_conf('wifi_ssid') + wifi_password = get_conf('wifi_password') + if wifi_ssid and wifi_password: + wifi_data = f"WIFI:S:{wifi_ssid};T:WPA;P:{wifi_password};;;" + qr_code_images['qr_wifi'] = generate_qr_code_image(wifi_data) + else: + access_point_data = f"WIFI:S:{get_access_point_ssid()};T:nopass;;;" + qr_code_images['qr_wifi'] = generate_qr_code_image(access_point_data) + + return qr_code_images diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/views/index.html b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/views/index.html new file mode 100644 index 00000000..a0b60f27 --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/views/index.html @@ -0,0 +1,45 @@ + + + + + + + + Odoo's IoT Box + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/views/logs.html b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/views/logs.html new file mode 100644 index 00000000..8363d0ac --- /dev/null +++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/views/logs.html @@ -0,0 +1,16 @@ + + + + + + + Odoo's IoT Box Logs + + + + + + +

+    
+
diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/views/status_display.html b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/views/status_display.html
new file mode 100644
index 00000000..54194d5a
--- /dev/null
+++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/views/status_display.html
@@ -0,0 +1,18 @@
+
+
+    
+        
+        
+
+        Odoo's IoT Box
+
+        
+
+        
+        
+        
+    
+    
+        
+    
+
diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/webrtc_client.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/webrtc_client.py
new file mode 100644
index 00000000..5bddb114
--- /dev/null
+++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/webrtc_client.py
@@ -0,0 +1,100 @@
+import asyncio
+import json
+import logging
+import pprint
+from threading import Thread
+import time
+from aiortc import RTCDataChannel, RTCPeerConnection, RTCSessionDescription
+
+from odoo.addons.iot_drivers import main
+
+_logger = logging.getLogger(__name__)
+
+
+class WebRtcClient(Thread):
+    daemon = True
+
+    def __init__(self):
+        super().__init__()
+        self.connections: set[RTCDataChannel] = set()
+        self.chunked_message_in_progress: dict[RTCDataChannel, str] = {}
+        self.event_loop = asyncio.get_event_loop_policy().get_event_loop()
+
+    def offer(self, request: dict):
+        return asyncio.run_coroutine_threadsafe(
+            self._offer(request), self.event_loop
+        ).result()
+
+    def send(self, data: dict):
+        asyncio.run_coroutine_threadsafe(
+            self._send(data), self.event_loop
+        )
+
+    async def _offer(self, request: dict):
+        offer = RTCSessionDescription(sdp=request["sdp"], type=request["type"])
+
+        peer_connection = RTCPeerConnection()
+
+        @peer_connection.on("datachannel")
+        def on_datachannel(channel: RTCDataChannel):
+            self.connections.add(channel)
+
+            @channel.on("message")
+            async def on_message(message_str: str):
+                # Handle chunked message
+                if self.chunked_message_in_progress.get(channel) is not None:
+                    if message_str == "chunked_end":
+                        message_str = self.chunked_message_in_progress.pop(channel)
+                    else:
+                        self.chunked_message_in_progress[channel] += message_str
+                        return
+                elif message_str == "chunked_start":
+                    self.chunked_message_in_progress[channel] = ""
+                    return
+
+                # Handle regular message
+                message = json.loads(message_str)
+                message_type = message["message_type"]
+                _logger.info("Received message of type %s:\n%s", message_type, pprint.pformat(message))
+                if message_type == "iot_action":
+                    device_identifier = message["device_identifier"]
+                    data = message["data"]
+                    data["session_id"] = message["session_id"]
+                    if device_identifier in main.iot_devices:
+                        _logger.info("device '%s' action started with: %s", device_identifier, pprint.pformat(data))
+                        await self.event_loop.run_in_executor(None, lambda: main.iot_devices[device_identifier].action(data))
+                    else:
+                        # Notify that the device is not connected
+                        self.send({
+                            'owner': message['session_id'],
+                            'device_identifier': device_identifier,
+                            'time': time.time(),
+                            'status': 'disconnected',
+                        })
+
+            @channel.on("close")
+            def on_close():
+                self.connections.discard(channel)
+
+        @peer_connection.on("connectionstatechange")
+        async def on_connectionstatechange():
+            if peer_connection.connectionState == "failed":
+                await peer_connection.close()
+
+        await peer_connection.setRemoteDescription(offer)
+
+        answer = await peer_connection.createAnswer()
+        await peer_connection.setLocalDescription(answer)
+
+        return {"sdp": peer_connection.localDescription.sdp, "type": peer_connection.localDescription.type}
+
+    async def _send(self, data: dict):
+        for connection in self.connections:
+            connection.send(json.dumps(data))
+
+    def run(self):
+        self.event_loop.run_forever()
+
+
+webrtc_client = WebRtcClient()
+webrtc_client.start()
diff --git a/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/websocket_client.py b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/websocket_client.py
new file mode 100644
index 00000000..918e779e
--- /dev/null
+++ b/odoo-bringout-oca-ocb-iot_drivers/iot_drivers/websocket_client.py
@@ -0,0 +1,170 @@
+import json
+import logging
+import platform
+import pprint
+import requests
+import time
+import urllib.parse
+import websocket
+
+from threading import Thread
+
+from odoo.addons.iot_drivers import main
+from odoo.addons.iot_drivers.tools import helpers
+from odoo.addons.iot_drivers.server_logger import close_server_log_sender_handler
+from odoo.addons.iot_drivers.webrtc_client import webrtc_client
+
+_logger = logging.getLogger(__name__)
+websocket.enableTrace(True, level=logging.getLevelName(_logger.getEffectiveLevel()))
+
+
+@helpers.require_db
+def send_to_controller(params, method="send_websocket", server_url=None):
+    """Confirm the operation's completion by sending a response back to the Odoo server
+
+    :param params: the parameters to send back to the server
+    :param method: method to call on the IoT box controller
+    :param server_url: URL of the Odoo server (provided by decorator).
+    """
+    request_path = f"{server_url}/iot/box/{method}"
+    try:
+        response = requests.post(request_path, json={'params': params}, timeout=5)
+        response.raise_for_status()
+    except requests.exceptions.RequestException:
+        _logger.exception('Could not reach database URL: %s', request_path)
+
+
+def on_error(ws, error):
+    _logger.error("websocket received an error: %s", error)
+
+
+@helpers.require_db
+class WebsocketClient(Thread):
+    channel = ""
+
+    def on_open(self, ws):
+        """
+            When the client is setup, this function send a message to subscribe to the iot websocket channel
+        """
+        ws.send(json.dumps({
+            'event_name': 'subscribe',
+            'data': {
+                'channels': [self.channel],
+                'last': self.last_message_id,
+                'identifier': helpers.get_identifier(),
+            }
+        }))
+
+    def on_message(self, ws, messages):
+        """Synchronously handle messages received by the websocket."""
+        for message in json.loads(messages):
+            _logger.debug("websocket received a message: %s", pprint.pformat(message))
+            self.last_message_id = message['id']
+            payload = message['message']['payload']
+
+            if not helpers.get_identifier() in payload.get('iot_identifiers', []):
+                continue
+
+            match message['message']['type']:
+                case 'iot_action':
+                    for device_identifier in payload['device_identifiers']:
+                        if device_identifier in main.iot_devices:
+                            _logger.debug("device '%s' action started with: %s", device_identifier, pprint.pformat(payload))
+                            main.iot_devices[device_identifier].action(payload)
+                        else:
+                            # Notify the controller that the device is not connected
+                            send_to_controller({
+                                'session_id': payload.get('session_id', '0'),
+                                'iot_box_identifier': helpers.get_identifier(),
+                                'device_identifier': device_identifier,
+                                'status': 'disconnected',
+                            })
+                case 'server_clear':
+                    helpers.disconnect_from_server()
+                    close_server_log_sender_handler()
+                case 'server_update':
+                    helpers.update_conf({
+                        'remote_server': payload['server_url']
+                    })
+                    helpers.get_odoo_server_url.cache_clear()
+                case 'restart_odoo':
+                    ws.close()
+                    helpers.odoo_restart()
+                case 'webrtc_offer':
+                    answer = webrtc_client.offer(payload['offer'])
+                    send_to_controller({
+                        'iot_box_identifier': helpers.get_identifier(),
+                        'answer': answer,
+                    }, method="webrtc_answer")
+                case 'remote_debug':
+                    if platform.system() == 'Windows':
+                        continue
+                    if not payload.get("status"):
+                        helpers.toggle_remote_connection(payload.get("token", ""))
+                        time.sleep(1)
+                    send_to_controller({
+                        'session_id': 0,
+                        'iot_box_identifier': helpers.get_identifier(),
+                        'device_identifier': None,
+                        'status': 'success',
+                        'result': {'enabled': helpers.is_ngrok_enabled()}
+                    })
+                case _:
+                    continue
+
+    def on_close(self, ws, close_status_code, close_msg):
+        _logger.debug("websocket closed with status: %s", close_status_code)
+        helpers.update_conf({'last_websocket_message_id': self.last_message_id})
+
+    def __init__(self, channel, server_url=None):
+        """This class will not be instantiated if no db is connected.
+
+        :param str channel: the channel to subscribe to
+        :param str server_url: URL of the Odoo server (provided by decorator).
+        """
+        self.channel = channel
+        self.last_message_id = int(helpers.get_conf('last_websocket_message_id') or 0)
+        self.server_url = server_url
+        url_parsed = urllib.parse.urlsplit(server_url)
+        scheme = url_parsed.scheme.replace("http", "ws", 1)
+        self.websocket_url = urllib.parse.urlunsplit((scheme, url_parsed.netloc, 'websocket', '', ''))
+        self.db_name = helpers.get_conf('db_name') or ''
+        self.session_id = ''
+        super().__init__()
+
+    def run(self):
+        if self.db_name:
+            session_response = requests.get(
+                self.server_url + "/web/login?db=" + self.db_name,
+                allow_redirects=False,
+                timeout=10,
+            )
+            if session_response.status_code in [200, 302]:
+                self.session_id = session_response.cookies['session_id']
+            else:
+                _logger.error("Failed to get session ID, status %s", session_response.status_code)
+
+        self.ws = websocket.WebSocketApp(self.websocket_url,
+            header={"User-Agent": "OdooIoTBox/1.0", "Cookie": f"session_id={self.session_id}"},
+            on_open=self.on_open, on_message=self.on_message,
+            on_error=on_error, on_close=self.on_close)
+
+        # The IoT synchronised servers can stop in 2 ways that we need to handle:
+        #  A. Gracefully:
+        #   In this case a disconnection signal is sent to the IoT-box
+        #   The websocket is properly closed, but it needs to be established a new connection when
+        #   the server will be back.
+        #
+        # B. Forced/killed:
+        #   In this case there is no disconnection signal received
+        #
+        #   This will also happen with the graceful quit as `reconnect` will trigger if the server
+        #   is offline while attempting the new connection
+        while True:
+            try:
+                run_res = self.ws.run_forever(reconnect=10)
+                _logger.debug("websocket run_forever return with %s", run_res)
+            except Exception:
+                _logger.exception("An unexpected exception happened when running the websocket")
+            _logger.debug('websocket will try to restart in 10 seconds')
+            time.sleep(10)
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/README.md b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/README.md
new file mode 100644
index 00000000..a6800f3d
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/README.md
@@ -0,0 +1,87 @@
+# Adyen
+
+## Technical details
+
+SDK: Web Components
+version `6.9.0`
+
+APIs:
+
+- [Checkout API](https://docs.adyen.com/api-explorer/Checkout/) version `71`
+- ~~[Recurring API](https://docs.adyen.com/api-explorer/Recurring/) version `68`~~
+
+This module relies on the Web Components SDK to render payment methods and their payment detail
+inputs on the payment form. The JS and CSS assets of the SDK are loaded directly from
+the `__manifest__.py` file.
+
+When a Web Component needs to fetch/push information from/to Adyen or when a payment operation
+(e.g., refund, offline payment) is executed from the backend, a server-to-server API call is made to
+the appropriate API endpoint.
+
+This combined solution allows the implementation of a good-quality direct payment flow whilst
+keeping the front-end development efforts low. The 3DS support is also entirely delegated to Adyen.
+
+This is achieved by following the
+"[Advanced flow](https://docs.adyen.com/online-payments/build-your-integration/advanced-flow/?platform=Web&integration=Components)".
+It is preferred over the recommended "Sessions flow" that only requires dealing with the `/sessions`
+endpoint instead of three `/payment/*` endpoints because two of those are still required to
+implement tokenization and handle 3DS redirects.
+
+## Supported features
+
+- Direct payment flow
+- Webhook notifications
+- Tokenization with or without payment
+- Full and partial manual capture
+- Full and partial refunds
+
+## Not implemented features
+
+- Express checkout
+
+## Module history
+
+- `17.0`
+  - The Web Drop-in SDK is replaced by the Web Components SDK (version 5.39.0); the Checkout and
+    Recurring APIs are updated to versions 70 and 68. odoo/odoo#120446
+  - The 'Checkout API URL' and 'Recurring API URL' fields are replaced by the 'API URL Prefix'
+    field. odoo/odoo#126831
+- `16.4`
+  - The responses of webhook notifications are sent with the proper HTTP code. odoo/odoo#117940
+- `16.2`
+  - The support for partial manual capture is added. odoo/odoo#87251
+- `16.0`
+  - Archiving a token no longer deactivates the related payment method on Adyen. odoo/odoo#93774
+- `15.3`
+  - The support for manual capture is added. odoo/odoo#70591
+- `15.2`
+  - An HTTP 404 "Forbidden" error is raised instead of a Validation error when the authenticity of
+    the webhook notification cannot be verified. odoo/odoo#81607
+- `15.0`
+  - The support for both full and partial refunds is added. odoo/odoo#70881
+  - The Web Drop-in SDK is migrated to version 4.7.3 and the Checkout API to version 67 to switch
+    from relying on origin keys and use client keys instead. odoo/odoo#74827
+- `14.3`
+  - The previous Hosted Payment Pages API that allowed for redirect payments is replaced by a 
+    combination of the Web Drop-in SDK (version 3.9.4) and the Checkout (version 53) and Recurring
+    (version 49) APIs. odoo/odoo#141661
+
+## Testing instructions
+
+https://docs.adyen.com/development-resources/testing/test-card-numbers/
+
+### VISA
+
+**Card Number**: `4111111145551142`
+
+**Expiry Date**: `03/30`
+
+**CVC Code**: `737`
+
+### 3D Secure 2
+
+**Card Number**: `5454545454545454`
+
+**Expiry Date**: `03/30`
+
+**CVC Code**: `737`
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/__init__.py b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/__init__.py
new file mode 100644
index 00000000..7058c93c
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/__init__.py
@@ -0,0 +1,15 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import controllers
+from . import models
+from . import wizards
+
+from odoo.addons.payment import setup_provider, reset_payment_provider
+
+
+def post_init_hook(env):
+    setup_provider(env, 'adyen')
+
+
+def uninstall_hook(env):
+    reset_payment_provider(env, 'adyen')
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/__manifest__.py b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/__manifest__.py
new file mode 100644
index 00000000..e738de08
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/__manifest__.py
@@ -0,0 +1,29 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+{
+    'name': 'Payment Provider: Adyen',
+    'version': '2.0',
+    'category': 'Accounting/Payment Providers',
+    'sequence': 350,
+    'summary': "A Dutch payment provider covering Europe and the US.",
+    'description': " ",  # Non-empty string to avoid loading the README file.
+    'depends': ['payment'],
+    'data': [
+        'views/payment_adyen_templates.xml',
+        'views/payment_form_templates.xml',
+        'views/payment_provider_views.xml',
+
+        'data/payment_provider_data.xml',  # Depends on views/payment_adyen_templates.xml
+
+        'wizards/payment_capture_wizard_views.xml',
+    ],
+    'post_init_hook': 'post_init_hook',
+    'uninstall_hook': 'uninstall_hook',
+    'assets': {
+        'web.assets_frontend': [
+            'payment_adyen/static/src/interactions/payment_form.js',
+        ],
+    },
+    'author': 'Odoo S.A.',
+    'license': 'LGPL-3',
+}
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/const.py b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/const.py
new file mode 100644
index 00000000..a4580729
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/const.py
@@ -0,0 +1,79 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+# Endpoints of the API.
+# See https://docs.adyen.com/api-explorer/#/CheckoutService/v70/overview for Checkout API
+# See https://docs.adyen.com/api-explorer/#/Recurring/v68/overview for Recurring API
+API_ENDPOINT_VERSIONS = {
+    '/disable': 68,                 # Recurring API; unused - to remove
+    '/paymentMethods': 71,          # Checkout API
+    '/payments': 71,                # Checkout API
+    '/payments/details': 71,        # Checkout API
+    '/payments/{}/cancels': 71,     # Checkout API
+    '/payments/{}/captures': 71,    # Checkout API
+    '/payments/{}/refunds': 71,     # Checkout API
+}
+
+# Adyen-specific mapping of currency codes in ISO 4217 format to the number of decimals.
+# Only currencies for which Adyen does not follow the ISO 4217 norm are listed here.
+# See https://docs.adyen.com/development-resources/currency-codes
+CURRENCY_DECIMALS = {
+    'CLP': 2,
+    'CVE': 0,
+    'IDR': 0,
+    'ISK': 2,
+}
+
+# The codes of the payment methods to activate when Adyen is activated.
+DEFAULT_PAYMENT_METHOD_CODES = {
+    # Primary payment methods.
+    'card',
+    # Brand payment methods.
+    'visa',
+    'mastercard',
+    'amex',
+    'discover',
+}
+
+# Mapping of payment method codes to Adyen codes.
+PAYMENT_METHODS_MAPPING = {
+    'ach_direct_debit': 'ach',
+    'apple_pay': 'applepay',
+    'bacs_direct_debit': 'directdebit_GB',
+    'bancontact_card': 'bcmc',
+    'bancontact': 'bcmc_mobile',
+    'cash_app_pay': 'cashapp',
+    'gopay': 'gopay_wallet',
+    'becs_direct_debit': 'au_becs_debit',
+    'afterpay': 'afterpaytouch',
+    'klarna_pay_over_time': 'klarna_account',
+    'momo': 'momo_wallet',
+    'napas_card': 'momo_atm',
+    'paytrail': 'ebanking_FI',
+    'online_banking_czech_republic': 'onlineBanking_CZ',
+    'online_banking_india': 'onlinebanking_IN',
+    'fpx': 'molpay_ebanking_fpx_MY',
+    'p24': 'onlineBanking_PL',
+    'mastercard': 'mc',
+    'online_banking_slovakia': 'onlineBanking_SK',
+    'online_banking_thailand': 'molpay_ebanking_TH',
+    'open_banking': 'paybybank',
+    'samsung_pay': 'samsungpay',
+    'sepa_direct_debit': 'sepadirectdebit',
+    'sofort': 'directEbanking',
+    'unionpay': 'cup',
+    'wallets_india': 'wallet_IN',
+    'wechat_pay': 'wechatpayQR',
+}
+
+# Mapping of transaction states to Adyen result codes.
+# See https://docs.adyen.com/checkout/payment-result-codes for the exhaustive list of result codes.
+RESULT_CODES_MAPPING = {
+    'pending': (
+        'ChallengeShopper', 'IdentifyShopper', 'Pending', 'PresentToShopper', 'Received',
+        'RedirectShopper'
+    ),
+    'done': ('Authorised',),
+    'cancel': ('Cancelled',),
+    'error': ('Error',),
+    'refused': ('Refused',),
+}
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/controllers/__init__.py b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/controllers/__init__.py
new file mode 100644
index 00000000..80ee4da1
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/controllers/__init__.py
@@ -0,0 +1,3 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import main
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/controllers/main.py b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/controllers/main.py
new file mode 100644
index 00000000..f4165708
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/controllers/main.py
@@ -0,0 +1,340 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import base64
+import binascii
+import hashlib
+import hmac
+import pprint
+
+from werkzeug.exceptions import Forbidden
+
+from odoo import _, http
+from odoo.exceptions import ValidationError
+from odoo.http import request
+from odoo.tools import py_to_js_locale, urls
+
+from odoo.addons.payment import utils as payment_utils
+from odoo.addons.payment.logging import get_payment_logger
+from odoo.addons.payment_adyen import utils as adyen_utils
+
+
+_logger = get_payment_logger(__name__)
+
+
+class AdyenController(http.Controller):
+
+    _webhook_url = '/payment/adyen/notification'
+
+    @http.route('/payment/adyen/payment_methods', type='jsonrpc', auth='public')
+    def adyen_payment_methods(self, provider_id, formatted_amount=None, partner_id=None):
+        """ Query the available payment methods based on the payment context.
+
+        :param int provider_id: The provider handling the transaction, as a `payment.provider` id
+        :param dict formatted_amount: The Adyen-formatted amount.
+        :param int partner_id: The partner making the transaction, as a `res.partner` id
+        :return: The JSON-formatted content of the response
+        :rtype: dict
+        """
+        provider_sudo = request.env['payment.provider'].sudo().browse(provider_id)
+        partner_sudo = partner_id and request.env['res.partner'].sudo().browse(partner_id).exists()
+        # The lang is taken from the context rather than from the partner because it is not required
+        # to be logged in to make a payment, and because the lang is not always set on the partner.
+        # Adyen only supports a limited set of languages but, instead of looking for the closest
+        # match in https://docs.adyen.com/checkout/components-web/localization-components, we simply
+        # provide the lang string as is (after adapting the format) and let Adyen find the best fit.
+        lang_code = py_to_js_locale(request.env.context.get('lang')) or 'en-US'
+        shopper_reference = partner_sudo and f'ODOO_PARTNER_{partner_sudo.id}'
+        partner_country_code = (
+            partner_sudo.country_id.code or provider_sudo.company_id.country_id.code or 'NL'
+        )
+        data = {
+            'merchantAccount': provider_sudo.adyen_merchant_account,
+            'amount': formatted_amount,
+            'countryCode': partner_country_code,  # ISO 3166-1 alpha-2 (e.g.: 'BE')
+            'shopperLocale': lang_code,  # IETF BCP 47 language tag (e.g.: 'fr-BE')
+            'shopperReference': shopper_reference,
+            'channel': 'Web',
+        }
+        response_content = provider_sudo._send_api_request('POST', '/paymentMethods', json=data)
+        response_content['country_code'] = partner_country_code
+        return response_content
+
+    @http.route('/payment/adyen/payments', type='jsonrpc', auth='public')
+    def adyen_payments(
+        self, provider_id, reference, converted_amount, currency_id, partner_id, payment_method,
+        access_token, browser_info=None
+    ):
+        """Make a payment request and process the payment data.
+
+        :param int provider_id: The provider handling the transaction, as a `payment.provider` id
+        :param str reference: The reference of the transaction
+        :param int converted_amount: The amount of the transaction in minor units of the currency
+        :param int currency_id: The currency of the transaction, as a `res.currency` id
+        :param int partner_id: The partner making the transaction, as a `res.partner` id
+        :param dict payment_method: The details of the payment method used for the transaction
+        :param str access_token: The access token used to verify the provided values
+        :param dict browser_info: The browser info to pass to Adyen
+        :return: The JSON-formatted content of the response
+        :rtype: dict
+        """
+        # Check that the transaction details have not been altered. This allows preventing users
+        # from validating transactions by paying less than agreed upon.
+        if not payment_utils.check_access_token(
+            access_token, reference, converted_amount, currency_id, partner_id
+        ):
+            raise ValidationError(_("Received tampered payment request data."))
+
+        # Prepare the payment request to Adyen
+        provider_sudo = request.env['payment.provider'].sudo().browse(provider_id).exists()
+        tx_sudo = request.env['payment.transaction'].sudo().search([('reference', '=', reference)])
+        data = {
+            'merchantAccount': provider_sudo.adyen_merchant_account,
+            'amount': {
+                'value': converted_amount,
+                'currency': request.env['res.currency'].browse(currency_id).name,  # ISO 4217
+            },
+            'reference': reference,
+            'paymentMethod': payment_method,
+            'shopperReference': provider_sudo._adyen_compute_shopper_reference(partner_id),
+            'recurringProcessingModel': 'CardOnFile',  # Most susceptible to trigger a 3DS check
+            'shopperIP': payment_utils.get_customer_ip_address(),
+            'shopperInteraction': 'Ecommerce',
+            'shopperEmail': tx_sudo.partner_email or "",
+            'shopperName': adyen_utils.format_partner_name(tx_sudo.partner_name),
+            'telephoneNumber': tx_sudo.partner_phone or "",
+            'storePaymentMethod': tx_sudo.tokenize,  # True by default on Adyen side
+            'authenticationData': {
+                'threeDSRequestData': {
+                    'nativeThreeDS': 'preferred',
+                }
+            },
+            'channel': 'web',  # Required to support 3DS
+            'origin': provider_sudo.get_base_url(),  # Required to support 3DS
+            'browserInfo': browser_info,  # Required to support 3DS
+            'returnUrl': urls.urljoin(
+                provider_sudo.get_base_url(),
+                # Include the reference in the return url to be able to match it after redirection.
+                # The key 'merchantReference' is chosen on purpose to be the same as that returned
+                # by the /payments endpoint of Adyen.
+                f'/payment/adyen/return?merchantReference={reference}',
+            ),
+            **adyen_utils.include_partner_addresses(tx_sudo),
+        }
+
+        # Force the capture delay on Adyen side if the provider is not configured for capturing
+        # payments manually. This is necessary because it's not possible to distinguish
+        # 'AUTHORISATION' events sent by Adyen with the merchant account's capture delay set to
+        # 'manual' from events with the capture delay set to 'immediate' or a number of hours. If
+        # the merchant account is configured to capture payments with a delay but the provider is
+        # not, we force the immediate capture to avoid considering authorized transactions as
+        # captured on Odoo.
+        if not provider_sudo.capture_manually:
+            data.update(captureDelayHours=0)
+
+        # Send the payment request to Adyen.
+        idempotency_key = payment_utils.generate_idempotency_key(
+            tx_sudo, scope='payment_request_controller'
+        )
+
+        response_content = provider_sudo._send_api_request(
+            'POST', '/payments', json=data, idempotency_key=idempotency_key
+        )
+        tx_sudo._process(
+            'adyen', dict(response_content, merchantReference=reference),  # Match the transaction
+        )
+        return response_content
+
+    @http.route('/payment/adyen/payments/details', type='jsonrpc', auth='public')
+    def adyen_payment_details(self, provider_id, reference, payment_details):
+        """Submit the details of the additional actions and process the payment data.
+
+         The additional actions can have been performed both from the inline form or during a
+         redirection.
+
+        :param int provider_id: The provider handling the transaction, as a `payment.provider` id
+        :param str reference: The reference of the transaction
+        :param dict payment_details: The details of the additional actions performed for the payment
+        :return: The JSON-formatted content of the response
+        :rtype: dict
+        """
+        # Make the payment details request to Adyen
+        provider_sudo = request.env['payment.provider'].browse(provider_id).sudo()
+        response_content = provider_sudo._send_api_request(
+            'POST', '/payments/details', json=payment_details
+        )
+
+        # Process the payment data request response.
+        request.env['payment.transaction'].sudo()._process(
+            'adyen', dict(response_content, merchantReference=reference),  # Match the transaction
+        )
+
+        return response_content
+
+    @http.route('/payment/adyen/return', type='http', auth='public', csrf=False, save_session=False)
+    def adyen_return_from_3ds_auth(self, **data):
+        """ Process the authentication data sent by Adyen after redirection from the 3DS1 page.
+
+        The route is flagged with `save_session=False` to prevent Odoo from assigning a new session
+        to the user if they are redirected to this route with a POST request. Indeed, as the session
+        cookie is created without a `SameSite` attribute, some browsers that don't implement the
+        recommended default `SameSite=Lax` behavior will not include the cookie in the redirection
+        request from the payment provider to Odoo. As the redirection to the '/payment/status' page
+        will satisfy any specification of the `SameSite` attribute, the session of the user will be
+        retrieved and with it the transaction which will be immediately post-processed.
+
+        :param dict data: The authentication result data. May include custom params sent to Adyen in
+                          the request to allow matching the transaction when redirected here.
+        """
+        # Retrieve the transaction based on the reference included in the return url
+        tx_sudo = request.env['payment.transaction'].sudo()._search_by_reference('adyen', data)
+        if not tx_sudo:
+            return request.redirect('/payment/status')
+
+        # Overwrite the operation to force the flow to 'redirect'. This is necessary because even
+        # though Adyen is implemented as a direct payment provider, it will redirect the user out
+        # of Odoo in some cases. For instance, when a 3DS1 authentication is required, or for
+        # special payment methods that are not handled by the drop-in (e.g. Sofort).
+        tx_sudo.operation = 'online_redirect'
+
+        # Query and process the result of the additional actions that have been performed
+        _logger.info(
+            "Handling redirection from Adyen for transaction %s with data:\n%s",
+            tx_sudo.reference, pprint.pformat(data)
+        )
+        self.adyen_payment_details(
+            tx_sudo.provider_id.id,
+            data['merchantReference'],
+            {
+                'details': {
+                    'redirectResult': data['redirectResult'],
+                },
+            },
+        )
+
+        # Redirect the user to the status page
+        return request.redirect('/payment/status')
+
+    @http.route(_webhook_url, type='http', methods=['POST'], auth='public', csrf=False)
+    def adyen_webhook(self):
+        """ Process the data sent by Adyen to the webhook based on the event code.
+
+        See https://docs.adyen.com/development-resources/webhooks/understand-notifications for the
+        exhaustive list of event codes.
+
+        :return: The '[accepted]' string to acknowledge the notification
+        :rtype: str
+        """
+        data = request.get_json_data()
+        for notification_item in data['notificationItems']:
+            payment_data = notification_item['NotificationRequestItem']
+
+            _logger.info(
+                "notification received from Adyen with data:\n%s", pprint.pformat(payment_data)
+            )
+            # Check the integrity of the notification.
+            tx_sudo = request.env['payment.transaction'].sudo()._search_by_reference(
+                'adyen', payment_data
+            )
+            if tx_sudo:
+                self._verify_signature(payment_data, tx_sudo)
+
+                # Check whether the event of the notification succeeded and reshape the notification
+                # data for parsing
+                success = payment_data['success'] == 'true'
+                event_code = payment_data['eventCode']
+                if event_code == 'AUTHORISATION' and success:
+                    payment_data['resultCode'] = 'Authorised'
+                elif event_code == 'CANCELLATION':
+                    payment_data['resultCode'] = 'Cancelled' if success else 'Error'
+                elif event_code in ['REFUND', 'CAPTURE']:
+                    payment_data['resultCode'] = 'Authorised' if success else 'Error'
+                elif event_code == 'CAPTURE_FAILED' and success:
+                    # The capture failed after a capture notification with success = True was sent
+                    payment_data['resultCode'] = 'Error'
+                else:
+                    continue  # Don't handle unsupported event codes and failed events
+                tx_sudo._process('adyen', payment_data)
+        return request.make_json_response('[accepted]')  # Acknowledge the notification
+
+    @staticmethod
+    def _verify_signature(payment_data, tx_sudo):
+        """Check that the received signature matches the expected one.
+
+        :param dict payment_data: The payment data containing the received signature.
+        :param payment.transaction tx_sudo: The sudoed transaction referenced by the payment data.
+        :return: None
+        :raise Forbidden: If the signatures don't match.
+        """
+        # Retrieve the received signature from the payload
+        received_signature = payment_data.get('additionalData', {}).get('hmacSignature')
+        if not received_signature:
+            _logger.warning("received payment data with missing signature")
+            raise Forbidden()
+
+        # Compare the received signature with the expected signature computed from the payload
+        hmac_key = tx_sudo.provider_id.adyen_hmac_key
+        expected_signature = AdyenController._compute_signature(payment_data, hmac_key)
+        if not hmac.compare_digest(received_signature, expected_signature):
+            _logger.warning("received payment data with invalid signature")
+            raise Forbidden()
+
+    @staticmethod
+    def _compute_signature(payload, hmac_key):
+        """ Compute the signature from the payload.
+
+        See https://docs.adyen.com/development-resources/webhooks/verify-hmac-signatures
+
+        :param dict payload: The notification payload
+        :param str hmac_key: The HMAC key of the provider handling the transaction
+        :return: The computed signature
+        :rtype: str
+        """
+        def _flatten_dict(_value, _path_base='', _separator='.'):
+            """ Recursively generate a flat representation of a dict.
+
+            :param Object _value: The value to flatten. A dict or an already flat value
+            :param str _path_base: They base path for keys of _value, including preceding separators
+            :param str _separator: The string to use as a separator in the key path
+            """
+            if isinstance(_value, dict):  # The inner value is a dict, flatten it
+                _path_base = _path_base if not _path_base else _path_base + _separator
+                for _key in _value:
+                    yield from _flatten_dict(_value[_key], _path_base + str(_key))
+            else:  # The inner value cannot be flattened, yield it
+                yield _path_base, _value
+
+        def _to_escaped_string(_value):
+            """ Escape payload values that are using illegal symbols and cast them to string.
+
+            String values containing `\\` or `:` are prefixed with `\\`.
+            Empty values (`None`) are replaced by an empty string.
+
+            :param Object _value: The value to escape
+            :return: The escaped value
+            :rtype: string
+            """
+            if isinstance(_value, str):
+                return _value.replace('\\', '\\\\').replace(':', '\\:')
+            elif _value is None:
+                return ''
+            else:
+                return str(_value)
+
+        signature_keys = [
+            'pspReference', 'originalReference', 'merchantAccountCode', 'merchantReference',
+            'amount.value', 'amount.currency', 'eventCode', 'success'
+        ]
+        # Flatten the payload to allow accessing inner dicts naively
+        flattened_payload = {k: v for k, v in _flatten_dict(payload)}
+        # Build the list of signature values as per the list of required signature keys
+        signature_values = [flattened_payload.get(key) for key in signature_keys]
+        # Escape values using forbidden symbols
+        escaped_values = [_to_escaped_string(value) for value in signature_values]
+        # Concatenate values together with ':' as delimiter
+        signing_string = ':'.join(escaped_values)
+        # Convert the HMAC key to the binary representation
+        binary_hmac_key = binascii.a2b_hex(hmac_key.encode('ascii'))
+        # Calculate the HMAC with the binary representation of the signing string with SHA-256
+        binary_hmac = hmac.new(binary_hmac_key, signing_string.encode('utf-8'), hashlib.sha256)
+        # Calculate the signature by encoding the result with Base64
+        return base64.b64encode(binary_hmac.digest()).decode()
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/data/neutralize.sql b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/data/neutralize.sql
new file mode 100644
index 00000000..89875580
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/data/neutralize.sql
@@ -0,0 +1,5 @@
+-- disable adyen payment provider
+UPDATE payment_provider
+   SET adyen_merchant_account = NULL,
+       adyen_api_key = NULL,
+       adyen_hmac_key = NULL;
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/data/payment_provider_data.xml b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/data/payment_provider_data.xml
new file mode 100644
index 00000000..8681756e
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/data/payment_provider_data.xml
@@ -0,0 +1,10 @@
+
+
+
+    
+        adyen
+        
+        True
+    
+
+
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/af.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/af.po
new file mode 100644
index 00000000..7bf0c161
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/af.po
@@ -0,0 +1,256 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 10.saas~18\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2017-09-20 09:53+0000\n"
+"Language-Team: Afrikaans (https://www.transifex.com/odoo/teams/41243/af/)\n"
+"Language: af\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/am.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/am.po
new file mode 100644
index 00000000..d912a801
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/am.po
@@ -0,0 +1,256 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 10.saas~18\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2017-09-20 09:53+0000\n"
+"Language-Team: Amharic (https://www.transifex.com/odoo/teams/41243/am/)\n"
+"Language: am\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ar.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ar.po
new file mode 100644
index 00000000..120ced76
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ar.po
@@ -0,0 +1,250 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Mustafa Rawi , 2019
+# hoxhe Aits , 2019
+# Osama Ahmaro , 2019
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 13:40+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Arabic \n"
+"Language: ar\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
+"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"تحذير: لتحصيل المبلغ يدوياً، تحتاج أيضاً تعيين إعدادات تأخير\n"
+"                    التحصيل لتصبح يدوية، في إعدادات حساب Adyen الخاص بك."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "مفتاح الواجهة البرمجية للتطبيق"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "الواجهة البرمجية لبادئة رابط URL"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr "حدث خطأ أثناء معالجة هذا الدفع. يرجى المحاولة مجدداً."
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "لا يمكن عرض استمارة الدفع"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "مفتاح العميل"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "رمز"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "اسم العرض"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "مفتاح HMAC"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "Has Adyen Tx"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "المُعرف"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "تفاصيل الدفع غير صحيحة"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "معرفة المزيد"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "حساب التاجر"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "معالج تحصيل الدفع"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "مزود الدفع"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "رمز الدفع"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "معاملة السداد"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "فشلت معالجة عملية الدفع"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "تم استلام البيانات مع حالة دفع غير صالحة: %s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "تم استلام البيانات دون حالة الدفع."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "بيانات طلب الدفع المستلمة المتلاعب بها."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "مرجع المتسوق"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "مفتاح الواجهة البرمجية للتطبيق لمستخدم خدمة الويب"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "مفتاح HMAC لـ webhook"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+"المبلغ الذي قام Adyen بمعالجته للمعاملة %s مختلف عن الذي طلبته. تم إنشاء "
+"معاملة أخرى بالمبلغ الصحيح."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "رابط URL الأساسي للنقاط النهائية للواجهة البرمجية"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"قد يستغرق تحصيل أو إبطال المعاملة بضع دقائق لتتم معالجته\n"
+"                    بواسطة Adyen وحتى يظهر في أودو."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "مفتاح الالعميل لمستخدم خدمة الويب"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr "كود حساب التاجر لاستخدامه مع مزود الدفع هذا"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "الكود التقني لمزود الدفع هذا."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "المرجع الفريد للشريك الذي يملك هذا الرمز"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "لقد تم رفض الدفع. يرجى المحاولة مجدداً."
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/az.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/az.po
new file mode 100644
index 00000000..7a164c3f
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/az.po
@@ -0,0 +1,235 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~11.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2018-08-24 09:21+0000\n"
+"Language-Team: Azerbaijani (https://www.transifex.com/odoo/teams/41243/az/)\n"
+"Language: az\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/bg.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/bg.po
new file mode 100644
index 00000000..67c3019c
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/bg.po
@@ -0,0 +1,235 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 10.saas~18\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2017-09-20 09:53+0000\n"
+"Language-Team: Bulgarian (https://www.transifex.com/odoo/teams/41243/bg/)\n"
+"Language: bg\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/bs.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/bs.po
new file mode 100644
index 00000000..6b6eecff
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/bs.po
@@ -0,0 +1,260 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Boško Stojaković , 2018
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~11.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2018-09-18 09:49+0000\n"
+"Last-Translator: Boško Stojaković , 2018\n"
+"Language-Team: Bosnian (https://www.transifex.com/odoo/teams/41243/bs/)\n"
+"Language: bs\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transakcija plaćanja"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ca.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ca.po
new file mode 100644
index 00000000..858d7604
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ca.po
@@ -0,0 +1,251 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Martin Trigaux, 2018
+# Lluís Dalmau , 2018
+# RGB Consulting , 2018
+# Joan Ignasi Florit , 2018
+# Quim - eccit , 2018
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~11.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 04:41+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Catalan \n"
+"Language: ca\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"Advertència: per capturar l'import manualment, també cal "
+"configurar\n"
+"                    el retard de captura com a manual en la configuració del "
+"teu compte Adyen."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "API Key"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "Prefix de l'URL de l'API"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+"S'ha produït un error durant el processament del seu pagament. Si us plau, "
+"intenti'l de nou."
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "Clau del client"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Codi"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "Tecla HMAC"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Veure més"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Compte de mercaderia"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Proveïdor de pagament"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Token de pagament"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transacció de pagament"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "Dades rebudes amb un estat de pagament no vàlid: %s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Dades rebudes amb estat de pagament absent."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "S'han rebut dades de sol·licitud de pagament manipulades."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "Referència del comprador"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "La clau API de l'usuari del servei web"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "La clau HMAC del webhook"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "La clau del client de l'usuari del servei web"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "El codi tècnic d'aquest proveïdor de pagaments."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "La referència única del soci que posseeix aquest token"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "El seu pagament ha estat rebutjat. Si us plau, intenti-ho de nou."
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/cs.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/cs.po
new file mode 100644
index 00000000..ae121559
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/cs.po
@@ -0,0 +1,243 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Michal Veselý , 2019
+# trendspotter , 2019
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 10:05+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Czech \n"
+"Language: cs\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n "
+"<= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "Klíč API"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Kód"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "Zobrazovací název"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ID"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "Nesprávné platební informace"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Další informace"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "Průvodce zachycením platby"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Poskytovatel platby"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Platební token"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Platební transakce"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Zpracování platby se nezdařilo"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Technický kód tohoto poskytovatele plateb."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/da.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/da.po
new file mode 100644
index 00000000..b754b864
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/da.po
@@ -0,0 +1,244 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# jonas jensen , 2019
+# Pernille Kristensen , 2019
+# Sanne Kristensen , 2019
+# "Dylan Kiss (dyki)" , 2025.
+# "Kira Petersen François (peti)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-25 13:33+0000\n"
+"Last-Translator: \"Kira Petersen François (peti)\" \n"
+"Language-Team: Danish \n"
+"Language: da\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "API nøgle"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Kode"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "Vis navn"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ID"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Lær mere"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Merchant konto"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Betalingsudbyder"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Betalingstoken"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Betalingstransaktion"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Behandlingen af betaling mislykkedes"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/de.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/de.po
new file mode 100644
index 00000000..383c520e
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/de.po
@@ -0,0 +1,255 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Martin Trigaux, 2019
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 04:41+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: German \n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"Warnung: Um den Betrag manuell zu erfassen, müssen Sie "
+"auch\n"
+"                    die Erfassungsverzögerung in den Einstellungen Ihres "
+"Adyen-Kontos auf manuell setzen."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "API-Schlüssel"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "API-URL-Präfix"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+"Bei der Bearbeitung dieser Zahlung ist ein Fehler aufgetreten. Bitte "
+"versuchen Sie es erneut."
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "Zahlungsformular konnte nicht angezeigt werden"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "Client-Schlüssel"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Code"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "Anzeigename"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "HMAC-Schlüssel"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "Hat Adyen Steuer"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ID"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "Fehlerhafte Zahlungsdetails"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Mehr erfahren"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Händler-Konto"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "Assistent für Zahlungserfassung"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Zahlungsanbieter"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Zahlungstoken"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Zahlungstransaktion"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Zahlungsverarbeitung fehlgeschlagen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "Erhaltene Daten mit ungültigem Zahlungsstatus: %s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Erhaltene Daten mit fehlendem Zahlungsstatus."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "Es wurden manipulierte Zahlungsanforderungsdaten empfangen."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "Referenz des Käufers"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "Der API-Schlüssel des Webservice-Benutzers"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "Der HMAC-Schlüssel des Webhooks"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+"Der von Adyen für die Transaktion %s verarbeitete Betrag unterscheidet sich "
+"von dem angeforderten Betrag. Es wird eine weitere Transaktion mit dem "
+"richtigen Betrag erstellt."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "Die Basis-URL für die API-Endpunkte"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"Die Erfassung oder Stornierung der Transaktion kann einige Minuten dauern,\n"
+"                     bis sie von Adyen verarbeitet und in Odoo wiedergegeben "
+"wird."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "Der Client-Schlüssel des Webservice-Benutzers"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+"Der Code des Händlerkontos, das mit diesem Anbieter verwendet werden soll."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Der technische Code dieses Zahlungsanbieters."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "Die eindeutige Referenz des Partners, der dieses Token besitzt"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "Ihre Zahlung wurde abgelehnt. Bitte versuchen Sie es erneut."
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/el.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/el.po
new file mode 100644
index 00000000..6af5c98b
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/el.po
@@ -0,0 +1,242 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Martin Trigaux, 2018
+# Kostas Goutoudis , 2018
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~11.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-24 19:22+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Greek \n"
+"Language: el\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "Κλειδί API"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Κωδικός"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Λογαριασμός Εμπόρου"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Πάροχος Πληρωμών"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Διακριτικό Πληρωμής"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Συναλλαγή Πληρωμής"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/es.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/es.po
new file mode 100644
index 00000000..52eca8b1
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/es.po
@@ -0,0 +1,253 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Martin Trigaux, 2019
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-17 17:23+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Spanish \n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"Advertencia: para capturar el importe manualmente, también "
+"debe configurar\n"
+"                   el retraso de captura como manual en los ajustes de su "
+"cuenta de Adyen."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "Clave API"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "Prefijo de la URL de la API"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+"Ocurrió un error durante el procesamiento de su pago. Por favor, inténtelo "
+"de nuevo."
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "No se puede mostrar el formulario de pago"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "Clave de cliente"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Código"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "Nombre para mostrar"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "Clave HMAC"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "Tiene Adyen Tx"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ID"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "Detalles de pago incorrectos"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Más información"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Cuenta de comerciante"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "Asistente de captura de pagos"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Proveedor de pago"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Token de pago"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transacción de pago"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Error al procesar el pago"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "Datos recibidos con un estado de pago no válido: %s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Datos recibidos sin estado de pago."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "Datos recibidos de solicitud de pago manipulados."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "Referencia del comprador"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "La clave API del usuario del servicio web"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "La clave HMAC del webhook"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+"El importe precesado por Adyen para la transacción %s es diferente que el "
+"importe pedido. Se creó otra transacción con el importe correcto."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "La URL de base para los puntos de conexión de la API"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"Es posible que Adyen tarde unos minutos en procesar la captura\n"
+"                    o anulación de la transacción para que se refleje en "
+"Odoo."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "La clave de cliente del usuario del servicio web"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr "El código de la cuenta comercial que se debe usar con este proveedor"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "El código técnico de este proveedor de pagos."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "La referencia única del contacto propietario de este token"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "Su pago ha sido rechazado. Por favor, inténtelo de nuevo."
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/es_419.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/es_419.po
new file mode 100644
index 00000000..1677beed
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/es_419.po
@@ -0,0 +1,275 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-17 07:46+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Spanish (Latin America) \n"
+"Language: es_419\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to set\n"
+"                    the Capture Delay to manual on your Adyen account settings."
+msgstr ""
+"Advertencia: Para capturar el importe de forma manual es "
+"necesario que configure\n"
+"                   el retraso de la captura con la opción manual en los "
+"ajustes de su cuenta de Adyen."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"A request was sent to void the transaction with reference %(reference)s "
+"(%(provider)s)."
+msgstr ""
+"Se envió una solicitud para anular la transacción con referencia %(reference)"
+"s (%(provider)s)."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "Clave API"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "Prefijo de la URL de la API"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr "Ocurrió un error al procesar su pago. Inténtelo de nuevo."
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "No se puede mostrar el formulario de pago"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "Clave de cliente"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Código"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "No se pudo establecer la conexión con la API."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "Clave HMAC"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "Tiene Adyen Tx"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "Detalles de pago incorrectos"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Más información"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Cuenta de comerciante"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "No se encontró ninguna transacción que coincida con la referencia %s."
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "Asistente de captura de pagos"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Proveedor de pago"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Token de pago"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transacción de pago"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Error al procesar el pago"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+"Datos recibidos para transacción secundaria con valores de transacción "
+"faltante"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "Datos recibidos con un estado de pago no válido: %s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr "Datos recibidos en los que falta la referencia del vendedor"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Datos recibidos con estado de pago pendiente."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "Datos recibidos de solicitud de pago manipulados."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "Referencia del comprador"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "La clave API del usuario del servicio web"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "La clave HMAC del webhook"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+"El importe procesado por Adyen para la transacción %s es distinto al "
+"solicitado. Se creó otra transacción con el importe correcto."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "La URL base para los puntos de conexión de la API"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr "Falló la captura de la transacción con la referencia %s."
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"Es posible que Adyen tarde unos minutos en procesar la captura\n"
+"                    o anulación de la transacción para que se refleje en "
+"Odoo."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s"
+" has been requested (%(provider_name)s)."
+msgstr ""
+"Se solicitó la captura de %(amount)s para la transacción con referencia "
+"%(ref)s (%(provider_name)s)."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "La clave de cliente del usuario del servicio web"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr "El código de la cuenta comercial que se debe usar con este proveedor"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "Ocurrió un error en la comunicación con la API. Detalles: %s"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "El código técnico de este proveedor de pagos."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "La transacción no está vinculada a un token."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "La referencia única del contacto propietario de este token"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr "Falló la anulación de la transacción con la referencia %s."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "Su pago fue rechazado, vuelva a intentarlo."
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/es_CL.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/es_CL.po
new file mode 100644
index 00000000..a8607cda
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/es_CL.po
@@ -0,0 +1,257 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 10.saas~18\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2017-09-20 09:53+0000\n"
+"Language-Team: Spanish (Chile) (https://www.transifex.com/odoo/teams/41243/"
+"es_CL/)\n"
+"Language: es_CL\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/et.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/et.po
new file mode 100644
index 00000000..9ced77e2
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/et.po
@@ -0,0 +1,262 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Eneli Õigus , 2018
+# Marek Pontus, 2018
+# Martin Aavastik , 2018
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~11.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2018-08-24 09:21+0000\n"
+"Last-Translator: Martin Aavastik , 2018\n"
+"Language-Team: Estonian (https://www.transifex.com/odoo/teams/41243/et/)\n"
+"Language: et\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Maksetehing"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/eu.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/eu.po
new file mode 100644
index 00000000..9952a4a6
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/eu.po
@@ -0,0 +1,256 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 10.saas~18\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2017-09-20 09:53+0000\n"
+"Language-Team: Basque (https://www.transifex.com/odoo/teams/41243/eu/)\n"
+"Language: eu\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fa.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fa.po
new file mode 100644
index 00000000..b99a15ed
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fa.po
@@ -0,0 +1,239 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Martin Trigaux, 2018
+# Hamed Mohammadi , 2018
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~11.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2018-09-18 09:49+0000\n"
+"Last-Translator: Hamed Mohammadi , 2018\n"
+"Language-Team: Persian (https://www.transifex.com/odoo/teams/41243/fa/)\n"
+"Language: fa\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "تراکنش پرداخت"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fi.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fi.po
new file mode 100644
index 00000000..db3b67bf
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fi.po
@@ -0,0 +1,252 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Martin Trigaux, 2018
+# Mikko Salmela , 2018
+# Jarmo Kortetjärvi , 2018
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~11.4\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 15:26+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Finnish \n"
+"Language: fi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"Varoitus: Jos haluat lukea summan manuaalisesti, sinun on "
+"myös asetettava seuraavat asetukset\n"
+"                    adyen-tilisi asetuksissa Capture Delay -viiveeksi "
+"manuaalinen."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "API-avain"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "API URL-etuliite"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr "Maksun käsittelyssä tapahtui virhe. Yritä uudelleen."
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "Maksulomaketta ei voi näyttää"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "Asiakasavain"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Koodi"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "Näyttönimi"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "HMAC-avain"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "Onko Adyen Tx"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "Tunnus"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "Virheelliset maksutiedot"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Lue lisää"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Kauppiaan tili"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "Ohjattu maksujen kerääminen"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Maksupalveluntarjoaja"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Maksutunniste"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Maksutapahtuma"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Maksun käsittely epäonnistui"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "Vastaanotettu data, jonka maksutila on virheellinen: %s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Vastaanotetut tiedot, joista puuttuu maksutila."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "Vastaanotettu väärennettyjä maksupyyntötietoja."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "Ostajan viite"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "Verkkopalvelun käyttäjän API-avain"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "Webhookin HMAC-avain"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+"Adyenin käsittelemä summa tapahtumalle %s on eri kuin pyydetty summa. "
+"Luodaan toinen tapahtuma, jossa summa on oikea."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "API-päätepisteiden perus-URL-osoite"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"Tapahtuman lukeminen tai mitätöinti saattaa kestää muutaman hetken\n"
+"                    ennen kuin Adyen on käsitellyt sen. Tämän jälkeen "
+"tapahtuma näkyy Odoossa."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "Verkkopalvelun käyttäjän asiakasavain"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr "Tämän palveluntarjoajan kanssa käytettävän kauppiastilin koodi"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Tämän maksupalveluntarjoajan tekninen koodi."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "Tämän käyttötunnisteen omistavan kumppanin yksilöllinen viite"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "Maksusi hylättiin. Yritä uudelleen."
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fo.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fo.po
new file mode 100644
index 00000000..38274cba
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fo.po
@@ -0,0 +1,256 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 10.saas~18\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2017-09-20 09:53+0000\n"
+"Language-Team: Faroese (https://www.transifex.com/odoo/teams/41243/fo/)\n"
+"Language: fo\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fr.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fr.po
new file mode 100644
index 00000000..3f053b6f
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fr.po
@@ -0,0 +1,253 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Martin Trigaux, 2019
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-17 17:21+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: French \n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n > 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"Avertissement : Pour capturer le montant manuellement, vous "
+"devez également définir\n"
+"                    le Délai de capture sur manuel dans les paramètres de "
+"votre compte Adyen."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "Clé API"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "Préfixe URL API"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+"Une erreur est survenue lors du traitement de votre paiement. Veuillez "
+"réessayer."
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "Impossible d'afficher le formulaire de paiement"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "Clé Client"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Code"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "Nom d'affichage"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "Clé HMAC"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "A Adyen Tx"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ID"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "Données de paiement incorrectes"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "En savoir plus"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Compte marchand"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "Assistant de capture de paiement"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Fournisseur de paiement"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Jeton de paiement"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transaction"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Échec du traitement du paiement"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "Réception de données avec un statut de paiement invalide : %s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Données reçues avec statut de paiement manquant."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "Réception de données de demande de paiement falsifiées."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "Référence acheteur"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "La clé API de l'utilisateur du service web"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "La clé HMAC du webhook"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+"Le montant traité par Adyen pour la transaction %s est différent de celui "
+"demandé. Une autre transaction est créée avec le bon montant."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "L'URL de base pour les points de terminaison de l'API"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"La capture ou l'annulation de la transaction peut prendre quelques minutes "
+"pour être \n"
+"traitée par Adyen et reflétée dans Odoo."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "La clé client de l'utilisateur du service web"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr "Le code du compte marchand à utiliser avec ce fournisseur"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Le code technique de ce fournisseur de paiement."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "La référence unique du partenaire à qui appartient ce jeton"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "Votre paiement a été refusé. Veuillez réessayer."
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fr_CA.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fr_CA.po
new file mode 100644
index 00000000..fe95ab27
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/fr_CA.po
@@ -0,0 +1,257 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 10.saas~18\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2017-09-20 09:53+0000\n"
+"Language-Team: French (Canada) (https://www.transifex.com/odoo/teams/41243/"
+"fr_CA/)\n"
+"Language: fr_CA\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/gl.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/gl.po
new file mode 100644
index 00000000..20496125
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/gl.po
@@ -0,0 +1,256 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 10.saas~18\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2017-09-20 09:53+0000\n"
+"Language-Team: Galician (https://www.transifex.com/odoo/teams/41243/gl/)\n"
+"Language: gl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/gu.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/gu.po
new file mode 100644
index 00000000..841b3472
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/gu.po
@@ -0,0 +1,256 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~11.4\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2018-08-02 09:56+0000\n"
+"Language-Team: Gujarati (https://www.transifex.com/odoo/teams/41243/gu/)\n"
+"Language: gu\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/he.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/he.po
new file mode 100644
index 00000000..a61ae31f
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/he.po
@@ -0,0 +1,242 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_adyen
+#
+# Translators:
+# Martin Trigaux, 2019
+# ExcaliberX , 2019
+# Yihya Hugirat , 2019
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2019-08-26 09:12+0000\n"
+"Last-Translator: Yihya Hugirat , 2019\n"
+"Language-Team: Hebrew (https://www.transifex.com/odoo/teams/41243/he/)\n"
+"Language: he\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % "
+"1 == 0) ? 1: (n % 10 == 0 && n % 1 == 0 && n > 10) ? 2 : 3;\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "עסקת תשלום"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/hi.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/hi.po
new file mode 100644
index 00000000..c2ca6b58
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/hi.po
@@ -0,0 +1,256 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to set\n"
+"                    the Capture Delay to manual on your Adyen account settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"A request was sent to void the transaction with reference %(reference)s "
+"(%(provider)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s"
+" has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/hr.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/hr.po
new file mode 100644
index 00000000..76b3351e
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/hr.po
@@ -0,0 +1,242 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_adyen
+#
+# Translators:
+# Bole , 2019
+# Karolina Tonković , 2019
+# Tina Milas, 2019
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2019-08-26 09:12+0000\n"
+"Last-Translator: Tina Milas, 2019\n"
+"Language-Team: Croatian (https://www.transifex.com/odoo/teams/41243/hr/)\n"
+"Language: hr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transakcija plaćanja"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/hu.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/hu.po
new file mode 100644
index 00000000..ab9bb0d6
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/hu.po
@@ -0,0 +1,243 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Martin Trigaux, 2019
+# krnkris, 2019
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-29 19:46+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Hungarian \n"
+"Language: hu\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "API kulcs"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Kód"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Tudjon meg többet"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Kereskedelmi számla"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Fizetési szolgáltató"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Fizetési tranzakció"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/id.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/id.po
new file mode 100644
index 00000000..09a21898
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/id.po
@@ -0,0 +1,249 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Wahyu Setiawan , 2017
+# Bonny Useful , 2017
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 10.saas~18\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 02:37+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Indonesian \n"
+"Language: id\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"Warning: Untuk mendapatkan jumlah secara manual, Anda juga "
+"harus menetapkan\n"
+"                    Capture Delay ke manual pada pengaturan akun Adyen Anda."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "API Key"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "Awalan API URL"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr "Terjadi error pada pemrosesan pembayaran Anda. Silakan coba lagi."
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "Tidak dapat menampilkan formulir pembayaran"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "Client Key"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Kode"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "Nama Tampilan"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "HMAC Key"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "Memiliki Adyen Tx"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ID"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "Detail pembayaran tidak tepat"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Pelajari Lebih"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Akun Pedagang"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "Wizard Capture Pembayaran"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Penyedia Pembayaran"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Token Pembayaran"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transaksi pembayaran"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Pemrosesan pembayaran gagal"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "Menerima data dengan status pembayaran tidak valid: %s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Menerima data dengan status pembayaran yang hilang."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "Menerima data permintaan pembayaran yang diubah tanpa izin."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "Referensi Pembelanja"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "API key dari webservice user"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "HMAC key dari webhook"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+"Jumlah yang diproses Adyen untuk transaksi %s berbeda dari yang diminta. "
+"Transaksi lain dibuat dengan jumlah yang tepat."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "URL dasar untuk API endpoint"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"Pengambilan atau pembatalan transaksi mungkin membutuhkan beberapa menit\n"
+"                    untuk diproses Adyen dan ditunjukkan di Odoo."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "Client key dari webservice user"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr "Kode akun pedagang untuk digunakan dengan penyedia ini"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Kode teknis penyedia pembayaran ini."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "Referensi unik partner yang memiliki token ini"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "Pembayaran Anda ditolak. Silakan coba lagi."
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/is.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/is.po
new file mode 100644
index 00000000..a5f8f269
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/is.po
@@ -0,0 +1,260 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Bjorn Ingvarsson , 2018
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~11.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2018-08-24 09:21+0000\n"
+"Last-Translator: Bjorn Ingvarsson , 2018\n"
+"Language-Team: Icelandic (https://www.transifex.com/odoo/teams/41243/is/)\n"
+"Language: is\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/it.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/it.po
new file mode 100644
index 00000000..b76031a6
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/it.po
@@ -0,0 +1,256 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Sergio Zanchetta , 2019
+# Martin Trigaux, 2019
+# SebastianoPistore , 2019
+# Paolo Valier, 2019
+# Luigia Cimmino Caserta , 2019
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-17 17:20+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Italian \n"
+"Language: it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"Attenzione: per acquisire l'importo manualmente è "
+"necessario configurare \n"
+"                    il Tempo di acquisizione su manuale dalle impostazioni "
+"dell'account Adyen."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "Chiave API"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "Prefisso URL API"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+"Si è verificato un errore durante l'elaborazione di questo pagamento. "
+"Riprovalo più tardi."
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "Impossibile visualizzare il modulo di pagamento"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "Client Key"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Codice"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "Nome visualizzato"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "HMAC Key"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "Ha Tx Adyen"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ID"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "Dettagli di pagamento non corretti"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Scopri di più"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Account commerciante"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "Procedura guidata cattura pagamento"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Fornitore di pagamenti"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Token di pagamento"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transazione di pagamento"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Elaborazione del pagamento non riuscita"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "Dati ricevuti con stato di pagamento non valido: %s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Dati ricevuti con stato di pagamento mancante."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "Ricevuto dati di richiesta di pagamento manomessi."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "Riferimento acquirente"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "La chiave API dell'utente del servizio web"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "La chiave HMAC del webhook"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+"L'importo elaborato da Adyen per l'operazione %s è diverso da quello "
+"richiesto. È stata creata un'altra operazione con l'importo corretto."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "L'URL di base per gli endpoint API"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"L'acquisizione o l'annullamento dell'operazione potrebbe impiegare alcuni "
+"minuti per essere\n"
+"                    elaborata da Adyen e trasmessa a Odoo."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "La chiave del client dell'utente dei servizi web"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr "Il codice del conto commerciante da usare con il fornitore"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Codice tecnico del fornitore di pagamenti."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "Il riferimento unico del partner che possiede questo token"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "Il tuo pagamento è stato rifiutato. Riprovalo."
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ja.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ja.po
new file mode 100644
index 00000000..3ccac34b
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ja.po
@@ -0,0 +1,248 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Yoshi Tashiro , 2018
+# 高木正勝 , 2018
+# Norimichi Sugimoto , 2018
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~11.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-14 21:20+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Japanese \n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"警告:金額を手動でキャプチャするには、\n"
+"                    アカウント設定で遅延キャプチャも設定する必要があります。"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "APIキー"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "API URL プレフィクス"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr "支払処理中にエラーが発生しました。再度試して下さい。"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "支払フォームを表示できません"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "クライアントキー"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "コード"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "表示名"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "HMACキー"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "Adyen Txあり"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ID"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "不正な支払詳細"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "もっと知る"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "加盟店アカウント"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "支払キャプチャウィザード"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "決済プロバイダー"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "支払トークン"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "決済トランザクション"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "支払処理に失敗しました"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "無効な支払ステイタス: %sのデータを受信しました。"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "支払ステータスが欠落しているデータを受信しました。"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "改ざんされた支払依頼データを受信しました。"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "買物客参照"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "ウェブサービスユーザのAPIキー"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "WebhookのHMACキー"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr "Adyonが処理した取引%s金額が、要求された金額と異なります。正しい金額で別の取引"
+"が作成されます。"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "APIエンドポイント用ベースURL"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"取引のキャプチャまたはボイドがAdyenで処理され、Odooに反映されるまでに\n"
+"数分かかる場合があります。"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "ウェブサービスユーザのクライアントキー"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr "このプロバイダを使用するために使われる加盟店アカウントのコード"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "この決済プロバイダーのテクニカルコード。"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "このトークンを所有している取引先の一意参照"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "支払が却下されました。もう一度試して下さい。"
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ka.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ka.po
new file mode 100644
index 00000000..7b74bfe7
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ka.po
@@ -0,0 +1,256 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 10.saas~18\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2017-09-20 09:53+0000\n"
+"Language-Team: Georgian (https://www.transifex.com/odoo/teams/41243/ka/)\n"
+"Language: ka\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/kab.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/kab.po
new file mode 100644
index 00000000..d83c2f52
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/kab.po
@@ -0,0 +1,256 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 10.saas~18\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2017-09-20 09:53+0000\n"
+"Language-Team: Kabyle (https://www.transifex.com/odoo/teams/41243/kab/)\n"
+"Language: kab\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/km.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/km.po
new file mode 100644
index 00000000..28d0f40a
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/km.po
@@ -0,0 +1,256 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~11.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2018-09-18 09:49+0000\n"
+"Language-Team: Khmer (https://www.transifex.com/odoo/teams/41243/km/)\n"
+"Language: km\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ko.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ko.po
new file mode 100644
index 00000000..b9048d52
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ko.po
@@ -0,0 +1,247 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# 최재호 , 2018
+# Linkup , 2018
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~11.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 04:41+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Korean \n"
+"Language: ko\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"경고: 금액을 수기로 매입하려면, Adyen 계정 설정에서\n"
+"                    매입 지연을 수동으로 설정해야 합니다."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "API 키"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "API URL 접두사"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr "결제를 처리하는 동안 오류가 발생했습니다. 다시 시도해 주세요."
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "결제 양식을 표시할 수 없습니다."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "클라이언트 키"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "코드"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "표시명"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "HMAC 키"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "Adyen Tx 있음"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ID"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "결제 정보가 잘못되었습니다."
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "추가 정보"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "상인 계정"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "결제 매입 마법사"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "결제대행업체"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "결제 토큰"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "지불 거래"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "결제 프로세스 실패"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "잘못된 결제 상태의 데이터가 수신되었습니다: %s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "결제 상태가 누락된 데이터가 수신되었습니다."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "변조된 결제 요청 데이터가 수신되었습니다."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "구매자 참조"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "웹서비스 사용자의 API 키"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "webhook의 HMAC 키"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr "거래 %s에 대해 Adyen에서 처리한 금액이 요청된 금액과 일치하지 않습니다. "
+"올바른 금액으로 다른 거래가 생성됩니다."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "API 엔드포인트의 기본 URL"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"거래의 매입 또는 무효화는 Adyen에서 처리되며, Odoo에 반영되기 까지\n"
+"                    몇 분 이상 소요될 수 있습니다."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "웹서비스 사용자의 클라이언트 키"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr "이 공급업체에서 사용할 판매자 계정 코드입니다."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "이 결제대행업체의 기술 코드입니다."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "이 토큰을 소유하고 있는 협력사의 고유 참조"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "결제가 승인되지 않았습니다. 다시 시도해 주세요."
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ku.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ku.po
new file mode 100644
index 00000000..c2ca6b58
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ku.po
@@ -0,0 +1,256 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to set\n"
+"                    the Capture Delay to manual on your Adyen account settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"A request was sent to void the transaction with reference %(reference)s "
+"(%(provider)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s"
+" has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/lb.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/lb.po
new file mode 100644
index 00000000..10e9939e
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/lb.po
@@ -0,0 +1,257 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2019-08-26 09:12+0000\n"
+"Language-Team: Luxembourgish (https://www.transifex.com/odoo/teams/41243/"
+"lb/)\n"
+"Language: lb\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/lo.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/lo.po
new file mode 100644
index 00000000..37845d46
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/lo.po
@@ -0,0 +1,256 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 10.saas~18\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2017-09-20 09:53+0000\n"
+"Language-Team: Lao (https://www.transifex.com/odoo/teams/41243/lo/)\n"
+"Language: lo\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/lt.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/lt.po
new file mode 100644
index 00000000..15ad6c5a
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/lt.po
@@ -0,0 +1,245 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Silvija Butko , 2019
+# digitouch UAB , 2019
+# Linas Versada , 2019
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 18:37+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Lithuanian \n"
+"Language: lt\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < "
+"11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 :"
+" n % 1 != 0 ? 2: 3);\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "API raktas"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Kodas"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "Rodomas pavadinimas"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ID"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Sužinoti daugiau"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Pardavėjo sąskaita"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Mokėjimo paslaugos tiekėjas"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Mokėjimo raktas"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Mokėjimo operacija"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/lv.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/lv.po
new file mode 100644
index 00000000..47b2090e
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/lv.po
@@ -0,0 +1,257 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 10.saas~18\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2017-09-20 09:53+0000\n"
+"Language-Team: Latvian (https://www.transifex.com/odoo/teams/41243/lv/)\n"
+"Language: lv\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : "
+"2);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/mk.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/mk.po
new file mode 100644
index 00000000..aa601c76
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/mk.po
@@ -0,0 +1,256 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 10.saas~18\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2017-09-20 09:53+0000\n"
+"Language-Team: Macedonian (https://www.transifex.com/odoo/teams/41243/mk/)\n"
+"Language: mk\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/mn.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/mn.po
new file mode 100644
index 00000000..4e92b316
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/mn.po
@@ -0,0 +1,240 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_adyen
+#
+# Translators:
+# Baskhuu Lodoikhuu , 2019
+# Martin Trigaux, 2019
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2019-08-26 09:12+0000\n"
+"Last-Translator: Martin Trigaux, 2019\n"
+"Language-Team: Mongolian (https://www.transifex.com/odoo/teams/41243/mn/)\n"
+"Language: mn\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Худалдагчийн Бүртгэл"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Төлбөрийн гүйлгээ"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/my.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/my.po
new file mode 100644
index 00000000..c2ca6b58
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/my.po
@@ -0,0 +1,256 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to set\n"
+"                    the Capture Delay to manual on your Adyen account settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"A request was sent to void the transaction with reference %(reference)s "
+"(%(provider)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s"
+" has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/nb.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/nb.po
new file mode 100644
index 00000000..157aabe4
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/nb.po
@@ -0,0 +1,242 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Martin Trigaux, 2019
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 18:37+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Norwegian Bokmål \n"
+"Language: nb\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "API-nøkkel"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Kode"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "Visningsnavn"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ID"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Betalingsleverandør"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Betalingstoken"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Betalingstransaksjon"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ne.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ne.po
new file mode 100644
index 00000000..23585d61
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ne.po
@@ -0,0 +1,256 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 10.saas~18\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2017-09-20 09:53+0000\n"
+"Language-Team: Nepali (https://www.transifex.com/odoo/teams/41243/ne/)\n"
+"Language: ne\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/nl.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/nl.po
new file mode 100644
index 00000000..b50fae0c
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/nl.po
@@ -0,0 +1,253 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Martin Trigaux, 2019
+# Erwin van der Ploeg , 2019
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-14 08:06+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Dutch \n"
+"Language: nl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"Waarschuwing: Om het bedrag handmatig vast te leggen, moet "
+"je ook \n"
+"                    de vastleggingstermijn handmatig bepalen in de "
+"instellingen van je Adyen account."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "API key"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "URL-voorvoegsel API"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+"Er is een fout opgetreden tijdens de verwerking van je betaling. Probeer het "
+"opnieuw."
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "Kan het betaalformulier niet weergeven"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "Clientsleutel"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Code"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "Schermnaam"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "HMAC-sleutel"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "Heeft Adyen Tx"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ID"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "Onjuiste betaalgegevens"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Leer meer"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Handelaarsaccount"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "Wizard voor het vastleggen van betalingen"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Betaalprovider"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Betalingstoken"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Betalingstransactie"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Betalingsverwerking mislukt"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "Gegevens ontvangen met ongeldige betalingsstatus: %s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Gegevens ontvangen met ontbrekende betalingsstatus."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "Ontvangen van geknoeid betalingsverzoekgegevens."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "Klantenreferentie"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "De API key van de webservicegebruiker"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "De HMAC-sleutel van de webhook"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+"Het door Adyen verwerkte bedrag voor de transactie %s verschilt van het "
+"gevraagde bedrag. Een andere transactie is aangemaakt met het juiste bedrag."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "De basis-URL voor de API-eindpunten"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"Het vasleggen of annuleren van de transactie kan een paar minuten duren\n"
+"                    om te worden verwerkt door Adyen en weergegeven in Odoo."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "De clientsleutel van de webservicegebruiker"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+"De code van het verkopersaccount die bij deze provider moet worden gebruikt"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "De technische code van deze betaalprovider."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "De unieke referentie van de partner die deze token bezit"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "Je betaling is geweigerd. Probeer het opnieuw."
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/payment_adyen.pot b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/payment_adyen.pot
new file mode 100644
index 00000000..fb77b080
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/payment_adyen.pot
@@ -0,0 +1,233 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 19.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-11 13:58+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to set\n"
+"                    the Capture Delay to manual on your Adyen account settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/pl.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/pl.po
new file mode 100644
index 00000000..bf149896
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/pl.po
@@ -0,0 +1,246 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Martin Trigaux, 2019
+# Dariusz Żbikowski , 2019
+# Piotr Szlązak , 2019
+# Maja Stawicka , 2019
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 10:05+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Polish \n"
+"Language: pl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && ("
+"n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && "
+"n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "Klucz API"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr "Wystąpił błąd podczas przetwarzania płatności. Spróbuj ponownie."
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Kod"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "Nazwa wyświetlana"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ID"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Dowiedz się więcej"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Merchant konto"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "Kreator przechwytywania płatności"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Dostawca Płatności"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Token płatności"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transakcja płatności"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Przetwarzanie płatności nie powiodło się"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Kod techniczny tego dostawcy usług płatniczych."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/pt.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/pt.po
new file mode 100644
index 00000000..cd568e06
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/pt.po
@@ -0,0 +1,248 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 18:37+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Portuguese \n"
+"Language: pt\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"Aviso: Para capturar o valor manualmente, você também "
+"precisa definir\n"
+"                    o Atraso de captura como manual nas definições da sua "
+"conta Adyen."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "Chave de API"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "Prefixo do URL da API"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+"Ocorreu um erro durante o processamento do seu pagamento. Tente novamente."
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "Não é possível exibir o formulário de pagamento"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "Chave do cliente"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Código"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "Chave HMAC"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "Tem transação Adyen"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "Informações de pagamento incorretas"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Saiba mais"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Conta comercial"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "Assistente de captura de pagamentos"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Provedor de serviços de pagamento"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Token de pagamento"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transação do pagamento"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Falha no processamento do pagamento"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "Dados recebidos com estado de pagamento inválido: %s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Dados recebidos sem estado de pagamento."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "Dados da solicitação de pagamento recebidos alterados."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "Referência do comprador"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "A chave da API do usuário do serviço web"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "A chave HMAC do webhook"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+"O valor processado pelo Adyen para a transação %s é diferente do valor "
+"solicitado. Outra transação foi criada com o valor correto."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "O URL de base dos endpoints da API"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"A captura ou anulação da transação pode levar alguns minutos para ser\n"
+"                    processada pelo Adyen e refletida no Odoo."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "A chave do cliente do usuário do serviço web"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr "O código da conta comercial a ser usada com este provedor"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "O código técnico deste provedor de pagamento."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "A referência exclusiva do usuário a quem pertence o token"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "Seu pagamento foi recusado. Tente novamente."
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/pt_BR.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/pt_BR.po
new file mode 100644
index 00000000..c045c449
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/pt_BR.po
@@ -0,0 +1,256 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Rodrigo de Almeida Sottomaior Macedo , 2019
+# Hildeberto Abreu Magalhães , 2019
+# danimaribeiro , 2019
+# Martin Trigaux, 2019
+# Mateus Lopes , 2019
+# grazziano , 2019
+# "Tiffany Chang (tic)" , 2025.
+# "Maitê Dietze (madi)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-24 19:22+0000\n"
+"Last-Translator: \"Maitê Dietze (madi)\" \n"
+"Language-Team: Portuguese (Brazil) \n"
+"Language: pt_BR\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n > 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"Aviso: Para capturar o valor manualmente, você também "
+"precisa definir\n"
+"                    o Atraso de captura como manual nas definições da sua "
+"conta Adyen."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr "Foi enviado um pedido para anular a transação %(reference)s."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "Chave de API"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "Prefixo do URL da API"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+"Ocorreu um erro durante o processamento do seu pagamento. Tente novamente."
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "Não é possível exibir o formulário de pagamento"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "Chave do cliente"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Código"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "Nome exibido"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "Chave HMAC"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "Tem transação Adyen"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ID"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "Informações de pagamento incorretas"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Saiba mais"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Conta comercial"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "Assistente de captura de pagamentos"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Provedor de serviços de pagamento"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Token de pagamento"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transação do pagamento"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Falha no processamento do pagamento"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "Dados recebidos com estado de pagamento inválido: %s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Dados recebidos sem estado de pagamento."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "Dados da solicitação de pagamento recebidos alterados."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "Referência do comprador"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "A chave da API do usuário do serviço web"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "A chave HMAC do webhook"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+"O valor processado pelo Adyen para a transação %s é diferente do valor "
+"solicitado. Outra transação foi criada com o valor correto."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "O URL de base dos endpoints da API"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"A captura ou anulação da transação pode levar alguns minutos para ser\n"
+"                    processada pelo Adyen e refletida no Odoo."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "A chave do cliente do usuário do serviço web"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr "O código da conta comercial a ser usada com este provedor"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "O código técnico deste provedor de pagamento."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "A referência exclusiva do usuário a quem pertence o token"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "Seu pagamento foi recusado. Tente novamente."
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ro.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ro.po
new file mode 100644
index 00000000..548b6987
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ro.po
@@ -0,0 +1,236 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2019-08-26 09:12+0000\n"
+"Language-Team: Romanian (https://www.transifex.com/odoo/teams/41243/ro/)\n"
+"Language: ro\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?"
+"2:1));\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ru.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ru.po
new file mode 100644
index 00000000..fc9cfbd3
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/ru.po
@@ -0,0 +1,288 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 02:35+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Russian \n"
+"Language: ru\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
+"n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || ("
+"n%100>=11 && n%100<=14)? 2 : 3);\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"Внимание: Чтобы зафиксировать сумму вручную, вам также "
+"необходимо установить\n"
+"                    задержку захвата вручную в настройках аккаунта Adyen."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "Ключ API"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "Префикс URL-адреса API"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+"Во время обработки вашего платежа произошла ошибка. Пожалуйста, попробуйте "
+"еще раз."
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "Невозможно отобразить форму оплаты"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "Ключ Клиента"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Код"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "Ключ HMAC"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "Has Adyen Tx"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "Неверные платежные реквизиты"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Узнать больше"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Мерчант аккаунт"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "Мастер захвата платежей"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Поставщик платежей"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Платежный токен"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Платеж"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Обработка платежа не удалась"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "Получены данные с недопустимым состоянием платежа: %s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Получены данные с отсутствующим состоянием платежа."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "Получение поддельных данных запроса на оплату."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "Ссылка на покупателя"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "API-ключ пользователя веб-сервиса"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "Ключ HMAC веб-крючка"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+"Сумма, обработанная Adyen для транзакции %s, отличается от запрашиваемой. "
+"Создается другая транзакция с правильной суммой."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "Базовый URL для конечных точек API"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"Захват или отмена транзакции может занять несколько минут, чтобы быть\n"
+"                    обработки в Adyen и отражения в Odoo."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "Клиентский ключ пользователя веб-сервиса"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr "Код торгового счета для использования с данным провайдером"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Технический код данного провайдера платежей."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "Уникальная ссылка на партнера, владеющего этим токеном"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "Ваш платеж был отклонен. Пожалуйста, попробуйте еще раз."
+
+#~ msgid "A request was sent to void the transaction with reference %s (%s)."
+#~ msgstr ""
+#~ "Был отправлен запрос на аннулирование транзакции со ссылкой %s (%s)."
+
+#~ msgid "Could not establish the connection to the API."
+#~ msgstr "Не удалось установить соединение с API."
+
+#~ msgid "No transaction found matching reference %s."
+#~ msgstr "Не найдено ни одной транзакции, соответствующей ссылке %s."
+
+#~ msgid "Received data for child transaction with missing transaction values"
+#~ msgstr ""
+#~ "Полученные данные для дочерней транзакции с отсутствующими значениями "
+#~ "транзакций"
+
+#~ msgid "Received data with missing merchant reference"
+#~ msgstr "Полученные данные с отсутствующей ссылкой на продавца"
+
+#~ msgid "The capture of the transaction with reference %s failed."
+#~ msgstr "Захват транзакции со ссылкой %s не удался."
+
+#~ msgid ""
+#~ "The capture request of %(amount)s for the transaction with reference %"
+#~ "(ref)s has been requested (%(provider_name)s)."
+#~ msgstr ""
+#~ "Запрос на захват %(amount)s для транзакции с ссылкой %(ref)s был запрошен "
+#~ "(%(provider_name)s)."
+
+#~ msgid "The communication with the API failed. Details: %s"
+#~ msgstr "Не удалось установить связь с API. Подробности: %s"
+
+#~ msgid "The transaction is not linked to a token."
+#~ msgstr "Транзакция не привязана к токену."
+
+#~ msgid "The void of the transaction with reference %s failed."
+#~ msgstr "Не удалось выполнить транзакцию со ссылкой %s."
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sk.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sk.po
new file mode 100644
index 00000000..f8ad5ded
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sk.po
@@ -0,0 +1,262 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Pavol Krnáč , 2018
+# Jaroslav Bosansky , 2018
+# Miroslav Fic , 2018
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~11.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2018-09-18 09:49+0000\n"
+"Last-Translator: Miroslav Fic , 2018\n"
+"Language-Team: Slovak (https://www.transifex.com/odoo/teams/41243/sk/)\n"
+"Language: sk\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n "
+">= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Účet obchodníka"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Platobná transakcia"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sl.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sl.po
new file mode 100644
index 00000000..b62be34c
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sl.po
@@ -0,0 +1,240 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 10.saas~18\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 21:17+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Slovenian \n"
+"Language: sl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || "
+"n%100==4 ? 2 : 3;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "API ključ"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Oznaka"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "Prikazani naziv"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ID"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Več o tem"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Račun trgovca"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Ponudnik plačil"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Plačilni žeton"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Plačilna transakcija"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sq.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sq.po
new file mode 100644
index 00000000..03d59463
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sq.po
@@ -0,0 +1,256 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 10.saas~18\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-10-26 21:56+0000\n"
+"PO-Revision-Date: 2017-09-20 09:53+0000\n"
+"Language-Team: Albanian (https://www.transifex.com/odoo/teams/41243/sq/)\n"
+"Language: sq\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction with reference %s (%s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data for child transaction with missing transaction values"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing merchant reference"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for the transaction with reference %(ref)s "
+"has been requested (%(provider_name)s)."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction with reference %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sr@latin.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sr@latin.po
new file mode 100644
index 00000000..cfa3a685
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sr@latin.po
@@ -0,0 +1,236 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~11.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2018-09-18 09:49+0000\n"
+"Language-Team: Serbian (https://www.transifex.com/odoo/teams/41243/sr/)\n"
+"Language: sr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sv.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sv.po
new file mode 100644
index 00000000..30f52e88
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/sv.po
@@ -0,0 +1,252 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Kristoffer Grundström , 2018
+# Anders Wallenquist , 2018
+# Daniel Forslund , 2018
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~11.4\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 21:38+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Swedish \n"
+"Language: sv\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"Varning: För att fånga beloppet manuellt måste du också "
+"ställa in\n"
+"                    Capture Delay till manuell i inställningarna för ditt "
+"Adyen-konto."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "API-nyckel"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "Prefix för API-URL"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+"Ett fel inträffade under behandlingen av din betalning. Vänligen försök igen."
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "Det går inte att visa betalningsformuläret"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "Kundnyckel"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Kod"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "Visningsnamn"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "HMAC-nyckel"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "Har Adyen Tx"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ID"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "Felaktiga betalningsuppgifter"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Läs mer"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Handelskonto"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "Guiden för att ta emot betalningar"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Betalningsleverantör"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Betalnings-token"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Betalningstransaktion"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Betalningshanteringen misslyckades"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "Mottagen data med ogiltigt betalningsstatus: %s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Mottagen data med saknad betalningsstatus."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "Mottagit manipulerade uppgifter om betalningsbegäran."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "Referens för shoppare"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "API-nyckeln för webbtjänstens användare"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "HMAC-nyckeln för webhooken"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+"Det belopp som Adyen behandlade för transaktionen %s skiljer sig från det "
+"begärda beloppet. En annan transaktion skapas med rätt belopp."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "Bas-URL för API-slutpunkterna"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"Det kan ta några minuter innan transaktionen registreras eller annulleras\n"
+"                    behandlas av Adyen och återspeglas i Odoo."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "Klientnyckel för användaren av webbtjänsten"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr "Koden för det handelskonto som ska användas med den här leverantören"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Den tekniska koden för denna betalningsleverantör."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "Den unika referensen för partnern som äger denna pollett"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "Din betalning har avvisats. Vänligen försök igen."
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/th.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/th.po
new file mode 100644
index 00000000..567908ca
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/th.po
@@ -0,0 +1,247 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Khwunchai Jaengsawang , 2018
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~11.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 21:22+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Thai \n"
+"Language: th\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"คำเตือน: เพื่อทำการตัดวงเงินด้วยตนเอง คุณยังต้อง\n"
+"                   ตั้งค่าการตัดวงเงินเป็นแบบกำหนดเองในการตั้งค่าบัญชี Adyen ของคุณด้วย"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "คีย์ API"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "คำนำหน้า URL API"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr "เกิดข้อผิดพลาดระหว่างการประมวลผลการชำระเงินของคุณ กรุณาลองใหม่อีกครั้ง"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "ไม่สามารถแสดงแบบฟอร์มการชำระเงินได้"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "รหัสลูกค้า"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "โค้ด"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "แสดงชื่อ"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "รหัส HMAC"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "มี Adyen Tx"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ไอดี"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "รายละเอียดการชำระเงินไม่ถูกต้อง"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "เรียนรู้เพิ่มเติม"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "บัญชีการค้า"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "ตัวช่วยสร้างการตัดวงเงินการชำระเงิน"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "ผู้ให้บริการชำระเงิน"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "โทเค็นการชำระเงิน"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "ธุรกรรมสำหรับการชำระเงิน"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "การประมวลผลการชำระเงินล้มเหลว"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "ข้อมูลที่ได้รับมีสถานะการชำระเงินไม่ถูกต้อง: %s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "ได้รับข้อมูลโดยไม่มีสถานะการชำระเงิน"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "ได้รับข้อมูลคำขอการชำระเงินที่ถูกแก้ไข"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "การอ้างอิงผู้ซื้อ"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "คีย์ API ของผู้ใช้บริการเว็บ"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "คีย์ HMAC ของเว็บฮุค"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+"จำนวนเงินที่ Adyen ประมวลผลสำหรับธุรกรรม %s แตกต่างจากจำนวนเงินที่ร้องขอ "
+"ธุรกรรมอื่นถูกสร้างขึ้นด้วยจำนวนเงินที่ถูกต้อง"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "URL พื้นฐานสำหรับจุดสิ้นสุด API"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"การยึดหรือทำให้ธุรกรรมเป็นโมฆะอาจใช้เวลาสักครู่\n"
+"                    ในการประมวลผลโดย Adyen และแสดงใน Odoo"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "รหัสลูกค้าของผู้ใช้บริการเว็บ"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr "รหัสของบัญชีผู้ค้าที่จะใช้กับผู้ให้บริการรายนี้"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "รหัสทางเทคนิคของผู้ให้บริการชำระเงินรายนี้"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "ข้อมูลอ้างอิงเฉพาะของพาร์ทเนอร์ที่เป็นเจ้าของโทเค็นนี้"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "การชำระเงินของคุณถูกปฏิเสธ กรุณาลองใหม่อีกครั้ง"
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/tr.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/tr.po
new file mode 100644
index 00000000..502abb34
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/tr.po
@@ -0,0 +1,245 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Ediz Duman , 2019
+# Ayhan KIZILTAN , 2019
+# Martin Trigaux, 2019
+# Ahmet Altinisik , 2019
+# Umur Akın , 2019
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 02:33+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Turkish \n"
+"Language: tr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "API Anahtarı"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr "Ödemenizin işlenmesi sırasında bir hata oluştu. Lütfen tekrar deneyin."
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "İstemci Anahtarı"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Kod"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "HMAC Anahtarı"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Daha Fazla Bilgi"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Ticari Kimliği (Merchant ID)"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Ödeme Sağlayıcı"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Ödeme Belirteci"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Ödeme İşlemi"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Ödeme işleme başarısız oldu"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "Geçersiz ödeme durumuyla veri alındı: %s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Ödeme durumu eksik olan veriler alındı."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "Üzerinde oynanmış ödeme isteği verileri alındı."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "Alışveriş Referansı"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "Web hizmeti kullanıcısının API anahtarı"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "Web kancasının HMAC tuşu"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "Web hizmeti kullanıcısının istemci anahtarı"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Bu ödeme sağlayıcısının teknik kodu."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "Bu belirtecin sahibi olan iş ortağının benzersiz referansı"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "Ödemeniz reddedildi. Lütfen tekrar deneyin."
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/uk.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/uk.po
new file mode 100644
index 00000000..9fd9ecfe
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/uk.po
@@ -0,0 +1,243 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_adyen
+#
+# Translators:
+# Martin Trigaux, 2019
+# Alina Lisnenko , 2019
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2019-08-26 09:12+0000\n"
+"Last-Translator: Alina Lisnenko , 2019\n"
+"Language-Team: Ukrainian (https://www.transifex.com/odoo/teams/41243/uk/)\n"
+"Language: uk\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != "
+"11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % "
+"100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || "
+"(n % 100 >=11 && n % 100 <=14 )) ? 2: 3);\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Комерційний обліковий запис"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Платіжна операція"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/vi.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/vi.po
new file mode 100644
index 00000000..2b3a17ab
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/vi.po
@@ -0,0 +1,253 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Nancy Momoland , 2019
+# Duy BQ , 2019
+# Dung Nguyen Thi , 2019
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 02:34+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Vietnamese \n"
+"Language: vi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"Cảnh báo: Để thu hồi số tiền theo cách thủ công, bạn cũng "
+"cần đặt\n"
+"                    Độ trễ thu hồi thành thủ công trên cài đặt tài khoản "
+"Adyen của mình."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "Mã khóa API"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "Tiền tố URL API"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr ""
+"Đã xảy ra lỗi trong quá trình xử lý khoản thanh toán của bạn. Vui lòng thử "
+"lại."
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "Không thể hiển thị biểu mẫu thanh toán"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "Mã khóa khách hàng"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "Mã"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "Tên hiển thị"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "Khoá HMAC"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "Có Adyen Tx"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ID"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "Thông thanh toán không chính xác"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "Tìm hiểu thêm"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "Tài khoản người bán"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "Công cụ thu hồi thanh toán"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "Nhà cung cấp dịch vụ thanh toán"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "Token thanh toán"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Giao dịch thanh toán"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Xử lý thanh toán không thành công"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "Dữ liệu đã nhận với trạng thái thanh toán không hợp lệ: %s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Dữ liệu đã nhận bị thiếu trạng thái thanh toán."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "Dữ liệu yêu cầu thanh toán giả mạo đã nhận."
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "Mã người mua"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "Mã khóa API của người dùng dịch vụ web"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "Khoá HMAC của webhook"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+"Số tiền được Adyen xử lý cho giao dịch %s khác với số tiền được yêu cầu. Một "
+"giao dịch khác được tạo với số tiền chính xác."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "URL cơ sở cho endpoint API"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"Việc thu hồi hoặc vô hiệu giao dịch có thể mất vài phút để được\n"
+"                    xử lý qua Adyen và phản ánh trong Odoo."
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "Mã khóa khách hàng của người dùng dịch vụ web"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr "Mã tài khoản người bán để sử dụng với nhà cung cấp này"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Mã kỹ thuật của nhà cung cấp dịch vụ thanh toán này."
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "Mã duy nhất của đối tác sở hữu token này"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "Khoản thanh toán của bạn đã bị từ chối. Vui lòng thử lại."
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/zh_CN.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/zh_CN.po
new file mode 100644
index 00000000..9b92a2c7
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/zh_CN.po
@@ -0,0 +1,246 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Martin Trigaux, 2019
+# inspur qiuguodong , 2019
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~12.5\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 15:26+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Chinese (Simplified Han script) \n"
+"Language: zh_CN\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"警告: 要手动捕获金额,您还需要\n"
+"                    在 Adyen 账户设置中将捕获延迟设置为手动。"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "API密钥"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "API URL 前缀"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr "在处理您的付款过程中发生了一个错误。请再试一次。"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "无法显示付款表单"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "客户端密钥"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "代码"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "显示名称"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "HMAC密钥"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "有 Adyen Tx"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "ID"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "付款信息不正确"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "了解更多"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "商业帐户"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "支付捕获向导"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "支付提供商"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "支付令牌"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "付款交易"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "付款处理失败"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "收到的数据为无效的支付状态:%s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "收到的数据中缺少支付状态。"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "收到了被篡改的付款请求数据。"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "购物者参考"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "网页服务用户的API密钥"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "Webhook的HMAC密钥"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr "Adyen 处理的交易%s金额与所请求金额不同。另一个交易已创建,并且金额正确。"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "应用程序接口端点的基本 URL"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"交易生效或作废可能需要几分钟时间\n"
+"才能由 Adyen 处理并反馈在 Odoo 中。"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "网络服务用户的客户密钥"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr "该提供商的商户账户代码"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "该支付提供商的技术代码。"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "拥有此令牌的合作伙伴的唯一编号"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "您的付款被拒绝。请再试一次。"
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/zh_TW.po b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/zh_TW.po
new file mode 100644
index 00000000..97424c2a
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/i18n/zh_TW.po
@@ -0,0 +1,281 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_adyen
+#
+# Translators:
+# Wil Odoo, 2025
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~18.3\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:58+0000\n"
+"PO-Revision-Date: 2025-09-16 08:10+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Chinese (Traditional Han script) \n"
+"Language: zh_TW\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid ""
+"Warning: To capture the amount manually, you also need to "
+"set\n"
+"                    the Capture Delay to manual on your Adyen account "
+"settings."
+msgstr ""
+"警告: 要手動捕捉金額,你仍需要在 \n"
+"                    Adyen 帳戶設定中,將捕捉延遲設為手動。"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "A request was sent to void the transaction %(reference)s."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_key
+msgid "API Key"
+msgstr "API 金鑰"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "API URL Prefix"
+msgstr "API 網址字首"
+
+#. module: payment_adyen
+#: model:ir.model.fields.selection,name:payment_adyen.selection__payment_provider__code__adyen
+msgid "Adyen"
+msgstr "Adyen"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment. Please try again."
+msgstr "處理付款過程中發生錯誤,請再試一次。"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Cannot display the payment form"
+msgstr "未能顯示付款表單"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_client_key
+msgid "Client Key"
+msgstr "客戶端密鑰"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__code
+msgid "Code"
+msgstr "代碼"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__display_name
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "顯示名稱"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "HMAC Key"
+msgstr "Hmac密鑰"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__has_adyen_tx
+msgid "Has Adyen Tx"
+msgstr "有Adyen Tx"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_capture_wizard__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__id
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_transaction__id
+msgid "ID"
+msgstr "識別號"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Incorrect payment details"
+msgstr "付款資料不正確"
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_provider_form
+msgid "Learn More"
+msgstr "瞭解更多"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "Merchant Account"
+msgstr "商業帳戶"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_capture_wizard
+msgid "Payment Capture Wizard"
+msgstr "付款捕捉精靈"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_provider
+msgid "Payment Provider"
+msgstr "付款服務商"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_token
+msgid "Payment Token"
+msgstr "付款代碼(token)"
+
+#. module: payment_adyen
+#: model:ir.model,name:payment_adyen.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "付款交易"
+
+#. module: payment_adyen
+#. odoo-javascript
+#: code:addons/payment_adyen/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "付款處理失敗"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with invalid payment state: %s"
+msgstr "收到的數據處於無效的付款狀態:%s"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "收到的數據中缺漏付款狀態。"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/controllers/main.py:0
+msgid "Received tampered payment request data."
+msgstr "收到被篡改的付款請求數據。"
+
+#. module: payment_adyen
+#: model:ir.model.fields,field_description:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "Shopper Reference"
+msgstr "購物者參考"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_key
+msgid "The API key of the webservice user"
+msgstr "網頁服務用戶 API 密鑰"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_hmac_key
+msgid "The HMAC key of the webhook"
+msgstr "網絡鈎子 HMAC 密鑰"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The amount processed by Adyen for the transaction %s is different than the "
+"one requested. Another transaction is created with the correct amount."
+msgstr ""
+"Adyen 處理交易 %s 的金額,與所請求金額不同。已建立金額正確的另一項交易。"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_api_url_prefix
+msgid "The base URL for the API endpoints"
+msgstr "API 終端點基礎網址"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The capture of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#: model_terms:ir.ui.view,arch_db:payment_adyen.payment_capture_wizard_view_form
+msgid ""
+"The capture or void of the transaction might take a few minutes to be\n"
+"                    processed by Adyen and reflected in Odoo."
+msgstr ""
+"交易捕捉或作廢可能需要幾分鐘時間,\n"
+"                    以由 Adyen 處理並反映在 Odoo 中。"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid ""
+"The capture request of %(amount)s for transaction %(ref)s has been sent."
+msgstr ""
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_client_key
+msgid "The client key of the webservice user"
+msgstr "網絡服務用戶的客戶密鑰"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__adyen_merchant_account
+msgid "The code of the merchant account to use with this provider"
+msgstr "此服務商的商戶賬戶代碼"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "此付款服務商的技術代碼。"
+
+#. module: payment_adyen
+#: model:ir.model.fields,help:payment_adyen.field_payment_token__adyen_shopper_reference
+msgid "The unique reference of the partner owning this token"
+msgstr "擁有此權杖的合作夥伴的唯一參考編號"
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "The void of the transaction %s failed."
+msgstr ""
+
+#. module: payment_adyen
+#. odoo-python
+#: code:addons/payment_adyen/models/payment_transaction.py:0
+msgid "Your payment was refused. Please try again."
+msgstr "你的付款被拒絕。請再試一次。"
+
+#~ msgid ""
+#~ "A request was sent to void the transaction with reference %(reference)s (%"
+#~ "(provider)s)."
+#~ msgstr "已發送交易作廢請求,參考:%(reference)s(%(provider)s)。"
+
+#~ msgid "Could not establish the connection to the API."
+#~ msgstr "無法建立與 API 的連線。"
+
+#~ msgid "No transaction found matching reference %s."
+#~ msgstr "沒有找到匹配參考 %s 的交易。"
+
+#~ msgid "Received data for child transaction with missing transaction values"
+#~ msgstr "收到的子級交易數據缺漏交易數值"
+
+#~ msgid "Received data with missing merchant reference"
+#~ msgstr "收到資料,但缺漏商家參考"
+
+#~ msgid "The capture of the transaction with reference %s failed."
+#~ msgstr "交易(參考:%s)捕捉失敗。"
+
+#~ msgid ""
+#~ "The capture request of %(amount)s for the transaction with reference %"
+#~ "(ref)s has been requested (%(provider_name)s)."
+#~ msgstr "已請求捕捉金額 %(amount)s(交易參考:%(ref)s)(%(provider_name)s)。"
+
+#~ msgid "The communication with the API failed. Details: %s"
+#~ msgstr "與 API 通訊失敗。詳情:%s"
+
+#~ msgid "The transaction is not linked to a token."
+#~ msgstr "交易未有連結至代碼。"
+
+#~ msgid "The void of the transaction with reference %s failed."
+#~ msgstr "交易(參考:%s)的作廢要求失敗。"
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/models/__init__.py b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/models/__init__.py
new file mode 100644
index 00000000..6b48b38c
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/models/__init__.py
@@ -0,0 +1,5 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import payment_provider
+from . import payment_token
+from . import payment_transaction
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/models/payment_provider.py b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/models/payment_provider.py
new file mode 100644
index 00000000..071a00df
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/models/payment_provider.py
@@ -0,0 +1,184 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import json
+import re
+
+from odoo import _, api, fields, models
+
+from odoo.addons.payment import utils as payment_utils
+from odoo.addons.payment.logging import get_payment_logger
+from odoo.addons.payment_adyen import const
+
+
+_logger = get_payment_logger(__name__)
+
+
+class PaymentProvider(models.Model):
+    _inherit = 'payment.provider'
+
+    code = fields.Selection(
+        selection_add=[('adyen', "Adyen")], ondelete={'adyen': 'set default'})
+    adyen_merchant_account = fields.Char(
+        string="Merchant Account",
+        help="The code of the merchant account to use with this provider",
+        required_if_provider='adyen',
+        copy=False,
+        groups='base.group_system',
+    )
+    adyen_api_key = fields.Char(
+        string="API Key",
+        help="The API key of the webservice user",
+        required_if_provider='adyen',
+        copy=False,
+        groups='base.group_system',
+    )
+    adyen_client_key = fields.Char(
+        string="Client Key",
+        help="The client key of the webservice user",
+        required_if_provider='adyen',
+        copy=False,
+    )
+    adyen_hmac_key = fields.Char(
+        string="HMAC Key",
+        help="The HMAC key of the webhook",
+        required_if_provider='adyen',
+        copy=False,
+        groups='base.group_system',
+    )
+    adyen_api_url_prefix = fields.Char(
+        string="API URL Prefix",
+        help="The base URL for the API endpoints",
+        required_if_provider='adyen',
+        copy=False,
+    )
+
+    # === CRUD METHODS === #
+
+    @api.model_create_multi
+    def create(self, vals_list):
+        for values in vals_list:
+            self._adyen_extract_prefix_from_api_url(values)
+        return super().create(vals_list)
+
+    def write(self, vals):
+        self._adyen_extract_prefix_from_api_url(vals)
+        return super().write(vals)
+
+    def _get_default_payment_method_codes(self):
+        """Override of `payment` to return the default payment method codes."""
+        self.ensure_one()
+        if self.code != 'adyen':
+            return super()._get_default_payment_method_codes()
+        return const.DEFAULT_PAYMENT_METHOD_CODES
+
+    @api.model
+    def _adyen_extract_prefix_from_api_url(self, values):
+        """ Update the create or write values with the prefix extracted from the API URL.
+
+        :param dict values: The create or write values.
+        :return: None
+        """
+        if values.get('adyen_api_url_prefix'):  # Test if we're duplicating a provider.
+            values['adyen_api_url_prefix'] = re.sub(
+                r'(?:https://)?(\w+-\w+).*', r'\1', values['adyen_api_url_prefix']
+            )
+
+    # === COMPUTE METHODS === #
+
+    def _compute_feature_support_fields(self):
+        """ Override of `payment` to enable additional features. """
+        super()._compute_feature_support_fields()
+        self.filtered(lambda p: p.code == 'adyen').update({
+            'support_manual_capture': 'partial',
+            'support_refund': 'partial',
+            'support_tokenization': True,
+        })
+
+    # === BUSINESS METHODS === #
+
+    def _adyen_get_inline_form_values(self, pm_code, amount=None, currency=None):
+        """ Return a serialized JSON of the required values to render the inline form.
+
+        Note: `self.ensure_one()`
+
+        :param str pm_code: The code of the payment method whose inline form to render.
+        :param float amount: The transaction amount.
+        :param res.currency currency: The transaction currency.
+        :return: The JSON serial of the required values to render the inline form.
+        :rtype: str
+        """
+        self.ensure_one()
+
+        inline_form_values = {
+            'client_key': self.adyen_client_key,
+            'adyen_pm_code': const.PAYMENT_METHODS_MAPPING.get(pm_code, pm_code),
+            'formatted_amount': self._adyen_get_formatted_amount(amount, currency),
+        }
+        return json.dumps(inline_form_values)
+
+    def _adyen_get_formatted_amount(self, amount=None, currency=None):
+        """ Return the amount in the format required by Adyen.
+
+        The formatted amount is a dict with keys 'value' and 'currency'.
+
+        :param float amount: The transaction amount.
+        :param res.currency currency: The transaction currency.
+        :return: The Adyen-formatted amount.
+        :rtype: dict
+        """
+        currency_code = currency and currency.name
+        converted_amount = amount and currency_code and payment_utils.to_minor_currency_units(
+            amount, currency, const.CURRENCY_DECIMALS.get(currency_code)
+        )
+        return {
+            'value': converted_amount,
+            'currency': currency_code,
+        }
+
+    def _adyen_compute_shopper_reference(self, partner_id):
+        """ Compute a unique reference of the partner for Adyen.
+
+        This is used for the `shopperReference` field in communications with Adyen and stored in the
+        `adyen_shopper_reference` field on `payment.token` if the payment method is tokenized.
+
+        :param recordset partner_id: The partner making the transaction, as a `res.partner` id
+        :return: The unique reference for the partner
+        :rtype: str
+        """
+        return f'ODOO_PARTNER_{partner_id}'
+
+    # === REQUEST HELPERS === #
+
+    def _build_request_url(self, endpoint, *, endpoint_param=None, **kwargs):
+        """Override of `payment` to build the request URL based on the API URL prefix.
+
+        The final URL follows the pattern `<_base>/V<_version>/<_endpoint>`.
+        """
+        if self.code != 'adyen':
+            return self._build_request_url(endpoint, endpoint_param=endpoint_param, **kwargs)
+
+        version = const.API_ENDPOINT_VERSIONS[endpoint]
+        endpoint = endpoint if not endpoint_param else endpoint.format(endpoint_param)
+        prefix_ = self.adyen_api_url_prefix.rstrip('/')  # Remove potential trailing slash.
+        endpoint = endpoint.lstrip('/')  # Remove potential leading slash.
+        test_mode_ = self.state == 'test'
+        prefix_ = f'{prefix_}.adyen' if test_mode_ else f'{prefix_}-checkout-live.adyenpayments'
+        return f'https://{prefix_}.com/checkout/V{version}/{endpoint}'
+
+    def _build_request_headers(self, method, *args, idempotency_key=None, **kwargs):
+        """Override of `payment` to include the API key and idempotency key in the headers."""
+        if self.code != 'adyen':
+            return super()._build_request_headers(
+                method, *args, idempotency_key=idempotency_key, **kwargs
+            )
+
+        headers = {'X-API-Key': self.adyen_api_key}
+        if method == 'POST' and idempotency_key:
+            headers['idempotency-key'] = idempotency_key
+        return headers
+
+    def _parse_response_error(self, response):
+        """Override of `payment` to extract the error message from the response."""
+        if self.code != 'adyen':
+            return super()._parse_response_error(response)
+        return response.json().get('message', '')
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/models/payment_token.py b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/models/payment_token.py
new file mode 100644
index 00000000..81a16274
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/models/payment_token.py
@@ -0,0 +1,11 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import fields, models
+
+
+class PaymentToken(models.Model):
+    _inherit = 'payment.token'
+
+    adyen_shopper_reference = fields.Char(
+        string="Shopper Reference", help="The unique reference of the partner owning this token",
+        readonly=True)
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/models/payment_transaction.py b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/models/payment_transaction.py
new file mode 100644
index 00000000..6764b99d
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/models/payment_transaction.py
@@ -0,0 +1,435 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import _, api, models
+from odoo.tools import format_amount
+
+from odoo.addons.payment import utils as payment_utils
+from odoo.addons.payment.logging import get_payment_logger
+from odoo.addons.payment_adyen import const
+from odoo.addons.payment_adyen import utils as adyen_utils
+
+
+_logger = get_payment_logger(__name__)
+
+
+class PaymentTransaction(models.Model):
+    _inherit = 'payment.transaction'
+
+    # === BUSINESS METHODS - PRE-PROCESSING === #
+
+    def _get_specific_processing_values(self, processing_values):
+        """ Override of payment to return Adyen-specific processing values.
+
+        Note: self.ensure_one() from `_get_processing_values`
+
+        :param dict processing_values: The generic processing values of the transaction
+        :return: The dict of provider-specific processing values
+        :rtype: dict
+        """
+        if self.provider_code != 'adyen':
+            return super()._get_specific_processing_values(processing_values)
+
+        converted_amount = payment_utils.to_minor_currency_units(
+            self.amount, self.currency_id, const.CURRENCY_DECIMALS.get(self.currency_id.name)
+        )
+        return {
+            'converted_amount': converted_amount,
+            'access_token': payment_utils.generate_access_token(
+                processing_values['reference'],
+                converted_amount,
+                self.currency_id.id,
+                processing_values['partner_id']
+            )
+        }
+
+    def _send_payment_request(self):
+        """Override of `payment` to send a payment request to Adyen."""
+        if self.provider_code != 'adyen':
+            return super()._send_payment_request()
+
+        # Prepare the payment request to Adyen.
+        converted_amount = payment_utils.to_minor_currency_units(
+            self.amount, self.currency_id, const.CURRENCY_DECIMALS.get(self.currency_id.name)
+        )
+        data = {
+            'merchantAccount': self.provider_id.adyen_merchant_account,
+            'amount': {
+                'value': converted_amount,
+                'currency': self.currency_id.name,
+            },
+            'reference': self.reference,
+            'paymentMethod': {
+                'storedPaymentMethodId': self.token_id.provider_ref,
+            },
+            'shopperReference': self.token_id.adyen_shopper_reference,
+            'recurringProcessingModel': 'Subscription',
+            'shopperIP': payment_utils.get_customer_ip_address(),
+            'shopperInteraction': 'ContAuth',
+            'shopperEmail': self.partner_email,
+            'shopperName': adyen_utils.format_partner_name(self.partner_name),
+            'telephoneNumber': self.partner_phone,
+            **adyen_utils.include_partner_addresses(self),
+        }
+
+        # Force the capture delay on Adyen side if the provider is not configured for capturing
+        # payments manually. This is necessary because it's not possible to distinguish
+        # 'AUTHORISATION' events sent by Adyen with the merchant account's capture delay set to
+        # 'manual' from events with the capture delay set to 'immediate' or a number of hours. If
+        # the merchant account is configured to capture payments with a delay but the provider is
+        # not, we force the immediate capture to avoid considering authorized transactions as
+        # captured on Odoo.
+        if not self.provider_id.capture_manually:
+            data.update(captureDelayHours=0)
+
+        # Send the payment request to Adyen.
+        response_content = self._send_api_request(
+            'POST',
+            '/payments',
+            json=data,
+            idempotency_key=payment_utils.generate_idempotency_key(
+                self, scope='payment_request_token'
+            )
+        )
+        self._process('adyen', response_content)
+
+    def _send_capture_request(self):
+        """Override of `payment` to send a capture request to Adyen."""
+        if self.provider_code != 'adyen':
+            return super()._send_capture_request()
+
+        # Send the capture request to Adyen.
+        converted_amount = payment_utils.to_minor_currency_units(
+            self.amount, self.currency_id, const.CURRENCY_DECIMALS.get(self.currency_id.name)
+        )
+        data = {
+            'merchantAccount': self.provider_id.adyen_merchant_account,
+            'amount': {
+                'value': converted_amount,
+                'currency': self.currency_id.name,
+            },
+            'reference': self.reference,
+        }
+
+        response_content = self._send_api_request(
+            'POST',
+            '/payments/{}/captures',
+            json=data,
+            endpoint_param=self.provider_reference,
+        )
+
+        # Process the capture request response.
+        status = response_content.get('status')
+        formatted_amount = format_amount(self.env, self.amount, self.currency_id)
+        if status == 'received':
+            self._log_message_on_linked_documents(_(
+                "The capture request of %(amount)s for transaction %(ref)s has been sent.",
+                amount=formatted_amount, ref=self.reference
+            ))
+
+        # The PSP reference associated with this capture request is different from the PSP
+        # reference associated with the original payment request.
+        self.provider_reference = response_content.get('pspReference')
+
+    def _send_void_request(self):
+        """Override of `payment` to send a void request to Adyen."""
+        if self.provider_code != 'adyen':
+            return super()._send_void_request()
+
+        data = {
+            'merchantAccount': self.provider_id.adyen_merchant_account,
+            'reference': self.reference,
+        }
+        response_content = self._send_api_request(
+            'POST',
+            '/payments/{}/cancels',
+            json=data,
+            endpoint_param=self.provider_reference,
+        )
+
+        # Process the void request response.
+        status = response_content.get('status')
+        if status == 'received':
+            self._log_message_on_linked_documents(_(
+                "A request was sent to void the transaction %(reference)s.",
+                reference=self.reference
+            ))
+
+        # The PSP reference associated with this void request is different from the PSP
+        # reference associated with the original payment request.
+        self.provider_reference = response_content.get('pspReference')
+
+    def _send_refund_request(self):
+        """Override of `payment` to send a refund request to Adyen."""
+        if self.provider_code != 'adyen':
+            super()._send_refund_request()
+
+        # Send the refund request to Adyen.
+        converted_amount = payment_utils.to_minor_currency_units(
+            -self.amount,  # The amount is negative for refund transactions
+            self.currency_id,
+            arbitrary_decimal_number=const.CURRENCY_DECIMALS.get(self.currency_id.name)
+        )
+        data = {
+            'merchantAccount': self.provider_id.adyen_merchant_account,
+            'amount': {
+                'value': converted_amount,
+                'currency': self.currency_id.name,
+            },
+            'reference': self.reference,
+        }
+        response_content = self._send_api_request(
+            'POST',
+            '/payments/{}/refunds',
+            json=data,
+            endpoint_param=self.source_transaction_id.provider_reference,
+        )
+
+        # Process the refund request response.
+        psp_reference = response_content.get('pspReference')
+        status = response_content.get('status')
+        if psp_reference and status == 'received':
+            # The PSP reference associated with this /refunds request is different from the psp
+            # reference associated with the original payment request.
+            self.provider_reference = psp_reference
+
+    # === BUSINESS METHODS - PROCESSING === #
+
+    @api.model
+    def _search_by_reference(self, provider_code, payment_data):
+        """Override of `payment` to search the transaction  with a specific logic for Adyen."""
+        if provider_code != 'adyen':
+            return super()._search_by_reference(provider_code, payment_data)
+
+        tx = self
+        reference = payment_data.get('merchantReference')
+        if not reference:
+            _logger.warning("Received data with missing reference.")
+            return tx
+
+        event_code = payment_data.get('eventCode', 'AUTHORISATION')  # Fallback on auth if S2S.
+        provider_reference = payment_data.get('pspReference')
+        source_reference = payment_data.get('originalReference')
+        if event_code == 'AUTHORISATION':
+            tx = self.search([('reference', '=', reference), ('provider_code', '=', 'adyen')])
+        elif event_code in ['CANCELLATION', 'CAPTURE', 'CAPTURE_FAILED']:
+            # The capture/void may be initiated from Adyen, so we can't trust the reference.
+            # We find the transaction based on the original provider reference since Adyen will have
+            # two different references: one for the original transaction and one for the capture or
+            # void. We keep the second one only for child transactions. For full capture/void, no
+            # child transaction are created. Thus, we first look for the source transaction before
+            # checking if we need to find/create a child transaction.
+            source_tx = self.search(
+                [('provider_reference', '=', source_reference), ('provider_code', '=', 'adyen')]
+            )
+            if source_tx:
+                payment_data_amount = payment_data.get('amount', {}).get('value')
+                converted_notification_amount = payment_utils.to_major_currency_units(
+                    payment_data_amount,
+                    source_tx.currency_id,
+                    arbitrary_decimal_number=const.CURRENCY_DECIMALS.get(self.currency_id.name),
+                )
+                if source_tx.amount == converted_notification_amount:  # Full capture/void.
+                    tx = source_tx
+                else:  # Partial capture/void; we search for the child transaction instead.
+                    tx = self.search([
+                        ('provider_reference', '=', provider_reference),
+                        ('provider_code', '=', 'adyen'),
+                    ])
+                    if tx and tx.amount != converted_notification_amount:
+                        # If the void was requested expecting a certain amount but, in the meantime,
+                        # others captures that Odoo was unaware of were done, the amount voided will
+                        # be different from the amount of the existing transaction.
+                        tx._set_error(_(
+                            "The amount processed by Adyen for the transaction %s is different than"
+                            " the one requested. Another transaction is created with the correct"
+                            " amount.", tx.reference
+                        ))
+                        tx = self.env['payment.transaction']
+                    if not tx:  # Partial capture/void initiated from Adyen or with a wrong amount.
+                        # Manually create a child transaction with a new reference. The reference of
+                        # the child transaction was personalized from Adyen and could be identical
+                        # to that of an existing transaction.
+                        tx = self._adyen_create_child_tx(source_tx, payment_data)
+            else:  # The capture/void was initiated for an unknown source transaction
+                pass  # Don't do anything with the capture/void notification
+        else:  # 'REFUND'
+            # The refund may be initiated from Adyen, so we can't trust the reference, which could
+            # be identical to another existing transaction. We find the transaction based on the
+            # provider reference.
+            tx = self.search(
+                [('provider_reference', '=', provider_reference), ('provider_code', '=', 'adyen')]
+            )
+            if not tx:  # The refund was initiated from Adyen
+                # Find the source transaction based on the original reference
+                source_tx = self.search(
+                    [('provider_reference', '=', source_reference), ('provider_code', '=', 'adyen')]
+                )
+                if source_tx:
+                    # Manually create a refund transaction with a new reference. The reference of
+                    # the refund transaction was personalized from Adyen and could be identical to
+                    # that of an existing transaction.
+                    tx = self._adyen_create_child_tx(source_tx, payment_data, is_refund=True)
+                else:  # The refund was initiated for an unknown source transaction
+                    pass  # Don't do anything with the refund notification
+        if not tx:
+            _logger.warning("No transaction found matching reference %s.", reference)
+        return tx
+
+    def _adyen_create_child_tx(self, source_tx, payment_data, is_refund=False):
+        """Create a child transaction based on Adyen data.
+
+        :param payment.transaction source_tx: The source transaction for which a new operation is
+                                              initiated.
+        :param dict payment_data: The payment data sent by the provider.
+        :return: The newly created child transaction.
+        :rtype: payment.transaction
+        """
+        provider_reference = payment_data.get('pspReference')
+        amount = payment_data.get('amount', {}).get('value')
+        if not provider_reference or amount is None:  # amount == 0 if success == False
+            _logger.warning("Received data for child transaction with missing transaction values.")
+            return self.env['payment.transaction']
+
+        converted_amount = payment_utils.to_major_currency_units(
+            amount,
+            source_tx.currency_id,
+            arbitrary_decimal_number=const.CURRENCY_DECIMALS.get(self.currency_id.name),
+        )
+        return source_tx._create_child_transaction(
+            converted_amount, is_refund=is_refund, provider_reference=provider_reference
+        )
+
+    def _extract_amount_data(self, payment_data):
+        """Override of `payment` to extract the amount and currency from the payment data."""
+        if self.provider_code != 'adyen':
+            return super()._extract_amount_data(payment_data)
+
+        amount_data = payment_data.get('amount', {})
+        amount = payment_utils.to_major_currency_units(
+            amount_data.get('value', 0),
+            self.currency_id,
+            arbitrary_decimal_number=const.CURRENCY_DECIMALS.get(self.currency_id.name),
+        )
+        currency_code = amount_data.get('currency')
+        return {
+            'amount': amount,
+            'currency_code': currency_code,
+        }
+
+    def _apply_updates(self, payment_data):
+        """Override of payment to update the transaction based on the payment data."""
+        if self.provider_code != 'adyen':
+            return super()._apply_updates(payment_data)
+
+        # Extract or assume the event code. If none is provided, the feedback data originate from a
+        # direct payment request whose feedback data share the same payload as an 'AUTHORISATION'
+        # webhook notification.
+        event_code = payment_data.get('eventCode', 'AUTHORISATION')
+
+        # Update the provider reference. If the event code is 'CAPTURE' or 'CANCELLATION', we
+        # discard the pspReference as it is different from the original pspReference of the tx.
+        if 'pspReference' in payment_data and event_code in ['AUTHORISATION', 'REFUND']:
+            self.provider_reference = payment_data.get('pspReference')
+
+        # Update the payment method.
+        payment_method_data = payment_data.get('paymentMethod', '')
+        if isinstance(payment_method_data, dict):  # Not from webhook: the data contain the PM code.
+            payment_method_type = payment_method_data['type']
+            if payment_method_type == 'scheme':  # card
+                payment_method_code = payment_method_data['brand']
+            else:
+                payment_method_code = payment_method_type
+        else:  # Sent from the webhook: the PM code is directly received as a string.
+            payment_method_code = payment_method_data
+
+        payment_method = self.env['payment.method']._get_from_code(
+            payment_method_code, mapping=const.PAYMENT_METHODS_MAPPING
+        )
+        self.payment_method_id = payment_method or self.payment_method_id
+
+        # Update the payment state.
+        payment_state = payment_data.get('resultCode')
+        refusal_reason = payment_data.get('refusalReason') or payment_data.get('reason')
+        if not payment_state:
+            self._set_error(_("Received data with missing payment state."))
+        elif payment_state in const.RESULT_CODES_MAPPING['pending']:
+            self._set_pending()
+        elif payment_state in const.RESULT_CODES_MAPPING['done']:
+            if not self.provider_id.capture_manually:
+                self._set_done()
+            else:  # The payment was configured for manual capture.
+                # Differentiate the state based on the event code.
+                if event_code == 'AUTHORISATION':
+                    self._set_authorized()
+                else:  # 'CAPTURE'
+                    self._set_done()
+
+            # Immediately post-process the transaction if it is a refund, as the post-processing
+            # will not be triggered by a customer browsing the transaction from the portal.
+            if self.operation == 'refund':
+                self.env.ref('payment.cron_post_process_payment_tx')._trigger()
+        elif payment_state in const.RESULT_CODES_MAPPING['cancel']:
+            self._set_canceled()
+        elif payment_state in const.RESULT_CODES_MAPPING['error']:
+            if event_code in ['AUTHORISATION', 'REFUND']:
+                _logger.warning(
+                    "The transaction %s underwent an error. reason: %s.",
+                    self.reference, refusal_reason,
+                )
+                self._set_error(
+                    _("An error occurred during the processing of your payment. Please try again.")
+                )
+            elif event_code == 'CANCELLATION':
+                _logger.warning(
+                    "The void of the transaction %s failed. reason: %s.",
+                    self.reference, refusal_reason,
+                )
+                if self.source_transaction_id:  # child tx => The event can't be retried.
+                    self._set_error(_("The void of the transaction %s failed.", self.reference))
+                else:  # source tx with failed void stays in its state, could be voided again
+                    self._log_message_on_linked_documents(
+                        _("The void of the transaction %s failed.", self.reference)
+                    )
+            else:  # 'CAPTURE', 'CAPTURE_FAILED'
+                _logger.warning(
+                    "The capture of the transaction %s failed. reason: %s.",
+                    self.reference, refusal_reason,
+                )
+                if self.source_transaction_id:  # child_tx => The event can't be retried.
+                    self._set_error(_(
+                        "The capture of the transaction %s failed.", self.reference
+                    ))
+                else:  # source tx with failed capture stays in its state, could be captured again
+                    self._log_message_on_linked_documents(_(
+                        "The capture of the transaction %s failed.", self.reference
+                    ))
+        elif payment_state in const.RESULT_CODES_MAPPING['refused']:
+            _logger.warning(
+                "the transaction %s was refused. reason: %s",
+                self.reference, refusal_reason
+            )
+            self._set_error(_("Your payment was refused. Please try again."))
+        else:  # Classify unsupported payment state as `error` tx state
+            _logger.warning(
+                "received data for transaction %s with invalid payment state: %s",
+                self.reference, payment_state
+            )
+            self._set_error(
+                "Adyen: " + _("Received data with invalid payment state: %s", payment_state)
+            )
+
+    def _extract_token_values(self, payment_data):
+        """Override of `payment` to extract the token values from the payment data."""
+        if self.provider_code != 'adyen':
+            return super()._extract_token_values(payment_data)
+
+        additional_data = payment_data['additionalData']
+
+        if 'recurring.recurringDetailReference' not in additional_data:
+            return {}
+
+        return {
+            'provider_ref': additional_data['recurring.recurringDetailReference'],
+            'payment_details': additional_data.get('cardSummary'),
+            'adyen_shopper_reference': additional_data['recurring.shopperReference'],
+        }
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/static/description/icon.png b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/static/description/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..293d0a14deac91138c89aed4262122f7d72dcecc
GIT binary patch
literal 587
zcmeAS@N?(olHy`uVBq!ia0y~yU`PRB4rT@h26vm(GzJES%mAMdR|WK((C
zL58aW&tJZ2v?}Q0)jQ{}+`4%6w$Z8}L$GNVFW)p+6?E|mNaW(x+qX4^|1dBxD3%2I
z1vBj1e_vsKLW9GC{f-Kb6ATmt)-TFG-|+r+!u#|4);0LQKfbNAiGhK!z|+MsB;(%O
z%cskl6+~Jeu5D0L^V;KDynfGr=W8u&hbB2rn`+klxj*1Rjk18!*B2ACw=(m2DY}&Y
zUHZyOexmjSR;PE9%MWyXxv}zs$Ffg{4Y_;X{LT(zcmL)-mEFDQsnd5WE)OjHeY^E-$W}Ud5wP7vJ*P37QPZZ
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/static/src/interactions/payment_form.js b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/static/src/interactions/payment_form.js
new file mode 100644
index 00000000..2e2f26ea
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/static/src/interactions/payment_form.js
@@ -0,0 +1,284 @@
+import { loadJS, loadCSS } from '@web/core/assets';
+import { _t } from '@web/core/l10n/translation';
+import { pyToJsLocale } from '@web/core/l10n/utils';
+import { rpc, RPCError } from '@web/core/network/rpc';
+import { patch } from '@web/core/utils/patch';
+
+import { PaymentForm } from '@payment/interactions/payment_form';
+
+patch(PaymentForm.prototype, {
+
+    setup() {
+        super.setup();
+        this.adyenCheckout = undefined;
+        this.adyenComponents = {}; // Store the component of each instantiated payment method.
+    },
+
+    // #=== DOM MANIPULATION ===#
+
+    /**
+     * Prepare the inline form of Adyen for direct payment.
+     *
+     * @override method from payment.payment_form
+     * @private
+     * @param {number} providerId - The id of the selected payment option's provider.
+     * @param {string} providerCode - The code of the selected payment option's provider.
+     * @param {number} paymentOptionId - The id of the selected payment option
+     * @param {string} paymentMethodCode - The code of the selected payment method, if any.
+     * @param {string} flow - The online payment flow of the selected payment option
+     * @return {void}
+     */
+    async _prepareInlineForm(providerId, providerCode, paymentOptionId, paymentMethodCode, flow) {
+        if (providerCode !== 'adyen') {
+            await super._prepareInlineForm(...arguments);
+            return;
+        }
+
+        // Check if instantiation of the component is needed.
+        if (flow === 'token') {
+            return; // No component for tokens.
+        } else if (this.adyenComponents[paymentOptionId]) {
+            this._setPaymentFlow('direct'); // Overwrite the flow even if no re-instantiation.
+            if (paymentMethodCode === 'paypal') { // PayPal uses its own button to submit.
+                this._hideInputs();
+            }
+            return; // Don't re-instantiate if already done for this payment method.
+        }
+
+        // Overwrite the flow of the selected payment method.
+        this._setPaymentFlow('direct');
+
+        // Extract and deserialize the inline form values.
+        const radio = document.querySelector('input[name="o_payment_radio"]:checked');
+        const inlineFormValues = JSON.parse(radio.dataset['adyenInlineFormValues']);
+        const formattedAmount = inlineFormValues['formatted_amount'];
+
+        this.el.parentElement.querySelector(
+            'script[src="https://checkoutshopper-live.adyen.com/checkoutshopper/sdk/5.39.0/adyen.js"]'
+        )?.remove();
+        this.el.parentElement.querySelector(
+            'link[href="https://checkoutshopper-live.adyen.com/checkoutshopper/sdk/5.39.0/adyen.css"]'
+        )?.remove();
+        await this.waitFor(
+            loadJS('https://checkoutshopper-live.adyen.com/checkoutshopper/sdk/6.9.0/adyen.js')
+        );
+        await this.waitFor(
+            loadCSS('https://checkoutshopper-live.adyen.com/checkoutshopper/sdk/6.9.0/adyen.css')
+        );
+        const { AdyenCheckout, createComponent } = window.AdyenWeb;
+
+        // Create the checkout object if not already done for another payment method.
+        if (!this.adyenCheckout) {
+            try {
+                // Await the RPC to let it create AdyenCheckout before using it.
+                const response = await this.waitFor(rpc(
+                    '/payment/adyen/payment_methods',
+                    {
+                        'provider_id': providerId,
+                        'partner_id': parseInt(this.paymentContext['partnerId']),
+                        'formatted_amount': formattedAmount,
+                    },
+                ));
+                // Create the Adyen Checkout SDK.
+                const providerState = this._getProviderState(radio);
+                const configuration = {
+                    paymentMethodsResponse: response,
+                    clientKey: inlineFormValues['client_key'],
+                    amount: formattedAmount,
+                    locale: pyToJsLocale(document.documentElement.getAttribute('lang')) || 'en-US',
+                    countryCode: response['country_code'],
+                    environment: providerState === 'enabled' ? 'live' : 'test',
+                    onAdditionalDetails: this._adyenOnSubmitAdditionalDetails.bind(this),
+                    onPaymentCompleted: this._adyenOnPaymentResolved.bind(this),
+                    onPaymentFailed: this._adyenOnPaymentResolved.bind(this),
+                    onError: this._adyenOnError.bind(this),
+                    onSubmit: this._adyenOnSubmit.bind(this),
+                };
+                this.adyenCheckout = await this.waitFor(AdyenCheckout(configuration));
+            } catch (error) {
+                if (error instanceof RPCError) {
+                    this._displayErrorDialog(
+                        _t("Cannot display the payment form"), error.data.message
+                    );
+                    this._enableButton();
+                    return;
+                }
+                else {
+                    return Promise.reject(error);
+                }
+            }
+        }
+
+        // Instantiate and mount the component.
+        const componentConfiguration = {
+            showPayButton: false,
+        };
+        if (paymentMethodCode === 'card') {
+            componentConfiguration['hasHolderName'] = true;
+            componentConfiguration['holderNameRequired'] = true;
+            // Forbid Bancontact cards in the card component.
+            componentConfiguration['brands'] = ['mc', 'visa', 'amex', 'discover'];
+        }
+        else if (paymentMethodCode === 'paypal') {
+            // PayPal requires the form to be submitted with its own button.
+            Object.assign(componentConfiguration, {
+                style: {
+                    disableMaxWidth: true
+                },
+                showPayButton: true,
+                blockPayPalCreditButton: true,
+                blockPayPalPayLaterButton: true
+            });
+            this._hideInputs();
+            // Define necessary fields as the step submitForm is missed.
+            Object.assign(this.paymentContext, {
+                tokenizationRequested: false,
+                providerId: providerId,
+                paymentMethodId: paymentOptionId,
+            });
+        }
+        const inlineForm = this._getInlineForm(radio);
+        const adyenContainer = inlineForm.querySelector('[name="o_adyen_component_container"]');
+        this.adyenComponents[paymentOptionId] = createComponent(
+            inlineFormValues['adyen_pm_code'],
+            this.adyenCheckout,
+            componentConfiguration
+        ).mount(adyenContainer);
+    },
+
+    // #=== PAYMENT FLOW ===#
+
+    /**
+     * Trigger the payment processing by submitting the component.
+     *
+     * The component is submitted here instead of in `_processDirectFlow` because we use the native
+     * submit button for PayPal, which does not follow the standard flow. The transaction is created
+     * in `_adyenOnSubmit`.
+     *
+     * @override method from payment.payment_form
+     * @private
+     * @param {string} providerCode - The code of the selected payment option's provider.
+     * @param {number} paymentOptionId - The id of the payment option handling the transaction.
+     * @param {string} paymentMethodCode - The code of the selected payment method, if any.
+     * @param {string} flow - The online payment flow of the transaction.
+     * @return {void}
+     */
+    async _initiatePaymentFlow(providerCode, paymentOptionId, paymentMethodCode, flow) {
+        if (providerCode !== 'adyen' || flow === 'token') {
+            // Tokens are handled by the generic flow
+            await super._initiatePaymentFlow(...arguments);
+            return;
+        }
+
+        if (!this.adyenComponents[paymentOptionId]) {  // Component creation failed.
+            this._enableButton();
+            return;
+        }
+
+        this.adyenComponents[paymentOptionId].submit();
+
+        // The `onError` event handler is not used to validate inputs anymore since v5.0.0.
+        if (!this.adyenComponents[paymentOptionId].isValid) {
+            this._displayErrorDialog(_t("Incorrect payment details"));
+            this._enableButton();
+        }
+    },
+
+    /**
+     * Handle the submit event of the component and initiate the payment.
+     *
+     * @private
+     * @param {object} state - The state of the component.
+     * @param {object} component - The component.
+     * @param {object} actions - The possible action handlers to call.
+     * @return {void}
+     */
+    async _adyenOnSubmit(state, component, actions) {
+        try {
+            // Create the transaction and retrieve the processing values.
+            const processingValues = await this.waitFor(rpc(
+                this.paymentContext['transactionRoute'],
+                this._prepareTransactionRouteParams(),
+            ));
+            component.reference = processingValues.reference; // Store final reference.
+            // Initiate the payment.
+            const paymentResponse = await this.waitFor(rpc('/payment/adyen/payments', {
+                'provider_id': processingValues.provider_id,
+                'reference': processingValues.reference,
+                'converted_amount': processingValues.converted_amount,
+                'currency_id': processingValues.currency_id,
+                'partner_id': processingValues.partner_id,
+                'payment_method': state.data.paymentMethod,
+                'access_token': processingValues.access_token,
+                'browser_info': state.data.browserInfo,
+            }));
+            if (!paymentResponse.resultCode) {
+                actions.reject();
+                return;
+            }
+            if (paymentResponse.action && paymentResponse.action.type !== 'redirect') {
+                this._hideInputs(); // Only the inputs of the inline form should be used.
+                 // The page is blocked at this point; unblock it.
+                this.env.bus.trigger('ui', 'unblock');
+            }
+            actions.resolve(paymentResponse);
+        } catch (error) {
+            const error_message = error instanceof RPCError ? error.data.message : error.message;
+            this._displayErrorDialog(_t("Payment processing failed"), error_message);
+            this._enableButton();
+        }
+    },
+
+    /**
+     * Handle the additional details event of the component.
+     *
+     * @private
+     * @param {object} state - The state of the component.
+     * @param {object} component - The component.
+     * @param {object} actions - The possible action handlers to call.
+     * @return {void}
+     */
+    async _adyenOnSubmitAdditionalDetails(state, component, actions) {
+        try {
+            const paymentDetails = await this.waitFor(rpc('/payment/adyen/payments/details', {
+                'provider_id': this.paymentContext['providerId'],
+                'reference': component.reference,
+                'payment_details': state.data,
+            }));
+            if (!paymentDetails.resultCode) {
+                actions.reject();
+                return;
+            }
+            actions.resolve(paymentDetails);
+        } catch (error) {
+            const error_message = error instanceof RPCError ? error.data.message : error.message;
+            this._displayErrorDialog(_t("Payment processing failed"), error_message);
+            this._enableButton();
+        }
+    },
+
+    /**
+    * Called when the payment is completed or failed.
+    *
+    * @private
+    * @param {object} result
+    * @param {object} component
+    * @return {void}
+    */
+    _adyenOnPaymentResolved(result, component) {
+        window.location = '/payment/status';
+    },
+
+    /**
+     * Handle the error event of the component.
+     *
+     * @private
+     * @param {object} error - The error in the component.
+     * @return {void}
+     */
+    _adyenOnError(error) {
+        this._displayErrorDialog(_t("Payment processing failed"), error.message);
+        this._enableButton();
+    },
+
+});
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/tests/__init__.py b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/tests/__init__.py
new file mode 100644
index 00000000..74a90847
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/tests/__init__.py
@@ -0,0 +1,4 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import common
+from . import test_adyen
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/tests/common.py b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/tests/common.py
new file mode 100644
index 00000000..9caf6579
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/tests/common.py
@@ -0,0 +1,52 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo.addons.payment import utils as payment_utils
+from odoo.addons.payment.tests.common import PaymentCommon
+
+
+class AdyenCommon(PaymentCommon):
+
+    @classmethod
+    def setUpClass(cls):
+        super().setUpClass()
+
+        cls.adyen = cls._prepare_provider('adyen', update_values={
+            'adyen_merchant_account': 'dummy',
+            'adyen_api_key': 'dummy',
+            'adyen_client_key': 'dummy',
+            'adyen_hmac_key': '12345678',
+            'adyen_api_url_prefix': 'prefix',
+        })
+
+        # Override default values
+        cls.provider = cls.adyen
+
+        cls.psp_reference = '0123456789ABCDEF'
+        cls.original_reference = 'FEDCBA9876543210'
+        cls.webhook_notification_payload = {
+            'additionalData': {
+                'hmacSignature': 'VcoiMGe4ClMsMhLlgSOgZRZMBNqaVh1NfTTn+vAuXa8='
+            },
+            'amount': {
+                'currency': cls.currency.name,
+                'value': payment_utils.to_minor_currency_units(cls.amount, cls.currency),
+            },
+            'eventCode': 'AUTHORISATION',
+            'merchantAccountCode': 'DuckSACom123',
+            'merchantReference': cls.reference,
+            'originalReference': cls.original_reference,
+            'pspReference': cls.psp_reference,
+            'success': 'true',
+        }  # Include all keys used in the computation of the signature to the payload
+        cls.webhook_notification_batch_data = {
+            'notificationItems': [
+                {
+                    'NotificationRequestItem': cls.webhook_notification_payload,
+                }
+            ]
+        }
+
+    def _create_transaction(self, *args, provider_reference=None, **kwargs):
+        if not provider_reference:
+            provider_reference = self.psp_reference
+        return super()._create_transaction(*args, provider_reference=provider_reference, **kwargs)
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/tests/test_adyen.py b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/tests/test_adyen.py
new file mode 100644
index 00000000..d4f8a9ec
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/tests/test_adyen.py
@@ -0,0 +1,495 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from unittest.mock import patch
+
+from werkzeug.exceptions import Forbidden
+
+from odoo.tests import tagged
+from odoo.tools import mute_logger
+
+from odoo.addons.payment import utils as payment_utils
+from odoo.addons.payment.tests.http_common import PaymentHttpCommon
+from odoo.addons.payment_adyen import utils as adyen_utils
+from odoo.addons.payment_adyen.controllers.main import AdyenController
+from odoo.addons.payment_adyen.tests.common import AdyenCommon
+
+
+@tagged('post_install', '-at_install')
+class AdyenTest(AdyenCommon, PaymentHttpCommon):
+
+    def test_processing_values(self):
+        tx = self._create_transaction(flow='direct')
+        with mute_logger('odoo.addons.payment.models.payment_transaction'), \
+            patch(
+                'odoo.addons.payment.utils.generate_access_token',
+                new=self._generate_test_access_token
+            ):
+            processing_values = tx._get_processing_values()
+
+        converted_amount = 111111
+        self.assertEqual(
+            payment_utils.to_minor_currency_units(self.amount, self.currency),
+            converted_amount,
+        )
+        self.assertEqual(processing_values['converted_amount'], converted_amount)
+        with patch(
+            'odoo.addons.payment.utils.generate_access_token', new=self._generate_test_access_token
+        ):
+            self.assertTrue(payment_utils.check_access_token(
+                processing_values['access_token'], self.reference, converted_amount, self.currency.id, self.partner.id
+            ))
+
+    @mute_logger('odoo.addons.payment_adyen.models.payment_transaction')
+    def test_send_refund_request(self):
+        self.provider.support_refund = 'full_only'  # Should simply not be False
+        tx = self._create_transaction(
+            'redirect', state='done', provider_reference='source_reference'
+        )
+        tx._post_process()  # Create the payment
+
+        # Send the refund request
+        with patch(
+            'odoo.addons.payment.models.payment_provider.PaymentProvider._send_api_request',
+            new=lambda *args, **kwargs: {'pspReference': "refund_reference", 'status': "received"}
+        ):
+            tx._refund()
+
+        refund_tx = self.env['payment.transaction'].search([('source_transaction_id', '=', tx.id)])
+        self.assertTrue(
+            refund_tx,
+            msg="Refunding an Adyen transaction should always create a refund transaction."
+        )
+        self.assertTrue(
+            refund_tx.state == 'draft',
+            msg="A refund request as been made, but the state of the refund tx stays as 'draft' "
+                "until a success notification is sent"
+        )
+        self.assertNotEqual(
+            refund_tx.provider_reference,
+            tx.provider_reference,
+            msg="The provider reference of the refund transaction should be different from that of "
+                "the source transaction."
+        )
+
+    def test_search_by_reference_returns_refund_tx(self):
+        source_tx = self._create_transaction(
+            'direct', state='done', provider_reference=self.original_reference
+        )
+        refund_tx = self._create_transaction(
+            'direct',
+            reference='RefundTx',
+            provider_reference=self.psp_reference,
+            amount=-source_tx.amount,
+            operation='refund',
+            source_transaction_id=source_tx.id
+        )
+        data = dict(
+            self.webhook_notification_payload,
+            amount={
+                'currency': self.currency.name,
+                'value': payment_utils.to_minor_currency_units(
+                    source_tx.amount, refund_tx.currency_id
+                ),
+            },
+            eventCode='REFUND',
+        )
+        returned_tx = self.env['payment.transaction']._search_by_reference('adyen', data)
+        self.assertEqual(returned_tx, refund_tx, msg="The existing refund tx is the one returned")
+
+    def test_search_by_reference_creates_refund_tx_when_missing(self):
+        source_tx = self._create_transaction(
+            'direct', state='done', provider_reference=self.original_reference
+        )
+        data = dict(
+            self.webhook_notification_payload,
+            amount={
+                'currency': self.currency.name,
+                'value': payment_utils.to_minor_currency_units(self.amount, source_tx.currency_id),
+            },
+            eventCode='REFUND',
+        )
+        refund_tx = self.env['payment.transaction']._search_by_reference('adyen', data)
+        self.assertTrue(
+            refund_tx,
+            msg="If no refund tx is found with received refund data, a refund tx should be created"
+        )
+        self.assertNotEqual(refund_tx, source_tx)
+        self.assertEqual(refund_tx.source_transaction_id, source_tx)
+
+    def test_search_by_reference_returns_partial_capture_child_tx(self):
+        self.provider.capture_manually = True
+        source_tx = self._create_transaction(
+            'direct', state='authorized', provider_reference=self.original_reference
+        )
+        capture_tx = self._create_transaction(
+            'direct',
+            reference='CaptureTx',
+            provider_reference=self.psp_reference,
+            amount=source_tx.amount-10,
+            operation=source_tx.operation,
+            source_transaction_id=source_tx.id,
+        )
+        data = dict(
+            self.webhook_notification_payload,
+            amount={
+                'currency': self.currency.name,
+                'value': payment_utils.to_minor_currency_units(
+                    source_tx.amount-10, capture_tx.currency_id
+                ),
+            },
+            eventCode='CAPTURE',
+        )
+        returned_tx = self.env['payment.transaction']._search_by_reference('adyen', data)
+        self.assertEqual(returned_tx, capture_tx, msg="The existing capture tx is the one returned")
+
+    def test_search_by_reference_creates_capture_tx_when_missing(self):
+        self.provider.capture_manually = True
+        source_tx = self._create_transaction(
+            'direct', state='authorized', provider_reference=self.original_reference
+        )
+        data = dict(
+            self.webhook_notification_payload,
+            amount={
+                'currency': self.currency.name,
+                'value': payment_utils.to_minor_currency_units(
+                    self.amount - 10, source_tx.currency_id
+                ),
+            },
+            eventCode='CAPTURE',
+        )
+        capture_tx = self.env['payment.transaction']._search_by_reference('adyen', data)
+        self.assertTrue(
+            capture_tx,
+            msg="If no child tx is found with received capture data, a child tx should be created.",
+        )
+        self.assertNotEqual(capture_tx, source_tx)
+        self.assertEqual(capture_tx.source_transaction_id, source_tx)
+
+    def test_search_by_reference_returns_void_tx(self):
+        self.provider.capture_manually = True
+        source_tx = self._create_transaction(
+            'direct', state='authorized', provider_reference=self.original_reference
+        )
+        cancel_tx = self._create_transaction(
+            'direct',
+            reference='CancelTx',
+            provider_reference=self.psp_reference,
+            amount=source_tx.amount - 10,
+            operation=source_tx.operation,
+            source_transaction_id=source_tx.id,
+        )
+        data = dict(
+            self.webhook_notification_payload,
+            amount={
+                'currency': self.currency.name,
+                'value': payment_utils.to_minor_currency_units(
+                    source_tx.amount - 10, cancel_tx.currency_id
+                ),
+            },
+            eventCode='CANCELLATION',
+        )
+        returned_tx = self.env['payment.transaction']._search_by_reference('adyen', data)
+        self.assertEqual(returned_tx, cancel_tx, msg="The existing void tx is the one returned")
+
+    def test_search_by_reference_creates_void_tx_when_missing(self):
+        self.provider.capture_manually = True
+        source_tx = self._create_transaction(
+            'direct', state='authorized', provider_reference=self.original_reference
+        )
+        data = dict(
+            self.webhook_notification_payload,
+            amount={
+                'currency': self.currency.name,
+                'value': payment_utils.to_minor_currency_units(
+                    self.amount - 10, source_tx.currency_id
+                ),
+            },
+            eventCode='CANCELLATION',
+        )
+        void_tx = self.env['payment.transaction']._search_by_reference('adyen', data)
+        self.assertTrue(
+            void_tx,
+            msg="If no child tx is found with received void data, a child tx should be created."
+        )
+        self.assertNotEqual(void_tx, source_tx)
+        self.assertEqual(void_tx.source_transaction_id, source_tx)
+
+    @mute_logger('odoo.addons.payment_adyen.models.payment_transaction')
+    def test_tx_state_after_send_full_capture_request(self):
+        self.provider.capture_manually = True
+        tx = self._create_transaction('direct', state='authorized')
+
+        with patch(
+            'odoo.addons.payment.models.payment_provider.PaymentProvider._send_api_request',
+            return_value={'status': 'received'},
+        ):
+            tx._capture()
+        self.assertEqual(
+            tx.state,
+            'authorized',
+            msg="A capture request as been made, but the state of the transaction stays as "
+                "'authorized' until a success notification is sent",
+        )
+
+    @mute_logger('odoo.addons.payment_adyen.models.payment_transaction')
+    def test_tx_state_after_partial_capture_request(self):
+        self.provider.capture_manually = True
+        tx = self._create_transaction('direct', state='authorized')
+
+        with patch(
+            'odoo.addons.payment.models.payment_provider.PaymentProvider._send_api_request',
+            return_value={'status': 'received'},
+        ):
+            tx._capture(amount_to_capture=10)
+        self.assertEqual(
+            tx.state,
+            'authorized',
+            msg="A partial capture request as been made, but the state of the source transaction "
+                "stays as 'authorized' until the full amount is either done or canceled.",
+        )
+        self.assertEqual(
+            tx.child_transaction_ids[0].state,
+            'draft',
+            msg="A partial capture request as been made, but the state of the child transaction "
+                "stays as 'draft' until a success notification is sent.",
+        )
+
+    @mute_logger('odoo.addons.payment_adyen.models.payment_transaction')
+    def test_tx_state_after_send_void_request(self):
+        self.provider.capture_manually = True
+        tx = self._create_transaction('direct', state='authorized')
+
+        with patch(
+            'odoo.addons.payment.models.payment_provider.PaymentProvider._send_api_request',
+            return_value={'status': 'received'},
+        ):
+            tx._void()
+        self.assertEqual(
+            tx.state,
+            'authorized',
+            msg="A void request as been made, but the state of the transaction stays as"
+                " 'authorized' until a success notification is sent",
+        )
+
+    def test_extract_token_values_maps_fields_correctly(self):
+        tx = self._create_transaction('direct')
+        payment_data = {
+            'additionalData': {
+                'recurring.recurringDetailReference': 'token_reference',
+                'cardSummary': '4242',
+                'recurring.shopperReference': 'partner_reference',
+            },
+        }
+        token_values = tx._extract_token_values(payment_data)
+        self.assertDictEqual(token_values, {
+            'provider_ref': 'token_reference',
+            'payment_details': '4242',
+            'adyen_shopper_reference': 'partner_reference',
+        })
+
+    def test_webhook_notification_confirms_transaction(self):
+        tx = self._create_transaction('direct')
+        self._webhook_notification_flow(self.webhook_notification_batch_data)
+        self.assertEqual(tx.state, 'done')
+
+    def test_webhook_notification_authorizes_transaction(self):
+        self.provider.capture_manually = True
+        tx = self._create_transaction('direct')
+        self._webhook_notification_flow(self.webhook_notification_batch_data)
+        self.assertEqual(
+            tx.state,
+            'authorized',
+            msg="The authorization succeeded, the manual capture is enabled, the tx state should be"
+                " 'authorized'.",
+        )
+
+    def test_webhook_notification_captures_transaction(self):
+        self.provider.capture_manually = True
+        tx = self._create_transaction(
+            'direct', state='authorized', provider_reference=self.original_reference, amount=9.99
+        )
+        payload = dict(self.webhook_notification_batch_data, notificationItems=[{
+            'NotificationRequestItem': dict(
+                self.webhook_notification_payload,
+                amount={
+                    'currency': self.currency.name,
+                    'value': payment_utils.to_minor_currency_units(9.99, tx.currency_id),
+                },
+                eventCode='CAPTURE',
+            )
+        }])
+        self._webhook_notification_flow(payload)
+        self.assertEqual(
+            tx.state, 'done',
+            msg="The capture succeeded, the tx state should be 'done'.",
+        )
+
+    def test_webhook_notification_cancels_transaction(self):
+        tx = self._create_transaction(
+            'direct', state='pending', provider_reference=self.original_reference, amount=9.99
+        )
+        payload = dict(self.webhook_notification_batch_data, notificationItems=[{
+            'NotificationRequestItem': dict(
+                self.webhook_notification_payload,
+                amount={
+                    'currency': self.currency.name,
+                    'value': payment_utils.to_minor_currency_units(9.99, tx.currency_id),
+                },
+                eventCode='CANCELLATION',
+            )
+        }])
+        self._webhook_notification_flow(payload)
+        self.assertEqual(
+            tx.state,
+            'cancel',
+            msg="The cancellation succeeded, the tx state should be 'cancel'.",
+        )
+
+    def test_webhook_notification_refunds_transaction(self):
+        source_tx = self._create_transaction(
+            'direct', state='done', provider_reference=self.original_reference
+        )
+        payload = dict(self.webhook_notification_batch_data, notificationItems=[{
+            'NotificationRequestItem': dict(
+                self.webhook_notification_payload,
+                amount={
+                    'currency': self.currency.name,
+                    'value': payment_utils.to_minor_currency_units(
+                        self.amount, source_tx.currency_id
+                    ),
+                },
+                eventCode='REFUND',
+            )
+        }])
+        self._webhook_notification_flow(payload)
+        refund_tx = self.env['payment.transaction'].search(
+            [('source_transaction_id', '=', source_tx.id)]
+        )
+        self.assertEqual(
+            refund_tx.state,
+            'done',
+            msg="After a successful refund notification, the refund state should be in 'done'.",
+        )
+
+    def test_failed_webhook_authorization_notification_leaves_transaction_in_draft(self):
+        tx = self._create_transaction('direct')
+        payload = dict(self.webhook_notification_batch_data, notificationItems=[
+            {'NotificationRequestItem': dict(self.webhook_notification_payload, success='false')}
+        ])
+        self._webhook_notification_flow(payload)
+        self.assertEqual(
+            tx.state, 'draft',
+            msg="The authorization failed, as we don't support failed authorization, the tx state "
+                "should still be 'draft'.",
+        )
+
+    def test_failed_webhook_capture_notification_leaves_transaction_authorized(self):
+        tx = self._create_transaction(
+            'direct', state='authorized', provider_reference=self.original_reference
+        )
+        payload = dict(self.webhook_notification_batch_data, notificationItems=[{
+            'NotificationRequestItem': dict(
+                self.webhook_notification_payload, eventCode='CAPTURE', success='false'
+            )
+        }])
+        self._webhook_notification_flow(payload)
+        self.assertEqual(
+            tx.state, 'authorized',
+            msg="The capture failed, the tx state should still be 'authorized'.",
+        )
+
+    def test_failed_webhook_cancellation_notification_leaves_transaction_authorized(self):
+        tx = self._create_transaction('direct', state='authorized')
+        payload = dict(self.webhook_notification_batch_data, notificationItems=[{
+            'NotificationRequestItem': dict(
+                self.webhook_notification_payload, eventCode='CANCELLATION', success='false'
+            )
+        }])
+        self._webhook_notification_flow(payload)
+        self.assertEqual(
+            tx.state, 'authorized',
+            msg="The cancellation failed, the tx state should still be 'authorized'.",
+        )
+
+    def test_failed_webhook_refund_notification_sets_refund_transaction_in_error(self):
+        source_tx = self._create_transaction(
+            'direct', state='done', provider_reference=self.original_reference
+        )
+        payload = dict(self.webhook_notification_batch_data, notificationItems=[{
+            'NotificationRequestItem': dict(
+                self.webhook_notification_payload,
+                amount={
+                    'currency': self.currency.name,
+                    'value': payment_utils.to_minor_currency_units(
+                        self.amount, source_tx.currency_id
+                    ),
+                },
+                eventCode='REFUND',
+                success='false',
+            )
+        }])
+        self._webhook_notification_flow(payload)
+        refund_tx = self.env['payment.transaction'].search([
+            ('source_transaction_id', '=', source_tx.id)]
+        )
+        self.assertEqual(
+            refund_tx.state,
+            'error',
+            msg="After a failed refund notification, the refund state should be in 'error'.",
+        )
+
+    @mute_logger('odoo.addons.payment_adyen.controllers.main')
+    @mute_logger('odoo.addons.payment_adyen.models.payment_transaction')
+    def _webhook_notification_flow(self, payload):
+        """ Send a notification to the webhook, ignore the signature, and check the response. """
+        url = self._build_url(AdyenController._webhook_url)
+        with patch('odoo.addons.payment_adyen.controllers.main.AdyenController._verify_signature'):
+            response = self._make_json_request(url, data=payload).json()
+        self.assertEqual(
+            response, '[accepted]', msg="The webhook should always respond '[accepted]'",
+        )
+
+    @mute_logger('odoo.addons.payment_adyen.controllers.main')
+    def test_webhook_notification_triggers_signature_check(self):
+        """ Test that receiving a webhook notification triggers a signature check. """
+        self._create_transaction('direct')
+        url = self._build_url(AdyenController._webhook_url)
+        with patch(
+            'odoo.addons.payment_adyen.controllers.main.AdyenController._verify_signature'
+        ) as signature_check_mock, patch(
+            'odoo.addons.payment.models.payment_transaction.PaymentTransaction._process'
+        ):
+            self._make_json_request(url, data=self.webhook_notification_batch_data)
+            self.assertEqual(signature_check_mock.call_count, 1)
+
+    def test_accept_webhook_notification_with_valid_signature(self):
+        """ Test the verification of a webhook notification with a valid signature. """
+        tx = self._create_transaction('direct')
+        self._assert_does_not_raise(
+            Forbidden, AdyenController._verify_signature, self.webhook_notification_payload, tx
+        )
+
+    @mute_logger('odoo.addons.payment_adyen.controllers.main')
+    def test_reject_webhook_notification_with_missing_signature(self):
+        """ Test the verification of a webhook notification with a missing signature. """
+        payload = dict(self.webhook_notification_payload, additionalData={'hmacSignature': None})
+        tx = self._create_transaction('direct')
+        self.assertRaises(Forbidden, AdyenController._verify_signature, payload, tx)
+
+    @mute_logger('odoo.addons.payment_adyen.controllers.main')
+    def test_reject_webhook_notification_with_invalid_signature(self):
+        """ Test the verification of a webhook notification with an invalid signature. """
+        payload = dict(self.webhook_notification_payload, additionalData={'hmacSignature': 'dummy'})
+        tx = self._create_transaction('direct')
+        self.assertRaises(Forbidden, AdyenController._verify_signature, payload, tx)
+
+    @mute_logger('odoo.addons.payment_adyen.models.payment_transaction')
+    def test_no_information_missing_from_partner_address(self):
+        test_partner = self.env['res.partner'].create({
+            'name': 'Dummy Partner',
+            'email': 'norbert.buyer@example.com',
+            'phone': '0032 12 34 56 78',
+        })
+        test_address = adyen_utils.format_partner_address(test_partner)
+        for key in ('city', 'country', 'stateOrProvince', 'street',):
+            self.assertTrue(test_address.get(key))
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/utils.py b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/utils.py
new file mode 100644
index 00000000..242cca3a
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/utils.py
@@ -0,0 +1,63 @@
+
+from odoo.addons.payment import utils as payment_utils
+
+
+def format_partner_name(partner_name):
+    """ Format the partner name to comply with the payload structure of the API request.
+
+    :param str partner_name: The name of the partner making the payment.
+    :return: The formatted partner name.
+    :rtype: dict
+    """
+    first_name, last_name = payment_utils.split_partner_name(partner_name)
+    return {
+        'firstName': first_name,
+        'lastName': last_name,
+    }
+
+
+def include_partner_addresses(tx_sudo):
+    """ Include the billing and delivery addresses of the related sales order to the payload of the
+    API request.
+
+    If no related sales order exists, the addresses are not included.
+
+    Note: `self.ensure_one()`
+
+    :param payment.transaction tx_sudo: The sudoed transaction of the payment.
+    :return: The subset of the API payload that includes the billing and delivery addresses.
+    :rtype: dict
+    """
+    tx_sudo.ensure_one()
+
+    if 'sale_order_ids' in tx_sudo._fields:  # The module `sale` is installed.
+        order = tx_sudo.sale_order_ids[:1]
+        if order:
+            return {
+                'billingAddress': format_partner_address(order.partner_invoice_id),
+                'deliveryAddress': format_partner_address(order.partner_shipping_id),
+            }
+    return {}
+
+
+def format_partner_address(partner):
+    """ Format the partner address to comply with the payload structure of the API request.
+
+    :param res.partner partner: The partner making the payment.
+    :return: The formatted partner address.
+    :rtype: dict
+    """
+    street_data = partner._get_street_split()
+    # Unlike what is stated in https://docs.adyen.com/risk-management/avs-checks/, not all fields
+    # are required at all time. Thus, we fall back to 'Unknown' when a field is not set to avoid
+    # blocking the payment (empty string are not accepted) or passing `False` (which may not pass
+    # the fraud check).
+    return {
+        'city': partner.city or 'Unknown',
+        'country': partner.country_id.code or 'ZZ',  # 'ZZ' if the country is not known.
+        'stateOrProvince': partner.state_id.code or 'Unknown',  # The state is not always required.
+        'postalCode': partner.zip or '',
+        # Fill in the address fields if the format is supported, or fallback to the raw address.
+        'street': street_data.get('street_name', partner.street) or 'Unknown',
+        'houseNumberOrName': street_data.get('street_number') or '',
+    }
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/views/payment_adyen_templates.xml b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/views/payment_adyen_templates.xml
new file mode 100644
index 00000000..073d91f4
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/views/payment_adyen_templates.xml
@@ -0,0 +1,8 @@
+
+
+
+    
+
+
diff --git a/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/views/payment_form_templates.xml b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/views/payment_form_templates.xml
new file mode 100644
index 00000000..6c1e6811
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_adyen/payment_adyen/views/payment_form_templates.xml
@@ -0,0 +1,27 @@
+
+
+
+    
+    
+
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/README.md b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/README.md
new file mode 100644
index 00000000..a78abbce
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/README.md
@@ -0,0 +1,44 @@
+# Worldline
+
+## Technical details
+
+API: [Worldline Direct API](https://docs.direct.worldline-solutions.com/en/api-reference)
+version `2`
+
+This module integrates Worldline using the generic payment with redirection flow based on form
+submission provided by the `payment` module.
+
+This is achieved by following the [Hosted Checkout Page]
+(https://docs.direct.worldline-solutions.com/en/integration/basic-integration-methods/hosted-checkout-page)
+guide.
+
+## Supported features
+
+- Payment with redirection flow
+- Webhook notifications
+- Tokenization with payment
+
+## Not implemented features
+
+- Tokenization without payment
+- Manual capture
+- Refunds
+
+## Module history
+
+- `18.0`
+  - The first version of the module is merged. odoo/odoo#175194.
+
+## Testing instructions
+
+https://docs.direct.worldline-solutions.com/en/integration/how-to-integrate/test-cases/index
+
+Use any name, any date in the future, and any 3 or 4 digits CVC.
+
+### VISA
+
+**Card Number**: `4330264936344675`
+
+### 3D Secure 2 (VISA)
+
+**Card Number**: `4874970686672022`
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/__init__.py b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/__init__.py
new file mode 100644
index 00000000..fda2a151
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/__init__.py
@@ -0,0 +1,14 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import controllers
+from . import models
+
+from odoo.addons.payment import setup_provider, reset_payment_provider
+
+
+def post_init_hook(env):
+    setup_provider(env, 'worldline')
+
+
+def uninstall_hook(env):
+    reset_payment_provider(env, 'worldline')
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/__manifest__.py b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/__manifest__.py
new file mode 100644
index 00000000..15ff0e74
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/__manifest__.py
@@ -0,0 +1,25 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+{
+    'name': "Payment Provider: Worldline",
+    'category': 'Accounting/Payment Providers',
+    'sequence': 350,
+    'summary': "A French payment provider covering several European countries.",
+    'description': " ",  # Non-empty string to avoid loading the README file.
+    'depends': ['payment'],
+    'data': [
+        'views/payment_provider_views.xml',
+        'views/payment_worldline_templates.xml',
+
+        'data/payment_provider_data.xml',
+    ],
+    'assets': {
+        'web.assets_frontend': [
+            'payment_worldline/static/src/interactions/payment_form.js',
+        ],
+    },
+    'post_init_hook': 'post_init_hook',
+    'uninstall_hook': 'uninstall_hook',
+    'author': 'Odoo S.A.',
+    'license': 'LGPL-3',
+}
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/const.py b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/const.py
new file mode 100644
index 00000000..e99ab8a7
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/const.py
@@ -0,0 +1,77 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+# The codes of the payment methods to activate when Worldline is activated.
+DEFAULT_PAYMENT_METHOD_CODES = {
+    # Primary payment methods.
+    'card',
+    # Brand payment methods.
+    'amex',
+    'discover',
+    'mastercard',
+    'visa',
+}
+
+# Mapping of payment method codes to Worldline codes.
+# See https://docs.direct.worldline-solutions.com/en/payment-methods-and-features/index.
+PAYMENT_METHODS_MAPPING = {
+    'alipay_plus': 5405,
+    'amex': 2,
+    'bancontact': 3012,
+    'bizum': 5001,
+    'cartes_bancaires': 130,
+    'cofidis': 3012,
+    'diners': 132,
+    'discover': 128,
+    'eps': 5406,
+    'floa_bank': 5139,
+    'ideal': 809,
+    'jcb': 125,
+    'klarna': 3301,
+    'maestro': 117,
+    'mastercard': 3,
+    'mbway': 5908,
+    'multibanco': 5500,
+    'p24': 3124,
+    'paypal': 840,
+    'post_finance_pay': 3203,
+    'twint': 5407,
+    'upi': 56,
+    'visa': 1,
+    'wechat_pay': 5404,
+}
+
+# The payment methods that involve a redirection to 3rd parties by Worldline.
+REDIRECT_PAYMENT_METHODS = {
+    'alipay_plus',
+    'bizum',
+    'eps',
+    'floa_bank',
+    'ideal',
+    'klarna',
+    'mbway',
+    'multibanco',
+    'p24',
+    'paypal',
+    'post_finance_pay',
+    'twint',
+    'wechat_pay',
+}
+
+# Mapping of transaction states to Worldline's payment statuses.
+# See https://docs.direct.worldline-solutions.com/en/integration/api-developer-guide/statuses.
+PAYMENT_STATUS_MAPPING = {
+    'pending': (
+        'CREATED', 'REDIRECTED', 'AUTHORIZATION_REQUESTED', 'PENDING_CAPTURE', 'CAPTURE_REQUESTED'
+    ),
+    'done': ('CAPTURED',),
+    'cancel': ('CANCELLED',),
+    'declined': ('REJECTED', 'REJECTED_CAPTURE'),
+}
+
+# Mapping of response codes indicating Worldline handled the request
+# See https://apireference.connect.worldline-solutions.com/s2sapi/v1/en_US/json/response-codes.html.
+VALID_RESPONSE_CODES = {
+    200: 'Successful',
+    201: 'Created',
+    402: 'Payment Rejected',
+}
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/controllers/__init__.py b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/controllers/__init__.py
new file mode 100644
index 00000000..80ee4da1
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/controllers/__init__.py
@@ -0,0 +1,3 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import main
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/controllers/main.py b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/controllers/main.py
new file mode 100644
index 00000000..8bce6166
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/controllers/main.py
@@ -0,0 +1,98 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import hashlib
+import hmac
+import pprint
+from base64 import b64encode
+
+from werkzeug.exceptions import Forbidden
+
+from odoo import http
+from odoo.exceptions import ValidationError
+from odoo.http import request
+
+from odoo.addons.payment.logging import get_payment_logger
+
+
+_logger = get_payment_logger(__name__)
+
+
+class WorldlineController(http.Controller):
+    _return_url = '/payment/worldline/return'
+    _webhook_url = '/payment/worldline/webhook'
+
+    @http.route(_return_url, type='http', auth='public', methods=['GET'])
+    def worldline_return_from_checkout(self, **data):
+        """Process the payment data sent by Worldline after redirection.
+
+        :param dict data: The payment data, including the provider id appended to the URL in
+                          `_get_specific_rendering_values`.
+        """
+        _logger.info("Handling redirection from Worldline with data:\n%s", pprint.pformat(data))
+
+        provider_id = int(data['provider_id'])
+        provider_sudo = request.env['payment.provider'].sudo().browse(provider_id).exists()
+        if not provider_sudo or provider_sudo.code != 'worldline':
+            _logger.warning("Received payment data with invalid provider id.")
+            raise Forbidden()
+
+        try:
+            # Fetch the checkout session data from Worldline.
+            checkout_session_data = provider_sudo._send_api_request(
+                'GET', f'hostedcheckouts/{data["hostedCheckoutId"]}'
+            )
+        except ValidationError:
+            _logger.error("Unable to process the payment data")
+        else:
+            payment_data = checkout_session_data.get('createdPaymentOutput', {})
+            request.env['payment.transaction'].sudo()._process(
+                'worldline', payment_data
+            )
+        return request.redirect('/payment/status')
+
+    @http.route(_webhook_url, type='http', auth='public', methods=['POST'], csrf=False)
+    def worldline_webhook(self):
+        """Process the payment data sent by Worldline to the webhook.
+
+        See https://docs.direct.worldline-solutions.com/en/integration/api-developer-guide/webhooks.
+
+        :return: An empty string to acknowledge the notification.
+        :rtype: str
+        """
+        data = request.get_json_data()
+        _logger.info(
+            "Notification received from Worldline with data:\n%s", pprint.pformat(data)
+        )
+
+        # Check the integrity of the notification.
+        tx_sudo = request.env['payment.transaction'].sudo()._search_by_reference('worldline', data)
+        if tx_sudo:
+            received_signature = request.httprequest.headers.get('X-GCS-Signature')
+            request_data = request.httprequest.data
+            self._verify_signature(request_data, received_signature, tx_sudo)
+            tx_sudo._process('worldline', data)
+        return request.make_json_response('')  # Acknowledge the notification.
+
+    @staticmethod
+    def _verify_signature(request_data, received_signature, tx_sudo):
+        """Check that the received signature matches the expected one.
+
+        :param dict|bytes request_data: The request data.
+        :param str received_signature: The signature to compare with the expected signature.
+        :param payment.transaction tx_sudo: The sudoed transaction referenced by the payment data.
+        :return: None
+        :raise Forbidden: If the signatures don't match.
+        """
+        # Retrieve the received signature from the payload.
+        if not received_signature:
+            _logger.warning("Received payment data with missing signature.")
+            raise Forbidden()
+
+        # Compare the received signature with the expected signature computed from the payload.
+        webhook_secret = tx_sudo.provider_id.worldline_webhook_secret
+        expected_signature = b64encode(
+            hmac.new(webhook_secret.encode(), request_data, hashlib.sha256).digest()
+        )
+        if not hmac.compare_digest(received_signature.encode(), expected_signature):
+            _logger.warning("Received payment data with invalid signature.")
+            raise Forbidden()
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/data/neutralize.sql b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/data/neutralize.sql
new file mode 100644
index 00000000..b9c7da57
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/data/neutralize.sql
@@ -0,0 +1,7 @@
+-- disable worldline payment provider
+UPDATE payment_provider
+   SET worldline_pspid = NULL,
+       worldline_api_key = NULL,
+       worldline_api_secret = NULL,
+       worldline_webhook_key = NULL,
+       worldline_webhook_secret = NULL;
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/data/payment_provider_data.xml b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/data/payment_provider_data.xml
new file mode 100644
index 00000000..db4c3a82
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/data/payment_provider_data.xml
@@ -0,0 +1,10 @@
+
+
+
+    
+        worldline
+        
+        True
+    
+
+
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ar.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ar.po
new file mode 100644
index 00000000..3f3996ce
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ar.po
@@ -0,0 +1,152 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 13:46+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Arabic \n"
+"Language: ar\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
+"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "مفتاح الواجهة البرمجية للتطبيق"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr "سر الواجهة البرمجية للتطبيق"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "رمز"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "تعذر إنشاء الاتصال بالواجهة البرمجية للتطبيق."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "لم يتم العثور على معاملة تطابق المرجع %s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "مزود الدفع"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "معاملة الدفع"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "تم استلام البيانات دون حالة الدفع."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "تم استلام البيانات دون مرجع %(ref)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr "تم استلام حالة معاملة غير صالحة %(status)s مع كود الخطأ %(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "فشل التواصل مع الواجهة البرمجية. التفاصيل: %s"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "الكود التقني لمزود الدفع هذا."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "المعاملة غير مرتبطة برمز."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr "تم إلغاء المعاملة مع رمز الخطأ %(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr "تم رفض المعاملة مع رمز الخطأ %(error_code)s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr "مفتاح Webhook"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "سر Webhook"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr "Worldline API Key"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr "Worldline API Secret"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr "Worldline PSPID"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr "Worldline Webhook Key"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr "Worldline Webhook Secret"
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/az.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/az.po
new file mode 100644
index 00000000..b3cc1162
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/az.po
@@ -0,0 +1,147 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_worldline
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/bg.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/bg.po
new file mode 100644
index 00000000..b3cc1162
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/bg.po
@@ -0,0 +1,147 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_worldline
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ca.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ca.po
new file mode 100644
index 00000000..e912dc5b
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ca.po
@@ -0,0 +1,151 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 04:48+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Catalan \n"
+"Language: ca\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "API Key"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr "Clau secreta de l'API"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Codi"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "No s'ha pogut establir la connexió a l'API."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "No s'ha trobat cap transacció que coincideixi amb la referència %s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Proveïdor de pagament"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transacció de pagament"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Dades rebudes amb estat de pagament absent."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "Dades rebudes sense referència %(ref)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "El codi tècnic d'aquest proveïdor de pagaments."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "La transacció no està enllaçada a un token."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/cs.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/cs.po
new file mode 100644
index 00000000..23eb7c4f
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/cs.po
@@ -0,0 +1,151 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-17 17:23+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Czech \n"
+"Language: cs\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "Klíč API"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Kód"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Nepodařilo se navázat spojení s rozhraním API."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Nebyla nalezena žádná transakce odpovídající odkazu %s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Poskytovatel platby"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Platební transakce"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Technický kód tohoto poskytovatele plateb."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "Transakce není spojena s tokenem."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/da.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/da.po
new file mode 100644
index 00000000..a7192a2c
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/da.po
@@ -0,0 +1,151 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-14 21:18+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Danish \n"
+"Language: da\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "API nøgle"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Kode"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Det var ikke muligt at oprette forbindelse til API'et."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Betalingsudbyder"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Betalingstransaktion"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Webhook-hemmelighed"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/de.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/de.po
new file mode 100644
index 00000000..6cf915b0
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/de.po
@@ -0,0 +1,153 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 02:32+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: German \n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "API-Schlüssel"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr "API-Geheimnis"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Code"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Verbindung mit API konnte nicht hergestellt werden."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Keine Transaktion gefunden, die der Referenz %s entspricht."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Zahlungsanbieter"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Zahlungstransaktion"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Erhaltene Daten mit fehlendem Zahlungsstatus."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "Erhaltene Daten mit fehlender Referenz %(ref)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+"Ungültigen Transaktionsstatus %(status)s mit Fehlercode %(error_code)s "
+"erhalten"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "Die Kommunikation mit der API ist fehlgeschlagen. Details: %s"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Der technische Code dieses Zahlungsanbieters."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "Die Transaktion ist nicht mit einem Token verknüpft."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr "Transaktion mit Fehlercode %(error_code)s storniert."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr "Transaktion mit Fehlercode %(error_code)s abgelehnt."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr "Webhook-Schlüssel"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Webhook-Geheimnis"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr "API-Schlüssel von Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr "API-Geheimnis von Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr "PSPID von Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr "Webhook-Schlüssel von Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr "Webhook-Geheimnis von Worldline"
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/el.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/el.po
new file mode 100644
index 00000000..27a052e5
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/el.po
@@ -0,0 +1,151 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-24 19:24+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Greek \n"
+"Language: el\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "Κλειδί API"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Κωδικός"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Πάροχος Πληρωμών"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Συναλλαγή Πληρωμής"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/es.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/es.po
new file mode 100644
index 00000000..22043f3d
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/es.po
@@ -0,0 +1,153 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-17 17:24+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Spanish \n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "Clave API"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr "Secreto API"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Código"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "No se ha podido establecer la conexión con la API."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "No se encontró ninguna transacción que coincida con la referencia %s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Proveedor de pago"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transacción de pago"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Datos recibidos sin estado de pago."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "Datos recibidos sin referencia %(ref)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+"Se ha recibido un estado de transacción no válido %(status)s con el código "
+"de error %(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "Falló la comunicación con la API. Más información: %s"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "El código técnico de este proveedor de pago."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "La transacción no está vinculada a un token."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr "Transacción cancelada con el código de error %(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr "Transacción rechazada con el código de error %(error_code)s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr "Clave del webhook"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Secreto de webhook"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr "Clave API de Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr "Secreto API de Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr "PSPID de Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr "Clave del webhook de Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr "Secreto del webhook de Worldline"
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/es_419.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/es_419.po
new file mode 100644
index 00000000..978aa77b
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/es_419.po
@@ -0,0 +1,153 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-17 06:31+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Spanish (Latin America) \n"
+"Language: es_419\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "Clave API"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr "Secreto de la API"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Código"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "No se pudo establecer la conexión con la API."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "No se encontró ninguna transacción que coincida con la referencia %s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "Identificador del proveedor de servicios de pago"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Proveedor de pago"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transacción de pago"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Datos recibidos con estado de pago pendiente."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "Se recibió información con la referencia faltante %(ref)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+"Se recibió el estado %(status)s de la transacción que no es válido con el "
+"código de error %(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "Ocurrió un error en la comunicación con la API. Detalles: %s"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "El código técnico de este proveedor de pagos."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "La transacción no está vinculada a un token."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr "Transacción cancelada con el código de error %(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr "Transacción rechazada con el código de error %(error_code)s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr "Clave del webhook"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Secreto del webhook"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr "Clave API de Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr "Secreto API de Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr "PSPID de Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr "Clave del webhook de Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr "Secreto del webhook de Worldline"
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/et.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/et.po
new file mode 100644
index 00000000..ceb5a6d2
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/et.po
@@ -0,0 +1,129 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_worldline
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 19.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:59+0000\n"
+"PO-Revision-Date: 2025-09-11 13:59+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/fa.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/fa.po
new file mode 100644
index 00000000..b3cc1162
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/fa.po
@@ -0,0 +1,147 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_worldline
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/fi.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/fi.po
new file mode 100644
index 00000000..0aa602b0
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/fi.po
@@ -0,0 +1,153 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 15:37+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Finnish \n"
+"Language: fi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "API-avain"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr "API-salaus"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Koodi"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Yhteyttä API:in ei voitu muodostaa."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Viitettä %s vastaavaa tapahtumaa ei löytynyt."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Maksupalveluntarjoaja"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Maksutapahtuma"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Vastaanotetut tiedot, joista puuttuu maksutila."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "Vastaanotetut tiedot, joista puuttuu viite %(ref)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+"Vastaanotettu virheellinen maksutapahtuman tila %(status)s, jonka virhekoodi "
+"%(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "Yhteyden muodostaminen API:in epäonnistui. Virhetiedot: %s"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Tämän maksupalveluntarjoajan tekninen koodi."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "Transaktio ei ole sidottu valtuutuskoodiin."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr "Maksutapahtuma peruutettiin virhekoodin %(error_code)s vuoksi."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr "Tapahtuma hylätty virhekoodilla %(error_code)s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr "Webhook-avain"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Webhookin salaisuus"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr "Worldline API-avain"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr "Worldline API-salaus"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr "Worldline PSPID"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr "Worldline Webhook-avain"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr "Worldline Webhook Secret"
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/fr.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/fr.po
new file mode 100644
index 00000000..0ef06b38
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/fr.po
@@ -0,0 +1,153 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-17 17:28+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: French \n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n > 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "Clé API"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr "Secret API"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Code"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Impossible d'établir la connexion à l'API."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Aucune transaction trouvée correspondant à la référence %s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Fournisseur de paiement"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transaction de paiement"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Données reçues avec un statut de paiement manquant."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "Données reçus avec référence manquante %(ref)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+"Statut de transaction invalide reçu : %(status)s avec le code d'erreur "
+"%(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "Échec de la communication avec l'API. Détails : %s"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Le code technique de ce fournisseur de paiement."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "La transaction n'est pas liée à un jeton."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr "Transaction annulée avec le code d'erreur %(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr "Transaction refusée avec le code d'erreur %(error_code)s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr "Clé Webhook"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Secret webhook"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr "Clé API Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr "Secret API Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr "PSPID Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr "Clé Webhook Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr "Secret Webhook Worldline"
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/he.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/he.po
new file mode 100644
index 00000000..b3cc1162
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/he.po
@@ -0,0 +1,147 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_worldline
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/hi.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/hi.po
new file mode 100644
index 00000000..b3cc1162
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/hi.po
@@ -0,0 +1,147 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_worldline
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/hr.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/hr.po
new file mode 100644
index 00000000..b3cc1162
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/hr.po
@@ -0,0 +1,147 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_worldline
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/hu.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/hu.po
new file mode 100644
index 00000000..4ab0a30a
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/hu.po
@@ -0,0 +1,151 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-29 19:48+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Hungarian \n"
+"Language: hu\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "API kulcs"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Kód"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Fizetési szolgáltató"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Fizetési tranzakció"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Webhook Secret"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/id.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/id.po
new file mode 100644
index 00000000..938cb55e
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/id.po
@@ -0,0 +1,153 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 02:35+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Indonesian \n"
+"Language: id\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "API Key"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr "API Secret"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Code"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Tidak dapat membuat hubungan ke API."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Tidak ada transaksi dengan referensi %s yang cocok."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Penyedia Pembayaran"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transaksi Tagihan"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Menerima data dengan status pembayaran yang hilang."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "Menerima data dengan referensi %(ref)s yang hilang."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+"Menerima status transaksi tidak valid %(status)s dengan kode error "
+"%(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "Komunikasi dengan API gagal. Detail: %s"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Kode teknis penyedia pembayaran ini."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "Transaksi ini tidak terhubung ke token."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr "Transaksi dibatalkan dengan kode error %(error_code)s"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr "Transaksi dibatalkan dengan kode error %(error_code)s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr "Webhook Key"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Webhook Secret"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr "Worldline API Key"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr "Worldline API Secret"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr "Worldline PSPID"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr "Worldline Webhook Key"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr "Worldline Webhook Secret"
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/it.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/it.po
new file mode 100644
index 00000000..07b6dd19
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/it.po
@@ -0,0 +1,153 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-17 17:21+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Italian \n"
+"Language: it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "Chiave API"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr "Chiave privata API"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Codice"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Impossibile stabilire la connessione all'API."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Nessuna transazione trovata corrispondente al riferimento %s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Fornitore di pagamenti"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transazione di pagamento"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Dati ricevuti con stato di pagamento mancante."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "Dati ricevuti privi di riferimento %(ref)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+"Stato transazione non valido ricevuto %(status)s con codice errore "
+"%(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "La comunicazione con l'API non è riuscita. Dettagli: %s"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Codice tecnico del fornitore di pagamenti."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "La transazione non è legata a un token."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr "Transazione annullata con codice errore %(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr "Transazione rifiutata con codice errore %(error_code)s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr "Chiave Webhook"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Segreto Webhook"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr "Chiave API Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr "Chiave segreta API Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr "PSPID Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr "Chiave Webhook Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr "Secret Webhook Worldline"
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ja.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ja.po
new file mode 100644
index 00000000..7f01c84f
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ja.po
@@ -0,0 +1,151 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-14 21:20+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Japanese \n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "APIキー"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr "APIシークレット"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "コード"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "APIへの接続を確立できませんでした。"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "参照に一致する取引が見つかりません%s。"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "決済プロバイダー"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "決済トランザクション"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "支払ステータスが欠落している受信データ"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "参照%(ref)sが欠落しているデータを受信しました。"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr "無効な取引ステータス%(status)sエラーコード: %(error_code)s を受信しました。"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "APIとの連絡に失敗しました。詳細: %s"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "この決済プロバイダーのテクニカルコード。"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "取引はトークンにリンクしていません。"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr "取引がキャンセルされました。エラーコード: %(error_code)s"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr "取引が却下されました。エラーコード: %(error_code)s"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr "Webhookキー"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Webhookシークレット"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr "Worldline APIキー"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr "Worldline APIシークレット"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr "Worldline PSPID"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr "Worldline Webhookキー"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr "Worldline Webhookシークレット"
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ko.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ko.po
new file mode 100644
index 00000000..2f4bfe1c
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ko.po
@@ -0,0 +1,151 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 04:48+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Korean \n"
+"Language: ko\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "API 키"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr "API 시크릿"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "코드"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "API 연결을 설정할 수 없습니다."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "%s 참조와 일치하는 거래 항목이 없습니다."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "결제대행업체"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "지불 거래"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "결제 상태가 누락된 데이터가 수신되었습니다."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "참조 %(ref)s가 누락된 데이터가 수신되었습니다."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr "잘못된 거래 상태 %(status)s 및 %(error_code)s 오류 코드가 수신되었습니다."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "API와의 통신에 실패했습니다. 세부 정보: %s"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "이 결제대행업체의 기술 코드입니다."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "거래가 토큰에 연결되어 있지 않습니다."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr "거래가 %(error_code)s 오류 코드로 취소되었습니다."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr "거래가 %(error_code)s 오류 코드로 거부되었습니다."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr "웹훅 키"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Webhook 보안"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr "Worldline API 키"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr "Worldline API 비밀번호"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr "월드라인 PSPID"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr "Worldline 웹훅 키"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr "Worldline 웹훅 비밀번호"
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ku.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ku.po
new file mode 100644
index 00000000..b3cc1162
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ku.po
@@ -0,0 +1,147 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_worldline
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/lt.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/lt.po
new file mode 100644
index 00000000..b3cc1162
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/lt.po
@@ -0,0 +1,147 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_worldline
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/mn.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/mn.po
new file mode 100644
index 00000000..b3cc1162
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/mn.po
@@ -0,0 +1,147 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_worldline
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/my.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/my.po
new file mode 100644
index 00000000..b3cc1162
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/my.po
@@ -0,0 +1,147 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_worldline
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/nb.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/nb.po
new file mode 100644
index 00000000..19d82b66
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/nb.po
@@ -0,0 +1,151 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 18:49+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Norwegian Bokmål \n"
+"Language: nb\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "API-nøkkel"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Kode"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Betalingsleverandør"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Betalingstransaksjon"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/nl.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/nl.po
new file mode 100644
index 00000000..6686f513
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/nl.po
@@ -0,0 +1,152 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-14 08:07+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Dutch \n"
+"Language: nl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "API key"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr "API Secret"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Code"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Kan geen verbinding maken met de API."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Geen transactie gevonden die overeenkomt met referentie %s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Betaalprovider"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Betalingstransactie"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Gegevens ontvangen met ontbrekende betalingsstatus."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "Gegevens ontvangen met ontbrekende referentie %(ref)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+"Ontvangen ongeldige transactiestatus %(status)s met foutcode %(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "De communicatie met de API is mislukt. Details: %s"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "De technische code van deze betaalprovider."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "De transactie is niet gekoppeld aan een token."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr "Transactie geannuleerd met foutcode %(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr "Transactie geweigerd met foutcode %(error_code)s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr "Webhook sleutel"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Webhook geheim"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr "Worldline API sleutel"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr "Worldline API Geheim"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr "PSPID Wereldlijn"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr "Worldline Webhook Sleutel"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr "Worldline Webhook Geheim"
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/payment_worldline.pot b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/payment_worldline.pot
new file mode 100644
index 00000000..ceb5a6d2
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/payment_worldline.pot
@@ -0,0 +1,129 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_worldline
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 19.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:59+0000\n"
+"PO-Revision-Date: 2025-09-11 13:59+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/pl.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/pl.po
new file mode 100644
index 00000000..f62ab43e
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/pl.po
@@ -0,0 +1,152 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-17 17:30+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Polish \n"
+"Language: pl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
+"|| n%100>=20) ? 1 : 2;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "Klucz API"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr "Klucz API"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Kod"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Nie można nawiązać połączenia z interfejsem API."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Nie znaleziono transakcji pasującej do referencji %s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Dostawca Płatności"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transakcja płatności"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Kod techniczny tego dostawcy usług płatniczych."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "Transakcja nie jest powiązana z tokenem."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Klucz Webhook"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr "Klucz API Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr "Klucz webhook worldline"
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/pt.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/pt.po
new file mode 100644
index 00000000..1defadff
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/pt.po
@@ -0,0 +1,153 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 18:49+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Portuguese \n"
+"Language: pt\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n > 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "Chave de API"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr "Segredo de API"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Código"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Não foi possível estabelecer a conexão com a API."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Nenhuma transação encontrada com a referência %s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Provedor de serviços de pagamento"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transação de pagamento"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Dados recebidos sem estado de pagamento."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "Dados recebidos sem a referência %(ref)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+"Status de transação inválido recebido %(status)s com código de erro "
+"%(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "A comunicação com a API falhou. Detalhes: %s"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "O código técnico deste provedor de pagamento."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "A transação não está vinculada a um token."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr "Transação cancelada com código de erro %(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr "Transação recusada com código de erro %(error_code)s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr "Chave do webhook"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Segredo do webhook"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr "Chave de API da Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr "Segredo da API da Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr "PSPID da Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr "Chave do Worldline Webhook"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr "Segredo do Worldline Webhook"
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/pt_BR.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/pt_BR.po
new file mode 100644
index 00000000..27c56838
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/pt_BR.po
@@ -0,0 +1,153 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-17 17:28+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Portuguese (Brazil) \n"
+"Language: pt_BR\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n > 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "Chave de API"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr "Segredo de API"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Código"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Não foi possível estabelecer a conexão com a API."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Nenhuma transação encontrada com a referência %s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Provedor de serviços de pagamento"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transação de pagamento"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Dados recebidos sem estado de pagamento."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "Dados recebidos sem a referência %(ref)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+"Status de transação inválido recebido %(status)s com código de erro "
+"%(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "A comunicação com a API falhou. Detalhes: %s"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "O código técnico deste provedor de pagamento."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "A transação não está vinculada a um token."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr "Transação cancelada com código de erro %(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr "Transação recusada com código de erro %(error_code)s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr "Chave do webhook"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Segredo do webhook"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr "Chave de API da Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr "Segredo da API da Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr "PSPID da Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr "Chave do Worldline Webhook"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr "Segredo do Worldline Webhook"
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ro.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ro.po
new file mode 100644
index 00000000..b3cc1162
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ro.po
@@ -0,0 +1,147 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_worldline
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ru.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ru.po
new file mode 100644
index 00000000..d0971b0d
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/ru.po
@@ -0,0 +1,152 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-17 17:29+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Russian \n"
+"Language: ru\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "Ключ API"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Код"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Не удалось установить соединение с API."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Не найдено ни одной транзакции, соответствующей ссылке %s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Поставщик платежей"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Платеж"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Получены данные с отсутствующим состоянием платежа."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "Получены данные с отсутствующей ссылкой %(ref)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "Не удалось установить связь с API. Подробности: %s"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Технический код данного провайдера платежей."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "Транзакция не привязана к токену."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Секрет вебхука"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/sl.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/sl.po
new file mode 100644
index 00000000..e4eb03be
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/sl.po
@@ -0,0 +1,152 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 21:29+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Slovenian \n"
+"Language: sl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || "
+"n%100==4 ? 2 : 3;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "API ključ"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Oznaka"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Ponudnik plačil"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Plačilna transakcija"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/sr@latin.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/sr@latin.po
new file mode 100644
index 00000000..b3cc1162
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/sr@latin.po
@@ -0,0 +1,147 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_worldline
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/sv.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/sv.po
new file mode 100644
index 00000000..583a8ca8
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/sv.po
@@ -0,0 +1,151 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 21:35+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Swedish \n"
+"Language: sv\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "API-nyckel"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Kod"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Det gick inte att upprätta anslutningen till API:et."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Ingen transaktion hittades som matchar referensen %s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Betalningsleverantör"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Betalningstransaktion"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Mottagen data med saknad betalningsstatus."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "Mottagna data med saknade referens %(ref)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "Kommunikationen med API:et misslyckades. Detaljerad information: %s"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Den tekniska koden för denna betalningsleverantör."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "Transaktionen är inte kopplad till en token."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Webhook hemlighet"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Världslinje"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/th.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/th.po
new file mode 100644
index 00000000..21d0fa22
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/th.po
@@ -0,0 +1,151 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 21:17+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Thai \n"
+"Language: th\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "API Key"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "โค้ด"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "ไม่สามารถสร้างการเชื่อมต่อกับ API ได้"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "ไม่พบธุรกรรมที่ตรงกับการอ้างอิง %s"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "ผู้ให้บริการชำระเงิน"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "ธุรกรรมสำหรับการชำระเงิน"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "ได้รับข้อมูลโดยไม่มีสถานะการชำระเงิน"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "ได้รับข้อมูลโดยไม่มีการอ้างอิง %(ref)s"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "การสื่อสารกับ API ล้มเหลว รายละเอียด: %s"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "รหัสทางเทคนิคของผู้ให้บริการชำระเงินรายนี้"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "ธุรกรรมไม่ได้เชื่อมโยงกับโทเค็น"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "เว็บฮุคลับ"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/tr.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/tr.po
new file mode 100644
index 00000000..4e36f24c
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/tr.po
@@ -0,0 +1,151 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-17 17:28+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Turkish \n"
+"Language: tr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "API Anahtarı"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Kod"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "API bağlantısı kurulamadı."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Referans %s eşleşen bir işlem bulunamadı."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Ödeme Sağlayıcı"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Ödeme İşlemi"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Ödeme durumu eksik olan veriler alındı."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Bu ödeme sağlayıcısının teknik kodu."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "İşlem bir belirteçle bağlantılı değildir."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/uk.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/uk.po
new file mode 100644
index 00000000..b3cc1162
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/uk.po
@@ -0,0 +1,147 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_worldline
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr ""
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/vi.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/vi.po
new file mode 100644
index 00000000..da4d7829
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/vi.po
@@ -0,0 +1,153 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 02:33+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Vietnamese \n"
+"Language: vi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "Khóa API"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr "Mã bí mật API"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "Mã"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Không thể thiết lập kết nối với API."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Không tìm thấy giao dịch nào khớp với mã %s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "Nhà cung cấp dịch vụ thanh toán"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Giao dịch thanh toán"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "Dữ liệu đã nhận bị thiếu trạng thái thanh toán."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "Dữ liệu đã nhận bị thiếu mã %(ref)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr ""
+"Trạng thái giao dịch không hợp lệ đã nhận %(status)s với mã lỗi "
+"%(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "Giao tiếp với API không thành công. Thông tin: %s"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Mã kỹ thuật của nhà cung cấp dịch vụ thanh toán này."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "Giao dịch không được liên kết với token."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr "Giao dịch bị hủy với mã lỗi %(error_code)s."
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr "Giao dịch bị từ chối với mã lỗi %(error_code)s."
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr "Khoá Webhook"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Mã bí mật Webhook"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr "Khoá API Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr "Mã bí mật API Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr "PSPID Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr "Khoá Webhook Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr "Mã bí mật Webhook Worldline"
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/zh_CN.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/zh_CN.po
new file mode 100644
index 00000000..3b1d318c
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/zh_CN.po
@@ -0,0 +1,151 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 15:37+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Chinese (Simplified Han script) \n"
+"Language: zh_CN\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "API 密钥"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr "API 密钥"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "代码"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "无法建立与API的连接。"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "没有发现与参考文献%s相匹配的交易。"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "支付提供商"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "付款交易"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "收到的数据中缺少支付状态。"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing reference %(ref)s."
+msgstr "收到的数据缺少参考编号%(ref)s。"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code "
+"%(error_code)s."
+msgstr "收到无效交易状态%(status)s,错误代码%(error_code)s。"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_provider.py:0
+msgid "The communication with the API failed. Details: %s"
+msgstr "与 API 通信失败。详情:%s"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "该支付提供商的技术代码。"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "该交易没有与令牌挂钩。"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr "交易已取消,错误代码:%(error_code)s。"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr "交易被拒绝,错误代码:%(error_code)s。"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr "Webhook 密钥"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "Webhook 密钥"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr "Worldline API 密钥"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr "Worldline API 密钥"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr "Worldline PSPID"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr "Worldline Webhook 密钥"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr "Worldline Webhook 密钥"
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/zh_TW.po b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/zh_TW.po
new file mode 100644
index 00000000..b58a6b13
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/i18n/zh_TW.po
@@ -0,0 +1,151 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_worldline
+#
+# Translators:
+# Wil Odoo, 2025
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~18.3\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:59+0000\n"
+"PO-Revision-Date: 2025-09-16 08:11+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Chinese (Traditional Han script) \n"
+"Language: zh_TW\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Key"
+msgstr "API 金鑰"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "API Secret"
+msgstr "API 秘密"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__code
+msgid "Code"
+msgstr "程式碼"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "顯示名稱"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_transaction__id
+msgid "ID"
+msgstr "識別號"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "PSPID"
+msgstr "PSPID"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_provider
+msgid "Payment Provider"
+msgstr "付款服務商"
+
+#. module: payment_worldline
+#: model:ir.model,name:payment_worldline.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "付款交易"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Received data with missing payment state."
+msgstr "收到的數據中缺漏付款狀態。"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid ""
+"Received invalid transaction status %(status)s with error code %"
+"(error_code)s."
+msgstr "收到無效交易,狀態:%(status)s,錯誤代碼:%(error_code)s。"
+
+#. module: payment_worldline
+#: model:ir.model.fields,help:payment_worldline.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "此付款服務商的技術代碼。"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction cancelled with error code %(error_code)s."
+msgstr "交易已取消,錯誤代碼:%(error_code)s。"
+
+#. module: payment_worldline
+#. odoo-python
+#: code:addons/payment_worldline/models/payment_transaction.py:0
+msgid "Transaction declined with error code %(error_code)s."
+msgstr "交易被拒絕,錯誤代碼:%(error_code)s。"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Key"
+msgstr "網絡鈎子密鑰"
+
+#. module: payment_worldline
+#: model_terms:ir.ui.view,arch_db:payment_worldline.payment_provider_form
+msgid "Webhook Secret"
+msgstr "網絡鈎子秘密"
+
+#. module: payment_worldline
+#: model:ir.model.fields.selection,name:payment_worldline.selection__payment_provider__code__worldline
+msgid "Worldline"
+msgstr "Worldline"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_key
+msgid "Worldline API Key"
+msgstr "Worldline API 金鑰"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_api_secret
+msgid "Worldline API Secret"
+msgstr "Worldline API 秘密"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_pspid
+msgid "Worldline PSPID"
+msgstr "Worldline PSPID"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_key
+msgid "Worldline Webhook Key"
+msgstr "Worldline 網絡鈎子金鑰"
+
+#. module: payment_worldline
+#: model:ir.model.fields,field_description:payment_worldline.field_payment_provider__worldline_webhook_secret
+msgid "Worldline Webhook Secret"
+msgstr "Worldline 網絡鈎子秘密"
+
+#~ msgid "Could not establish the connection to the API."
+#~ msgstr "未能建立與 API 的連線。"
+
+#~ msgid "No transaction found matching reference %s."
+#~ msgstr "沒有找到匹配參考 %s 的交易。"
+
+#~ msgid "Received data with missing reference %(ref)s."
+#~ msgstr "收到的數據中缺漏參考編號 %(ref)s。"
+
+#~ msgid "The communication with the API failed. Details: %s"
+#~ msgstr "與 API 通訊失敗。詳情:%s"
+
+#~ msgid "The transaction is not linked to a token."
+#~ msgstr "交易未有連結至代碼。"
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/models/__init__.py b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/models/__init__.py
new file mode 100644
index 00000000..08dfb8af
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/models/__init__.py
@@ -0,0 +1,4 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import payment_provider
+from . import payment_transaction
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/models/payment_provider.py b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/models/payment_provider.py
new file mode 100644
index 00000000..a9c521b3
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/models/payment_provider.py
@@ -0,0 +1,142 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import base64
+import hashlib
+import hmac
+from wsgiref.handlers import format_date_time
+
+from odoo import fields, models
+from odoo.fields import Datetime
+
+from odoo.addons.payment.logging import get_payment_logger
+from odoo.addons.payment_worldline import const
+
+
+_logger = get_payment_logger(__name__)
+
+
+class PaymentProvider(models.Model):
+    _inherit = 'payment.provider'
+
+    code = fields.Selection(
+        selection_add=[('worldline', "Worldline")], ondelete={'worldline': 'set default'}
+    )
+    worldline_pspid = fields.Char(
+        string="Worldline PSPID",
+        required_if_provider='worldline',
+        copy=False,
+    )
+    worldline_api_key = fields.Char(
+        string="Worldline API Key",
+        required_if_provider='worldline',
+        copy=False,
+    )
+    worldline_api_secret = fields.Char(
+        string="Worldline API Secret",
+        required_if_provider='worldline',
+        copy=False,
+    )
+    worldline_webhook_key = fields.Char(
+        string="Worldline Webhook Key",
+        required_if_provider='worldline',
+        copy=False,
+    )
+    worldline_webhook_secret = fields.Char(
+        string="Worldline Webhook Secret",
+        required_if_provider='worldline',
+        copy=False,
+    )
+
+    # === COMPUTE METHODS === #
+
+    def _compute_feature_support_fields(self):
+        """ Override of `payment` to enable additional features. """
+        super()._compute_feature_support_fields()
+        self.filtered(lambda p: p.code == 'worldline').update({
+            'support_tokenization': True,
+        })
+
+    # === CRUD METHODS === #
+
+    def _get_default_payment_method_codes(self):
+        """ Override of `payment` to return the default payment method codes. """
+        self.ensure_one()
+        if self.code != 'worldline':
+            return super()._get_default_payment_method_codes()
+        return const.DEFAULT_PAYMENT_METHOD_CODES
+
+    # === REQUEST HELPERS === #
+
+    def _build_request_url(self, endpoint, **kwargs):
+        """Override of `payment` to build the request URL."""
+        if self.code != 'worldline':
+            return super()._build_request_url(endpoint, **kwargs)
+        api_url = self._worldline_get_api_url()
+        return f'{api_url}/v2/{self.worldline_pspid}/{endpoint}'
+
+    def _worldline_get_api_url(self):
+        """ Return the URL of the API corresponding to the provider's state.
+
+        :return: The API URL.
+        :rtype: str
+        """
+        if self.state == 'enabled':
+            return 'https://payment.direct.worldline-solutions.com'
+        else:  # 'test'
+            return 'https://payment.preprod.direct.worldline-solutions.com'
+
+    def _build_request_headers(self, method, endpoint, *args, idempotency_key=None, **kwargs):
+        """Override of `payment` to build the request headers."""
+        if self.code != 'worldline':
+            return super()._build_request_headers(
+               method, endpoint, *args, idempotency_key=idempotency_key, **kwargs
+            )
+
+        content_type = 'application/json; charset=utf-8' if method == 'POST' else ''
+        dt = format_date_time(Datetime.now().timestamp())  # Datetime in locale-independent RFC1123
+        signature = self._worldline_calculate_signature(
+            method, endpoint, content_type, dt, idempotency_key=idempotency_key
+        )
+        authorization_header = f'GCS v1HMAC:{self.worldline_api_key}:{signature}'
+        headers = {
+            'Authorization': authorization_header,
+            'Date': dt,
+            'Content-Type': content_type,
+        }
+        if method == 'POST' and idempotency_key:
+            headers['X-GCS-Idempotence-Key'] = idempotency_key
+        return headers
+
+    def _worldline_calculate_signature(
+        self, method, endpoint, content_type, dt_rfc, idempotency_key=None
+    ):
+        """ Compute the signature for the provided data.
+
+        See https://docs.direct.worldline-solutions.com/en/integration/api-developer-guide/authentication.
+
+        :param str method: The HTTP method of the request
+        :param str endpoint: The endpoint to be reached by the request.
+        :param str content_type: The 'Content-Type' header of the request.
+        :param datetime.datetime dt_rfc: The timestamp of the request, in RFC1123 format.
+        :param str idempotency_key: The idempotency key to pass in the request.
+        :return: The calculated signature.
+        :rtype: str
+        """
+        # specific order required: method, content_type, date, custom headers, endpoint
+        values_to_sign = [method, content_type, dt_rfc]
+        if idempotency_key:
+            values_to_sign.append(f'x-gcs-idempotence-key:{idempotency_key}')
+        values_to_sign.append(f'/v2/{self.worldline_pspid}/{endpoint}')
+
+        signing_str = '\n'.join(values_to_sign) + '\n'
+        signature = hmac.new(
+            self.worldline_api_secret.encode(), signing_str.encode(), hashlib.sha256
+        )
+        return base64.b64encode(signature.digest()).decode('utf-8')
+
+    def _parse_response_error(self, response):
+        """Override of `payment` to parse the error message."""
+        if self.code != 'worldline':
+            return super()._parse_response_error(response)
+        msg = ', '.join([error.get('message', '') for error in response.json().get('errors', [])])
+        return msg
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/models/payment_transaction.py b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/models/payment_transaction.py
new file mode 100644
index 00000000..9a9ef941
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/models/payment_transaction.py
@@ -0,0 +1,333 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from werkzeug.urls import url_encode
+
+from odoo import _, api, models
+from odoo.exceptions import ValidationError
+from odoo.tools import urls
+
+from odoo.addons.payment import utils as payment_utils
+from odoo.addons.payment.logging import get_payment_logger
+from odoo.addons.payment_worldline import const
+from odoo.addons.payment_worldline.controllers.main import WorldlineController
+
+
+_logger = get_payment_logger(__name__)
+
+
+class PaymentTransaction(models.Model):
+    _inherit = 'payment.transaction'
+
+    def _compute_reference(self, provider_code, prefix=None, separator='-', **kwargs):
+        """ Override of `payment` to ensure that Worldline requirement for references is satisfied.
+
+        Worldline requires for references to be at most 30 characters long.
+
+        :param str provider_code: The code of the provider handling the transaction.
+        :param str prefix: The custom prefix used to compute the full reference.
+        :param str separator: The custom separator used to separate the prefix from the suffix.
+        :return: The unique reference for the transaction.
+        :rtype: str
+        """
+        reference = super()._compute_reference(
+            provider_code, prefix=prefix, separator=separator, **kwargs
+        )
+        if provider_code != 'worldline':
+            return reference
+
+        if len(reference) <= 30:  # Worldline transaction merchantReference is limited to 30 chars
+            return reference
+
+        prefix = payment_utils.singularize_reference_prefix(prefix='WL')
+        return super()._compute_reference(
+            provider_code, prefix=prefix, separator=separator, **kwargs
+        )
+
+    def _get_specific_processing_values(self, processing_values):
+        """ Override of `payment` to redirect failed token-flow transactions.
+
+        If the financial institution insists on user authentication,
+        this override will reset the transaction, and switch the flow to redirect.
+
+        Note: self.ensure_one() from `_get_processing_values`.
+
+        :param dict processing_values: The generic processing values of the transaction.
+        :return: The dict of provider-specific processing values.
+        :rtype: dict
+        """
+        if (
+            self.provider_code == 'worldline'
+            and self.operation == 'online_token'
+            and self.state == 'error'
+            and self.state_message.endswith('AUTHORIZATION_REQUESTED')
+        ):
+            # Tokenized payment failed due to 3-D Secure authentication request.
+            # Reset transaction to draft and switch to redirect flow.
+            self.write({
+                'state': 'draft',
+                'operation': 'online_redirect',
+            })
+            return {'force_flow': 'redirect'}
+        return super()._get_specific_processing_values(processing_values)
+
+    def _get_specific_rendering_values(self, processing_values):
+        """ Override of `payment` to return Worldline-specific processing values.
+
+        Note: self.ensure_one() from `_get_processing_values`.
+
+        :param dict processing_values: The generic processing values of the transaction.
+        :return: The dict of provider-specific processing values.
+        :rtype: dict
+        """
+        if self.provider_code != 'worldline':
+            return super()._get_specific_rendering_values(processing_values)
+
+        checkout_session_data = self._worldline_create_checkout_session()
+        return {'api_url': checkout_session_data['redirectUrl']}
+
+    def _worldline_create_checkout_session(self):
+        """ Create a hosted checkout session and return the response data.
+
+        :return: The hosted checkout session data.
+        :rtype: dict
+        """
+        self.ensure_one()
+
+        base_url = self.provider_id.get_base_url()
+        return_route = WorldlineController._return_url
+        return_url_params = url_encode({'provider_id': str(self.provider_id.id)})
+        return_url = f'{urls.urljoin(base_url, return_route)}?{return_url_params}'
+        first_name, last_name = payment_utils.split_partner_name(self.partner_name)
+        payload = {
+            'hostedCheckoutSpecificInput': {
+                'locale': self.partner_lang or '',
+                'returnUrl': return_url,
+                'showResultPage': False,
+            },
+            'order': {
+                'amountOfMoney': {
+                    'amount': payment_utils.to_minor_currency_units(self.amount, self.currency_id),
+                    'currencyCode': self.currency_id.name,
+                },
+                'customer': {  # required to create a token and for some redirected payment methods
+                    'billingAddress': {
+                        'city': self.partner_city or '',
+                        'countryCode': self.partner_country_id.code or '',
+                        'state': self.partner_state_id.name or '',
+                        'street': self.partner_address or '',
+                        'zip': self.partner_zip or '',
+                    },
+                    'contactDetails': {
+                        'emailAddress': self.partner_email or '',
+                        'phoneNumber': self.partner_phone or '',
+                    },
+                    'personalInformation': {
+                        'name': {
+                            'firstName': first_name or '',
+                            'surname': last_name or '',
+                        },
+                    },
+                },
+                'references': {
+                    'descriptor': self.reference,
+                    'merchantReference': self.reference,
+                },
+            },
+        }
+        if self.payment_method_id.code in const.REDIRECT_PAYMENT_METHODS:
+            payload['redirectPaymentMethodSpecificInput'] = {
+                'requiresApproval': False,  # Force the capture.
+                'paymentProductId': const.PAYMENT_METHODS_MAPPING[self.payment_method_id.code],
+                'redirectionData': {
+                    'returnUrl': return_url,
+                },
+            }
+        else:
+            payload['cardPaymentMethodSpecificInput'] = {
+                'authorizationMode': 'SALE',  # Force the capture.
+                'tokenize': self.tokenize,
+            }
+            if not self.payment_method_id.brand_ids and self.payment_method_id.code != 'card':
+                worldline_code = const.PAYMENT_METHODS_MAPPING.get(self.payment_method_id.code, 0)
+                payload['cardPaymentMethodSpecificInput']['paymentProductId'] = worldline_code
+            else:
+                payload['hostedCheckoutSpecificInput']['paymentProductFilters'] = {
+                    'restrictTo': {
+                        'groups': ['cards'],
+                    },
+                }
+
+        checkout_session_data = self._send_api_request('POST', 'hostedcheckouts', json=payload)
+
+        return checkout_session_data
+
+    def _send_payment_request(self):
+        """Override of `payment` to send a payment request to Worldline."""
+        if self.provider_code != 'worldline':
+            return super()._send_payment_request()
+
+        # Prepare the payment request to Worldline.
+        payload = {
+            'cardPaymentMethodSpecificInput': {
+                'authorizationMode': 'SALE',  # Force the capture.
+                'token': self.token_id.provider_ref,
+                'unscheduledCardOnFileRequestor': 'merchantInitiated',
+                'unscheduledCardOnFileSequenceIndicator': 'subsequent',
+            },
+            'order': {
+                'amountOfMoney': {
+                    'amount': payment_utils.to_minor_currency_units(self.amount, self.currency_id),
+                    'currencyCode': self.currency_id.name,
+                },
+                'references': {
+                    'merchantReference': self.reference,
+                },
+            },
+        }
+
+        try:
+            # Send the payment request to Worldline.
+            response_content = self._send_api_request(
+                'POST',
+                'payments',
+                json=payload,
+                idempotency_key=payment_utils.generate_idempotency_key(
+                    self, scope='payment_request_token'
+                )
+            )
+        except ValidationError as e:
+            self._set_error(str(e))
+        else:
+            self._process('worldline', response_content)
+
+    @api.model
+    def _extract_reference(self, provider_code, payment_data):
+        """Override of `payment` to extract the reference from the payment data."""
+        if provider_code != 'worldline':
+            return super()._extract_reference(provider_code, payment_data)
+
+        # In case of failed payment, paymentResult could be given as a separate key
+        payment_result = payment_data.get('paymentResult', payment_data)
+        payment_output = payment_result.get('payment', {}).get('paymentOutput', {})
+        return payment_output.get('references', {}).get('merchantReference', '')
+
+    def _extract_amount_data(self, payment_data):
+        """Override of payment to extract the amount and currency from the payment data."""
+        if self.provider_code != 'worldline':
+            return super()._extract_amount_data(payment_data)
+
+        # In case of failed payment, paymentResult could be given as a separate key
+        payment_result = payment_data.get('paymentResult', payment_data)
+        amount_of_money = payment_result.get('payment', {}).get('paymentOutput', {}).get(
+            'amountOfMoney', {}
+        )
+        amount = payment_utils.to_major_currency_units(
+            amount_of_money.get('amount', 0), self.currency_id
+        )
+        currency_code = amount_of_money.get('currencyCode')
+        return {
+            'amount': amount,
+            'currency_code': currency_code,
+        }
+
+    def _apply_updates(self, payment_data):
+        """ Override of `payment' to process the transaction based on Worldline data.
+
+        Note: self.ensure_one()
+
+        :param dict payment_data: The payment data sent by the provider.
+        :return: None
+        """
+        if self.provider_code != 'worldline':
+            return super()._apply_updates(payment_data)
+
+        # In case of failed payment, paymentResult could be given as a separate key
+        payment_result = payment_data.get('paymentResult', payment_data)
+        payment_data = payment_result.get('payment', {})
+
+        # Update the provider reference.
+        self.provider_reference = payment_data.get('id', '').rsplit('_', 1)[0]
+
+        # Update the payment method.
+        payment_method_data = self._worldline_extract_payment_method_data(payment_data)
+        payment_method_code = payment_method_data.get('paymentProductId', '')
+        payment_method = self.env['payment.method']._get_from_code(
+            payment_method_code, mapping=const.PAYMENT_METHODS_MAPPING
+        )
+        self.payment_method_id = payment_method or self.payment_method_id
+
+        # Update the payment state.
+        status = payment_data.get('status')
+        has_token_data = 'token' in payment_method_data
+        if not status:
+            self._set_error(_("Received data with missing payment state."))
+        elif status in const.PAYMENT_STATUS_MAPPING['pending']:
+            if status == 'AUTHORIZATION_REQUESTED':
+                self._set_error(status)
+            elif self.operation == 'validation' \
+                 and status in {'PENDING_CAPTURE', 'CAPTURE_REQUESTED'} \
+                 and has_token_data:
+                    self._set_done()
+            else:
+                self._set_pending()
+        elif status in const.PAYMENT_STATUS_MAPPING['done']:
+            self._set_done()
+        else:
+            error_code = None
+            if errors := payment_data.get('statusOutput', {}).get('errors'):
+                error_code = errors[0].get('errorCode')
+            if status in const.PAYMENT_STATUS_MAPPING['cancel']:
+                self._set_canceled(_(
+                    "Transaction cancelled with error code %(error_code)s.",
+                    error_code=error_code,
+                ))
+            elif status in const.PAYMENT_STATUS_MAPPING['declined']:
+                self._set_error(_(
+                    "Transaction declined with error code %(error_code)s.",
+                    error_code=error_code,
+                ))
+            else:  # Classify unsupported payment status as the `error` tx state.
+                _logger.info(
+                    "Received data with invalid payment status (%(status)s) for transaction with "
+                    "reference %(ref)s.",
+                    {'status': status, 'ref': self.reference},
+                )
+                self._set_error(_(
+                    "Received invalid transaction status %(status)s with error code "
+                    "%(error_code)s.",
+                    status=status,
+                    error_code=error_code,
+                ))
+
+    @staticmethod
+    def _worldline_extract_payment_method_data(payment_data):
+        payment_output = payment_data.get('paymentOutput', {})
+        if 'cardPaymentMethodSpecificOutput' in payment_output:
+            payment_method_data = payment_output['cardPaymentMethodSpecificOutput']
+        else:
+            payment_method_data = payment_output.get('redirectPaymentMethodSpecificOutput', {})
+        return payment_method_data
+
+    def _extract_token_values(self, payment_data):
+        """Override of `payment` to return token data based on Worldline data.
+
+        Note: self.ensure_one() from :meth: `_tokenize`
+
+        :param dict payment_data: The payment data sent by the provider.
+        :return: Data to create a token.
+        :rtype: dict
+        """
+        if self.provider_code != 'worldline':
+            return super()._extract_token_values(payment_data)
+
+        payment_data = payment_data.get('payment', {})
+        payment_method_data = self._worldline_extract_payment_method_data(payment_data)
+        if 'token' not in payment_method_data:
+            return {}
+
+        # Padded with *
+        payment_details = payment_method_data.get('card', {}).get('cardNumber', '')[-4:]
+        return {
+            'payment_details': payment_details,
+            'provider_ref': payment_method_data['token'],
+        }
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/static/description/icon.png b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/static/description/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..b925454678838c9b75c196522ee719163b13bde5
GIT binary patch
literal 1149
zcmeAS@N?(olHy`uVBq!ia0y~yU`PRB4rT@h26vm(GzJES`~aU2R|Wl5zn8QA
z=A5$UXWN`(t9PH4K3K=F)h0dg;vd#(mbChRi)R~~EPheE$L`3aCa%>MiLT`*Z5Mqj
z`ferK@};wawWwlnVUqSIwwB;wK2s!DLP>WXX4T?(VEPgxTX}#ihX_Au;EZX
zYs%gCY2D2NEIT**WTbLrP0sUUK6+}F(3KaS+A^2rg;&(j|dG3f@#(In8cy4FSt@gYwEAy;ts7vEuF|)zsyEJ1sAAT#X8JH*G3u
zb5qK5>(!j0_EMw6MWk_dVA|A-#Qw)-?=-GBEN0WP4l!xmEAT+6?@&;auSw9IZ<}=V
zpEhhb5NNX8LAm*qg0^nQ=Zd(avZ)5K($y1Y7T;3en^^!yE@!5z&`B^aup>d_fqFGI=
zUKEJjICAFnN6X^Pv&~oVCmy$Ak&t3?bYP#mJTGqpk4)-1i&ek5^}K7i{CyKnaa!u%P;~ZAIn#xAdkeFleCH5SS-eR3^RX)>&tx{{y4p{6XMFLzMR5{~T0u|sr?4lH
z;?;^ppE`M(E=h)d@A>jXG=cGG^rZNo-!=c&K6xa0dY@R3aKFfVy=4xjMkdn_F-ht_
zOP^q_Q`h-N
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/static/src/interactions/payment_form.js b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/static/src/interactions/payment_form.js
new file mode 100644
index 00000000..c2def3d2
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/static/src/interactions/payment_form.js
@@ -0,0 +1,25 @@
+import { patch } from '@web/core/utils/patch';
+
+import { PaymentForm } from '@payment/interactions/payment_form';
+
+patch(PaymentForm.prototype, {
+    /**
+     * Allow forcing redirect to 3-D Secure authentication for Ogone token flow.
+     *
+     * @override method from @payment/js/payment_form
+     * @private
+     * @param {string} providerCode - The code of the selected payment option's provider.
+     * @param {number} paymentOptionId - The id of the selected payment option.
+     * @param {string} paymentMethodCode - The code of the selected payment method, if any.
+     * @param {object} processingValues - The processing values of the transaction.
+     * @return {void}
+     */
+    _processTokenFlow(providerCode, paymentOptionId, paymentMethodCode, processingValues) {
+        if (providerCode === 'worldline' && processingValues.force_flow === 'redirect') {
+            delete processingValues.force_flow;
+            this._processRedirectFlow(...arguments);
+        } else {
+            super._processTokenFlow(...arguments);
+        }
+    },
+});
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/tests/__init__.py b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/tests/__init__.py
new file mode 100644
index 00000000..12f4e0fb
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/tests/__init__.py
@@ -0,0 +1,4 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import common
+from . import test_worldline
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/tests/common.py b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/tests/common.py
new file mode 100644
index 00000000..d0201aa4
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/tests/common.py
@@ -0,0 +1,155 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo.addons.payment import utils as payment_utils
+from odoo.addons.payment.tests.common import PaymentCommon
+
+
+class WorldlineCommon(PaymentCommon):
+
+    @classmethod
+    def setUpClass(cls):
+        super().setUpClass()
+
+        cls.worldline = cls._prepare_provider('worldline', update_values={
+            'worldline_pspid': 'dummy',
+            'worldline_api_key': 'dummy',
+            'worldline_api_secret': 'dummy',
+            'worldline_webhook_key': 'dummy',
+            'worldline_webhook_secret': 'dummy',
+        })
+
+        cls.provider = cls.worldline
+        cls.currency = cls.currency_euro
+        cls.notification_amount_and_currency = {
+            'amount': payment_utils.to_minor_currency_units(cls.amount, cls.currency),
+            'currencyCode': cls.currency.name,
+        }
+
+        cls.payment_data = {
+            'payment': {
+                'paymentOutput': {
+                    'references': {
+                        'merchantReference': cls.reference,
+                    },
+                    'cardPaymentMethodSpecificOutput': {
+                        'paymentProductId': 1,
+                        'card': {
+                            'cardNumber': "******4242"
+                        },
+                        'token': 'whateverToken'
+                    },
+                    'amountOfMoney': cls.notification_amount_and_currency,
+                },
+                'id': '1234567890_0',
+                'status': 'CAPTURED',
+            },
+        }
+
+        cls.payment_data_insufficient_funds = {
+            'errorId': 'ffffffff-fff-fffff-ffff-ffffffffffff',
+            'errors': [{
+                'category': 'IO_ERROR',
+                'code': '9999',
+                'errorCode': '30511001',
+                'httpStatusCode': 402,
+                'id': 'EXTERNAL_ACQUIRER_ERROR',
+                'message': '',
+                'retriable': False,
+            }],
+            'paymentResult': {
+                'creationOutput': {
+                    'externalReference': 'aaaaaaaa-5555-eeee-eeee-eeeeeeeeeeee',
+                    'isNewToken': False,
+                    'token': 'aaaaaaaa-5555-eeee-eeee-eeeeeeeeeeee',
+                    'tokenizationSucceeded': False,
+                },
+                'payment': {
+                    'id': '7777777000_0',
+                    'paymentOutput': {
+                        'acquiredAmount': {'amount': 0, 'currencyCode': 'EUR'},
+                        'amountOfMoney': cls.notification_amount_and_currency,
+                        'cardPaymentMethodSpecificOutput': {
+                            'acquirerInformation': {'name': "Test Pay"},
+                            'card': {
+                                'bin': '50010000',
+                                'cardNumber': '************7777',
+                                'countryCode': 'BE',
+                                'expiryDate': '1244',
+                            },
+                            'fraudResults': {'cvvResult': 'P', 'fraudServiceResult': 'accepted'},
+                            'paymentProductId': 3,
+                            'threeDSecureResults': {'eci': '9', 'xid': 'zOMTQ5TcODUxMg=='},
+                            'token': 'aaaaaaaa-5555-eeee-eeee-eeeeeeeeeeee',
+                        },
+                        'customer': {'device': {'ipAddressCountryCode': '99'}},
+                        'paymentMethod': 'card',
+                        'references': {'merchantReference': cls.reference},
+                    },
+                    'status': 'REJECTED',
+                    'statusOutput': {
+                        'errors': [{
+                            'category': 'IO_ERROR',
+                            'code': '9999',
+                            'errorCode': '30511001',
+                            'httpStatusCode': 402,
+                            'id': 'EXTERNAL_ACQUIRER_ERROR',
+                            'message': '',
+                            'retriable': False,
+                        }],
+                        'isAuthorized': False,
+                        'isCancellable': False,
+                        'isRefundable': False,
+                        'statusCategory': 'UNSUCCESSFUL',
+                        'statusCode': 2,
+                    },
+                },
+            },
+        }
+
+        cls.payment_data_expired_card = {
+            'apiFullVersion': 'v1.1',
+            'apiVersion': 'v1',
+            'created': '2025-02-20T03:09:47.3706109+01:00',
+            'id': 'ffffffff-fff-fffff-ffff-ffffffffffff',
+            'merchantId': 'MyCompany',
+            'payment': {
+                'id': '9999999999_0',
+                'paymentOutput': {
+                    'acquiredAmount': {'amount': 0, 'currencyCode': 'EUR'},
+                    'amountOfMoney': cls.notification_amount_and_currency,
+                    'cardPaymentMethodSpecificOutput': {
+                        'acquirerInformation': {'name': "Test Pay"},
+                        'card': {
+                            'bin': '47777700',
+                            'cardNumber': '************9999',
+                            'countryCode': 'FR',
+                            'expiryDate': '1234',
+                        },
+                        'fraudResults': {'cvvResult': 'P', 'fraudServiceResult': 'accepted'},
+                        'paymentProductId': 1,
+                        'threeDSecureResults': {'eci': '9'},
+                        'token': 'ODOO-ALIAS-eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'},
+                    'customer': {'device': {'ipAddressCountryCode': '99'}},
+                    'paymentMethod': 'card',
+                    'references': {'merchantReference': cls.reference},
+                },
+                'status': 'REJECTED',
+                'statusOutput': {
+                    'errors': [{
+                        'category': 'PAYMENT_PLATFORM_ERROR',
+                        'code': '9999',
+                        'errorCode': '30331001',
+                        'httpStatusCode': 402,
+                        'id': 'INVALID_CARD',
+                        'message': '',
+                        'retriable': False,
+                    }],
+                    'isAuthorized': False,
+                    'isCancellable': False,
+                    'isRefundable': False,
+                    'statusCategory': 'UNSUCCESSFUL',
+                    'statusCode': 2
+                },
+            },
+            'type': 'payment.rejected',
+        }
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/tests/test_worldline.py b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/tests/test_worldline.py
new file mode 100644
index 00000000..2ccc4178
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/tests/test_worldline.py
@@ -0,0 +1,157 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import hashlib
+import hmac
+import json
+from base64 import b64encode
+from unittest.mock import patch
+
+from werkzeug.exceptions import Forbidden
+
+from odoo.tests import tagged
+from odoo.tools import mute_logger
+
+from odoo.addons.payment.tests.http_common import PaymentHttpCommon
+from odoo.addons.payment_worldline.controllers.main import WorldlineController
+from odoo.addons.payment_worldline.tests.common import WorldlineCommon
+
+
+@tagged('post_install', '-at_install')
+class WorldlineTest(WorldlineCommon, PaymentHttpCommon):
+
+    @mute_logger('odoo.addons.payment_worldline.controllers.main')
+    def _webhook_notification_flow(self, payload):
+        """ Send a notification to the webhook, ignore the signature, and check the response. """
+        url = self._build_url(WorldlineController._webhook_url)
+        with patch(
+            'odoo.addons.payment_worldline.controllers.main.WorldlineController._verify_signature'
+        ):
+            response = self._make_json_request(url, data=payload)
+        self.assertEqual(
+            response.json(), '', msg="The webhook should always respond ''.",
+        )
+
+    @mute_logger('odoo.addons.payment_worldline.controllers.main')
+    def test_webhook_notification_confirms_transaction(self):
+        """ Test the processing of a webhook notification. """
+        tx = self._create_transaction('redirect')
+        self.assertFalse(tx.tokenize, "No token should be asked.")
+        self._webhook_notification_flow(self.payment_data)
+        self.assertFalse(tx.token_id, "No token should be created.")
+        self.assertEqual(tx.state, 'done')
+        self.assertEqual(tx.provider_reference, '1234567890')
+
+    @mute_logger('odoo.addons.payment_worldline.controllers.main')
+    def test_webhook_notification_creates_token(self):
+        """ Test the processing of a webhook notification when creating a token. """
+        tx = self._create_transaction('redirect', tokenize=True)
+        self.assertTrue(tx.tokenize, "A token should be asked.")
+        self._webhook_notification_flow(self.payment_data)
+        self.assertEqual(tx.state, 'done')
+        self.assertFalse(tx.tokenize, "No token should be asked any more.")
+        self.assertTrue(tx.token_id, "A token should have been created and linked to the tx.")
+        self.assertEqual(tx.token_id.provider_ref, 'whateverToken')
+        self.assertEqual(tx.token_id.payment_details, '4242')
+
+    @mute_logger('odoo.addons.payment_worldline.controllers.main')
+    def test_failed_webhook_notification_set_tx_as_error_1(self):
+        """ Test the processing of a webhook notification for a failed transaction. """
+        tx = self._create_transaction('redirect')
+        test = self.payment_data_insufficient_funds
+        self._webhook_notification_flow(test)
+        self.assertEqual(tx.state, 'error')
+        self.assertEqual(
+            tx.state_message,
+            "Transaction declined with error code 30511001.",
+        )
+
+    @mute_logger('odoo.addons.payment_worldline.controllers.main')
+    def test_failed_webhook_notification_set_tx_as_error_2(self):
+        """ Test the processing of a webhook notification for a failed transaction. """
+        tx = self._create_transaction('redirect')
+        test = self.payment_data_expired_card
+        self._webhook_notification_flow(test)
+        self.assertEqual(tx.state, 'error')
+        self.assertEqual(
+            tx.state_message,
+            "Transaction declined with error code 30331001.",
+        )
+
+    @mute_logger('odoo.addons.payment_worldline.controllers.main')
+    def test_failed_webhook_notification_set_tx_as_cancel(self):
+        """Test the processing of a webhook notification for a cancelled transaction."""
+        tx = self._create_transaction('redirect')
+        test = {
+            'payment': {
+                'paymentOutput': self.payment_data['payment']['paymentOutput'],
+                'hostedCheckoutSpecificOutput': {
+                    'hostedCheckoutId': '123456789',
+                },
+                'status': 'CANCELLED',
+                'statusOutput': {
+                    'errors': [{
+                        'errorCode': '30171001',
+                    }],
+                },
+            },
+        }
+        self._webhook_notification_flow(test)
+        self.assertEqual(tx.state, 'cancel')
+        self.assertEqual(
+            tx.state_message,
+            "Transaction cancelled with error code 30171001.",
+        )
+
+    @mute_logger('odoo.addons.payment_worldline.controllers.main')
+    def test_webhook_notification_triggers_signature_check(self):
+        """ Test that receiving a webhook notification triggers a signature check. """
+        self._create_transaction('redirect')
+        url = self._build_url(WorldlineController._webhook_url)
+        with patch(
+            'odoo.addons.payment_worldline.controllers.main.WorldlineController._verify_signature'
+        ) as signature_check_mock, patch(
+            'odoo.addons.payment.models.payment_transaction.PaymentTransaction._process'
+        ):
+            self._make_json_request(url, data=self.payment_data)
+            self.assertEqual(signature_check_mock.call_count, 1)
+
+    def test_accept_notification_with_valid_signature(self):
+        """ Test the verification of a notification with a valid signature. """
+        tx = self._create_transaction('redirect')
+        unencoded_result = hmac.new(
+            self.worldline.worldline_webhook_secret.encode(),
+            json.dumps(self.payment_data).encode(),
+            hashlib.sha256,
+        ).digest()
+        expected_signature = b64encode(unencoded_result)
+        self._assert_does_not_raise(
+            Forbidden,
+            WorldlineController._verify_signature,
+            json.dumps(self.payment_data).encode(),
+            expected_signature,
+            tx,
+        )
+
+    @mute_logger('odoo.addons.payment_worldline.controllers.main')
+    def test_reject_notification_with_missing_signature(self):
+        """ Test the verification of a notification with a missing signature. """
+        tx = self._create_transaction('redirect')
+        self.assertRaises(
+            Forbidden,
+            WorldlineController._verify_signature,
+            json.dumps(self.payment_data).encode(),
+            None,
+            tx,
+        )
+
+    @mute_logger('odoo.addons.payment_worldline.controllers.main')
+    def test_reject_notification_with_invalid_signature(self):
+        """ Test the verification of a notification with an invalid signature. """
+        tx = self._create_transaction('redirect')
+        self.assertRaises(
+            Forbidden,
+            WorldlineController._verify_signature,
+            json.dumps(self.payment_data).encode(),
+            'dummy',
+            tx,
+        )
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/views/payment_provider_views.xml b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/views/payment_provider_views.xml
new file mode 100644
index 00000000..e8f295d1
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/views/payment_provider_views.xml
@@ -0,0 +1,43 @@
+
+
+
+    
+        Worldline Provider Form
+        payment.provider
+        
+        
+            
+                
+                    
+                    
+                    
+                    
+                    
+                
+            
+        
+    
+
+
diff --git a/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/views/payment_worldline_templates.xml b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/views/payment_worldline_templates.xml
new file mode 100644
index 00000000..28813d66
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_worldline/payment_worldline/views/payment_worldline_templates.xml
@@ -0,0 +1,8 @@
+
+
+
+    
+
+
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/README.md b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/README.md
new file mode 100644
index 00000000..62ca2a8f
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/README.md
@@ -0,0 +1,46 @@
+# Xendit
+
+## Technical details
+
+APIs:
+- [Invoices API](https://developers.xendit.co/api-reference/#create-invoice) version `2`
+- [Credit Charge API](https://developers.xendit.co/api-reference/#create-charge) version `1`
+
+SDK: [Xendit.js](https://docs.xendit.co/credit-cards/integrations/tokenization)
+
+This module integrates Xendit with different payment flows depending on the payment method:
+
+- For `Card` payments, it renders a self-hosted payment form with regular (non-iframe) inputs and 
+  relies on the Xendit.js SDK to create a (single-use or multiple-use) token that is used to make
+  the payment. When the payment is successful, and the user opts to save the payment method, the
+  token is saved in Odoo. Other communications with Xendit are performed via server-to-server API
+  calls.
+
+  The JS assets are loaded in JavaScript when the payment form is submitted.
+
+  As payment details are retrieved in clear but are immediately passed to the Xendit.js SDK, the
+  solution qualifies for SAQ A-EP.
+
+- For other payment methods, this module uses the generic payment with redirection flow based on
+  form submission provided by the `payment` module.
+
+This implementation allows supporting tokenization for `Card` payments whilst retaining support for
+other payment methods via the redirection flow.
+
+## Supported features
+
+- Direct Payment flow for `Card` payment methods
+- Payment with redirection flow for other payment methods
+- Webhook notifications
+- Tokenization with or without payment
+
+## Module history
+
+- `17.4`
+  - The support for tokenization via `Card` is added. odoo/odoo#158445
+- `17.0`
+  - The first version of the module is merged. odoo/odoo#141661
+
+## Testing instructions
+
+https://developers.xendit.co/api-reference/#test-scenarios
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/__init__.py b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/__init__.py
new file mode 100644
index 00000000..9fa28e85
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/__init__.py
@@ -0,0 +1,14 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import controllers
+from . import models
+
+from odoo.addons.payment import setup_provider, reset_payment_provider
+
+
+def post_init_hook(env):
+    setup_provider(env, 'xendit')
+
+
+def uninstall_hook(env):
+    reset_payment_provider(env, 'xendit')
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/__manifest__.py b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/__manifest__.py
new file mode 100644
index 00000000..f0d0555d
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/__manifest__.py
@@ -0,0 +1,26 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+{
+    'name': "Payment Provider: Xendit",
+    'version': '1.0',
+    'category': 'Accounting/Payment Providers',
+    'sequence': 350,
+    'summary': "A payment provider for Indonesian and the Philippines.",
+    'description': " ",  # Non-empty string to avoid loading the README file.
+    'depends': ['payment'],
+    'data': [
+        'views/payment_provider_views.xml',
+        'views/payment_xendit_templates.xml',
+
+        'data/payment_provider_data.xml',  # Depends on payment_xendit_templates.xml
+    ],
+    'post_init_hook': 'post_init_hook',
+    'uninstall_hook': 'uninstall_hook',
+    'assets': {
+        'web.assets_frontend': [
+            'payment_xendit/static/src/**/*',
+        ]
+    },
+    'author': 'Odoo S.A.',
+    'license': 'LGPL-3',
+}
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/const.py b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/const.py
new file mode 100644
index 00000000..6caa02b9
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/const.py
@@ -0,0 +1,45 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+# The currencies supported by Xendit, in ISO 4217 format.
+SUPPORTED_CURRENCIES = [
+    'IDR',
+    'PHP',
+]
+
+# To correctly allow lowest decimal place rounding
+# https://docs.xendit.co/payment-link/payment-channels
+CURRENCY_DECIMALS = {
+    'IDR': 0,
+    'PHP': 0,
+}
+
+# The codes of the payment methods to activate when Xendit is activated.
+DEFAULT_PAYMENT_METHOD_CODES = {
+    # Primary payment methods.
+    'card',
+    'dana',
+    'ovo',
+    'qris',
+
+    # Brand payment methods.
+    'visa',
+    'mastercard',
+}
+
+# Mapping of payment code to channel code according to Xendit API
+PAYMENT_METHODS_MAPPING = {
+    'bank_bca': 'BCA',
+    'bank_permata': 'PERMATA',
+    'bpi': 'DD_BPI',
+    'card': 'CREDIT_CARD',
+    'maya': 'PAYMAYA',
+}
+
+# Mapping of transaction states to Xendit payment statuses.
+PAYMENT_STATUS_MAPPING = {
+    'draft': (),
+    'pending': ('PENDING'),
+    'done': ('SUCCEEDED', 'PAID', 'CAPTURED'),
+    'cancel': ('CANCELLED', 'EXPIRED'),
+    'error': ('FAILED',)
+}
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/controllers/__init__.py b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/controllers/__init__.py
new file mode 100644
index 00000000..80ee4da1
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/controllers/__init__.py
@@ -0,0 +1,3 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import main
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/controllers/main.py b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/controllers/main.py
new file mode 100644
index 00000000..06b0f233
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/controllers/main.py
@@ -0,0 +1,80 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import pprint
+
+from werkzeug.exceptions import Forbidden
+
+from odoo import http
+from odoo.http import request
+from odoo.tools import consteq, str2bool
+
+from odoo.addons.payment import utils as payment_utils
+from odoo.addons.payment.logging import get_payment_logger
+
+
+_logger = get_payment_logger(__name__)
+
+
+class XenditController(http.Controller):
+
+    _webhook_url = '/payment/xendit/webhook'
+    _return_url = '/payment/xendit/return'
+
+    @http.route('/payment/xendit/payment', type='jsonrpc', auth='public')
+    def xendit_payment(self, reference, token_ref, auth_id=None):
+        """ Make a payment by token request and handle the response.
+
+        :param str reference: The reference of the transaction.
+        :param str token_ref: The reference of the Xendit token to use to make the payment.
+        :param str auth_id: The authentication id to use to make the payment.
+        :return: None
+        """
+        tx_sudo = request.env['payment.transaction'].sudo().search([('reference', '=', reference)])
+        tx_sudo._xendit_create_charge(token_ref, auth_id=auth_id)
+
+    @http.route(_webhook_url, type='http', methods=['POST'], auth='public', csrf=False)
+    def xendit_webhook(self):
+        """Process the payment data sent by Xendit to the webhook.
+
+        :return: The 'accepted' string to acknowledge the notification.
+        """
+        data = request.get_json_data()
+        _logger.info("Notification received from Xendit with data:\n%s", pprint.pformat(data))
+
+        received_token = request.httprequest.headers.get('x-callback-token')
+        tx_sudo = request.env['payment.transaction'].sudo()._search_by_reference('xendit', data)
+        if tx_sudo:
+            self._verify_notification_token(received_token, tx_sudo)
+            tx_sudo._process('xendit', data)
+
+        return request.make_json_response(['accepted'], status=200)
+
+    @http.route(_return_url, type='http', methods=['GET'], auth='public')
+    def xendit_return(self, tx_ref=None, success=False, access_token=None, **data):
+        """Set draft transaction to pending after successfully returning from Xendit."""
+        if access_token and str2bool(success, default=False):
+            tx_sudo = request.env['payment.transaction'].sudo().search([
+                ('provider_code', '=', 'xendit'),
+                ('reference', '=', tx_ref),
+                ('state', '=', 'draft'),
+            ], limit=1)
+            if tx_sudo and payment_utils.check_access_token(access_token, tx_ref, tx_sudo.amount):
+                tx_sudo._set_pending()
+        return request.redirect('/payment/status')
+
+    def _verify_notification_token(self, received_token, tx_sudo):
+        """ Check that the received token matches the saved webhook token.
+
+        :param str received_token: The callback token received with the payment data.
+        :param payment.transaction tx_sudo: The transaction referenced by the payment data.
+        :return: None
+        :raise Forbidden: If the tokens don't match.
+        """
+        # Check for the received token.
+        if not received_token:
+            _logger.warning("Received payment data with missing token.")
+            raise Forbidden()
+
+        if not consteq(tx_sudo.provider_id.xendit_webhook_token, received_token):
+            _logger.warning("Received payment data with invalid callback token %r.", received_token)
+            raise Forbidden()
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/data/neutralize.sql b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/data/neutralize.sql
new file mode 100644
index 00000000..edbdcd49
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/data/neutralize.sql
@@ -0,0 +1,3 @@
+UPDATE payment_provider
+   SET xendit_secret_key = 'dummysecret',
+       xendit_webhook_token = 'dummytoken';
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/data/payment_provider_data.xml b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/data/payment_provider_data.xml
new file mode 100644
index 00000000..32c0819c
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/data/payment_provider_data.xml
@@ -0,0 +1,10 @@
+
+
+
+    
+        xendit
+        
+        
+    
+
+
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ar.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ar.po
new file mode 100644
index 00000000..cbdfbbce
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ar.po
@@ -0,0 +1,202 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 13:44+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Arabic \n"
+"Language: ar\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
+"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr "حدث خطأ أثناء معالجة مدفوعاتك (%s). يرجى المحاولة مجدداً."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "رمز البطاقة"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr "الاسم الأول لحامل البطاقة"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr "اسم العائلة لحامل البطاقة"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "رقم البطاقة"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "رمز"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "تعذر إنشاء الاتصال بالواجهة البرمجية للتطبيق."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "البريد الإلكتروني"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "تاريخ الانتهاء"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr "Invalid CVN"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr "رقم البطاقة غير صالح"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr "التاريخ غير صالح"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "John"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "لم يتم العثور على معاملة تطابق المرجع %s."
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "مزود الدفع"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "معاملة الدفع"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "فشلت معالجة عملية الدفع"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "رقم الهاتف"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "مفتاح عام"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr "تم استلام البيانات دون مرجع."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "المفتاح السري"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "Smith"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+"فشل التواصل مع الواجهة البرمجية للتطبيق. لقد منحنا Xendit المعلومات التالية: "
+"'%s'"
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "الكود التقني لمزود الدفع هذا."
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "المعاملة غير مرتبطة برمز."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "رمز Webhook"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr "المفتاح العام لـ Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "المفتاح السري لـ Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "رمز ويب هوك Xendit"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "YYYY"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "john.smith@example.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/az.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/az.po
new file mode 100644
index 00000000..a2211754
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/az.po
@@ -0,0 +1,195 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_xendit
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/bg.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/bg.po
new file mode 100644
index 00000000..a2211754
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/bg.po
@@ -0,0 +1,195 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_xendit
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ca.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ca.po
new file mode 100644
index 00000000..de7cf484
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ca.po
@@ -0,0 +1,201 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 02:32+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Catalan \n"
+"Language: ca\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+"S'ha produït un error durant el processament del teu pagament (%s). Si us "
+"plau, torna-ho a intentar."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "Codi de targeta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr "Nom del titular de la targeta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr "Cognom del titular de la targeta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Número de targeta"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Codi"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "No s'ha pogut establir la connexió a l'API."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "Correu electrònic"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Caducitat"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr "Número de targeta no vàlid"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "No s'ha trobat cap transacció que coincideixi amb la referència %s."
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Proveïdor de pagament"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transacció de pagament"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Número de telèfon"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "Clau pública"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Clau secreta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "El codi tècnic d'aquest proveïdor de pagaments."
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "La transacció no està enllaçada a un token."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "john.smith@example.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/cs.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/cs.po
new file mode 100644
index 00000000..e92b9483
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/cs.po
@@ -0,0 +1,199 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-17 17:19+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Czech \n"
+"Language: cs\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Číslo karty"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Kód"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Nepodařilo se navázat spojení s rozhraním API."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "Email"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Vypršení"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "John"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Nebyla nalezena žádná transakce odpovídající odkazu %s."
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Poskytovatel platby"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Platební transakce"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Zpracování platby se nezdařilo"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Telefonní číslo"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Tajný klíč"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "Smith"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Technický kód tohoto poskytovatele plateb."
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "Transakce není spojena s tokenem."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "YYYY"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "jan.novak@priklad.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/da.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/da.po
new file mode 100644
index 00000000..a46d87fa
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/da.po
@@ -0,0 +1,199 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-14 21:15+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Danish \n"
+"Language: da\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Kortnummer"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Kode"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Det var ikke muligt at oprette forbindelse til API'et."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "E-mail"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Udløbsdato"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Betalingsudbyder"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Betalingstransaktion"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Behandlingen af betaling mislykkedes"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Telefonnummer"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "Offentlig nøgle"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Hemmelig nøgle"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "john.smith@example.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/de.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/de.po
new file mode 100644
index 00000000..3dd3afc7
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/de.po
@@ -0,0 +1,203 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 02:36+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: German \n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+"Bei der Bearbeitung dieser Zahlung (%s) ist ein Fehler aufgetreten. Bitte "
+"versuchen Sie es erneut."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "Kartencode"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr "Vorname des Karteninhabers"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr "Nachname des Karteninhabers"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Kartennummer"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Code"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Verbindung mit API konnte nicht hergestellt werden."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "E-Mail"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Gültigkeit"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr "Ungültige Prüfnummer"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr "Ungültige Kartennummer"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr "Ungültiges Datum"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "John"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Keine Transaktion gefunden, die der Referenz %s entspricht."
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Zahlungsanbieter"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Zahlungstransaktion"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Zahlungsverarbeitung fehlgeschlagen"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Telefonnummer"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "Öffentlicher Schlüssel"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr "Erhaltene Daten mit fehlender Referenz."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Geheimer Schlüssel"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "Smith"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+"Die Kommunikation mit der API ist fehlgeschlagen. Xendit hat uns folgende "
+"Informationen übermittelt: „%s“"
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Der technische Code dieses Zahlungsanbieters."
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "Die Transaktion ist nicht mit einem Token verknüpft."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "Webhook-Token"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr "Öffentlicher Schlüssel von Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "Geheimer Schlüssel von Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "Webhook-Token von Xendit"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "JJJJ"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "john.smith@beispiel.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/el.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/el.po
new file mode 100644
index 00000000..b25625bc
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/el.po
@@ -0,0 +1,199 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-24 19:23+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Greek \n"
+"Language: el\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Κωδικός"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "Email"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Πάροχος Πληρωμών"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Συναλλαγή Πληρωμής"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Αριθμός τηλεφώνου"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Κρυφό Κλειδί"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/es.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/es.po
new file mode 100644
index 00000000..603e1d1b
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/es.po
@@ -0,0 +1,202 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-17 17:20+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Spanish \n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr "Ocurrió un error al procesar su pago (%s). Inténtelo de nuevo."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "Código de la tarjeta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr "Nombre del titular de la tarjeta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr "Apellido del titular de la tarjeta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Número de tarjeta"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Código"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "No se ha podido establecer la conexión con el API."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "Correo electrónico"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Vencimiento"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr "CVC no válido"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr "Número de tarjeta no válido"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr "Fecha no válida"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "John"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+"No se ha encontrado ninguna transacción que coincida con la referencia %s."
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Proveedor de pago"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transacción de pago"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Error al procesar el pago"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Número de teléfono"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "Clave pública"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr "Datos recibidos sin referencia."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Clave secreta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "Smith"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+"Falló la comunicación con la API. Xendit nos dio la siguiente información: "
+"'%s'"
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "El código técnico de este proveedor de pago."
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "La transacción no está vinculada a un token."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "Token de Webhook"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr "Clave pública de Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "Clave secreta de Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "Token de webhook de Xendit"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "AAAA"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "john.smith@example.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/es_419.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/es_419.po
new file mode 100644
index 00000000..66e6b868
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/es_419.po
@@ -0,0 +1,201 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-17 07:44+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Spanish (Latin America) \n"
+"Language: es_419\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr "Ocurrió un error al procesar su pago (%s). Inténtelo de nuevo."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "Código de tarjeta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr "Nombre del titular de la tarjeta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr "Apellido del titular de la tarjeta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Número de tarjeta"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Código"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "No se pudo establecer la conexión con la API."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "Correo electrónico"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Vencimiento"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr "CVC erróneo"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr "Número de tarjeta erróneo"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr "Fecha inválida"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "John"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "No se encontró ninguna transacción que coincida con la referencia %s."
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Proveedor de pago"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transacción de pago"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Error al procesar el pago"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Número de teléfono"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "Clave pública"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr "Datos recibidos sin referencia."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Clave secreta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "Smith"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+"La comunicación con la API falló. Xendit nos envió la siguiente información: "
+"'%s'"
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "El código técnico de este proveedor de pagos."
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "La transacción no está vinculada a un token."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "Token de Webhook"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr "Clave pública de Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "Clave secreta de Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "Token de webhook de Xendit"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "AAAA"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "john.smith@ejemplo.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/et.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/et.po
new file mode 100644
index 00000000..75b79338
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/et.po
@@ -0,0 +1,175 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_xendit
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 19.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:59+0000\n"
+"PO-Revision-Date: 2025-09-11 13:59+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/interactions/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/interactions/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/interactions/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/fa.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/fa.po
new file mode 100644
index 00000000..a2211754
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/fa.po
@@ -0,0 +1,195 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_xendit
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/fi.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/fi.po
new file mode 100644
index 00000000..9aa3dfb5
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/fi.po
@@ -0,0 +1,201 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 15:34+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Finnish \n"
+"Language: fi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr "Maksun käsittelyssä tapahtui virhe (%s). Yritä uudelleen."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "Kortin koodi"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr "Kortinhaltijan etunimi"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr "Kortinhaltijan sukunimi"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Kortin numero"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Koodi"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Yhteyttä API:in ei voitu muodostaa."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "Sähköposti"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Voimassaolo"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr "Virheellinen CVN"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr "Virheellinen kortin numero"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr "Virheellinen Päivämäärä"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "Matti"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "KK"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Viitettä %s vastaavaa tapahtumaa ei löytynyt."
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Maksupalveluntarjoaja"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Maksutapahtuma"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Maksun käsittely epäonnistui"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Puhelinnumero"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "Julkinen avain"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr "Vastaanotetut tiedot, joista puuttuu viite."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Salainen avain"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "Smith"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+"Yhteyden muodostaminen API:in epäonnistui. Xendit antoi seuraavat tiedot: "
+"'%s'"
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Tämän maksupalveluntarjoajan tekninen koodi."
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "Transaktio ei ole sidottu valtuutuskoodiin."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "Webhook-pääsytunniste"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr "Xenditin julkinen avain"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "Xenditin salainen avain"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "Xendit Webhook käyttötunniste"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "VVVV"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "matti.meikalainen@esimerkki.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/fr.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/fr.po
new file mode 100644
index 00000000..f4c8d8f9
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/fr.po
@@ -0,0 +1,203 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-17 17:23+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: French \n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n > 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+"Une erreur est survenue lors du traitement de votre paiement (%s). Veuillez "
+"réessayer."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "Code de la carte"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr "Prénom du titulaire de la carte"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr "Nom du titulaire de la carte"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Numéro de carte"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Code"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Impossible d'établir la connexion à l'API."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "E-mail"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Expiration"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr "CVC invalide"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr "Numéro de carte invalide"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr "Date invalide"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "John"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Aucune transaction ne correspond à la référence %s."
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Fournisseur de paiement"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transaction de paiement"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Échec du traitement du paiement"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Numéro de téléphone"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "Clé publique"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr "Données reçues avec référence manquante."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Clé secrète"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "Smith"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+"Échec de la communication avec l'API. Xendit nous a fourni les informations "
+"suivantes : '%s'"
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Le code technique de ce fournisseur de paiement."
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "La transaction n'est pas liée à un jeton."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "Jeton Webhook"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr "Clé publique Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "Clé secrète Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "Jeton Webhook Xendit"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "AAAA"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "john.smith@example.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/he.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/he.po
new file mode 100644
index 00000000..a2211754
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/he.po
@@ -0,0 +1,195 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_xendit
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/hi.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/hi.po
new file mode 100644
index 00000000..a2211754
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/hi.po
@@ -0,0 +1,195 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_xendit
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/hr.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/hr.po
new file mode 100644
index 00000000..a2211754
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/hr.po
@@ -0,0 +1,195 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_xendit
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/hu.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/hu.po
new file mode 100644
index 00000000..2550a419
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/hu.po
@@ -0,0 +1,199 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-29 19:47+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Hungarian \n"
+"Language: hu\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Kártya szám"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Kód"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "Email"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Lejárat"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Fizetési szolgáltató"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Fizetési tranzakció"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Telefonszám"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Titkos kulcs"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/id.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/id.po
new file mode 100644
index 00000000..c172da9b
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/id.po
@@ -0,0 +1,202 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 04:45+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Indonesian \n"
+"Language: id\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+"Terjadi error selama pemrosesan pembayaran Anda (%s). Silakan coba lagi "
+"nanti."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "Kode Kartu"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr "Nama Pertama Pemegang Kartu"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr "Nama Belakang Pemegang Kartu"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Nomor Kartu"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Kode"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Tidak dapat membuat hubungan ke API."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "Email"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Kadaluwarsa"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr "CVN Tidak Valid"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr "Nomor Kartu Tidak Valid"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr "Tanggal Tidak Valid"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "John"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Tidak ada transaksi dengan referensi %s yang cocok."
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Penyedia Pembayaran"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transaksi Tagihan"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Pemrosesan pembayaran gagal"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Nomor Telepon"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "Public Key"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr "Menerima data dengan referensi yang kurang lengkap."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Secret Key"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "Smith"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+"Komunikasi dengan API gagal. Xendit memberikan kami informasi berikut: '%s'"
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Kode teknis penyedia pembayaran ini."
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "Transaksi ini tidak terhubung ke token."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "Token Webhook"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr "Xendit Public Key"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "Xendit Secret Key"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "Xendit Webhook Token"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "YYYY"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "john.smith@example.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/it.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/it.po
new file mode 100644
index 00000000..611e7e38
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/it.po
@@ -0,0 +1,203 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-17 17:27+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Italian \n"
+"Language: it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+"Si è verificato un errore durante l'elaborazione del pagamento (%s). Riprova "
+"più tardi."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "Codice Carta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr "Nome proprietario carta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr "Cognome proprietario carta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Numero carta"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Codice"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Impossibile stabilire la connessione all'API."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "E-mail"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Scadenza"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr "CVN non valido"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr "Numero carta non valido"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr "Data non valida"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "John"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Nessuna transazione trovata che corrisponde al riferimento %s."
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Fornitore di pagamenti"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transazione di pagamento"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Elaborazione del pagamento non riuscita"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Numero di telefono"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "Chiave pubblica"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr "Dati ricevuti privi di riferimento,"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Chiave segreta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "Smith"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+"La comunicazione con l'API non è riuscita. Xendit ha fornito le seguenti "
+"informazioni: '%s'"
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Codice tecnico del fornitore di pagamenti."
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "La transazione non è legata a un token."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "Token Webhook"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr "Chiave pubblica Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "Chiave privata Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "Token Webhook Xendit"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "AAAA"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "mario.rossi@example.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ja.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ja.po
new file mode 100644
index 00000000..e63bf4fa
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ja.po
@@ -0,0 +1,199 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-14 21:16+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Japanese \n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr "支払処理中にエラーが発生しました(%s)。再度試して下さい。"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "カードコード"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr "カード所有者名"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr "カード所有者姓"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "カード番号"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "コード"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "APIへの接続を確立できませんでした。"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "メール"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "有効期限"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr "無効なCVN"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr "無効なカード番号"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr "無効な日付"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "John"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "参照に一致する取引が見つかりません%s。"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "決済プロバイダー"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "決済トランザクション"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "支払処理に失敗しました"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "電話番号"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "公開キー"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr "参照が欠落しているデータを受信しました。"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "シークレットキー"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "Smith"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr "APIとの通信に失敗しました。Xenditから以下の情報が得られました: '%s'"
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "この決済プロバイダーのテクニカルコード。"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "取引はトークンにリンクしていません。"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "Webhookトークン"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr "Xendit公開キー"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "Xenditシークレットキー"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "Xendit Webhookトークン"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "YYYY"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "john.smith@example.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ko.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ko.po
new file mode 100644
index 00000000..face2ec4
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ko.po
@@ -0,0 +1,199 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 04:45+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Korean \n"
+"Language: ko\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr "결제를 처리하는 동안 오류가 발생했습니다 (%s). 다시 시도해 주세요."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "카드 코드"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr "카드 소유자 이름"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr "카드 소유자 성"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "카드 번호"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "코드"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "API 연결을 설정할 수 없습니다."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "이메일"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "만료일"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr "잘못된 CVN"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr "유효하지 않은 카드 번호"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr "유효하지 않은 날짜"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "홍길동"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "월"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "%s 참조와 일치하는 거래 항목이 없습니다."
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "결제대행업체"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "지불 거래"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "결제 프로세스 실패"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "전화번호"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "일반 키"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr "참조가 누락된 데이터가 수신되었습니다."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "비밀 키"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "홍길동"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr "API와의 통신에 실패했습니다. Xendit에서 다음 정보를 확인했습니다: '%s'"
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "이 결제대행업체의 기술 코드입니다."
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "거래가 토큰에 연결되어 있지 않습니다."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "웹훅 토큰"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr "Xendit 공개 키"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "Xendit 보안 키"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "Xendit 웹훅 토큰"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "YYYY"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "john.smith@example.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ku.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ku.po
new file mode 100644
index 00000000..a2211754
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ku.po
@@ -0,0 +1,195 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_xendit
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/lt.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/lt.po
new file mode 100644
index 00000000..a2211754
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/lt.po
@@ -0,0 +1,195 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_xendit
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/mn.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/mn.po
new file mode 100644
index 00000000..a2211754
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/mn.po
@@ -0,0 +1,195 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_xendit
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/my.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/my.po
new file mode 100644
index 00000000..a2211754
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/my.po
@@ -0,0 +1,195 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_xendit
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/nb.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/nb.po
new file mode 100644
index 00000000..6629153e
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/nb.po
@@ -0,0 +1,199 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 18:44+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Norwegian Bokmål \n"
+"Language: nb\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Kortnummer"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Kode"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "E-post"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Utløpsdato"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Betalingsleverandør"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Betalingstransaksjon"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Telefonnummer"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Hemmelig nøkkel"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/nl.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/nl.po
new file mode 100644
index 00000000..1f664eed
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/nl.po
@@ -0,0 +1,203 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-14 08:06+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Dutch \n"
+"Language: nl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+"Er is een fout opgetreden tijdens de verwerking van je betaling (%s). "
+"Probeer het opnieuw."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "Kaartcode"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr "Voornaam kaarthouder"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr "Achternaam kaarthouder"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Kaartnummer"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Code"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Kan geen verbinding maken met de API."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "E-mail"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Vervaldatum"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr "Ongeldige CVN"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr "Ongeldig kaartnummer"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr "Ongeldige datum"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "John"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Geen transactie gevonden die overeenkomt met referentie %s."
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Betaalprovider"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Betalingstransactie"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Betalingsverwerking mislukt"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Telefoonnummer"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "Publieke sleutel"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr "Gegevens ontvangen met ontbrekende referentie."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Geheime sleutel"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "Smith"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+"De communicatie met de API is mislukt. Xendit gaf ons de volgende informatie:"
+" '%s'"
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "De technische code van deze betaalprovider."
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "De transactie is niet gekoppeld aan een token."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "Token Webhook"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr "Xendit openbare sleutel"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "Xendit Secret Key"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "Xendit Webhook Token"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "JJJJ"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "john.smith@example.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/payment_xendit.pot b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/payment_xendit.pot
new file mode 100644
index 00000000..75b79338
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/payment_xendit.pot
@@ -0,0 +1,175 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_xendit
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 19.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:59+0000\n"
+"PO-Revision-Date: 2025-09-11 13:59+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/interactions/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/interactions/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/interactions/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/pl.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/pl.po
new file mode 100644
index 00000000..4f5133b0
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/pl.po
@@ -0,0 +1,200 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-17 17:31+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Polish \n"
+"Language: pl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
+"|| n%100>=20) ? 1 : 2;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Numer karty"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Kod"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Nie można nawiązać połączenia z interfejsem API."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "E-mail"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Wygaśnięcie"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "Jan"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Nie znaleziono transakcji pasującej do referencji %s."
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Dostawca Płatności"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transakcja płatności"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Przetwarzanie płatności nie powiodło się"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Numer Telefonu"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "Klucz publiczny"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Tajny klucz"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "Kowalski"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Kod techniczny tego dostawcy usług płatniczych."
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "Transakcja nie jest powiązana z tokenem."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "Tajny klucz Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "RRRR"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "john.smith@example.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/pt.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/pt.po
new file mode 100644
index 00000000..c1787a66
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/pt.po
@@ -0,0 +1,203 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 18:44+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Portuguese \n"
+"Language: pt\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n > 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+"Ocorreu um erro durante o processamento de seu pagamento (%s). Tente "
+"novamente."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "Código do cartão"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr "Nome do titular do cartão"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr "Sobrenome do titular do cartão"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Número do cartão"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Código"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Não foi possível estabelecer a conexão com a API."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "E-mail"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Expiração"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr "CVN inválido"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr "Número de cartão inválido"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr "Data inválida"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "João"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Nenhuma transação encontrada com a referência %s."
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Provedor de serviços de pagamento"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transação do pagamento"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Falha no processamento do pagamento"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Número de telefone"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "Chave pública"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr "Dados recebidos com referência ausente."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Chave secreta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "Silva"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+"A comunicação com a API falhou. O Xendit nos forneceu as seguintes "
+"informações: '%s'"
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "O código técnico deste provedor de pagamento."
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "A transação não está vinculada a um token."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "Token do webhook"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr "Chave pública do Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "Xendit - Chave secreta"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "Xendit - Token do webhook"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "AAAA"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "john.smith@exemplo.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/pt_BR.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/pt_BR.po
new file mode 100644
index 00000000..a7182f83
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/pt_BR.po
@@ -0,0 +1,203 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-17 17:21+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Portuguese (Brazil) \n"
+"Language: pt_BR\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n > 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+"Ocorreu um erro durante o processamento de seu pagamento (%s). Tente "
+"novamente."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "Código do cartão"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr "Nome do titular do cartão"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr "Sobrenome do titular do cartão"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Número do cartão"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Código"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Não foi possível estabelecer a conexão com a API."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "E-mail"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Expiração"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr "CVN inválido"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr "Número de cartão inválido"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr "Data inválida"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "João"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Nenhuma transação encontrada com a referência %s."
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Provedor de serviços de pagamento"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Transação do pagamento"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Falha no processamento do pagamento"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Número de telefone"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "Chave pública"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr "Dados recebidos com referência ausente."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Chave secreta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "Silva"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+"A comunicação com a API falhou. O Xendit nos forneceu as seguintes "
+"informações: '%s'"
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "O código técnico deste provedor de pagamento."
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "A transação não está vinculada a um token."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "Token do webhook"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr "Chave pública do Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "Xendit - Chave secreta"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "Xendit - Token do webhook"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "AAAA"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "john.smith@exemplo.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ro.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ro.po
new file mode 100644
index 00000000..a2211754
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ro.po
@@ -0,0 +1,195 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_xendit
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ru.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ru.po
new file mode 100644
index 00000000..7955fdaa
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/ru.po
@@ -0,0 +1,207 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# Translators:
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 17.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:59+0000\n"
+"PO-Revision-Date: 2025-09-16 02:35+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Russian \n"
+"Language: ru\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
+"n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || ("
+"n%100>=11 && n%100<=14)? 2 : 3);\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+"Произошла ошибка при обработке вашего платежа (%s). Пожалуйста, попробуйте "
+"снова."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "Код карты"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Номер карты"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Код"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "Email"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Действительно до"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_transaction__id
+msgid "ID"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/interactions/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/interactions/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/interactions/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "ММ"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Поставщик платежей"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Платеж"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Обработка платежа не удалась"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Номер телефона"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "Открытый ключ"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Секретный ключ"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Технический код данного провайдера платежей."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "Токен вебхука"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "Секретный ключ Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "Xendit Webhook Token"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "ГГГГ"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "fedor.kuznetsov@mail.ru"
+
+#~ msgid ""
+#~ "An error occurred during the processing of your payment (status %s). "
+#~ "Please try again."
+#~ msgstr ""
+#~ "Во время обработки вашего платежа произошла ошибка (статус %s). "
+#~ "Пожалуйста, попробуйте еще раз."
+
+#~ msgid "Could not establish the connection to the API."
+#~ msgstr "Не удалось установить соединение с API."
+
+#~ msgid "No transaction found matching reference %s."
+#~ msgstr "Не найдено ни одной транзакции, соответствующей ссылке %s."
+
+#~ msgid "Received data with missing reference."
+#~ msgstr "Получены данные с отсутствующей ссылкой."
+
+#~ msgid ""
+#~ "The communication with the API failed. Xendit gave us the following "
+#~ "information: '%s'"
+#~ msgstr ""
+#~ "Связь с API завершилась неудачей. Xendit выдал нам следующую информацию: "
+#~ "'%s'"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/sl.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/sl.po
new file mode 100644
index 00000000..3edb46e5
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/sl.po
@@ -0,0 +1,200 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 21:37+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Slovenian \n"
+"Language: sl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || "
+"n%100==4 ? 2 : 3;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Številka kartice"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Oznaka"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "E-pošta"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Veljavnost"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Ponudnik plačil"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Plačilna transakcija"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Telefonska številka"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "Javni ključ"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Skrivni ključ"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/sr@latin.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/sr@latin.po
new file mode 100644
index 00000000..a2211754
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/sr@latin.po
@@ -0,0 +1,195 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_xendit
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/sv.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/sv.po
new file mode 100644
index 00000000..2d122205
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/sv.po
@@ -0,0 +1,203 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 21:14+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Swedish \n"
+"Language: sv\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+"Ett fel uppstod under behandlingen av din betalning (%s). Vänligen försök "
+"igen."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "Kortkod"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr "Kortinnehavarens förnamn"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr "Kortinnehavarens efternamn"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Kortnummer"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Kod"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Det gick inte att upprätta anslutningen till API:et."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "E-post"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Utgång"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr "Ogiltigt CVN"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr "Ogiltigt kortnummer"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr "Ogiltigt datum"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "Nisse"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Ingen transaktion hittades som matchar referensen %s."
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Betalningsleverantör"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Betalningstransaktion"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Betalningshanteringen misslyckades"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Telefonnummer"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "Publik nyckel"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr "Mottagen data med saknad referens."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Hemlig nyckel"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "Hult"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+"Kommunikationen med API:et misslyckades. Xendit gav oss följande information:"
+" \"%s"
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Den tekniska koden för denna betalningsleverantör."
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "Transaktionen är inte kopplad till en token."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "Webhook Pollett"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr "Xendit publik nyckel"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "Xendit hemlig nyckel"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "Xendit Webhook Pollett"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "ÅÅÅÅ"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "nisse.hult@exempel.se"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/th.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/th.po
new file mode 100644
index 00000000..5ae20095
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/th.po
@@ -0,0 +1,199 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 21:20+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Thai \n"
+"Language: th\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr "เกิดข้อผิดพลาดระหว่างการประมวลผลการชำระเงินของคุณ (%s) กรุณาลองอีกครั้ง"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "รหัสบัตร"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "หมายเลขบัตร"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "โค้ด"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "ไม่สามารถสร้างการเชื่อมต่อกับ API ได้"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "อีเมล"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "สิ้นสุด"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "ไม่พบธุรกรรมที่ตรงกับการอ้างอิง %s"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "ผู้ให้บริการชำระเงิน"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "ธุรกรรมสำหรับการชำระเงิน"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "การประมวลผลการชำระเงินล้มเหลว"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "หมายเลขโทรศัพท์"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "คีย์สาธารณะ"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr "ได้รับข้อมูลโดยไม่มีการอ้างอิง"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "คีย์ลับ"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr "การสื่อสารกับ API ล้มเหลว Xendit ให้ข้อมูลต่อไปนี้กับเรา: '%s'"
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "รหัสทางเทคนิคของผู้ให้บริการชำระเงินรายนี้"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "ธุรกรรมไม่ได้เชื่อมโยงกับโทเค็น"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "โทเค็นเว็บฮุค"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "คีย์รหัส Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "เว็บฮุคโทเค็น Xendit"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "john.smith@example.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/tr.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/tr.po
new file mode 100644
index 00000000..a2211754
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/tr.po
@@ -0,0 +1,195 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_xendit
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/uk.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/uk.po
new file mode 100644
index 00000000..a2211754
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/uk.po
@@ -0,0 +1,195 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* payment_xendit
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2024-09-26 08:56+0000\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr ""
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr ""
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr ""
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr ""
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/vi.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/vi.po
new file mode 100644
index 00000000..d37bdb4f
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/vi.po
@@ -0,0 +1,203 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 02:34+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Vietnamese \n"
+"Language: vi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr ""
+"Đã xảy ra lỗi trong quá trình xử lý khoản thanh toán của bạn (%s). Vui lòng "
+"thử lại."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "Mã thẻ"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr "Tên chủ thẻ"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr "Họ chủ thẻ"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "Số thẻ"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "Mã"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "Không thể thiết lập kết nối với API."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "Email"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "Ngày hết hạn"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr "CVN không hợp lệ"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr "Số thẻ không hợp lệ"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr "Ngày không hợp lệ"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "John"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "MM"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "Không tìm thấy giao dịch nào khớp với mã %s."
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "Nhà cung cấp dịch vụ thanh toán"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "Giao dịch thanh toán"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "Xử lý thanh toán không thành công"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "Số điện thoại"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "Mã khóa công khai"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr "Dữ liệu đã nhận bị thiếu mã."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "Mã khóa bí mật"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "Smith"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr ""
+"Giao tiếp với API không thành công. Xendit đã cung cấp cho chúng tôi thông "
+"tin sau: '%s'"
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "Mã kỹ thuật của nhà cung cấp dịch vụ thanh toán này."
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "Giao dịch không được liên kết với token."
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "Token webhook"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr "Khoá công khai Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "Khoá bí mật Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "Token Webhook Xendit"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "YYYY"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "john.smith@example.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/zh_CN.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/zh_CN.po
new file mode 100644
index 00000000..41008e0d
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/zh_CN.po
@@ -0,0 +1,199 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# "Tiffany Chang (tic)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 18.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-09-26 08:56+0000\n"
+"PO-Revision-Date: 2025-09-16 15:34+0000\n"
+"Last-Translator: \"Tiffany Chang (tic)\" \n"
+"Language-Team: Chinese (Simplified Han script) \n"
+"Language: zh_CN\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr "处理付款过程中发生错误,请再试一次。(付款:%s)"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "卡代码"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr "持卡人名字"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr "持卡人姓氏"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "卡号"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "代码"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid "Could not establish the connection to the API."
+msgstr "无法建立与API的连接。"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "电子邮件"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "到期"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid CVN"
+msgstr "CVN 无效"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr "卡号码无效"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Invalid Date"
+msgstr "无效日期"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "John"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "月"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "No transaction found matching reference %s."
+msgstr "没有找到与参考文献%s相匹配的交易."
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "支付提供商"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "付款交易"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/js/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "付款处理失败"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "电话号码"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "公开密钥"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "Received data with missing reference."
+msgstr "收到的数据缺少参考编号。"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "密钥"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "Smith"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_provider.py:0
+msgid ""
+"The communication with the API failed. Xendit gave us the following "
+"information: '%s'"
+msgstr "与 API 的通信失败。Xendit 提供了以下失败报错信息: '%s'"
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "该支付提供商的技术代码。"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid "The transaction is not linked to a token."
+msgstr "该交易没有与令牌挂钩。"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "Webhook的令牌"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr "Xendit 公开密钥"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "Xendit 秘密密钥"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "Xendit Webhook 令牌"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "YYYY"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "john.smith@example.com"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/zh_TW.po b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/zh_TW.po
new file mode 100644
index 00000000..2453a834
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/i18n/zh_TW.po
@@ -0,0 +1,199 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * payment_xendit
+#
+# Translators:
+# Wil Odoo, 2025
+#
+# "Dylan Kiss (dyki)" , 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server saas~18.3\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-09-11 13:59+0000\n"
+"PO-Revision-Date: 2025-09-16 08:11+0000\n"
+"Last-Translator: \"Dylan Kiss (dyki)\" \n"
+"Language-Team: Chinese (Traditional Han script) \n"
+"Language: zh_TW\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 5.12.2\n"
+
+#. module: payment_xendit
+#. odoo-python
+#: code:addons/payment_xendit/models/payment_transaction.py:0
+msgid ""
+"An error occurred during the processing of your payment (%s). Please try "
+"again."
+msgstr "處理付款過程中發生錯誤,請再試一次。(付款:%s)"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Code"
+msgstr "卡代碼"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder First Name"
+msgstr "持卡人名字"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Holder Last Name"
+msgstr "持卡人姓氏"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Card Number"
+msgstr "卡號碼"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__code
+msgid "Code"
+msgstr "代碼"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__display_name
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_transaction__display_name
+msgid "Display Name"
+msgstr "顯示名稱"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Email"
+msgstr "電郵"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Expiration"
+msgstr "截止日期"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__id
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_transaction__id
+msgid "ID"
+msgstr "識別號"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/interactions/payment_form.js:0
+msgid "Invalid CVN"
+msgstr "CVN 無效"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/interactions/payment_form.js:0
+msgid "Invalid Card Number"
+msgstr "卡號碼無效"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/interactions/payment_form.js:0
+msgid "Invalid Date"
+msgstr "日期無效"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "John"
+msgstr "John"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "MM"
+msgstr "月月"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_provider
+msgid "Payment Provider"
+msgstr "付款服務商"
+
+#. module: payment_xendit
+#: model:ir.model,name:payment_xendit.model_payment_transaction
+msgid "Payment Transaction"
+msgstr "付款交易"
+
+#. module: payment_xendit
+#. odoo-javascript
+#: code:addons/payment_xendit/static/src/interactions/payment_form.js:0
+msgid "Payment processing failed"
+msgstr "付款處理失敗"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Phone Number"
+msgstr "電話號碼"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Public Key"
+msgstr "公鑰"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Secret Key"
+msgstr "密鑰"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "Smith"
+msgstr "Smith"
+
+#. module: payment_xendit
+#: model:ir.model.fields,help:payment_xendit.field_payment_provider__code
+msgid "The technical code of this payment provider."
+msgstr "此付款服務商的技術代碼。"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.payment_provider_form_xendit
+msgid "Webhook Token"
+msgstr "網絡鈎子權杖"
+
+#. module: payment_xendit
+#: model:ir.model.fields.selection,name:payment_xendit.selection__payment_provider__code__xendit
+msgid "Xendit"
+msgstr "Xendit"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_public_key
+msgid "Xendit Public Key"
+msgstr "Xendit 公開金鑰"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_secret_key
+msgid "Xendit Secret Key"
+msgstr "Xendit 秘密密鑰"
+
+#. module: payment_xendit
+#: model:ir.model.fields,field_description:payment_xendit.field_payment_provider__xendit_webhook_token
+msgid "Xendit Webhook Token"
+msgstr "Xendit 網絡鈎子權杖"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "YYYY"
+msgstr "年年年年"
+
+#. module: payment_xendit
+#: model_terms:ir.ui.view,arch_db:payment_xendit.inline_form
+msgid "john.smith@example.com"
+msgstr "例:alex.wong@example.com"
+
+#~ msgid "Could not establish the connection to the API."
+#~ msgstr "未能建立與 API 的連線。"
+
+#~ msgid "No transaction found matching reference %s."
+#~ msgstr "找不到符合參考 %s 的交易。"
+
+#~ msgid "Received data with missing reference."
+#~ msgstr "收到的數據缺漏參考編號。"
+
+#~ msgid ""
+#~ "The communication with the API failed. Xendit gave us the following "
+#~ "information: '%s'"
+#~ msgstr "與 API 通訊失敗。Xendit 提供了以下資訊:%s"
+
+#~ msgid "The transaction is not linked to a token."
+#~ msgstr "交易未有連結至代碼。"
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/models/__init__.py b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/models/__init__.py
new file mode 100644
index 00000000..08dfb8af
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/models/__init__.py
@@ -0,0 +1,4 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import payment_provider
+from . import payment_transaction
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/models/payment_provider.py b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/models/payment_provider.py
new file mode 100644
index 00000000..5614ac72
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/models/payment_provider.py
@@ -0,0 +1,102 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import fields, models
+
+from odoo.addons.payment.logging import get_payment_logger
+from odoo.addons.payment_xendit import const
+
+
+_logger = get_payment_logger(__name__)
+
+
+class PaymentProvider(models.Model):
+    _inherit = 'payment.provider'
+
+    code = fields.Selection(
+        selection_add=[('xendit', "Xendit")], ondelete={'xendit': 'set default'}
+    )
+    xendit_public_key = fields.Char(
+        string="Xendit Public Key",
+        required_if_provider='xendit',
+        copy=False,
+        groups='base.group_system',
+    )
+    xendit_secret_key = fields.Char(
+        string="Xendit Secret Key",
+        required_if_provider='xendit',
+        copy=False,
+        groups='base.group_system',
+    )
+    xendit_webhook_token = fields.Char(
+        string="Xendit Webhook Token",
+        required_if_provider='xendit',
+        copy=False,
+        groups='base.group_system',
+    )
+
+    # === COMPUTE METHODS === #
+
+    def _compute_feature_support_fields(self):
+        """ Override of `payment` to enable additional features. """
+        super()._compute_feature_support_fields()
+        self.filtered(lambda p: p.code == 'xendit').support_tokenization = True
+
+    def _get_supported_currencies(self):
+        """ Override of `payment` to return the supported currencies. """
+        supported_currencies = super()._get_supported_currencies()
+        if self.code == 'xendit':
+            supported_currencies = supported_currencies.filtered(
+                lambda c: c.name in const.SUPPORTED_CURRENCIES
+            )
+        return supported_currencies
+
+    # === CRUD METHODS === #
+
+    def _get_default_payment_method_codes(self):
+        """ Override of `payment` to return the default payment method codes. """
+        self.ensure_one()
+        if self.code != 'xendit':
+            return super()._get_default_payment_method_codes()
+        return const.DEFAULT_PAYMENT_METHOD_CODES
+
+    # === BUSINESS METHODS === #
+
+    def _get_redirect_form_view(self, is_validation=False):
+        """ Override of `payment` to avoid rendering the form view for validation operations.
+
+        Unlike other compatible payment methods in Xendit, `Card` is implemented using a direct
+        flow. To avoid rendering a useless template, and also to avoid computing wrong values, this
+        method returns `None` for Xendit's validation operations (Card is and will always be the
+        sole tokenizable payment method for Xendit).
+
+        Note: `self.ensure_one()`
+
+        :param bool is_validation: Whether the operation is a validation.
+        :return: The view of the redirect form template or None.
+        :rtype: ir.ui.view | None
+        """
+        self.ensure_one()
+
+        if self.code == 'xendit' and is_validation:
+            return None
+        return super()._get_redirect_form_view(is_validation)
+
+    # === REQUEST HELPERS ===#
+
+    def _build_request_url(self, endpoint, **kwargs):
+        """Override of `payment` to build the request URL."""
+        if self.code != 'xendit':
+            return super()._build_request_url(endpoint, **kwargs)
+        return f'https://api.xendit.co/{endpoint}'
+
+    def _build_request_auth(self, **kwargs):
+        """Override of `payment` to build the request Auth."""
+        if self.code != 'xendit':
+            return super()._build_request_auth(**kwargs)
+        return self.xendit_secret_key, ''
+
+    def _parse_response_error(self, response):
+        """Override of `payment` to parse the error message."""
+        if self.code != 'xendit':
+            return super()._parse_response_error(response)
+        return response.json().get('message')
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/models/payment_transaction.py b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/models/payment_transaction.py
new file mode 100644
index 00000000..299984e8
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/models/payment_transaction.py
@@ -0,0 +1,222 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from werkzeug import urls
+
+from odoo import _, api, models
+from odoo.exceptions import ValidationError
+from odoo.tools import float_round
+from odoo.tools.urls import urljoin
+
+from odoo.addons.payment import utils as payment_utils
+from odoo.addons.payment.logging import get_payment_logger
+from odoo.addons.payment_xendit import const
+from odoo.addons.payment_xendit.controllers.main import XenditController
+
+
+_logger = get_payment_logger(__name__)
+
+
+class PaymentTransaction(models.Model):
+    _inherit = 'payment.transaction'
+
+    def _get_specific_processing_values(self, processing_values):
+        """ Override of payment to return Xendit-specific processing values.
+
+        Note: self.ensure_one() from `_get_processing_values`
+
+        :param dict processing_values: The generic processing values of the transaction
+        :return: The dict of provider-specific processing values
+        :rtype: dict
+        """
+        if self.provider_code != 'xendit':
+            return super()._get_specific_processing_values(processing_values)
+
+        return {
+            'rounded_amount': self._get_rounded_amount(),
+        }
+
+    def _get_specific_rendering_values(self, processing_values):
+        """ Override of `payment` to return Xendit-specific rendering values.
+
+        Note: self.ensure_one() from `_get_processing_values`
+
+        :param dict processing_values: The generic and specific processing values of the transaction
+        :return: The dict of provider-specific processing values.
+        :rtype: dict
+        """
+        res = super()._get_specific_rendering_values(processing_values)
+        if self.provider_code != 'xendit' or self.payment_method_code == 'card':
+            return res
+
+        # Initiate the payment and retrieve the invoice data.
+        payload = self._xendit_prepare_invoice_request_payload()
+        try:
+            invoice_data = self._send_api_request('POST', 'v2/invoices', json=payload)
+        except ValidationError as error:
+            self._set_error(str(error))
+            return {}
+
+        # Extract the payment link URL and embed it in the redirect form.
+        rendering_values = {
+            'api_url': invoice_data.get('invoice_url')
+        }
+        return rendering_values
+
+    def _xendit_prepare_invoice_request_payload(self):
+        """ Create the payload for the invoice request based on the transaction values.
+
+        :return: The request payload.
+        :rtype: dict
+        """
+        base_url = self.provider_id.get_base_url()
+        redirect_url = urljoin(base_url, XenditController._return_url)
+        access_token = payment_utils.generate_access_token(self.reference, self.amount)
+        success_url_params = urls.url_encode({
+            'tx_ref': self.reference,
+            'access_token': access_token,
+            'success': 'true',
+        })
+        payload = {
+            'external_id': self.reference,
+            'amount': self._get_rounded_amount(),
+            'description': self.reference,
+            'customer': {
+                'given_names': self.partner_name,
+            },
+            'success_redirect_url': f'{redirect_url}?{success_url_params}',
+            'failure_redirect_url': redirect_url,
+            'payment_methods': [const.PAYMENT_METHODS_MAPPING.get(
+                self.payment_method_code, self.payment_method_code.upper())
+            ],
+            'currency': self.currency_id.name,
+        }
+        # Extra payload values that must not be included if empty.
+        if self.partner_email:
+            payload['customer']['email'] = self.partner_email
+        if phone := self.partner_id.phone:
+            payload['customer']['mobile_number'] = phone
+        address_details = {}
+        if self.partner_city:
+            address_details['city'] = self.partner_city
+        if self.partner_country_id.name:
+            address_details['country'] = self.partner_country_id.name
+        if self.partner_zip:
+            address_details['postal_code'] = self.partner_zip
+        if self.partner_state_id.name:
+            address_details['state'] = self.partner_state_id.name
+        if self.partner_address:
+            address_details['street_line1'] = self.partner_address
+        if address_details:
+            payload['customer']['addresses'] = [address_details]
+
+        return payload
+
+    def _send_payment_request(self):
+        """Override of `payment` to send a payment request to Xendit."""
+        if self.provider_code != 'xendit':
+            return super()._send_payment_request()
+
+        self._xendit_create_charge(self.token_id.provider_ref)
+
+    def _xendit_create_charge(self, token_ref, auth_id=None):
+        """ Create a charge on Xendit using the `credit_card_charges` endpoint.
+
+        :param str token_ref: The reference of the Xendit token to use to make the payment.
+        :param str auth_id: The authentication id to use to make the payment.
+        :return: None
+        """
+        payload = {
+            'token_id': token_ref,
+            'external_id': self.reference,
+            'amount': self._get_rounded_amount(),
+            'currency': self.currency_id.name,
+        }
+        if auth_id:  # The payment goes through an authentication.
+            payload['authentication_id'] = auth_id
+
+        if self.token_id or self.tokenize:  # The tx uses a token or is tokenized.
+            payload['is_recurring'] = True  # Ensure that next payments will not require 3DS.
+
+        try:
+            charge_payment_data = self._send_api_request(
+                'POST', 'credit_card_charges', json=payload
+            )
+        except ValidationError as error:
+            self._set_error(str(error))
+        else:
+            self._process('xendit', charge_payment_data)
+
+    def _get_rounded_amount(self):
+        decimal_places = const.CURRENCY_DECIMALS.get(
+            self.currency_id.name, self.currency_id.decimal_places
+        )
+        return float_round(self.amount, decimal_places, rounding_method='DOWN')
+
+    @api.model
+    def _extract_reference(self, provider_code, payment_data):
+        """Override of `payment` to extract the reference from the payment data."""
+        if provider_code != 'xendit':
+            return super()._extract_reference(provider_code, payment_data)
+        return payment_data.get('external_id')
+
+    def _extract_amount_data(self, payment_data):
+        """Override of payment to extract the amount and currency from the payment data."""
+        if self.provider_code != 'xendit':
+            return super()._extract_amount_data(payment_data)
+
+        amount = payment_data.get('amount') or payment_data.get('authorized_amount')
+        currency_code = payment_data.get('currency')
+        return {
+            'amount': float(amount),
+            'currency_code': currency_code,
+            'precision_digits': const.CURRENCY_DECIMALS.get(currency_code),
+        }
+
+    def _apply_updates(self, payment_data):
+        """Override of `payment` to update the transaction based on the payment data."""
+        if self.provider_code != 'xendit':
+            return super()._apply_updates(payment_data)
+
+        # Update the provider reference.
+        self.provider_reference = payment_data.get('id')
+
+        # Update payment method.
+        payment_method_code = payment_data.get('payment_method', '')
+        payment_method = self.env['payment.method']._get_from_code(
+            payment_method_code, mapping=const.PAYMENT_METHODS_MAPPING
+        )
+        self.payment_method_id = payment_method or self.payment_method_id
+
+        # Update the payment state.
+        payment_status = payment_data.get('status')
+        if payment_status in const.PAYMENT_STATUS_MAPPING['pending']:
+            self._set_pending()
+        elif payment_status in const.PAYMENT_STATUS_MAPPING['done']:
+            self._set_done()
+        elif payment_status in const.PAYMENT_STATUS_MAPPING['cancel']:
+            self._set_canceled()
+        elif payment_status in const.PAYMENT_STATUS_MAPPING['error']:
+            failure_reason = payment_data.get('failure_reason')
+            self._set_error(_(
+                "An error occurred during the processing of your payment (%s). Please try again.",
+                failure_reason,
+            ))
+
+    def _extract_token_values(self, payment_data):
+        """Override of `payment` to return token data based on Xendit data.
+
+        Note: self.ensure_one() from :meth: `_tokenize`
+
+        :param dict payment_data: The payment data sent by the provider.
+        :return: Data to create a token.
+        :rtype: dict
+        """
+        if self.provider_code != 'xendit':
+            return super()._extract_token_values(payment_data)
+
+        card_info = payment_data['masked_card_number'][-4:]  # Xendit pads details with X's.
+
+        return {
+            'payment_details': card_info,
+            'provider_ref': payment_data['credit_card_token_id'],
+        }
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/description/icon.png b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/description/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..199f849265995aa8e3a500346dda5c1cc76be8d4
GIT binary patch
literal 3296
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
MboFyt=akR{0L&sr!~g&Q

literal 0
HcmV?d00001

diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/description/icon.svg b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/description/icon.svg
new file mode 100644
index 00000000..2aedb238
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/description/icon.svg
@@ -0,0 +1 @@
+
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/src/interactions/payment_form.js b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/src/interactions/payment_form.js
new file mode 100644
index 00000000..558e56c8
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/src/interactions/payment_form.js
@@ -0,0 +1,254 @@
+/* global Xendit */
+
+import { loadJS } from '@web/core/assets';
+import { _t } from '@web/core/l10n/translation';
+import { rpc, RPCError } from '@web/core/network/rpc';
+import { patch } from '@web/core/utils/patch';
+
+import { PaymentForm } from '@payment/interactions/payment_form';
+
+patch(PaymentForm.prototype, {
+    setup() {
+        super.setup();
+        this.xenditData = {}; // Store the form and public key of each instantiated Card method.
+    },
+
+    // #=== DOM MANIPULATION ===#
+
+    /**
+     * Prepare the inline form of Xendit for direct payment.
+     *
+     * @override method from @payment/js/payment_form
+     * @private
+     * @param {number} providerId - The id of the selected payment option's provider.
+     * @param {string} providerCode - The code of the selected payment option's provider.
+     * @param {number} paymentOptionId - The id of the selected payment option.
+     * @param {string} paymentMethodCode - The code of the selected payment method, if any.
+     * @param {string} flow - The online payment flow of the selected payment option.
+     * @return {void}
+     */
+    async _prepareInlineForm(providerId, providerCode, paymentOptionId, paymentMethodCode, flow) {
+        if (providerCode !== 'xendit' || paymentMethodCode !== 'card') {
+            await super._prepareInlineForm(...arguments);
+            return;
+        }
+
+        // Check if instantiation of the inline form is needed.
+        if (flow === 'token') {
+            return; // No inline form for tokens.
+        } else if (this.xenditData[paymentOptionId]) {
+            this._setPaymentFlow('direct'); // Overwrite the flow even if no re-instantiation.
+            return; // Don't re-extract the data if already done for this payment method.
+        }
+
+        // Overwrite the flow of the selected payment method.
+        this._setPaymentFlow('direct');
+
+        // Extract and store the public key.
+        const radio = document.querySelector('input[name="o_payment_radio"]:checked');
+        const inlineForm = this._getInlineForm(radio);
+        const xenditInlineForm = inlineForm.querySelector('[name="o_xendit_form"]');
+        this.xenditData[paymentOptionId] = {
+            publicKey: xenditInlineForm.dataset['xenditPublicKey'],
+            inlineForm: xenditInlineForm,
+        };
+
+        // Load the SDK.
+        await this.waitFor(loadJS('https://js.xendit.co/v1/xendit.min.js'));
+        Xendit.setPublishableKey(this.xenditData[paymentOptionId].publicKey);
+    },
+
+    // #=== PAYMENT FLOW ===#
+
+    /**
+     * Validate the form inputs before initiating the payment flow.
+     *
+     * @override method from @payment/js/payment_form
+     * @private
+     * @param {string} providerCode - The code of the selected payment option's provider.
+     * @param {number} paymentOptionId - The id of the selected payment option.
+     * @param {string} paymentMethodCode - The code of the selected payment method, if any.
+     * @param {string} flow - The payment flow of the selected payment option.
+     * @return {void}
+     */
+    async _initiatePaymentFlow(providerCode, paymentOptionId, paymentMethodCode, flow) {
+        if (providerCode !== 'xendit' || flow === 'token' || paymentMethodCode !== 'card') {
+            // Tokens are handled by the generic flow and other payment methods have no inline form.
+            await super._initiatePaymentFlow(...arguments);
+            return;
+        }
+
+        const formInputs = this._xenditGetInlineFormInputs(paymentOptionId);
+        const details = this._xenditGetPaymentDetails(paymentOptionId);
+
+        // Set custom validity messages on inputs based on Xendit's feedback.
+        Object.keys(formInputs).forEach(el => formInputs[el].setCustomValidity(""));
+        if (!Xendit.card.validateCardNumber(details.card_number)){
+            formInputs['card'].setCustomValidity(_t("Invalid Card Number"));
+        }
+        if (!Xendit.card.validateExpiry(details.card_exp_month, details.card_exp_year)) {
+            formInputs['month'].setCustomValidity(_t("Invalid Date"));
+            formInputs['year'].setCustomValidity(_t("Invalid Date"));
+        }
+        if (!Xendit.card.validateCvn(details.card_cvn)){
+            formInputs['cvn'].setCustomValidity(_t("Invalid CVN"));
+        }
+
+        // Ensure that all inputs are valid.
+        if (!Object.values(formInputs).every(element => element.reportValidity())) {
+            this._enableButton(); // The submit button is disabled at this point, enable it.
+            return;
+        }
+        await super._initiatePaymentFlow(...arguments);
+    },
+
+    /**
+     * Process the direct payment flow by creating a token and proceeding with a token payment flow.
+     *
+     * @override method from @payment/js/payment_form
+     * @private
+     * @param {string} providerCode - The code of the selected payment option's provider.
+     * @param {number} paymentOptionId - The id of the selected payment option.
+     * @param {string} paymentMethodCode - The code of the selected payment method, if any.
+     * @param {object} processingValues - The processing values of the transaction.
+     * @return {void}
+     */
+    async _processDirectFlow(providerCode, paymentOptionId, paymentMethodCode, processingValues) {
+        if (providerCode !== 'xendit') {
+            await super._processDirectFlow(...arguments);
+            return;
+        }
+
+        Xendit.card.createToken(
+            {
+                ...this._xenditGetPaymentDetails(paymentOptionId),
+                // Allow reusing tokens when the transaction should be tokenized.
+                is_multiple_use: processingValues['should_tokenize'],
+                amount: processingValues['rounded_amount'],
+            },
+            async (err, token) =>
+                {
+                    // if any errors are reported, immediately report it
+                    if (err) {
+                        this._xenditHandleResponse(err, token, processingValues, '');
+                    }
+                    // For multiple use tokens, we have to create an authentication first before
+                    // charging.
+                    if (processingValues['should_tokenize']) {
+                        Xendit.card.createAuthentication({
+                            amount: processingValues.amount,
+                            token_id: token.id
+                        }, async (err, result) => {
+                            await this._xenditHandleResponse(err, result, processingValues, 'auth');
+                        });
+                    }
+                    else {
+                        await this._xenditHandleResponse(err, token, processingValues, 'token');
+                    }
+                },
+        );
+    },
+
+    /**
+     * Handle the token creation response and initiate the token payment.
+     *
+     * @private
+     * @param {object} err - The error with the cause.
+     * @param {object} token - The created token's data.
+     * @param {object} processingValues - The processing values of the transaction.
+     * @param {string} mode - The mode of the charge: 'auth' or 'token'.
+     * @return {void}
+     */
+    async _xenditHandleResponse(err, token, processingValues, mode) {
+        if (err) {
+            let errMessage = err.message;
+
+            if (err.error_code === 'API_VALIDATION_ERROR') {  // Invalid user input
+                errMessage = err.errors[0].message; // Wrong field format
+            }
+            this._displayErrorDialog(_t("Payment processing failed"), errMessage);
+            this._enableButton();
+            return;
+        }
+        if (token.status === 'VERIFIED') {
+            const payload = {
+                'reference': processingValues.reference,
+                'partner_id': processingValues.partner_id,
+            };
+            // Verified state could come from either authorization or tokenization. If it comes from
+            // authentication, we must pass auth_id.
+            if (mode === 'auth') {
+                Object.assign(payload, {
+                    'token_ref': token.credit_card_token_id,
+                    'auth_id': token.id,
+                });
+            }
+            else { // 'token'
+                payload['token_ref'] = token.id;
+            }
+            try {
+                await this.waitFor(rpc('/payment/xendit/payment', payload));
+                window.location = '/payment/status';
+            } catch (error) {
+                if (error instanceof RPCError) {
+                    this._displayErrorDialog(_t("Payment processing failed"), error.data.message);
+                    this._enableButton();
+                } else {
+                    return Promise.reject(error);
+                }
+            }
+        } else if (token.status === 'FAILED') {
+            this._displayErrorDialog(_t("Payment processing failed"), token.failure_reason);
+            document.querySelector('#three-ds-container').style.display = 'none';
+            this._enableButton();
+        } else if (token.status === 'IN_REVIEW') {
+            document.querySelector('#three-ds-container').style.display = 'block';
+            window.open(token.payer_authentication_url, 'authorization-form');
+        }
+    },
+
+    // #=== GETTERS ===#
+
+    /**
+     * Return all relevant inline form inputs of the provided payment option.
+     *
+     * @private
+     * @param {number} paymentOptionId - The id of the selected payment option.
+     * @return {Object} - An object mapping the name of inline form inputs to their DOM element.
+     */
+    _xenditGetInlineFormInputs(paymentOptionId) {
+        const form = this.xenditData[paymentOptionId]['inlineForm'];
+        return {
+            card: form.querySelector('#o_xendit_card'),
+            month: form.querySelector('#o_xendit_month'),
+            year: form.querySelector('#o_xendit_year'),
+            cvn: form.querySelector('#o_xendit_cvn'),
+            first_name: form.querySelector('#o_xendit_first_name'),
+            last_name: form.querySelector('#o_xendit_last_name'),
+            phone: form.querySelector('#o_xendit_phone'),
+            email: form.querySelector('#o_xendit_email'),
+        };
+    },
+
+    /**
+     * Return the credit card data to prepare the payload for the create token request.
+     *
+     * @private
+     * @param {number} paymentOptionId - The id of the selected payment option.
+     * @return {Object} - Data to pass to the Xendit createToken request.
+     */
+    _xenditGetPaymentDetails(paymentOptionId) {
+        const inputs = this._xenditGetInlineFormInputs(paymentOptionId);
+        return {
+            card_number: inputs.card.value.replace(/ /g, ''),
+            card_exp_month: inputs.month.value,
+            card_exp_year: inputs.year.value,
+            card_cvn: inputs.cvn.value,
+            card_holder_email: inputs.email.value,
+            card_holder_first_name: inputs.first_name.value,
+            card_holder_last_name: inputs.last_name.value,
+            card_holder_phone_number: inputs.phone.value
+        };
+    },
+
+});
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/src/js/auth_service.js b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/src/js/auth_service.js
new file mode 100644
index 00000000..c8854f32
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/src/js/auth_service.js
@@ -0,0 +1,12 @@
+import { EventBus } from '@odoo/owl';
+import { registry } from '@web/core/registry';
+import { AuthUI } from './auth_ui';
+
+const bus = new EventBus();
+
+export const authService = {
+    start(env) {
+        registry.category('main_components').add('AuthUI', { Component: AuthUI, props: { bus } });
+    }
+}
+registry.category('services').add('auth_ui', authService);
diff --git a/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/src/js/auth_ui.js b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/src/js/auth_ui.js
new file mode 100644
index 00000000..ef2be443
--- /dev/null
+++ b/odoo-bringout-oca-ocb-payment_xendit/payment_xendit/static/src/js/auth_ui.js
@@ -0,0 +1,29 @@
+import { Component, EventBus, xml } from '@odoo/owl';
+
+export class AuthUI extends Component {
+    static props = {
+        bus: EventBus,
+    }
+
+    // Has to be in front of the block UI layer (which is z-index: 1070).
+    static template = xml`
+        
+