> ## Documentation Index
> Fetch the complete documentation index at: https://docs.useduro.com/llms.txt
> Use this file to discover all available pages before exploring further.

# PrestaShop

> The PrestaShop 1.7 / 8.x payment module for Nomba hosted checkout, with a custom held-payment order state and an admin refund panel.

`integrations/prestashop/nomba/` is a PrestaShop payment module that adds Nomba hosted checkout on PrestaShop 1.7 and 8.x. It ships a custom order state for held payments, an admin refund panel, unit-tested protocol classes (19 tests), and was verified end to end against a real PrestaShop 8.1 store (checkout, all webhook cases, admin refund). A parallel Duro module lives alongside it under `prestashop/duro/`. Source: `prestashop/README.md`.

## Structure

```
nomba/
  nomba.php                          PaymentModule subclass (install, uninstall, hooks)
  classes/
    NombaClient.php                  token issue (cached) + checkout/verify/refund
    NombaSignature.php               nine-field HMAC signature verification
  controllers/front/
    redirect.php                     create the Nomba order, redirect to checkoutLink
    return.php                       return-URL verification, completes the order
    webhook.php                      signed webhook handler, re-verifies before granting value
  views/templates/
    front/payment_infos.tpl          payment option blurb
    front/payment_return.tpl         order confirmation blurb
    admin/refund_panel.tpl           admin order-page refund form
  logo.png
  index.php                          security guard, copied into every subdirectory
```

## Install

Build with `bash tools/build.sh` (produces `dist/nomba-prestashop.zip`, a single `nomba/` folder with the module, classes, controllers, views, logo, and index guards; no tests or tooling). Then upload it via **Modules, Upload a module**, or drop the `nomba/` folder into `/modules/` and install it from the back office's module list.

## Config (module settings)

Enable, test mode, **Account ID** (must be the parent/business account, not a sub-account, which the real API rejects with 403), optional **Sub-account ID** (routes payment into that sub-account via `order.accountId`), **Client ID**, **Client secret**, and the webhook **Signature key**.

## Lifecycle

The module implements the shared [verification-first lifecycle](/integrations/architecture) through PrestaShop's payment hooks:

1. **`hookPaymentOptions`** shows Nomba as a checkout option when the module is enabled, configured, and the cart currency is allowed.
2. **`redirect.php`** calls `POST {prefix}/checkout/order` and sends the shopper to `data.checkoutLink`. The `nomba_transaction` table records the order reference, cart id, and mode (test or live).
3. **`return.php`** calls `verifyOrder` and completes the order only when the API reports it paid with a matching amount; a mismatch holds the order in the module's own **`Awaiting Nomba review`** state instead.
4. **`webhook.php`** verifies the nine-field HMAC signature from the `nomba-signature` header against the `nomba-timestamp` header, then **re-verifies** the transaction through the Nomba API before granting value. The API response is the source of truth, not the webhook payload. `payment_success` completes or holds the order depending on the verified amount; `payment_reversal` marks a paid order refunded.
5. **Refunds** run from the module's panel on the admin order page (`hookDisplayAdminOrder`) or from PrestaShop's native credit-slip flow (`hookActionOrderSlipAdd`), both through `POST {prefix}/refund` with the stored transaction id; partial amounts are supported. Refunds use the mode the order was paid in.

<Note>
  The custom **`Awaiting Nomba review`** order state is how a verified-amount mismatch is surfaced: a held order is parked in a module-owned state rather than silently completed or cancelled, so an operator reviews it before fulfilling.
</Note>

## Environments

Test mode targets `https://sandbox.nomba.com`; live mode targets `https://api.nomba.com`. Both use the same `/v1/checkout` prefix; only the host differs. The base URL can be overridden for local testing with the `NOMBA_API_BASE` PHP constant, which `NombaClient::baseUrl()` checks before the mode switch; the demo store's Docker Compose sets it via an `auto_prepend_file` shim (see `tools/demo/prestashop/README.md`).

## Tests and demo

The PHPUnit suite (19 tests) covers the pure classes (`NombaClient`, `NombaSignature`) against a stubbed HTTP layer. The framework-dependent code (`nomba.php`, the front controllers) is not unit-testable without a running PrestaShop; it is verified in the demo store and against the real PrestaShop 8.1 store instead.

```bash theme={null}
docker run --rm -v "$PWD":/repo -w /repo/tools/tests composer:2.7 composer install
docker run --rm -v "$PWD":/repo -w /repo/tools/tests php:8.3-cli vendor/bin/phpunit
```

A full local checkout, webhook, and refund walkthrough against the mock Nomba server lives in `tools/demo/prestashop/README.md`.
