Skip to content

Releases: originalconcepts/giorgio

1.10.3

Choose a tag to compare

@originalconcepts originalconcepts released this 21 Sep 10:04

Bundle-aware order sync with OC Bundles, plus the unreleased 1.9.1 fix. Needs OC Bundles 1.5.2 or newer (1.5.4 is current); on an older version a bundle line is handled as a plain product line and a warning is logged once per request.

Bundles in the order payload, both directions (1.10.0 - 1.10.1)

  • An order line that is a bundle is sent to Giorgio with its components: product, quantity, unit, surcharge, swap origin and weighed quantity. Money that moved onto the invoice split lines is reported back on the bundle line.
  • An incoming order rebuild updates an existing bundle line in place through the OC Bundles order-line API (swaps, quantities, weighed amounts, externally priced lines) instead of dropping it and re-adding a plain product.
  • A component re-expressed in another unit (2 portions of 0.2 kg to 0.4 kg) keeps that unit on the order line, in the split lines and in component stock.

Hardening before release (1.10.2 - 1.10.3)

  • An update that arrives without a component list no longer reverts the customer's swaps, and no longer leaves the bundle line un-split: the list is rebuilt from the line itself, so the line is re-split and the order total stays what was charged.
  • Component stock and the ledger that records it are written together, on both the release and the add path, so a rebuild that fails and is retried neither inflates nor double-takes stock.
  • The same bundle itemId twice in one payload no longer creates a second bundle line.
  • A fractional bundle quantity is rounded to whole bundles (minimum 1).
  • Split lines from before 1.5.0 are matched to their bundle line by uid, and split pro-rata when the same bundle appears twice, so no money is missing from the outgoing payload.
  • Failures are caught as Throwable, not only Exception.

1.9.1 (tagged here for the first time)

  • The stale club-discount fee is removed on an incoming Giorgio rebuild.

1.9.0

Choose a tag to compare

@originalconcepts originalconcepts released this 23 Aug 23:28

Two changes: Giorgio-owns-Cardcom-capture mode, and the REST logs move out of public reach.

Giorgio-owns-Cardcom-capture (option giorgio_owns_cardcom_capture, OFF by default). With it on, the Cardcom gateway only places the checkout J5 hold; Giorgio charges the token at picking and pushes the result back. The gateway's capture hooks are detached, the token is handed over in the outgoing order and the OrderPayment webhook, the webhook never reports a capture (hold only), and Giorgio's payment result — transaction id, paid date, Cardcom meta, refunds — is applied from the incoming payload. Switching the option on re-sends open Cardcom orders from the last 60 days so Giorgio takes ownership of orders that already exist.

Logs are no longer public. The plugin wrote both REST logs to wp-content/uploads/giorgio/, and these servers hand that directory out as static files — every log was downloadable with no authentication. Verified live: HTTP 200, 17 MB on one store, carrying customer names, phones, emails, addresses, order contents and Cardcom deal numbers. A WAF rule does not help, because static files never reach that layer. REST_INCOMING_LOG_DIR is now .giorgio, a dot-named directory the web server refuses to serve.

Secrets are redacted before writing. redact_secrets_for_log() masks token, CardcomToken, cardcom_token_val, api_token and github_token anywhere in a record, on both writers. This matters most in capture mode, which puts the live Cardcom token in the outgoing payload — token plus expiry is enough to charge the customer, and that should not sit in a file at all.

Sites carrying the temporary mu-plugin that disables payload logging can drop it once this version is deployed; the old files were archived under uploads/.giorgio-logs-archive/.

Syntax-checked against PHP 7.4 before release.

1.8.3

Choose a tag to compare

@originalconcepts originalconcepts released this 19 Aug 11:27

Stops a false "capture failed" report being sent to Giorgio while the capture is still running.

The save/meta hooks (updated_post_meta, added_post_meta, woocommerce_update_order) run after the completed status is persisted but BEFORE the gateway's capture hook (woocommerce_order_status_completed, priority 10) has finished charging the J5 hold. The capture flag therefore still reads no, and the dispatch reported failed: cardcom_capture_not_confirmed for a charge that succeeded seconds later — zano-dagim order 43663 sent "failed" at 10:33:31 for a capture that completed at 10:33:33.

