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();
| Method | Purpose |
|---|---|
getDetails(): array | Returns 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): array | Builds 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): array | Called 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): ?string | Rebuilds 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(): ApiService | Returns the plugin's ApiService component (Plugin::$plugin->get('api')). |
getSdk(): SimplePaySdkService | Returns the plugin's SimplePaySdkService component, which lazily loads OTP Mobil's bundled SDK (src/simplepay/SimplePaySdk.php). |
getLicense(): LicenseService | Returns 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).
| Method | Purpose |
|---|---|
prepare(array $data, array $items): self | Builds 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): ?string | Returns the paymentUrl SimplePay returned for the prepared transaction, or null if prepare() failed. |
getParams(): array | Returns the full payment data array built during prepare() (see placeOrder()'s extra payload above). |
buildConfigForCurrency(?string $currency = null): array | Builds 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(): bool | Returns 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:
- Requires both
r(base64 payload) ands(signature) query parameters — throwsInvalidArgumentExceptionif either is missing. - Builds a
SimplePayBacktransaction and checks the signature withisBackSignatureCheck($r, $s), using per-currency SDK config resolved viaguessCurrencyFromResponse()(reads the currency suffix out of the base64-decodedrpayload'smfield, e.g....HUF→HUF). - Throws
RuntimeExceptionif the signature check fails, or if the decoded notification isn't a non-empty array. - On success, returns the raw notification array (
SimplePayBack::getRawNotification()), which includes thee(event/status) andt(transaction ID) keys used bypostValidate()andResultService.
Return statuses
ResultService (Plugin::$plugin->get('result')) maps the notification's
e value to a store redirect route and a flashed session message:
e value | Meaning | Redirects to |
|---|---|---|
SUCCESS | Payment completed. | order success URL |
FAIL | Payment failed. | order failed URL |
CANCEL | Payment cancelled by the customer. | order failed URL |
TIMEOUT | Payment 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 sharedyui_orders/yui_payment_transactionstables, filtered topayment_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
statusvaluespaid,success, andcompletedcount as successful; every other status counts as failed. getSavedLayout()/saveLayoutData()persist the admin's dashboard block arrangement toSettings::$dashboardLayout(a new settings property inv1.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-simplepaypermission, same as Settings.
Control panel routes
Registered on UrlManager::EVENT_REGISTER_CP_URL_RULES:
yui-simplepay/dashboard— CP dashboard page, new inv1.3.0(DashboardController::actionIndex).yui-simplepay/settings— redirects toyui-simplepay/settings/general(SettingsController::actionIndex). As ofv1.3.0settings 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, sharedAbstractLicenseControllerflow 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().