# Stripe integration for Cinema Booking v2.1

This package adds Stripe Checkout (hosted) to **CinemaBookingDev-v2.1**, using the
same payment flow as the existing PayPal / Authorize.net plugins so it feels native
to the codebase.

It is delivered as:

- `pjStripe/` — a self-contained plugin folder (drop into `app/plugins/`)
- `stripe-integration.patch` — a unified diff for the 6 core files that must be
  touched to wire the plugin in
- `modified/` — full copies of those same 6 files, already edited, in case you
  prefer to drop them in rather than apply the patch

Everything here follows v2.1 conventions (the plugin is modelled on the shipped
`pjPaypal` plugin, not copied from the older CinemaBookingDev tree).

---

## 1. Install the plugin

Copy the plugin folder into place:

```
cp -r pjStripe  app/plugins/
```

## 2. Run the SQL

From `app/plugins/pjStripe/config/`, run **in this order**:

1. `database.sql` — creates the `plugin_stripe` table and registers the admin
   labels for its columns.
2. `updates/update_2026_07_02_10_00_00.sql` — adds the three Stripe options,
   registers `stripe` as a selectable payment method, and extends the
   `bookings` / `bookings_payments` `payment_method` enums.

The update file is idempotent (it deletes its own rows before re-inserting), so
it is safe to re-run.

## 3. Enable the plugin

Add `pjStripe` to the plugins array in **both**:

- `app/config/config.inc.php`
- `app/config/config.sample.php`

```php
$CONFIG['plugins'] = array( ... , 'pjSms', 'pjStripe');
```

> The bundled `modified/app/config/options.inc.php` already contains this change
> for the internal defaults list; `config.inc.php` / `config.sample.php` are your
> environment files and still need the one-line edit above.

## 4. Apply the core wiring

Either apply the patch from the project root:

```
git apply stripe-integration.patch      # or:  patch -p1 < stripe-integration.patch
```

…or copy the six files from `modified/` over your originals. The six touched files
and what each change does:

| File | Change |
|------|--------|
| `app/config/options.inc.php` | adds `pjStripe` to the internal plugins list |
| `app/controllers/pjFront.controller.php` | adds the `case 'stripe'` builder in `pjActionConfirmForm()` and the `pjActionConfirmStripe()` return handler |
| `app/views/pjFront/elements/layout_1/payment.php` | renders the Stripe redirect form when `payment_method = stripe` |
| `app/views/pjAdminOptions/pjActionBooking.php` | shows/hides the key fields under **Allow Stripe payments** |
| `app/web/js/pjTicketBooking.js` | registers `stripe` in the front payment switch (redirect is self-triggered by the returned form) |
| `app/web/js/pjAdminOptions.js` | toggles the `.boxStripe` rows when the option changes |

## 5. Configure

In the admin, open **Options → Booking/Payments** and set:

- **Allow Stripe payments** → Yes
- **Stripe publishable key** → `pk_live_...` / `pk_test_...`
- **Stripe secret key** → `sk_live_...` / `sk_test_...`

Stripe now appears in the front-end payment-method dropdown.

---

## Flow

1. Customer picks **Stripe** and confirms → `pjFront::pjActionConfirmForm()`
   (`case 'stripe'`) builds the params and renders `pjStripe::pjActionForm`.
2. `pjActionForm` creates a Checkout Session and the view redirects the browser
   to Stripe via `stripe.redirectToCheckout()`.
3. On success Stripe returns to
   `pjFront::pjActionConfirmStripe()` with the invoice id and the checkout
   session id.
4. That handler calls `pjStripe::pjActionConfirm` → `pjActionProcess`, which
   **retrieves the session from Stripe, verifies it was paid and that the
   amount/currency match**, stores the payment in `plugin_stripe`, and returns
   the transaction id.
5. The booking, its online payment row and the invoice are marked paid and the
   confirmation email is sent.

## Notes / deviations from the CinemaBookingDev reference

The logic mirrors the reference implementation, adapted to v2.1 conventions. A
few deliberate changes were made so the port is correct and native — see the
accompanying message for the reasoning:

- **Invoice lookup fixed.** The return handler matches the invoice on its own
  `uuid` (the value passed back as `id`), not on `order_id`. In the reference
  this was reversed, which prevented paid bookings from ever being confirmed.
- **Reliable verification.** Payment is confirmed by retrieving the Checkout
  Session directly (primary) with the today's-events scan kept only as a
  fallback, and the charged amount/currency are checked against what was
  expected.
- **Safe amount conversion.** Amounts are converted to Stripe's minor units with
  integer rounding and a zero-decimal-currency list (JPY, KRW, …).
- **Native DB/model/migration style.** Table `plugin_stripe`, `source='plugin'`
  field labels, and a dated `config/updates/` migration — matching `pjPaypal`
  rather than the reference's older layout.

### Optional hardening (not included)
- A Stripe **webhook** endpoint so payments still reconcile if the buyer never
  returns to the success URL.
- Enabling TLS peer verification in the HTTP client.
- Moving to a newer pinned Stripe API version.