process_cardcom_meta_present_for_order() now returns without dispatching when the gateway is Cardcom and the capture state is not_captured, logging why. A genuine capture failure is still reported: woocommerce_order_status_changed (priority 99) fires after the capture hook and dispatches with the persisted outcome.

One trade-off worth knowing: on an order that was already completed in an earlier request, a later capture retry that fails is no longer reported from the meta hook, because no status transition fires to carry it. Such an order has already been reported once at its original transition.

Syntax-checked against PHP 7.4 before release; the released tree is byte-identical to the reviewed branch.

1.8.2

Choose a tag to compare

@originalconcepts originalconcepts released this 16 Aug 21:48

Sends the capture's Cardcom deal number in outgoing payloads, not the hold's.

A Capture Charge on a suspended (J5) deal creates a NEW transaction with a new number at Cardcom; the original suspended deal keeps answering as a hold forever. Payloads built from a cached order instance in the same request as the capture still carried the pre-capture deal number, so Giorgio's charge verification queried the hold and raised false "charged 0" mismatch alarms on orders that were actually paid (Zano-Dagim). The Giorgio backend fix is already deployed; this completes the plugin side so the real charge transaction is sent and the amount can be verified.

resolve_cardcom_transaction_id_for_payload() reads the deal number from the newest database row, uncached (get_order_meta_values_uncached() — the same rule get_cardcom_capture_state() already uses), preferring Cardcom Payment ID then CardcomInternalDealNumber, and falls back to the previous cached read when the database has nothing (meta written on the in-memory instance but not yet saved). Used by the outgoing Order payload, the OrderPayment v2 payload, and the guard that holds the webhook back until a deal number exists.

Behaviour before a capture is unchanged: with a single meta row the newest row is the same row the old code read. One intentional difference — when Cardcom Payment ID holds 0 and CardcomInternalDealNumber holds a real number, the real number is now sent instead of 0, which stops the guard from deferring the webhook for no reason.

Not changed: the internalNumber field in the outgoing Order payload still comes from the cached read. Confirmed with the Giorgio backend that it does not bind that field in any model, does not store it, and never queries Cardcom with it — all lookups use payment.transactionId.

Syntax-checked against PHP 7.4 before release; the released tree is byte-identical to the reviewed branch.

1.8.1

Choose a tag to compare

@originalconcepts originalconcepts released this 15 Aug 23:50

Follow-up to 1.8.0. Reads the newest Cardcom capture flag row instead of the oldest.

WooCommerce meta is not unique per key: a gateway writing the same key on a second payment attempt adds a row rather than replacing the first. get_meta() and a LIMIT 1 read both answer with the OLDEST row, which for a payment flag is the stale one. An attempt that failed and left no, followed by an attempt that succeeded and wrote yes, is a PAID order — and 1.8.0 would have reported it to Giorgio as failed, the exact reverse of the bug 1.8.0 set out to fix.

get_order_meta_values_uncached() returns every row ordered by the auto-increment id (meta_id on postmeta, id on the HPOS table), and the capture state comes from the last one. When the rows disagree the newest still wins and a warning is logged with all values in write order, so it is visible how often one order carries several payment attempts.

Behaviour is unchanged for the single-row case, which is every order on delinka except 18326 — that one carries two cardcom_charge_captured rows (both no), two cardcom_token_val rows (one all-zeros, which is what Cardcom rejected with Error 5143) and two cardcom_CardOwnerID rows: two attempts, two different cards, one order.

Syntax-checked against PHP 7.4 before release; the released tree is byte-identical to the reviewed branch.

1.8.0

Choose a tag to compare

@originalconcepts originalconcepts released this 15 Aug 23:14

Two fixes to how orders are reported to Giorgio, plus delivery-recipient fields.

Uncaptured Cardcom holds were reported as charged. OrderPayment derived status: success from the presence of the Cardcom deal number, which is written when the J5 hold is placed and survives a failed capture. Order 18326 (delinka) sent five "charged" reports for a capture that failed with Error 5143 : Token Parameter Is Missing. Status now follows the gateway's cardcom_charge_captured flag, and isFinished follows the capture rather than the WooCommerce status (which Giorgio itself pushes over REST). The incoming REST endpoint answers 409 with a paymentCapture block instead of a blind 200.

