OpenCart

Install and configure the Qasimha payment extension for OpenCart 4, including status mapping, webhooks and the order-page actions.

The Qasimha extension adds "Qasimha - pay in instalments" to an OpenCart 4 store. The shopper is sent to the Qasimha hosted checkout and comes back to your thank-you page. The store marks the order paid only after it has read the order back from Qasimha. Fulfilment, refunds and status checks run from the order page.

Requirements

ItemRequirement
OpenCart4.0.2.0 or later
PHP8.1 or later with curl, json and mbstring
CurrencySaudi riyal (SAR) configured as a store currency. Qasimha is offered when the shopper's selected currency is SAR.
HTTPSRequired (plain http works only on localhost)
Packageqasimha-opencart-<version>.ocmod.zip
LicenseMIT

Install

  1. Download qasimha-opencart-<version>.ocmod.zip from the extension's releases.
  2. In the admin, open Extensions → Installer, upload the file, then press Install on the row that appears.
  3. Open Extensions → Extensions, choose the type Payments, find Qasimha and press Install. This creates the tables oc_qasimha_order and oc_qasimha_webhook_event and registers the storefront events for the widget.
  4. Press Edit and fill in the settings below.

If your Arabic language uses a directory other than ar (for example ar-sa), copy extension/qasimha/admin/language/ar and extension/qasimha/catalog/language/ar to that name.

Uninstalling from the Payments list removes the events and the webhook table but keeps oc_qasimha_order, so past orders keep their Qasimha order id.

Configure

Go to Extensions → Extensions → Payments → Qasimha → Edit.

TabSettingWhat to enter
GeneralStatusEnables the payment method.
GeneralEnvironmentSandbox uses the sk_test_ key and never moves money. Production uses the sk_live_ key.
GeneralMinimum / Maximum totalQasimha is offered only when the cart total in riyals is in this range. 0 means no limit.
GeneralDebug logWrites each step to storage/logs/qasimha.log.
GeneralSort orderPosition in the payment-method list.
API keysSandbox / Production secret keyFrom the Merchant Portal, Settings → API keys. Shown masked after saving; leave empty to keep the stored key. A key from the other environment is refused.
API keysPublishable keypk_test_... or pk_live_.... The only key that reaches the browser.
API keysWebhook URLRead-only. Register it in the Merchant Portal.
API keysWebhook secretThe secret the Merchant Portal shows for that webhook.
API keysTest connectionChecks the keys in the form (saved or not) and reports the environment and order count.
Order statusesSix mappingsSee the next section.
WidgetProduct / cart page, placement selectorsSee Widget placement.

Order status mapping

Set these on the Order statuses tab.

MappingDefaultWhen it is applied
Awaiting checkoutPendingThe checkout session was created and the shopper was sent to Qasimha.
Payment confirmedProcessingThe order was read back from Qasimha and is Confirmed with the same reference and total.
FulfilledShippedAfter Fulfil in Qasimha on the order page.
Fully refundedRefundedRefunds bring the refunded amount to the order total. Partial refunds add a history comment and keep the status.
VoidedVoidedQasimha reports the order voided or cancelled.
DeclinedDeniedQasimha declined the order. Only applied while the order is still awaiting checkout.

The extension never moves an order backwards. A paid order is not set back to pending by a later webhook.

Register the webhook

Register this URL in the Merchant Portal and paste the secret into Webhook secret:

https://<your-store>/index.php?route=extension/qasimha/payment/qasimha.webhook

The webhook answers:

StatusMeaning
200Received ({"received":true,"action":…})
400Bad signature or bad body
503No webhook secret configured
500The order could not be read back from Qasimha — Qasimha retries

The event body only says which order to look at. The extension reads the order from Qasimha before changing anything.

