Ελληνικά:
Ανεξάρτητο πρόσθετο πύλης πληρωμής WooCommerce από τη WebHosting4U για
την υπηρεσία ePay Paycenter Redirection της Τράπεζας Πειραιώς /
Euronet Merchant Services. Υλοποιεί πλήρως την επίσημη προδιαγραφή
Redirection v2.9:
- Έκδοση μοναδικού εισιτηρίου (TranTicket) μέσω SOAP Ticketing Web
Service με κωδικοποίηση UTF-8.
- Αυτόματη ανακατεύθυνση POST στην ασφαλή σελίδα πληρωμής της τράπεζας
(pay.aspx) — τα δεδομένα κάρτας δεν περνούν ποτέ από τον διακομιστή
του καταστήματος.
- Πλήρης επαλήθευση HashKey HMAC-SHA256 σε κάθε επιτυχημένη απάντηση
πριν χαρακτηριστεί η παραγγελία ως εξοφλημένη.
- Υποστήριξη συναλλαγών Sale και Προέγκρισης (Preauthorization).
- Συμπλήρωση πεδίων 3-D Secure από τη διεύθυνση χρέωσης / αποστολής
του WooCommerce.
- Συμβατότητα με HPOS (Custom Order Tables) και WooCommerce Blocks
checkout.
Προϋπόθεση: πρέπει να έχετε υπογεγραμμένο συμβόλαιο αποδοχής με την
Euronet Merchant Services / Τράπεζα Πειραιώς και να διαθέτετε τα
διαπιστευτήρια AcquirerId, MerchantId, PosId, Username,
Password. Το πρόσθετο δεν παρέχει δικούς του δοκιμαστικούς
λογαριασμούς.
Η πλήρης ελληνική μετάφραση της σελίδας του προσθέτου στο WordPress.org
θα είναι διαθέσιμη μέσω του translate.wordpress.org
μόλις εγκριθεί από την κοινότητα. Δείτε επίσης το συνοδευτικό
readme-el.txt για την ολοκληρωμένη ελληνική τεκμηρίωση.
English:
This plugin integrates WooCommerce with the ePay Paycenter Redirection
service operated by Piraeus Bank / Euronet Merchant Services. It implements
the official Redirection v2.9 specification end to end:
- SOAP Ticketing Web Service (
IssueNewTicket) with UTF-8 payload.
- Auto-submitted HTML form POST redirection to the Paycenter secure
payment page (pay.aspx) so card data never touches your server.
- Full HMAC-SHA256 HashKey verification for every successful callback
before marking an order as paid.
- Support for Sale and Preauthorization transactions.
- 3-D Secure auxiliary fields populated from the WooCommerce billing /
shipping address.
- HPOS (Custom Order Tables) and WooCommerce Blocks checkout support.
You must have signed an acquiring contract with Euronet Merchant
Services / Piraeus Bank and obtained AcquirerId, MerchantId, PosId,
Username and Password credentials before using this plugin. The
plugin does not provide test or sandbox accounts on its own; please
contact Euronet Merchant Services to request one.
Affiliation and trademark notice
This plugin is independent software published by WebHosting4U and is
not affiliated with, endorsed by, sponsored by, or otherwise officially
connected to Piraeus Bank S.A., Euronet Merchant Services, or
Automattic Inc. The third-party names “ePay”, “Paycenter”, “Piraeus Bank”
and “WooCommerce” are trademarks of their respective owners and are
used here in good faith, after the unaffiliation marker “for”, solely
to describe the third-party service this plugin integrates with, in
line with the WordPress.org Detailed Plugin Guidelines on third-party
trademarks. The bundled accepted card brands image
(assets/img/wp-cards.png) is included with the rights-holder’s
authorization for the merchant distribution scope of this plugin.
User tracking and consent
This plugin does not load any analytics, telemetry, advertising,
fingerprinting, profiling or behavioural tracking code, neither on the
storefront nor in the WordPress admin. It does not set cookies on
visitor browsers, does not contact any first-party or third-party
analytics endpoint, and does not collect aggregated or individual
usage statistics from the merchant’s installation. The only outbound
network traffic the plugin generates is the strictly transactional
traffic documented in the External services section below, which
is required to complete a payment the merchant has explicitly
configured the plugin to perform. No user-tracking consent prompt is
therefore required by this plugin (Plugin Review Team Guidelines 7
and 9).
External services
This plugin reaches out to three external services. Two are operated
by Euronet Merchant Services on behalf of Piraeus Bank S.A. for the
“ePay Paycenter” payment redirection product (mandatory for the
plugin’s core function). The third is a publicly available Cloudflare
endpoint used only in the admin panel to help store owners configure
firewall rules for payment callbacks.
1. ePay Paycenter Ticketing Web Service
- What it is: a SOAP / ASMX endpoint published by Euronet Merchant
Services that issues a single-use TranTicket for each card
payment attempt. The ticket is then handed to the customer’s
browser as a hidden form field that POSTs to the secure payment
page, so cardholder data never touches the merchant server.
- Endpoint:
https://paycenter.piraeusbank.gr/services/tickets/issuer.asmx
- What is sent: the merchant credentials provided by Euronet Merchant
Services (AcquirerId, MerchantId, PosId, Username and an MD5 hash
of the Password), the order’s MerchantReference (numeric WooCommerce
order id with a short random suffix), the transaction amount and
ISO 4217 numeric currency code, the request type (Sale or
Preauthorization), and the 3-D Secure auxiliary fields populated
from the WooCommerce order: billing email, cardholder name,
billing address (city / lines / post code / state / ISO 3166
numeric country code), shipping address when present, and the
customer’s mobile phone number formatted as CC-Number. No
cardholder data, no PAN, no CVV, no expiry, and no analytics
identifier is ever transmitted; cardholder data is collected
exclusively on the bank’s secure payment page.
- When it is sent: once per successful checkout submission, at the
moment WooCommerce hands control to the gateway’s
Pay for order page, immediately before the customer is
auto-redirected to the bank.
2. ePay Paycenter Redirection page
- What it is: the bank-hosted secure payment page where the customer
enters card details and completes the 3-D Secure challenge. The
plugin renders an auto-submitted HTML form whose action attribute
is the URL below.
- Endpoint:
https://paycenter.piraeusbank.gr/redirection/pay.aspx
- What is sent: the merchant identifiers (AcquirerId, MerchantId,
PosId, User), the language code, the MerchantReference issued
during ticketing, and a per-order ParamBackLink so the bank’s
Cancel button returns the customer to the correct WordPress
endpoint. The TranTicket itself is read by the customer’s
browser from the hidden form field; the merchant server is not
the originator of the redirect POST.
- When it is sent: once per checkout, immediately after the
Ticketing call above succeeds.
- Inbound counterpart: Paycenter posts a signed transaction
response (HMAC-SHA256 HashKey) back to the plugin’s WC-API
callback URL on the merchant site
(https://<merchant-site>/?wc-api=epay_paycenter). This is the
same service – the merchant site is the Notification / Success /
Failure / Backlink target the merchant configures in the
Euronet portal. No data leaves the merchant server on this
inbound leg; the plugin only reads, verifies, and acts on the
response.
Service operator and legal links
Both endpoints above are operated by Euronet Merchant Services
(epay) for Piraeus Bank S.A.. Before activating the gateway,
merchants must review and agree to the operator’s terms and
privacy policy:
If any of the above URLs change after publication, please consult
the live operator websites for the current version of the relevant
document. The plugin’s behaviour is not affected by such updates
because the operator’s terms apply to the merchant’s relationship
with Euronet Merchant Services / Piraeus Bank, not to the plugin
itself. Merchants remain responsible for keeping their own
privacy policy and terms aligned with the data flows documented
above (notably the transmission of billing / shipping address
fields and customer email / phone to the bank for 3-D Secure
authentication).
3. Cloudflare IPv4 list
- What it is: a publicly available plain-text file published by
Cloudflare, Inc. that lists the current IPv4 CIDR ranges used by
Cloudflare’s edge network. The plugin fetches this file once every
12 hours (or 15 minutes on failure) via wp_safe_remote_get() and
caches the result in a WordPress transient.
- Endpoint:
https://www.cloudflare.com/ips-v4/
- What is sent: a standard HTTP GET request with no personal data,
no order information, no credentials, and no cookies. The only
identifying information in the request is the plugin’s User-Agent
string (secure-card-gateway-for-epay-paycenter-piraeus-bank/VERSION).
- Why: when the plugin’s admin settings page detects that the
WordPress site is served through Cloudflare (via the CF-Ray /
CF-Connecting-IP / CDN-Loop request headers), it displays the
current Cloudflare IPv4 ranges so the store owner can copy them
into an email to Euronet Merchant Services to whitelist them for
payment callbacks. Without this list, callbacks routed through
Cloudflare edge IPs may be rejected by the bank’s firewall.
- When: only when an administrator views the gateway’s WooCommerce
settings page and Cloudflare is detected on the incoming request.
It is never triggered on the storefront or by guest/customer visits.
- Cloudflare service homepage: https://www.cloudflare.com/
- Cloudflare Privacy Policy: https://www.cloudflare.com/privacypolicy/
- Cloudflare Terms of Service: https://www.cloudflare.com/terms/
No data is sent to any third party other than the three endpoints
listed above.
WAF compatibility
Payment-gateway callbacks are a recurring source of false-positive hits
on shared-hosting firewalls. Paycenter’s failure-case response bodies
contain patterns – TransactionDateTime=-, empty HashKey on declined
transactions, dash-only separators, Greek ResponseDescription text –
that overlap with signatures used for SQL injection, generic anomaly
scoring, and Java / Jetty CVE probes. If your host enables those
rules with default severity, callbacks for every test case except the
approved one can be dropped with a 403 Forbidden before they reach
PHP, leaving you with an order stuck in pending payment and no
entry in WooCommerce logs.
The plugin ships three things to help with this:
- A “Callback diagnostics” card on the gateway settings screen with a
one-click Test callback URL button. It POSTs a realistic
declined-transaction payload from the WordPress server to the
plugin’s own ?wc-api=epay_paycenter endpoint and reports whether
the request was intercepted by a host WAF (403 / 406 / 501) or
reached PHP (302 redirect back to checkout, the expected outcome
for a synthetic merchant reference). No order state is modified.
Use it before enabling live payments.
- An early “Callback envelope” INFO log line (since 1.0.10) so any
callback that is accepted by PHP but rejected later can be
distinguished from callbacks that never reached PHP at all.
- The following copy-paste exclusion snippets for the most common
hosting stacks. Always scope exclusions to your callback URL, never
globally:
-
cPanel / cPFence (the rule that flagged this plugin with
id 243420 is a Jetty CVE rule that has no defensive value on a
PHP / WordPress site):
cpfence --disable-waf-domain-byid yourdomain.tld 243420
If further generic-anomaly rules fire, prefer domain-scoped
disables over server-wide ones.
-
ModSecurity + OWASP CRS (Plesk, managed Apache, LiteSpeed in
ModSec mode). Drop the following stanza into a .htaccess
override next to your WordPress root (or ask your host to add it
to the vhost config):
<LocationMatch "^/(wc-api/epay_paycenter/?|\?wc-api=epay_paycenter)">
SecRuleRemoveById 942100 942110 942120 942150 942180 942200 942260 942330 942340 942360 942370 942410 942440 942450 942480
SecRuleRemoveById 920272 920273 920274
SecRuleRemoveById 932100 932105 932115
SecRuleRemoveById 921110 921120 921140 921150 921160
</LocationMatch>
The IDs above are the SQLi, generic-protocol and command-injection
families most frequently triggered by payment-callback bodies.
-
Imunify360: disable the owasp ruleset for the callback URL
via the Imunify360 admin, or add to an .htaccess override:
<LocationMatch "wc-api/?epay_paycenter">
SecRuleEngine DetectionOnly
</LocationMatch>
-
BitNinja: whitelist the URL in the BitNinja panel under
WAF 2.0 → Exceptions. Match pattern:
/wc-api/epay_paycenter/ (and /?wc-api=epay_paycenter).
- LiteSpeed WAF / QUIC.cloud: in QUIC.cloud → WAF → Exception
Rules, add both the path and query-string forms of the callback
URL.
Important notes:
- Whitelisting must be scoped to the callback URL, not server-wide.
Never disable a WAF rule globally for this plugin.
- If you run Cloudflare / Sucuri / Akamai in front of your origin,
those CDN-level WAFs must be tested separately – the in-admin
self-test loops back on your origin and will not exercise them.
Cloudflare users can open a Firewall Event in the dashboard,
find the blocked event matching the callback URL, and click
Create rule skip scoped to the URL.
- When using the plugin’s “Bank integration data” card, submit the
canonical single-URL form (https://your-site.tld/?wc-api=epay_paycenter)
to Euronet Merchant Services. Do not paste the URL into two portal
fields (base + path) – some merchant portals concatenate them, which
produces a malformed callback URL that will be blocked regardless
of WAF configuration.
Troubleshooting: customer sees only “-1” after the bank return
A literal -1 rendered in the browser after the shopper is
redirected back from the Paycenter page is almost always one of
three things. Use WooCommerce -> Status -> Logs to disambiguate
by searching the epay-paycenter-* log file for the transaction
timestamp:
Callback envelope line is present, Paycenter callback received
is present, Paycenter failure redirect issued is present. The
plugin handled the callback end-to-end. The -1 came from a
downstream redirect target (most often a Blocks-based /checkout/
page that does not render legacy wc_add_notice() errors). Since
1.0.12 the failure redirect targets the order’s Pay-for-order URL
instead of /checkout/, which renders notices correctly; since
1.0.14 the decline message is also queued as an order-scoped
transient so it is rendered on the pay-for-order page regardless
of whether the cross-origin POST from the bank carried the
WooCommerce session cookie (SameSite=Lax commonly strips it).
Callback envelope line is present but the other two are
missing. The callback reached PHP but the handler aborted early
(missing MerchantReference, mismatched order, HashKey mismatch,
already-paid order). The log entry that immediately follows
the envelope tells you which branch fired.
- None of the three lines are present. The callback POST never
reached PHP. Either a host WAF dropped it (see the exclusion
snippets above) or the URL registered in the Euronet portal does
not match this WordPress site’s WC-API URL. Confirm with the
in-admin “Test callback URL” diagnostic.
- A
Paycenter callback received on a malformed URL line appears
(ERROR severity), with received_wc_api showing a composite
value such as epay_paycenter/wc-api/epay_paycenter/. This
means the Euronet portal has been configured with a doubled
callback URL – usually because the merchant pasted the full URL
into a portal field while the portal’s own base URL already
contained the /wc-api/epay_paycenter/ path, or pasted a
relative path where an absolute URL was expected. Since 1.0.13
the plugin re-maps such malformed requests to the canonical
handler so the payment still completes, but the ERROR entry
will keep firing on every transaction until the merchant
corrects the URL in the Euronet Merchant Services portal. Set
Success / Failure URL to exactly
https:///?wc-api=epay_paycenter (no trailing
slash, no extra path) and the ERROR entries stop.
The “-1” itself comes from WooCommerce core: WC_API::handle_api_requests()
ends every WC-API request with an unconditional die( '-1' ). Two
classes of request used to trigger it and both are now fixed:
- Listener-not-registered race (solved in 1.0.12): the plugin
now registers its callback listener at plugins_loaded through a
dedicated dispatcher so the listener is always present before the
dispatch fires, even when a conflicting plugin delays gateway
instantiation.
- Malformed
wc-api query var (solved in 1.0.13): doubled /
path-suffixed callback URLs configured in the Euronet portal are
now transparently normalised at parse_request priority -10, so
the dispatcher receives the canonical gateway id and never falls
through to the die( '-1' ) tail.