Tutor LMS Direct Gateway – Paymob & Fawaterak
Paymob and Fawaterak payments for Tutor LMS: no WooCommerce, no missed enrollments
Status: setup checklist, both gateways shown at checkout, reconciliation at a glance
مفتاح الترخيص يظهر في حسابك (مفاتيح الترخيص الخاصة بي) بمجرد تأكيد الدفع، ويُرسل إلى بريدك أيضًا.
نظرة عامة
If you sell courses in Egypt or the Gulf, your students want to pay with a local card, a mobile wallet or a Fawry reference. Tutor LMS ships with its own Native eCommerce, but its built-in gateways do not cover Paymob or Fawaterak. Until now the usual workaround was to install WooCommerce just to take payments. Tutor LMS Direct Gateway plugs Paymob and Fawaterak straight into Tutor's own checkout, orders and enrollment.
Sell directly, enroll automatically
The student picks Paymob or Fawaterak at Tutor's checkout and pays on the gateway's secure hosted page. Once the payment is verified, the plugin marks the Tutor order as paid through Tutor's own payment hook. Tutor then enrolls the student and records your earnings exactly as it does for its built-in gateways. Coupons, taxes and order history stay where they already are, inside Tutor.
Built so no paid enrollment is missed
- Verified, not trusted: Paymob callbacks and redirects are checked with HMAC-SHA512. Fawaterak webhooks are checked with their hashKey and then re-confirmed through the Fawaterak API.
- Webhook reconciliation: every hour, payments still pending after 10 minutes are checked against the gateway APIs, and paid orders are completed even if the webhook never arrived. A Reconcile now button and an event log let you see exactly what happened.
- Idempotent: the webhook, the customer redirect and the reconciliation run can all arrive for the same order. The student is enrolled once.
- Amount guard: an order is never completed for less than the amount that was sent to the gateway.
Local payment methods your students already use
Paymob Unified Checkout shows the integrations you add: cards, mobile wallets such as Vodafone Cash, kiosk and Fawry references, and ValU. It works with Paymob accounts in Egypt, the UAE, Saudi Arabia and Oman. Fawaterak's invoice page offers every method enabled on your Fawaterak account. Fawry payments made days later are still picked up, by webhook or by reconciliation.
Simple to run
A status screen tells you what is missing, and connection-test buttons confirm your keys before you go live. Copy-ready callback URLs and separate sandbox and live credentials make the switch to live one click. If your Tutor store prices are in USD but you settle in EGP, choose a charge currency and an exchange rate. The admin comes in English and Arabic with full RTL support, and saved secrets are never displayed again or written to logs.
المميزات
No WooCommerce needed
Works inside Tutor LMS Native eCommerce: Tutor's checkout, orders, coupons, taxes and enrollment, with no extra store plugin.
Paymob Unified Checkout
Intention API with your card, wallet, kiosk/Fawry and ValU integration IDs. Supports Egypt, UAE, KSA and Oman accounts.
Fawaterak invoice checkout
Hosted invoice page with every method enabled on your Fawaterak account: cards, wallets, Fawry and more.
Signature-verified payments
HMAC-SHA512 for Paymob callbacks and redirects. Fawaterak hashKey plus an API re-check of the paid flag, amount and currency.
Automatic enrollment
Verified payments mark the Tutor order paid through Tutor's own hook, so Tutor enrolls the student and records earnings.
Hourly webhook reconciliation
Payments still pending after 10 minutes are checked against the gateway APIs and completed if they were paid. Includes a Reconcile now button.
Never enrolls twice
An idempotent completion path with a per-order lock: webhook, redirect and reconciliation can all arrive safely.
Amount and currency guard
An order is never completed if the gateway reports less than, or a different currency from, what was charged.
Sandbox and live switch
Separate test and live credentials for each gateway, plus connection-test buttons that check your keys without creating a payment.
Charge currency and exchange rate
Charge in EGP, AED, SAR, OMR or USD, even when your Tutor store currency is different.
Event log
The latest 200 events with filters: payments started, verified callbacks, rejections, recoveries and connection tests. Secrets are always redacted.
English and Arabic, RTL-ready
Translation-ready, with Arabic included and an admin that works right-to-left.
التثبيت
- 1Make sure Tutor LMS 3.0 or newer is active and Tutor → Settings → Monetization uses the Native eCommerce engine.
- 2Upload the plugin zip under Plugins → Add New → Upload Plugin, then activate it.
- 3Open Tutor LMS → Paymob & Fawaterak → License and activate the license key from your engzaki.pro purchase e-mail.
- 4Enter your Paymob and/or Fawaterak sandbox credentials, save, and click Test connection.
- 5Copy the callback and webhook URLs shown on each tab into the Paymob and Fawaterak dashboards.
- 6In Tutor LMS → Settings → Monetization → Payment Methods, switch Paymob and Fawaterak on and save.
- 7Buy a course with a test card, confirm the order is paid and the student is enrolled, then switch to Live credentials.
الشرح والتوثيق
اعرض الشرح كاملاخفِ الشرح+
Sell Tutor LMS courses with Paymob and Fawaterak directly through Tutor's Native eCommerce, without WooCommerce. A student is enrolled only after the payment is verified. The plugin supports local cards, mobile wallets and Fawry. Webhook reconciliation completes any paid order whose webhook never arrived.
- Plugin slug / text domain:
zi-tutor-paymob-fawaterak - Version: 1.0.0. Requires WordPress 6.0+ (tested up to 6.8), PHP 7.4 – 8.3, and Tutor LMS 3.0+ with the Native eCommerce engine.
- Author: Zaki International – https://engzaki.pro
- Product page: https://engzaki.pro/en/products/tutor-lms-paymob-gateway
1. Overview
| Paymob | Fawaterak | |
|---|---|---|
| Checkout | Intention API → Unified Checkout (hosted) | createInvoiceLink → hosted invoice page |
| Methods | Whatever integration IDs you add: card, mobile wallet, kiosk/Fawry, ValU | Whatever is enabled on your Fawaterak account (cards, wallets, Fawry, Aman, …) |
| Regions | Egypt, UAE, KSA, Oman | Egypt (EGP) and the other currencies your account accepts |
| Server notification | "Transaction processed" callback, HMAC-SHA512 | Webhook (…/webhook_json), hashKey HMAC-SHA256 |
| Customer return | Signed redirect (HMAC-SHA512) | Return URL, confirmed server-side with getInvoiceData |
| Reconciliation | auth/tokens + orders/transaction_inquiry (+ order lookup fallback) |
getInvoiceData/{id} |
| Sandbox | Test keys + test integration IDs | staging.fawaterk.com |
Nothing marks an order paid without a valid signature or a server-to-server confirmation from the gateway API.
2. Requirements
- WordPress 6.0+, PHP 7.4+ (tested on 7.4 and 8.3), HTTPS.
- Tutor LMS 3.0+ (free is enough), with Tutor LMS → Settings → Monetization → eCommerce engine = Native.
- A Paymob merchant account (Secret key, Public key, HMAC secret, integration IDs; API key for reconciliation) and/or a Fawaterak account (API key, vendor key).
- WP-Cron running. On low-traffic sites, add a real cron job that calls
wp-cron.php. - A license key from engzaki.pro.
3. Installation
- Plugins → Add New → Upload Plugin → choose
zi-tutor-paymob-fawaterak-1.0.0.zip→ Activate. - A new menu appears under Tutor LMS → Paymob & Fawaterak. If Tutor is inactive, it appears under Settings and shows a notice instead.
- Activate the license (section 4.6).
- Configure the gateways, then switch them on in Tutor (section 5).
4. Configuration, screen by screen
4.1 Status
This screen shows a setup checklist: Tutor active, Monetization = Native, license, and store currency → charge currency. For each gateway it shows the mode (Sandbox/Live), whether the credentials are complete, whether the gateway is enabled in Tutor's Payment Methods, and whether it is shown at checkout. It also shows reconciliation figures: last run, next run, pending payments and payments completed through the plugin.
4.2 Paymob
| Field | Where to find it / notes |
|---|---|
| Checkout title | The label students see on Tutor's checkout. |
| Mode | Sandbox or Live. Paymob uses different secret/public keys and integration IDs per mode, so both sets are stored. |
| Region | Egypt accept.paymob.com, UAE uae.paymob.com, KSA ksa.paymob.com, Oman oman.paymob.com. |
| HMAC secret | Dashboard → Settings → Account info → HMAC. Required. Every callback and redirect is verified with it. |
| API key | Dashboard → Settings → Account info → API key. Used only for reconciliation lookups and the connection test. |
| Secret key / Public key | Dashboard → Settings → Account info (sk_test_… / sk_live_…, …_pk_test_… / …_pk_live_…). |
| Card / Wallet / Kiosk (Fawry) / ValU integration IDs | Developers → Payment Integrations. Card can hold several comma-separated IDs. Only the IDs you fill in are offered on Unified Checkout. |
URLs for the Paymob dashboard (with Copy buttons):
- Transaction processed callback:
https://your-site/wp-json/zi-tpf/v1/paymob/callback - Transaction response callback:
https://your-site/wp-json/zi-tpf/v1/paymob/return
Both URLs are sent with every intention (notification_url / redirection_url). Paymob honours notification_url for card integrations. For wallet and kiosk integrations, also paste the callback URL into the integration's settings in the Paymob dashboard.
Saved secrets are never printed back to the page. The field shows ••••abcd – saved, leave blank to keep, and a Remove checkbox clears it.
Test connection checks:
- The secret key, by sending an empty intention request: Paymob must answer "invalid data", not "unauthenticated". No payment is created.
- The public key prefix against the selected mode, the HMAC secret and the integration IDs.
- The API key, by requesting an auth token.
4.3 Fawaterak
| Field | Notes |
|---|---|
| Checkout title | Label at checkout. |
| Mode | Sandbox (https://staging.fawaterk.com/api/v2) or Live (https://app.fawaterk.com/api/v2). |
| API key (token) | Fawaterak dashboard → Integrations. Sent as Authorization: Bearer …. |
| Vendor key | Used to verify the webhook hashKey. Some accounts sign with the API key instead, so both keys are accepted. Every paid webhook is also re-confirmed with getInvoiceData (paid flag, amount, currency). |
Webhook URL: https://your-site/wp-json/zi-tpf/v1/fawaterak/webhook_json. Paste it in Fawaterak → Integrations → Webhook. The _json suffix makes Fawaterak post JSON. The URL is also sent per invoice in redirectionUrls.webhookUrl.
Test connection calls getPaymentmethods and lists the methods enabled on your account.
4.4 Currency & General
- Charge currency: either "Same as the Tutor store currency" or a fixed EGP, AED, SAR, OMR or USD. Paymob Egypt settles EGP, UAE AED, KSA SAR and Oman OMR.
- Exchange rate: used only when the charge currency differs from the Tutor store currency. Amount charged = Tutor order total × rate, rounded to the currency's decimals (OMR uses 3). You must keep this rate up to date yourself.
- Reconcile pending payments for (days): 1–30, default 3. Fawry references can be paid days later.
- Declined payments: optionally mark the Tutor order failed when the gateway declines. This is off by default, so the order stays unpaid and the student can retry.
- Debug log: also log ignored callbacks and "not paid yet" checks.
- Uninstall: delete settings, payment records and logs when the plugin is deleted. Tutor orders and enrollments are never touched.
4.5 Reconciliation & Log
- Reconcile now runs a pass immediately (up to 100 pending payments) and reports how many payments it checked, how many it recovered as paid, and how many errors it hit.
- The event log shows the latest 200 events, filterable by source (Paymob / Fawaterak / System) and level. It covers intentions and invoices created, verified callbacks, rejected signatures, amount mismatches, completions, reconciliation runs and connection tests. Order numbers link to Tutor's order screen. The table keeps the newest 500 rows. Secrets, tokens, HMACs and card PANs are redacted before anything is stored.
4.6 License
Paste the key and click Activate. The result is cached for 12 hours. If engzaki.pro cannot be reached, the last valid state is kept for a 7-day grace period. Deactivate on this site frees the domain. localhost, *.local and *.test validate without using an activation.
Without a valid license:
- All settings stay editable.
- Paymob and Fawaterak are hidden at checkout (
is_configured()returns false to Tutor), and an admin notice links to the product page. - Webhooks, redirects and reconciliation for payments that were already started keep working, so a paying student is never left without enrollment.
5. Switch the gateways on in Tutor
Go to Tutor LMS → Settings → Monetization → Payment Methods. "Paymob – Cards, Wallets & Fawry" and "Fawaterak – Cards, Wallets & Fawry" appear in the list (title editable in the plugin). Toggle them on and save. Tutor's modal for these gateways only shows Tutor's generic webhook URL; that URL also works, but the plugin's own URLs from 4.2 / 4.3 are recommended.
6. How it works
6.1 Integration with Tutor LMS (hooks used)
Based on the Tutor LMS source (themeum/tutor, ecommerce/), checked against Tutor 4.1.1:
| Tutor API | Used for |
|---|---|
filter tutor_payment_gateways_with_class (Ecommerce::payment_gateways_with_ref()) |
Registers zi_paymob / zi_fawaterak with their gateway + config classes. |
filter tutor_payment_gateways (Settings::ajax_tutor_payment_gateways()) |
Adds both gateways to Tutor's admin "Payment Methods" list. |
filter tutor_default_automate_payment_gateways |
Exposes the gateways (label, icon, active state). |
filter tutor_payment_method_labels |
Checkout / order labels. |
class Tutor\PaymentGateways\GatewayBase |
ZiTpf\Tutor\PaymobGateway, ZiTpf\Tutor\FawaterakGateway. |
Ollyo PaymentHub BasePayment / BaseConfig / ConfigContract (bundled in Tutor) |
…Payment::createPayment() starts the hosted checkout. …Config::is_configured() decides checkout visibility (license + credentials). |
filters tutor_ecommerce_payment_success_url_args / …_cancelled_url_args |
Same success / cancel URLs as Tutor's own gateways. |
action tutor_order_payment_updated (handled by HooksHandler::handle_payment_updated_webhook) |
Fired with payment_status = paid. Tutor completes the order, then tutor_order_payment_status_changed enrolls the student and records earnings. |
tutor_redirect_after_payment() |
Sends the student to Tutor's order-placement success / failed page. |
route tutor/v1/ecommerce-webhook/{gateway} |
Also supported: verifyAndCreateOrderData() delegates to the same verified handlers. |
The gateway classes are loaded lazily by an autoloader, only after Tutor has loaded its own base classes. If Tutor is missing or too old, nothing loads and nothing breaks.
6.2 Payment flow
- A student picks Paymob / Fawaterak on Tutor's checkout. Tutor creates the order (
unpaid) and callscreatePayment(). - The plugin converts the amount if needed and creates a Paymob intention (
special_reference = tutor-{order}-{random}, amount in minor units, one line item for the whole order) or a Fawaterak invoice (payLoadcarries the order and reference). It stores an attempt row (wp_zi_tpf_payments) with the expected amount and currency, then redirects to the hosted page. - The gateway notifies the site:
- Paymob callback: verify HMAC-SHA512 over the 20 documented fields → find the attempt by
merchant_order_id(or Paymob order id) → classify (paid / pending / declined / refunded / voided) → complete if paid. - Paymob redirect: same HMAC check on the flattened query string. Without a valid HMAC the plugin asks the Paymob API instead.
- Fawaterak webhook: verify
hashKey(InvoiceId=…&InvoiceKey=…&PaymentMethod=…) → match invoice id + key → re-checkgetInvoiceData→ complete. - Fawaterak return: always confirmed server-side with
getInvoiceData.
- Paymob callback: verify HMAC-SHA512 over the 20 documented fields → find the attempt by
- Completion (
ZI_TPF_Orders::complete()):- Refuse if the paid amount is below the expected amount or the currency differs.
- Skip if the order is already paid.
- Take an atomic per-order lock (
add_optionon a unique key) and re-read the order. - Fire
tutor_order_payment_updated, verify that the order is now paid, mark the attempt paid and supersede the order's other attempts.
- Reconciliation (hourly cron
zi_tpf_reconcile): attempts stillpendingafter 10 minutes and inside the look-back window are checked with the gateway API, and paid ones go through the same completion path. Attempts older than the window becomeabandoned.
6.3 Data
wp_zi_tpf_payments: one row per checkout attempt (order, gateway, mode, reference, remote ids, expected amount, status, transaction id, check count).wp_zi_tpf_log: event log.- Options:
zi_tpf_settings,zi_tpf_license_state,zi_tpf_last_reconcile, versions. Locks are short-livedzi_tpf_lock_{order}rows.
6.4 Developer hooks
| Hook | Purpose |
|---|---|
zi_tpf_is_licensed (filter) |
Force the gateways on/off. |
zi_tpf_capability (filter) |
Capability for the admin screens (default manage_options). |
zi_tpf_supported_currencies, zi_tpf_currency_decimals, zi_tpf_exchange_rate |
Currency handling. |
zi_tpf_paymob_regions |
Add or override Paymob regions and base URLs. |
zi_tpf_paymob_amount_minor, zi_tpf_paymob_intention_payload |
Adjust the Paymob intention. |
zi_tpf_fawaterak_invoice_payload, zi_tpf_fawaterak_base_url |
Adjust the Fawaterak invoice / endpoint. |
zi_tpf_endpoint_url |
Change the public callback URLs (e.g. behind a proxy). |
zi_tpf_reconcile_batch |
Attempts checked per pass. |
zi_tpf_payment_hub_autoload |
Path to Tutor's bundled PaymentHub autoloader. |
zi_tpf_order_paid (action) |
Runs after an order is completed: ( $order_id, $attempt, $source ). |
7. Troubleshooting
| Symptom | Check |
|---|---|
| Gateway not shown at checkout | Status tab: license active, credentials complete, enabled in Tutor Payment Methods, Monetization = Native. The store or charge currency must be supported. |
| "Rejected Paymob callback: HMAC mismatch" in the log | Wrong HMAC secret, or the callback comes from a different Paymob account / region. |
| Paid on Paymob but order still unpaid | Look for amount_mismatch, currency_mismatch or unknown_order in the log. Make sure the API key is set so reconciliation can work. Wallet / kiosk integrations need the callback URL in the Paymob dashboard. |
| Fawaterak "hashKey mismatch" | Vendor key wrong, or test/live keys mixed. The API key is accepted too. |
| Nothing happens hourly | WP-Cron disabled or the site gets no traffic. Add a server cron for wp-cron.php, or use Reconcile now. |
| REST URLs return 404 | Permalinks must not be "Plain", or use the ?rest_route= form. Security plugins must allow /wp-json/zi-tpf/v1/*. |
| Customer sees "We could not confirm your payment yet" | The return arrived before the gateway marked the payment as paid. The webhook or the next reconciliation completes the order automatically. |
8. FAQ
- WooCommerce? Not needed and not used.
- Subscriptions / memberships? Not supported in 1.0 (
support_subscription = false). One-time course and bundle orders only. - Refunds? Make them in the gateway dashboard and update the Tutor order. Refund / void callbacks are logged but enrollment is not changed automatically.
- Coupons and taxes? Tutor computes the order total and the plugin charges that total.
- Multisite? Works per site. Each site needs its own activation.
- What leaves my site? Order total, currency, student name, email and phone go to the payment gateway you configured. License key + domain + plugin slug go to engzaki.pro. There is no tracking and no external assets.
9. What the merchant still has to do
- Complete the merchant onboarding / KYC with Paymob or Fawaterak and enable the payment methods you want.
- Test end to end in sandbox before switching to live, with at least one card payment, one declined payment and one Fawry/kiosk reference.
- Keep the exchange rate current if you charge in a different currency than your store currency.
- Handle refunds and chargebacks in the gateway dashboard.
- Make sure your checkout, terms and privacy pages meet your local legal requirements. The plugin does not provide PCI or legal certification; card data never touches your server, because payment happens on the gateway's hosted page.
10. Changelog
- 1.0.0: first release.
سجل التحديثات
= 1.0.0 = * First release: Paymob Intention API / Unified Checkout, Fawaterak invoice link, HMAC-verified callbacks, idempotent enrollment, hourly reconciliation, event log, connection tests, multi-currency charge with exchange rate, English + Arabic.
الأسئلة الشائعة
+Do I need WooCommerce?
No. The plugin integrates with Tutor LMS's own Native eCommerce, so orders, coupons, taxes and enrollment all stay in Tutor.
+Which Tutor LMS version do I need?
Tutor LMS 3.0 or newer, the free version included, with the Monetization eCommerce engine set to Native.
+What happens if a webhook never reaches my site?
Every hour the plugin asks Paymob or Fawaterak about payments still pending after 10 minutes and completes the paid ones automatically. You can also click Reconcile now.
+Can a student be enrolled twice?
No. Each order is completed once. Later webhooks, redirects and reconciliation runs for the same order are logged as already paid.
+Does it support Fawry and mobile wallets?
Yes. With Paymob, add your wallet and kiosk/Fawry integration IDs. With Fawaterak, every method enabled on your account appears on the invoice page. Reference payments made later are picked up by webhook or reconciliation.
+My store prices are in USD but Paymob Egypt charges EGP. Can I still use it?
Yes. Set the charge currency to EGP and enter an exchange rate. The student pays the Tutor price multiplied by the rate. You keep the rate up to date yourself.
+Which Paymob countries are supported?
Egypt, the United Arab Emirates, Saudi Arabia and Oman. Pick your region in the settings.
+Are subscriptions or automatic refunds supported?
Not in version 1.0. It handles one-time course and bundle purchases. Refunds are made in the gateway dashboard and the Tutor order is updated manually.
+What happens if my license expires?
Nothing breaks. The gateways are hidden at checkout until you renew, the settings stay editable, and payments that were already started are still confirmed and enrolled.
الدعم الفني
كل عملية شراء تشمل دعمًا مباشرًا من المطوّر. لو في حاجة مش شغالة زي الموصوف، ابعتلنا مفتاح الترخيص ورابط موقعك وهنساعدك لحد ما تشتغل.