Skip to main content
Version: 2.0.0

Developer / API

Plugin API

Yui\G24pay\Plugin implements yStore's yui\craft\base\collector\PaymentMethodRegistryInterface and registers itself with the store's PaymentMethodRegistry once all plugins have loaded (Plugins::EVENT_AFTER_LOAD_PLUGINS). The methods below are the contract yStore calls into; they are not normally called directly from custom code, but are useful to know when debugging a checkout integration.

use Yui\G24pay\Plugin;

$details = Plugin::$plugin->getDetails();
MethodPurpose
getDetails(): arrayReturns the payment method descriptor yStore uses to list 24Pay at checkout: name, code/handle (g24pay), type (online), instructions, price (always 0 — see README → Known behavior), enabled, plus url, logo, and description for the CP/checkout UI. Delegates to G24payGateway::getDetails().
placeOrder(array $data, array $items, ?string $code = null): arrayDelegates to G24payGateway::placeOrder(). Returns ['redirectUrl' => ..., 'extra' => [...], 'form' => ['action' => ..., 'fields' => [...]]] on success, or [] if the order data/items are invalid.
postValidate(array $params): arrayDelegates to G24payGateway::postValidate(). Reads Result from the callback $params and returns `['success' => bool, 'paid' => float
getPaymentRetryUrl(array $order, array $items): ?stringDelegates to G24payGateway::getPaymentRetryUrl() — rebuilds the order's callback URLs and prepares a fresh payment request, returning a new redirect URL to retry a failed/abandoned payment.
getApi(): ApiServiceReturns the plugin's ApiService component (Plugin::$plugin->get('api')).
getLicense(): LicenseServiceReturns the plugin's license service component, shared with the CP License page.

G24payGateway

Yui\G24pay\gateways\G24payGateway extends yStore's BasePaymentGateway and holds the actual gateway logic; Plugin methods above are thin delegates to it. Its handle is g24pay (Plugin::PLUGIN_HANDLE).

MethodPurpose
getDetails(): arrayBuilds the payment method descriptor from the plugin Settings model. Catches and logs any exception under g24pay-gateway:getDetails, returning [] on failure.
placeOrder(array $data, array $items, ?string $code = null): arrayNormalizes $data/$items via the shared prepareOrderData() / prepareOrderItems() helpers from BasePaymentGateway, then calls ApiService::prepare() and returns the redirect URL and form fields. Logs under g24pay-gateway:placeOrder on failure.
postValidate(array $params): arrayReads $params['Result']; 'OK' → success, anything else throws internally and is logged (both the error message and the full $params payload, under a shared random key for correlated lookup) under g24pay-gateway:postValidate.
getPaymentRetryUrl(array $order, array $items): ?stringRebuilds callback URLs on $order via buildOrderUrls(), then re-runs the same prepare() flow as placeOrder() and returns just the redirect URL, or null on failure/invalid data.

ApiService

Yui\G24pay\services\ApiService (Plugin::$plugin->get('api') / Plugin::$plugin->getApi()) talks directly to 24Pay's pay_gate HTTP endpoints — there is no vendor SDK.

public const G24PAY_URL_SANDBOX = 'https://test.24-pay.eu';
public const G24PAY_URL_PRODUCTION = 'https://admin.24-pay.eu';

The active domain is chosen from Enable SandboxMode on every call via getServiceDomain().

MethodPurpose
prepare(array $data, array $items): selfValidates $data/$items are non-empty, then calls initPayment() to build and sign the payload. Chainable — call ->getRedirectUri() / ->getParams() next. Throws \Exception('Missing data.') if either argument is empty.
getRedirectUri(?string $operation = null): ?stringReturns the prepared pay_gate/paygt submit URL (getSubmitUrl()) after a successful prepare() call, or null if preparation failed.
getParams(): arrayReturns the full signed payload built by initPayment() — the fields a checkout form posts to getSubmitUrl().
getCheckUrl(): string{domain}/pay_gate/check — not called by this plugin version's flow; available for a custom status-check integration.
getSubmitUrl(): string{domain}/pay_gate/paygt — the hosted card entry page the customer is sent to.
testCredentials(): boolPosts ESHOP_ID/MID (from settings) to {G24PAY_INSTALL_URL} (https://admin.24-pay.eu/pay_gate/install, not environment-aware — always the production install endpoint) via a raw file_get_contents() stream context with TLS verification disabled, and returns true if the JSON response decodes to a non-empty array. Used by the settings page's Test Credentials action.

initPayment() payload

Built internally by prepare() from the normalized order $data and the plugin settings, then signed and stored on the service instance (getParams() returns it):

[
'Mid' => $settings->merchantNumber,
'EshopId' => $settings->eshopId,
'MsTxnId' => $data['increment_id'],
'Amount' => number_format((float)$data['total'], 2, '.', ''),
'CurrAlphaCode' => 'EUR', // hardcoded, not $settings->defaultCurrency
'ClientId' => substr(hash('sha1', $data['email']), 0, 9),
'FirstName' => ..., 'FamilyName' => ..., // split from customer_name
'Email' => $data['email'],
'Country' => 'SVK', // hardcoded
'Timestamp' => date('Y-m-d H:i:s'),
'Sign' => '', // filled in by getSign() below
'RURL' => $data['callbackUrl'],
'NURL' => $data['callbackUrl'],
]

Throws (and logs under g24pay:api-service:prepare) if merchantNumber, eshopId, or key is missing from settings, or if defaultCurrency doesn't resolve to a known ISO 4217 code via StoreHelper::getIso4217Code() — even though the resolved code isn't actually used in the request (see README → Known behavior).

Request signing

getSign() computes the Sign field:

  1. Concatenates Mid, Amount, CurrAlphaCode, MsTxnId, FirstName, FamilyName, Timestamp (in that order, no separator).
  2. SHA-1 hashes the concatenated string (raw binary output).
  3. Encrypts the hash with AES-256-CBC (openssl_encrypt, when the openssl extension is available), using an IV derived from merchantNumber reversed and appended to itself, and a key built by packing the hex-encoded key setting (pack('H*', $settings->key)). A mcrypt_encrypt(MCRYPT_RIJNDAEL_128, ...) fallback exists in source for environments without openssl, but ext-mcrypt was removed in PHP 7.2 — this fallback path is not reachable on any currently supported PHP version.
  4. Returns the first 16 bytes of the ciphertext, hex-encoded and uppercased.

Control panel routes

Registered on UrlManager::EVENT_REGISTER_CP_URL_RULES, all under g24pay/*:

  • g24pay/settings — settings page (SettingsController::actionIndex).
  • g24pay/settings/test — runs ApiService::testCredentials() and redirects back with a success/error flash (SettingsController::actionTest).
  • g24pay/license, g24pay/license/redeem, g24pay/license/activate, g24pay/license/revoke, g24pay/license/delete, g24pay/license/copy-token — license management, shared AbstractLicenseController flow used by other YUI plugins.

There are no anonymous/site-facing routes registered by this plugin directly — the checkout redirect to 24Pay and the return callback are driven through yStore's own checkout controllers calling Plugin::placeOrder() / Plugin::postValidate(), not through 24Pay-specific URLs.

Extensibility

This plugin version does not register its own Craft events, permissions, or MCP tools — extension points are the public Plugin / G24payGateway / ApiService methods above. To call 24Pay directly outside the standard checkout flow (for example, a custom reconciliation job against getCheckUrl()), instantiate ApiService through Plugin::$plugin->getApi() rather than duplicating the signing logic.