Skip to main content
Version: 2.0.0

Developer / API

Plugin API

Yui\SimplePay\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), but only if the plugin is enabled. 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\SimplePay\Plugin;

$details = Plugin::$plugin->getDetails();
MethodPurpose
getDetails(): arrayReturns the payment method descriptor yStore uses to list SimplePay at checkout: name, code/handle (yui-simplepay), type (online), instructions, price, enabled, plus url, logo, and description for the CP/checkout UI. Returns [] and logs on error.
placeOrder(array $data, array $items, ?string $code = null): arrayBuilds and starts the SimplePay transaction for an order. Returns ['redirectUrl' => ..., 'extra' => [...]] on success, or [] if the order data/items are invalid or SimplePay returned no payment URL.
postValidate(array $params): arrayCalled on the checkout return/callback. Validates the signed r/s query parameters, and returns ['success' => bool, 'paid' => '*'|0, 'status' => string|null]. success is only true when the notification status is SUCCESS.
getPaymentRetryUrl(array $order, array $items): ?stringRebuilds the store's success/failed/callback URLs for the given order, then starts a new SimplePay transaction the same way placeOrder() does, to let the customer retry a failed payment. Returns null on any error.
getApi(): ApiServiceReturns the plugin's ApiService component (Plugin::$plugin->get('api')).
getSdk(): SimplePaySdkServiceReturns the plugin's SimplePaySdkService component, which lazily loads OTP Mobil's bundled SDK (src/simplepay/SimplePaySdk.php).
getLicense(): LicenseServiceReturns the plugin's license service component, shared with the CP License page.

placeOrder() success payload

[
'redirectUrl' => $paymentUrl, // SimplePay's hosted payment page
'extra' => [
// increment_id, email, name, country, city, zip, address, address2,
// company, language, currency, total, RURL, NURL, plus the raw
// SimplePay start response and 'transactionBase'
],
];

redirectUrl is what the storefront sends the customer's browser to.

ApiService

Yui\SimplePay\services\ApiService (Plugin::$plugin->get('api') / Plugin::$plugin->getApi()) wraps OTP Mobil's SimplePay v2.1 SDK (SimplePayStart/SimplePayBack, loaded via SimplePaySdkService).

