# Stripe payment integration — CGYachtListing v3.1 (both surfaces)

Stripe is integrated into BOTH PayPal-wired payment surfaces, for full parity:

1. **Listing payments** — a yacht owner pays (admin side) to publish/extend a
   listing for a period. Mirrors the CG-listings PayPal flow.
2. **Front bookings** — a customer books a yacht and pays at checkout. Mirrors the
   booking PayPal flow across all four front layouts (layout1/2/3/website).

Both use Stripe Checkout (hosted redirect). A single `pjStripe` plugin serves both;
each surface points Stripe's return at its own confirm handler.

## What was added

New plugin — `app/plugins/pjStripe/` (PLUGIN_ID 303)
- `config/database.sql` — creates `plugin_stripe` + field labels
- `config/updates/update_2026_07_07_10_00_00.sql`:
  - `o_stripe_public_key` / `o_stripe_secret_key` / `o_stripe_cancel_url` (tab 3) —
    used by BOTH surfaces (one Stripe account)
  - `o_allow_stripe` (Yes/No, tab 3) — enables Stripe at the booking checkout
  - `payment_methods_ARRAY_stripe` (+ redirect message) — booking method label
  - ALTERs `bookings` / `bookings_payments` `payment_method` enums to add `stripe`
- `controllers/pjStripe.controller.php` — createOrder / confirm / save / form +
  admin transactions grid. `createOrder` builds the Stripe success URL from a
  `notify_url` passed per surface, so one plugin serves both confirm handlers.
- `models/pjStripe.model.php`, `views/pjStripe/*`, `web/js/pjStripe.js`

Wiring (additions only, no lines removed)

Surface 1 — listing payments
- `app/config/options.inc.php` — `pjStripe` registered
- `app/controllers/pjListings.controller.php` — `pjActionConfirmStripe()` (listing
  return handler; reuses the exact `pjActionConfirmPayment` insert + `status='E'` +
  `expire` extension logic)
- `app/controllers/pjAdminListings.controller.php` — `pjActionGetStripeForm()`
- `app/views/pjAdminListings/pjActionGetStripeForm.php` — renders the Stripe form
- `app/views/pjAdminListings/pjActionPayment.php` — "Pay with Stripe" button + container
- `app/web/js/pjAdminListings.js` — click handler

Surface 2 — front bookings
- `app/controllers/pjListings.controller.php` — `case 'stripe'` in the booking
  `pjActionGetPaymentForm` switch + `pjActionConfirmStripeBooking()` (booking return
  handler; reuses the `pjActionConfirmPaypal` status + `bookings_payments` paid +
  email logic)
- `templates/{layout1,layout2,layout3,website}/pjActionGetPaymentForm.php` —
  `case 'stripe'` renders the redirect form
- `app/views/pjAdminOptions/pjActionBooking.php` — Stripe key rows grouped under the
  Allow-Stripe toggle
- `app/web/js/pjAdminOptions.js` — show/hide those rows on toggle
- (No reserve-template edit needed: the checkout `<select>` auto-lists Stripe once
  `o_allow_stripe = Yes`, because it renders every payment method not set to "No".)

## Install

1. Deploy this project (or copy it over your existing v3.1 tree).
2. Run the plugin SQL (prefix-less, like pjPaypal; the `yachtlisting_` prefix is
   applied on install — add it by hand if running raw SQL):
   - `app/plugins/pjStripe/config/database.sql`
   - `app/plugins/pjStripe/config/updates/update_2026_07_07_10_00_00.sql`
3. Add `'pjStripe'` to the plugins array in your `app/config/config.inc.php` and
   `app/config/config.sample.php` (internal defaults in `options.inc.php` already updated).
4. Admin → Options → Payments (tab): enter the Stripe Publishable + Secret keys.
   Set **Allow Stripe payments = Yes** to offer Stripe at the front booking checkout.
   (The listing-payment "Pay with Stripe" button appears whenever the plugin is
   installed and keys are set.)

## Design note

PayPal here uses two accounts (a site account for listing fees via
`o_paypal_*`, and an "owner" account for bookings via `o_owner_paypal_*`). For
Stripe, both surfaces use one account (`o_stripe_*`), which is the common case and
keeps configuration simple. If you need a separate Stripe account for bookings, add
`o_owner_stripe_*` options and pass them in the booking `case 'stripe'` params — the
plugin already reads the key set from the params it's given.

## Notes

- Amounts convert to Stripe minor units, with zero-decimal currencies handled.
- All Stripe calls use the framework `pjHttp`; no third-party SDK is bundled.
- SQL couldn't be executed here (no database); it mirrors pjPaypal — run it against
  staging first.
- Test vs live is determined by the key prefix; there's no separate toggle.
