=== KosTeams Payments for Yandex Pay and Yandex Split for WooCommerce ===
Contributors: pro100kostia
Tags: yandex, payments, split, pay, installments
Requires at least: 6.0
Tested up to: 6.9
Requires PHP: 8.0.0
Stable tag: 2.0.6
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Accept payments via Yandex Pay, Yandex Split, or a combination of both. Increase conversion with flexible payment options using the KosTeams plugin.

== Description ==
This plugin adds popular Yandex payment methods to your WooCommerce store:
- **Yandex Pay**: Instant card payment without entering card details.
- **Yandex Split**: Interest-free installments for up to 6 months.
- **Combined payment**: Pay part by card and the rest in installments.

= Modern Technology Compatibility =
- **Full WooCommerce Block Editor support** — the plugin works with both classic and block checkout
- **Gutenberg compatible** — integration with modern WordPress themes
- **React components** — modern architecture for fast performance

For advanced features (installment badges, widgets in cart and catalog), the [Pro version](https://kosteams.com/plugins/bejdzhi-i-vidzhety-yandex-split-i-yandex-pay-dlya-wordpress/) is available.

== Important Fiscalization Information ==

**Please note:** When using Yandex Pay and Yandex Split, you must comply with Russian legislation requirements for payment fiscalization.

= 54-FZ Requirements =
According to the Federal Law "On the Application of Cash Register Equipment" (54-FZ):
- Fiscal receipts must be issued for all forms of non-cash payments
- Yandex Pay and Yandex Split do not send fiscal receipts automatically
- The seller is responsible for complying with fiscalization requirements

= Possible Solutions =
To ensure 54-FZ compliance, consider the following options:
- Integration with online cash registers (ATOL, Evotor, OFD, etc.)
- Using specialized plugins for automatic receipt generation
- Setting up API integration with your fiscal service provider
- Consulting with certified cash register integrators

= Penalties for Non-Compliance =
- For individual entrepreneurs: from 10,000 rubles per violation
- For legal entities: from 30,000 rubles per violation
- Business operations may be suspended for up to 90 days

**Recommendation:** Be sure to set up fiscalization before accepting payments via Yandex Pay. For detailed advice, consult your accountant or online cash register service provider.

== Installation ==
1. Install the plugin through the WordPress admin panel.
2. Activate it in the "Plugins" section.
3. Go to WooCommerce → Settings → Payments → Yandex Pay and Yandex Split.
4. Enter your Merchant ID and API key (obtained through a partner agreement with Yandex).
5. Enable the desired payment methods and save changes.
6. **Important:** Set up payment fiscalization in accordance with 54-FZ.

== Frequently Asked Questions ==

= Why is the payment not going through? =
Check whether your store has passed moderation in the Yandex Pay dashboard (it should show a green status). If the status is gray, payments will only work in test mode.

= Is a contract with Yandex required? =
Yes, the plugin requires a connection to Yandex Pay through a partner agreement.

= Why is the payment method not displayed on the checkout page? =
The payment method will only be displayed if it is enabled in WooCommerce settings and meets the conditions (e.g., currency, country, or shipping method).
Check:
1. Whether the method is enabled in WooCommerce → Settings → Payments.
2. Whether the availability conditions are correctly configured.
3. Whether there are conflicts with other plugins or the theme.

= How does Split work for the buyer? =
The buyer places an order, makes the first payment, and receives the product immediately. The remaining payments are charged on schedule. The store receives the full amount immediately, just like a regular purchase.

= How do I add installment badges to product pages? =
This feature is available in the Pro version, which allows you to customize the design, positioning, and display conditions of elements.

= Why are widgets not displayed in the cart? =
Cart and checkout integration is supported in the Pro version. The free version focuses on basic payment implementation.

= How do I test in sandbox mode? =
Use the test data provided by Yandex. Real money will not be charged.

= How do I ensure payment fiscalization? =
Yandex Pay does not send fiscal receipts automatically. Recommended solutions:

**Ready-made solution (recommended):**
- [KosTeams ATOL Receipts](https://kosteams.com/plugins/atol-receipts-yandex-v4/) — a specialized plugin that automatically sends receipts for all Yandex Pay and Split payments

**Alternative options:**
- Connect an online cash register (ATOL, Evotor, etc.) and set up API integration
- Use other fiscalization plugins
- Develop your own OFD integration
- Consult your cash register service provider

= What are the penalties for not having fiscalization? =
According to 54-FZ, fines for non-use of cash register equipment start from 10,000 rubles for individual entrepreneurs and from 30,000 rubles for legal entities per violation.

== Version Features ==
**Free version includes:**
- Yandex Pay and Yandex Split support
- Combined payment (card + installments)
- Configuration through the WooCommerce interface
- Compatibility with both classic and Gutenberg block editor

**Pro version adds:**
- Installment/cashback badges on product pages
- Installment/cashback badges in the product catalog
- Payment widgets in cart and catalog
- Yandex payment button on the checkout page
- 20+ element positioning options

== Recommended Add-ons ==

To ensure full compliance with Russian legislation and extend functionality, the following solutions are recommended:

= Payment Fiscalization (required for 54-FZ compliance) =

**[KosTeams ATOL Receipts](https://kosteams.com/plugins/atol-receipts-yandex-v4/)** — A specialized plugin for automatic fiscalization of payments via Yandex Pay and Yandex Split.

Key features:
- Automatic fiscal receipt generation via ATOL Online for every payment
- Full support for ATOL API v4 and v5
- Automatic detection of Yandex Pay and Split payments
- HPOS (High-Performance Order Storage) support
- Automatic refund receipts when orders are cancelled
- Real-time fiscalization status monitoring
- Detailed logging for diagnostics

**Why this plugin:**
- Designed specifically for integration with Yandex payment systems
- Automatically detects payments that require fiscalization
- Fully compliant with 54-FZ requirements
- Tested together with this plugin

= Alternative Fiscalization Solutions =
- Other ATOL Online integration plugins
- Evotor integration solutions
- Modules for connecting to other OFD providers
- API integration with your cash register service provider

= Conversion Improvement =
**[KosTeams Payments for Yandex Pay and Yandex Split for WooCommerce Pro](https://kosteams.com/plugins/bejdzhi-i-vidzhety-yandex-split-i-yandex-pay-dlya-wordpress/)** — Extended version of this plugin with additional features:
- Installment/cashback badges on product pages and in the catalog
- Payment widgets in cart and on product pages
- 20+ element positioning options
- Advanced design and behavior settings

**Important:** Regardless of the fiscalization solution you choose, setting it up is mandatory before accepting payments via Yandex Pay to comply with 54-FZ requirements.

== Links ==
- [Setup Documentation](https://kosteams.com/plugins/bejdzhi-i-vidzhety-yandex-split-i-yandex-pay-dlya-wordpress/)
- [Buy Pro Version](https://kosteams.com/plugins/bejdzhi-i-vidzhety-yandex-split-i-yandex-pay-dlya-wordpress/)
- [Information about 54-FZ and Fiscalization](https://www.consultant.ru/document/cons_doc_LAW_42359/12a6477d0e22968564d9416e594a80202a7024db/)

== Changelog ==
= 2.0.6 (2026-03-05) =

**Fiscalization**
* Cloud cash register support for Yandex Pay: `receipt` data transmission (VAT, payment method type, payment subject type, unit of measurement)
* Auto-detection of VAT rate from WooCommerce or forced "No VAT" mode
* Filter `kosteams_payments_for_yandex_item_receipt` for customization

**Wallet plugin compatibility**
* Negative fees (wallet, certificates) are skipped, item `total` values are proportionally recalculated
* Removed `externalAmount` — works without special API permissions
* Full compatibility with TeraWallet, WooCommerce Wallet, and others

**Bug fixes**
* JWT webhook: uses the full JWKS key set (`JWK::parseKeySet`) instead of just the last key
* Refund: targetCart includes VAT, correct orderId for CARD_SPLIT
* Fixed PHP Notice for `$existing_payment_url` on 409 error
* Webhook registered once (static flag)
* API logging info only when debug_mode is enabled, errors are always logged

**Improvements**
* API key is hidden (type=password)
* Removed Yandex Pay SDK loading from the base plugin (handled by Pro)
* Removed unused: class-validator.php, duplicate `get_order_info()`, duplicate validation in `create_payment()`
* CSS version tied to plugin version
* i18n for refund order notes

= 2.0.5 (2026-01-23) =

**Maintenance:**
* Synchronized YPS_KOSTEAMS_VERSION constant with plugin header
* Code audit for compliance with WooCommerce Payment Gateway API documentation
* Code audit for compliance with Yandex Pay Web SDK documentation
* Updated plugin page links
* Updated firebase/php-jwt library to v6.11.1

= 2.0.4 (2025-11-11) =

**CRITICAL FIX: VAT calculation in payment creation**

**ISSUE:**
* With VAT enabled in WooCommerce, amount mismatch occurred:
  - Order total in WooCommerce (with VAT): e.g., 1200 RUB
  - Amount sent to Yandex Pay API (without VAT): e.g., 1000 RUB
  - Result: ERROR — payment was not created due to amount mismatch

**CAUSE:**
* `$item->get_total()` returns the amount WITHOUT taxes
* `$order->get_total()` returns the amount WITH taxes
* When calculating `calculated_total`, taxes were not included, causing a mismatch with `woocommerce_total`

**FIXED in `includes/class-gateway.php`:**

1. **Products (line 794):**
   - WAS: `$line_total = round((float)$item->get_total(), 2);`
   - NOW: `$line_total = round((float)$item->get_total() + (float)$item->get_total_tax(), 2);`

2. **Shipping (line 820):**
   - WAS: `$shipping_cost = round((float)$shipping_item->get_total(), 2);`
   - NOW: `$shipping_cost = round((float)$shipping_item->get_total() + (float)$shipping_item->get_total_tax(), 2);`

3. **Fees (line 836):**
   - WAS: `$fee_amount = round((float)$fee_item->get_total(), 2);`
   - NOW: `$fee_amount = round((float)$fee_item->get_total() + (float)$fee_item->get_total_tax(), 2);`

**RESULT:**
* Full amount WITH VAT is now sent to Yandex Pay API
* WooCommerce order total = Yandex Pay total (100% match)
* No discrepancies between the dashboard and the payment system
* Customer pays the correct amount shown in the cart

**IMPORTANT:** This is a critical fix for all stores using taxes/VAT in WooCommerce. Immediate update is recommended.

= 2.0.3 (2025-10-27) =

**CRITICAL FIX: Amount calculation accuracy**
* Completely rewritten data calculation logic for Yandex API
* Fixed amount mismatch between WooCommerce and data sent to Yandex
* Now uses native WooCommerce methods to get item totals

**Fixed:**
- **ISSUE**: Plugin manually calculated and distributed discounts across all items proportionally, leading to incorrect distribution (coupons applied to all items even when configured for specific items only)
- **FIXED**: Now uses `$item->get_total()` — WooCommerce correctly calculates the final amount including all discounts

- **ISSUE**: Items with quantity > 1 were split into separate line items with quantity = 1, causing rounding issues
- **FIXED**: Items are now sent with their actual quantity

- **ISSUE**: When totals didn't match, the last item was adjusted, masking logic errors
- **FIXED**: No more adjustments, amounts match exactly

- **ISSUE**: Unnecessary fields (`unitPrice`, `discountedUnitPrice`, `subtotal`) were sent, which are not needed for Yandex Split
- **FIXED**: Only `total` with the exact final amount is sent

**Result:**
* Yandex data = WooCommerce data (100% match)
* Code reduced from ~270 lines to ~70 lines (4x simplification)
* No manual calculations or adjustments
* All discounts (coupons, promo codes, loyalty programs) applied correctly

**Technical:**
* Simplified `cart.items[]` data structure:
  - Required fields: `productId`, `title`, `quantity.count`, `total`
  - Optional fields: `description`
  - Removed: `unitPrice`, `discountedUnitPrice`, `subtotal` (not required by API)
* Removed bonus discount calculation block (lines 782-817)
* Removed discount distribution logic (lines 826-877)
* Removed item splitting logic (lines 898-937)
* Removed last item adjustment (lines 1023-1051)

= 2.0.2 (2025-10-09) =

**Security fixes:**
- Product descriptions are now stripped of HTML tags before being sent to external systems

= 2.0.1 (2025-09-30) =

**BUG FIXES**
* Fixed critical block initialization error in WP Cron context
* Fixed "Call to a member function get_cart_contents() on null" error during cron tasks
* Fixed "Call to a member function get_available_payment_gateways() on null" error
* Added lazy loading for payment gateways in block editor
* Improved compatibility with plugins that filter available payment methods

**TECHNICAL**
* Implemented protection against premature WooCommerce object initialization
* Changed gateway retrieval method: uses `payment_gateways()` instead of `get_available_payment_gateways()`
* Added existence checks for `WC()` and `WC()->payment_gateways` objects before access
* `initialize()` method no longer triggers WooCommerce filters during initial load

= 2.0.0 (2025-09-28) =

MAJOR UPDATE
* **Full WooCommerce Block Editor support**
* Compatibility with modern WordPress themes (Gutenberg blocks)
* Automatic registration of Yandex Pay and Yandex Split in block cart and checkout
* Payment method icons and descriptions in the block interface
* Modern architecture with React component support
* Build process for JavaScript files (webpack, babel)
* Plugin fully restructured: now works equally stable with both classic and block checkout
* **Added refund support via Yandex API**

---

**MAXIMUM DB OPTIMIZATION**
* Eliminated last meta_key query warning
* Replaced all meta_key queries with global delete_metadata() function
* Maximum efficiency for metadata deletion during uninstall

**PERFORMANCE OPTIMIZATION**
* Eliminated slow meta_query warning
* Using fields => 'ids' to retrieve only order IDs
* Direct metadata deletion via delete_post_meta()

**RESULT**
* Significantly improved performance during plugin uninstall
* Plugin fully ready for WordPress.org, all Plugin Check tests passed

---

**NAMING FIXES**
* Unified payment service names throughout the plugin
* All variations standardized to consistent naming

**RESULT**
* Uniform naming conventions
* Improved user experience
* Optimized plugin size

---

**REFUNDS**
* Fixed refund amount availability check logic
* Support for resending existing refunds to Yandex API
* Eliminated WooCommerce refund duplication on API errors
* Added detailed logging for refund amounts and statuses

---

**USER EXPERIENCE**
* Replaced HTML tags with plain text in error messages
* Clear instructions when settings are missing (Merchant ID, API key)
* Merchant ID format validation (UUID) with informative messages


= 1.0.13 =
* Date: 2025-08-23
* Minor improvements

= 1.0.12 =
* Date: 2025-08-03
* **CRITICAL FIX**: Fixed ORDER_AMOUNT_MISMATCH error when creating payments
* Fixed: Amount calculation accuracy with discounts and rounding
* Fixed: Discount distribution inaccuracies across items
* Improved: Correction algorithm for totals to meet Yandex API requirements
* Improved: Mathematical precision for monetary calculations
* Added: Automatic rounding error correction in the last cart item
* Added: Additional logging for debugging amount calculations
* **Technical**: WordPress Coding Standards compliance for internationalization
* **Technical**: Added translator comments for all localizable strings
* **Technical**: Ordered placeholders in translatable strings (%1$s, %2$s)

= ORDER_AMOUNT_MISMATCH Fix Details =
The error occurred due to formula mismatch: `cart_total = items_sum - discounts_sum`
* Added precise rounding at all calculation stages (round with 2 decimal places)
* Implemented calculated_total vs woocommerce_total verification
* Automatic correction of last item when discrepancy >= 0.01
* Improved distribution of remaining discounts across items
* Added final validation of all amounts before sending to API

= Technical Description =
* All monetary operations now use `round($value, 2)`
* Added check `abs($calculated_total - $woocommerce_total) >= 0.01`
* Implemented correction via last cart item adjustment
* Improved logging with output of all intermediate sums for debugging
* Brought up to WordPress standards for proper localization

= 1.0.11 =
* Date: 2025-07-20
* Added: Protection against status changes for orders paid via other payment systems
* Added: Intelligent webhook processing considering the payment method
* Improved: Order status processing logic to prevent conflicts between payment systems
* Improved: Handling of legitimate cancel/refund operations for Yandex orders
* Fixed: Issue with cancellation of paid orders when receiving Yandex webhook after payment via another method

= Order Protection =
* If an order was paid via another payment system, Yandex webhooks will no longer change its status
* Orders paid via Yandex correctly handle cancel and refund operations from the Yandex dashboard
* Informative notes added to orders when status change attempts occur

= Technical Description =
* `process_order_status_from_webhook` method now checks the order payment method before applying changes
* Added `$is_yandex_payment` check to determine the payment source
* Improved logging to track all status change attempts

= 1.0.10 =
* Date: 2025-06-17
* Added: Extended Yandex Pay webhook processing
* Added: Flexible payment status mapping system
* Added: Custom filters for developers
* Improved: Webhook processing refactoring for increased reliability
* Improved: Payment operation logging
* Improved: Security of incoming request processing

= Developer Filters =

1. `kosteams_payments_for_yandex_webhook_status_map`
Modifies the Yandex → WooCommerce status mapping
Parameters:
- $status_map (array) - Current status mapping
- $order (WC_Order) - Order object
- $payment_status (string) - Status from Yandex

Example:
add_filter('kosteams_payments_for_yandex_webhook_status_map', function($status_map, $order, $payment_status) {
    $status_map['CAPTURED'] = 'completed';
    return $status_map;
}, 10, 3);

2. `kosteams_payments_for_yandex_before_process_status`
Modifies the status before applying it to the order
Parameters:
- $new_status (string) - Planned status
- $payment_status (string) - Status from Yandex
- $order (WC_Order) - Order object

3. `kosteams_payments_for_yandex_handle_webhook_status`
Full custom status handling (returning true cancels default processing)
Parameters:
- $handled (bool) - Processing flag
- $payment_status (string) - Status from Yandex
- $order (WC_Order) - Order object

4. `kosteams_payments_for_yandex_status_change_note`
Modifies the note when order status changes
Parameters:
- $note (string) - Note text
- $order (WC_Order) - Order object
- $old_status (string) - Old status
- $new_status (string) - New status

5. `kosteams_payments_for_yandex_partial_refund_note`
Modifies the note for partial refunds
Parameters:
- $note (string) - Note text
- $order (WC_Order) - Order object

= Security Improvements =
* Strengthened incoming data validation
* Improved error decoding handling

= Fixed =
* Issues with PARTIALLY_REFUNDED status processing

= 1.0.9 =
- Dynamic icon switching in the Yandex Split payment gateway depending on the selected payment method
- When selecting "Split", the standard Split icon is displayed
- When selecting "Card + Split", the combined icon is displayed

= 1.0.8 =
= Improved Discount Distribution =
- All discount types (coupons, bonuses, negative fees) are combined into a total discount amount
- Discounts are distributed proportionally across items
- Remaining discount is added to the last item for precise distribution
= Improved Cart Building =
- Items with quantity > 1 are created as separate line items
- Discounts are evenly distributed between units of an item
- Discounts are applied only to products (not to shipping and fees)

= 1.0.7 =
- Style separation implemented
- Minor fixes
- Improved documentation

= 1.0.6 =
**Main changes:**
- Added separate payment gateways:
  * `Yandex Split` — installment payments
  * `Yandex Pay` — classic card payment
- Shared logic extracted to base class (`WC_Yandex_Base_Gateway`)
- Improved payment URL storage:
  * Payment URLs are saved to order metadata
  * Duplicate payment creation prevented for existing orders

= 1.0.5 =
- Fixed compatibility with WooCommerce 8.7
- Updated test scenarios for PHP 8.3

= 1.0.4 =
- Added multilingual site support
- Optimized script loading

= 1.0 =
- Initial release
- Basic Yandex Pay/Split integration
- Classic editor support

== License ==
This plugin is distributed under the GPLv2 license. Advanced features are available in the Pro version.

== Support and Security ==

= Payment Security =
- All transactions are processed through Yandex secure servers
- Card data is not stored on your site
- PCI DSS compliant

= Legal Compliance =
- The plugin provides technical integration with payment systems
- Fiscalization compliance (54-FZ) requires additional solutions
- Consulting with lawyers and accountants is recommended

= Getting Support =
- Technical support through official channels
- Documentation and FAQ on the developer's website
- User community for experience sharing