Payment & Messaging Plugins
Payments bring money in. Messaging proves identity. Both are infrastructure: if they fail, nothing else matters.
How plugin gateways work
A plugin gateway does three things:
- Declares itself in the
gatewayregistry. - Starts a charge through the
payment.chargefilter. - Verifies its callback and calls
payment.complete.
Core owns completion. It credits the wallet, marks the order paid, activates the subscription, or finishes the promotion. The plugin never duplicates that logic.
// Declare
$this->ctx->registry->register('gateway', 'mygateway', [
'id' => 'mygateway',
'label' => 'My Gateway',
'module' => 'MyGateway',
'ipn_route' => 'mygateway.ipn',
'settings_prefix' => 'mygateway',
'enabled_option' => 'mygateway_enabled',
]);
// Charge
$this->ctx->hooks->addFilter('payment.charge', function (mixed $result, array $context) {
if (($context['gateway'] ?? '') !== 'mygateway') {
return $result; // pass through
}
// create a payment, return a redirect response
});
// Complete
\PluginsFramework\PluginFramework::applyFilters('payment.complete', [], [
'type' => 'order',
'id' => $orderId,
'transaction_id' => $transactionId,
]);
Pesapal
What Pesapal does
Pesapal API v3 hosted checkout for cards and mobile money.
- Hosted payment page.
- IPN and return-URL verification.
- Merchant reference encodes the payment type and record ID, so one callback route settles orders, wallet deposits, subscriptions, and NDA fees.
- No plugin tables.
- Permission:
pesapal-settings.
Pesapal setup
- Create a Pesapal merchant account.
- Get the consumer key and secret.
- Choose sandbox or live.
- Activate
pesapal-payment-gateway. - Open Admin → Pesapal.
- Enter the keys.
- Set the IPN URL to the route the plugin shows.
- Register the IPN URL with Pesapal if required.
- Enable the gateway in checkout settings.
- Place a small live test order and refund it.
Currency
Pesapal settles in supported currencies. If your display currency is not supported, the site converts before charging. Confirm the charged amount on the Pesapal receipt.
Pesapal limits
- The IPN must be reachable from the public internet.
- A sandbox key will not settle live money.
- Refunds are handled in the Pesapal dashboard unless the plugin exposes them.
SePay
What SePay does
VietQR bank transfer with automatic confirmation.
- Generates a VietQR code.
- Matches the transfer by payment code.
- HMAC or API-key webhook verification.
- VND conversion.
- IPN at
/sepay/ipn. - Permission:
sepay-settings.
Payment codes
{PREFIX}{LETTER}{RECORD_ID}
| Letter | Record |
|---|---|
WC | Wallet deposit, client |
WF | Wallet deposit, freelancer |
O | Order |
S | Subscription |
P | Promotion |
The prefix comes from settings. The letter identifies the record type. The ID ties it to the row.
SePay setup
- Open a SePay account and connect your bank.
- Get the webhook secret or API key.
- Activate
sepay-payment-gateway. - Open Admin → SePay.
- Enter the credentials and prefix.
- Set the webhook URL to
/sepay/ipn. - Enable the gateway.
- Make a small transfer with the generated code.
- Confirm the order moves to paid.
SePay limits
- The transfer description must contain the code exactly.
- Bank delays can take minutes; the order stays pending until the webhook arrives.
- Manual edits to the transfer description break matching.
- Refunds are manual bank transfers.
SMS Gateway
What SMS Gateway does
Sends OTP codes and notifications through 23+ providers.
Providers by region:
- Global: Twilio, Vonage, Sinch, Plivo, Infobip, Gupshup, Sendra.
- India: MSG91, Fast2SMS, TextLocal.
- Bangladesh: SSL Wireless, BulkSMSBD, AlphaNet.
- Middle East: Mimosms, SMSMisr, Msegat, Unifonic.
- Africa: Africa's Talking, Termii, BulkSMS, Hubtel.
- Latin America: Zenvia.
- WhatsApp: Wati.
Location
The plugin lives at core/plugins/sms-gateway, not plugins/sms-gateway. It must be available
during login, before the framework boots. Do not move it.
Service: SmsGateway\Services\OtpService.
SMS Gateway setup
- Create an account with a provider.
- Get the API key, sender ID, and endpoint.
- Open the SMS settings page.
- Choose the provider.
- Enter the credentials.
- Send a test OTP to your own number.
- Enable phone verification.
Phone verification
When enabled:
- Unverified users are redirected to the phone screen.
- Routes:
phone.verify,resend.phone.code,update.phone.number. - Middleware:
UserPhoneVerify. - API responses expose
is_phone_verified.
If the plugin or provider config is missing, verification fails open. This prevents a total lockout but means phone verification is not enforced. Monitor the setting.
SMS Gateway limits
- Delivery depends on the provider and the destination carrier.
- Short codes may be blocked in some countries.
- Costs are per message; rate-limit resends.
- WhatsApp delivery requires a template approved by Meta.
CoinPayments (port)
What CoinPayments (port) does
Crypto checkout through CoinPayments.
gatewayregistry entry.- IPN verification.
payment.completesettlement.- Ported with
legacyName: CoinPaymentGateway.
CoinPayments (port) setup
- Create a CoinPayments merchant account.
- Get the merchant ID and IPN secret.
- Activate
coin-payment-gateway. - Enter the credentials.
- Set the IPN URL.
- Enable the gateway.
- Test with a small amount.
CoinPayments (port) limits
- Network fees and confirmation times vary.
- Exchange-rate volatility is borne by the payer or the merchant, depending on the coin settings.
- Refunds are manual.
YooMoney (port)
What YooMoney (port) does
YooMoney wallet and card payments.
gatewayregistry entry.- IPN verification.
payment.completesettlement.- Ported with
legacyName: YooMoneyPaymentGateway.
YooMoney (port) setup
- Create a YooMoney merchant account.
- Get the shop ID and secret.
- Activate
yoomoney-payment-gateway. - Enter the credentials.
- Set the notification URL.
- Enable the gateway.
- Test with a small amount.
YooMoney (port) limits
- Availability depends on your country and entity type.
- Currency support is limited.
- Refunds are handled in the YooMoney dashboard.
Which gateway should I enable?
| Your market | Start with |
|---|---|
| East Africa | Pesapal |
| Vietnam | SePay |
| Global cards | A core card gateway, plus Pesapal for local |
| Crypto | CoinPayments |
| Russia and CIS | YooMoney |
| Wallet-first | Core wallet, plus one gateway for top-ups |
Do not enable every gateway. Each one adds settings, callbacks, reconciliation, and support.
Testing checklist
- Sandbox credentials work.
- A successful payment marks the record paid.
- A failed payment leaves it pending.
- A duplicate callback does not double-credit.
- A cancelled payment can be retried.
- The amount and currency match the receipt.
- The invoice number is created once.
- The admin sees the transaction ID.
- The user sees the correct status.
- A refund path is documented.
Security
- Verify every callback signature.
- Reject callbacks with a mismatched amount or currency.
- Use
hash_equals()for secret comparison. - Do not trust a return URL alone; wait for the IPN.
- Log the transaction ID, not the full payload with secrets.
- Keep gateway secrets out of the repository.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Order stays pending | IPN not reachable | Check the public URL and firewall |
| Callback rejected | Wrong secret or signature | Re-enter the secret |
| Amount mismatch | Currency conversion | Confirm the charged currency |
| Duplicate credit | Missing idempotency | Check the transaction ID logic |
| SePay code not matched | Description edited | Recreate the payment |
| OTP not delivered | Provider or carrier | Check provider logs and balance |
| Pesapal sandbox fails | Sandbox URL or key | Confirm environment and keys |
Last updated: October 21, 2026