Duplicate POSTs to Giorgio. Every guard was check-then-act, so two processes entering the same few-second window both passed. Adds a cross-process lock (INSERT IGNORE on the unique option_name index), uncached meta re-reads inside the lock, a per-order X-Idempotency-Key, and holds the OrderPayment webhook until Cardcom has saved a deal number.

Delivery recipient. "Shipping to someone else" from OC Woo Shipping was never sent, so orders showed under the buyer's name and shipped to them. Sends recipient name/phone plus an isOther flag, and prepends a recipient line to the customer notes for picking.

Syntax-checked against PHP 7.4 before release.

1.7.7

Choose a tag to compare

@AfifMansour91 AfifMansour91 released this 09 Jul 15:53

Full Changelog: 1.7.5...1.7.7

Giorgio Integration 1.7.5

Choose a tag to compare

@Thomas-T0ma Thomas-T0ma released this 18 Jun 06:53
  • renamed files from version 1.7.4
  • added dynamic labels feature
  • updated Api calls and added secured token for requests

Full Changelog: 1.7.0...1.7.5

Giorgio Integration 1.7.2

Choose a tag to compare

@originalconcepts originalconcepts released this 14 Jun 13:42

Giorgio Integration 1.7.2

  • "Settings" link added to the plugin row on the Plugins screen — opens the plugin's settings page directly.
  • (1.7.1) Optional GitHub token support for auto-updates from a private repo, via a new "GitHub Token" setting or the OC_GIORGIO_GH_TOKEN constant. Not needed while the repo is public.

Giorgio Integration 1.7.0

Choose a tag to compare

@originalconcepts originalconcepts released this 14 Jun 12:13

Giorgio Integration 1.7.0

Major hardening + rebrand release. (Previously published code in this repo was V1.3.)

Security

  • Inbound REST authentication. Incoming endpoints now run through a permission check instead of being fully open. Staged via a new setting: off → log → enforce. Default is off, so nothing breaks on update. Giorgio must send a shared secret in X-OC-Giorgio-Token (or X-Api-Key / Authorization: Bearer).
    • Backend action: start sending the header, verify in "log" mode, then switch the site to "enforce".
  • Removed a hardcoded debug email that sent full order payloads (customer PII) on every order. Debug email is now opt-in with a configurable recipient.

WooCommerce HPOS

  • Declared High-Performance Order Storage compatibility.
  • All order-meta writes moved to the HPOS-safe order API; added an order-save trigger so the Cardcom-transaction flow fires under custom order tables too.

Order reconciliation

  • Incoming orders now compare Giorgio's orderTotal against the total WooCommerce computed. On mismatch: a warning log + an order note + a reconciliation block in the REST response. Item-count differences (manager add/remove) are treated as normal and do NOT alert — only a real total mismatch does. Catches VAT misconfig and silently-dropped items.

Logging / debugging

  • New separate outgoing log capturing both the Order (authorization) and OrderPayment (capture) calls + Giorgio's responses.
  • Optional debug emails: AUTHORIZATION (at intake) and CAPTURE (at charge, incl. Giorgio's response).
  • Verbose error_log gated behind a debug flag / WP_DEBUG. Logs now under wp-content/uploads/giorgio/; WC log source is giorgio.

Rebrand (StoreOS → Giorgio)

  • All user-facing text, plugin name, and author (Original Concepts) rebranded.
  • REST namespace is now giorgio/v1. The legacy oc-storeos/v1 is still registered as an alias, so existing Giorgio calls keep working.
    • Backend action: migrate to giorgio/v1 when convenient; the legacy namespace can be retired afterwards.
  • Internal identifiers (option key, order meta keys, hooks) intentionally unchanged, so existing settings and order data carry over with no migration.

Updates

  • GitHub-based auto-update enabled by default (per-site opt-out via the oc_giorgio_enable_auto_update filter).

Cleanup

  • Removed dead/debug code and a leftover merge-conflict marker; added a PHP 8 undefined-index guard.

Reviewed, no change

  • OrderPayment isFinished: confirmed correct — the order is only completed after a successful Cardcom charge, so completion implies a successful capture.