How a payment flows

  1. Confirm. The shopper presses Continue to Qasimha. The extension creates the checkout session from the order, sets Awaiting checkout and redirects the shopper.
  2. Reference. The reference is the OpenCart order id. If the shopper cancels and places the same order again, the next attempt is <id>-2, <id>-3, and the abandoned Qasimha order is cancelled.
  3. Return. The shopper returns to the qasimha.callback route with the order id and a token. The extension checks the token, reads the order from Qasimha, and marks it paid only when it is Confirmed with the same reference and total. Otherwise OpenCart's payment-failed page is shown.
  4. Decline. The shopper sees one line — "Your Qasimha payment was not completed. Please choose another payment method." — and never a reason.

Widget placement

With a publishable key saved, the extension shows the instalment summary (<qasimha-widget type="summary">) on product pages (under the price) and the cart page (under the totals), and a "pay in instalments with Qasimha" card at checkout.

Placement is a list of CSS selectors tried left to right, separated by ||. The widget is inserted after the first match. Defaults for the OpenCart 4 default theme:

  • Product page: #content h2 || .product-price || .price
  • Cart page: #checkout-total || #content .table:last-of-type

Change them if your theme uses different markup. The widget is only injected when the shopper's currency is SAR and renders nothing when the amount is outside your plans. If you use a Content Security Policy, allow connect-src for the Qasimha API host of your environment; the script itself is served from your store. See Plans widget.

Fulfilment, refunds and cancellations

Open Sales → Orders, then an order paid with Qasimha. The Qasimha tab shows the Qasimha order id, reference, environment and last known status, with three actions:

  • Check status — reads the order again and shows captured, refunded and refundable amounts.
  • Fulfil in Qasimha — reports the whole order as fulfilled, once. The order moves to the Fulfilled status.
  • Refund via Qasimha — enter an amount and an optional reason. History is updated only when Qasimha accepts. A refund above the refundable amount shows Qasimha's AMOUNT_EXCEEDED message as is.

Fulfilment is manual on OpenCart

Shipping the order in OpenCart does not notify Qasimha. Press Fulfil in Qasimha when you ship. Qasimha needs this call to release your settlement.

When the shopper cancels on the hosted checkout, the cancel route cancels the Qasimha order and returns the shopper to the cart.

Test in UAT

  • Environment Sandbox, sk_test_ and pk_test_ keys saved; Test connection passes.
  • Webhook URL registered for sandbox and the secret saved.
  • Widget shows under the product price and the cart totals (adjust selectors if not).
  • Complete a hosted checkout: order moves to Payment confirmed (default Processing).
  • Cancel on the hosted checkout: you are back in the cart.
  • Fulfil in Qasimha: order moves to Fulfilled.
  • Partial refund, then a refund larger than what is left: the second shows AMOUNT_EXCEEDED.
  • storage/logs/qasimha.log shows no errors.

Troubleshooting

Qasimha is not offered at checkout

Check that Status is enabled, the shopper's currency is SAR, and the cart total is inside the minimum/maximum range.

The widget does not appear

Check that a publishable key is saved, the widget is turned on for that page, and one of the placement selectors matches an element in your theme. The widget also renders nothing when the amount is outside your plans.

Arabic text is missing

Your Arabic language directory is not named ar. Copy the two language/ar directories to your directory name (see Install).

Webhook returns 503

No webhook secret is saved. Paste the secret from the Merchant Portal.

Security

  • Admin: every save and button checks the admin user_token and the modify permission on extension/qasimha/payment/qasimha. Give that permission only to trusted admin users.
  • Keys: the secret keys and webhook secret are saved in OpenCart's setting table without encryption and shown masked on the settings page. Restrict database and backup access accordingly.
  • Browser: only the publishable key.
  • Return route: checks a per-attempt token and reads the order from Qasimha before changing it.
  • Webhook route: verifies the HMAC signature (5-minute tolerance, secret rotation) and de-duplicates on the event id. See Webhook signatures.
  • Logs: secret keys, the webhook secret and customer data are never written; key-shaped strings are masked.
  • PCI DSS: no card data passes through the store; you stay in SAQ-A scope.

Report security issues privately, never in a public issue.

Next steps


Did this page help you?