MethodPurpose
prepare(array $data, array $items): selfBuilds and starts a SimplePay transaction from raw order $data and $items. Chainable — call ->getRedirectUri() next. Throws if $data or $items is empty, or if merchantId/secretKey is missing from settings.
getRedirectUri(?string $operation = null): ?stringReturns the paymentUrl SimplePay returned for the prepared transaction, or null if prepare() failed.
getParams(): arrayReturns the full payment data array built during prepare() (see placeOrder()'s extra payload above).
buildConfigForCurrency(?string $currency = null): arrayBuilds the SDK config array ({CURRENCY}_MERCHANT, {CURRENCY}_SECRET_KEY, merchantAccount, SANDBOX, request data) for a given currency, falling back to Default currency when none is passed. Used both when starting a payment and when validating a return signature.
testCredentials(): boolReturns true when both merchantId and secretKey are non-empty in settings. This is a presence check only — it does not call SimplePay. Used by the settings page's Test Credentials action.

Currency configuration

SimplePay's SDK expects per-currency config keys (HUF_MERCHANT, HUF_SECRET_KEY, EUR_MERCHANT, EUR_SECRET_KEY, and so on). This plugin only exposes a single Merchant ID/API Secret Key pair in settings and copies that same pair into whichever currency key is active for the current transaction (buildConfig() in ApiService). If a store needs genuinely different SimplePay credentials per currency, that requires a code change — the settings model does not currently support per-currency credential pairs.

Invoice data

ApiService only attaches invoice data (SimplePayHelper::shouldSendInvoiceData()) when the order's billing address has firstname, lastname, country_id, city, postcode, and street all present — these guard against specific SimplePay validation error codes (5309–5312) that occur when invoice data is sent incomplete. If any of those fields is missing, the transaction is still started, just without invoice data.

Checkout return validation

Plugin::postValidate() (via the private validateSimplePayReturn()) is the signature-check entry point for the checkout callback:

  1. Requires both r (base64 payload) and s (signature) query parameters — throws InvalidArgumentException if either is missing.
  2. Builds a SimplePayBack transaction and checks the signature with isBackSignatureCheck($r, $s), using per-currency SDK config resolved via guessCurrencyFromResponse() (reads the currency suffix out of the base64-decoded r payload's m field, e.g. ...HUFHUF).
  3. Throws RuntimeException if the signature check fails, or if the decoded notification isn't a non-empty array.
  4. On success, returns the raw notification array (SimplePayBack::getRawNotification()), which includes the e (event/status) and t (transaction ID) keys used by postValidate() and ResultService.

Return statuses

ResultService (Plugin::$plugin->get('result')) maps the notification's e value to a store redirect route and a flashed session message:

e valueMeaningRedirects to
SUCCESSPayment completed.order success URL
FAILPayment failed.order failed URL
CANCELPayment cancelled by the customer.order failed URL
TIMEOUTPayment session timed out.order failed URL

Only SUCCESS is treated as a paid order in Plugin::postValidate(). ResultService::checkOrderPaid() exists as a hook for marking the order complete on success, but its body is commented out in this plugin version — order completion is currently driven entirely by postValidate()'s return value back to yStore's checkout controller, not by ResultService itself.

Dashboard

New in v1.3.0. Yui\SimplePay\services\DashboardService (Plugin::$plugin->getDashboard() / Plugin::$plugin->get('dashboard')) extends ycore's CoreDashboardService and backs the CP Dashboard page (DashboardController, which itself extends ycore's AbstractDashboardController).

$dashboard = Plugin::$plugin->getDashboard();
  • buildModules() queries the shared yui_orders / yui_payment_transactions tables, filtered to payment_method/code = yui-simplepay, and returns the block layout rendered by the dashboard template: 4 KPI cards (total orders, revenue, successful, failed), a 30-day transaction trend chart, a status breakdown list, and a recent-transactions table (last 15). The date range defaults to the last 30 days when no range is requested.
  • Transaction status values paid, success, and completed count as successful; every other status counts as failed.
  • getSavedLayout() / saveLayoutData() persist the admin's dashboard block arrangement to Settings::$dashboardLayout (a new settings property in v1.3.0) via the plugin's normal settings save path — the layout is not a separate database table.
  • The dashboard page requires the accessPlugin-yui-simplepay permission, same as Settings.

Control panel routes

Registered on UrlManager::EVENT_REGISTER_CP_URL_RULES:

  • yui-simplepay/dashboard — CP dashboard page, new in v1.3.0 (DashboardController::actionIndex).
  • yui-simplepay/settings — redirects to yui-simplepay/settings/general (SettingsController::actionIndex). As of v1.3.0 settings are split across five routes/tabs, each with its own controller action: yui-simplepay/settings/general, yui-simplepay/settings/credentials, yui-simplepay/settings/pricing, yui-simplepay/settings/restrictions, yui-simplepay/settings/test-cards.
  • yui-simplepay/settings/test — runs the credentials presence check and redirects back with a success/error flash (SettingsController::actionTest).
  • yui-simplepay/license, yui-simplepay/license/redeem, yui-simplepay/license/activate, yui-simplepay/license/revoke, yui-simplepay/license/delete, yui-simplepay/license/copy-token — license management, shared AbstractLicenseController flow used by other YUI plugins.

The simplepay/settings/check-payments route pattern from earlier plugin versions — which had no corresponding controller action and always returned a routing error — was removed in v1.3.0 along with the old simplepay/-prefixed route registrations.

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

Translations

Yui\SimplePay\Plugin::PLUGIN_HANDLE is yui-simplepay, and CP strings are wrapped in Craft::t('yui-simplepay', ...). Translation files exist for cs, de, hu, and sk under src/translations/, but in this plugin version they all return an empty array — every string currently falls back to the English source text regardless of the active CP language.

Extensibility

This plugin version does not register its own Craft events (besides the internal payment-method registration on plugin load), permissions, or MCP tools — extension points are the public Plugin/ApiService methods above. To react to a SimplePay payment outside the standard checkout flow, call Plugin::$plugin->getApi() and drive the SDK's SimplePayStart/SimplePayBack classes directly, following the same pattern as ApiService/postValidate().