# Kling Payments for WooCommerce

Accept payments in Iceland via Kling — card payments with hosted or embedded checkout.

## Installation (for merchants)

### Option 1 — Upload via WordPress Admin

1. Download `kling-payments-<version>.zip`
2. In WordPress Admin, go to **Plugins → Add New → Upload Plugin**
3. Select the ZIP, click **Install Now**, then **Activate**
4. Go to **WooCommerce → Settings → Payments → Kling**
5. Paste your Secret API Key (from the [Kling Dashboard](https://kling.is/dashboard/settings/api-keys))
6. Enable the gateway and save

### Option 2 — Manual install

1. Unzip the plugin
2. Upload the `kling-payments/` folder to `wp-content/plugins/`
3. Activate in **Plugins** and configure under **WooCommerce → Settings → Payments → Kling**

## Settings

| Setting | Description |
|---|---|
| Title | Payment method name shown at checkout |
| Description | Text shown below the payment method |
| Secret API Key | `sk_test_…` for testing, `sk_live_…` for production |
| Checkout mode | **Embedded** (overlay) or **Redirect** (hosted page) |
| Checkout language | Auto / Icelandic / English |
| Webhook secret | Signing secret of the Kling webhook that confirms orders (see below) |

## Webhook (recommended)

The thank-you page verifies a payment when the customer returns to the shop. The
webhook confirms it even when they do not, for example when they close the tab
on the bank's 3-D Secure page.

1. In the Kling dashboard go to **Notifications → Webhooks** and add an endpoint:
   `https://<your-shop>/wp-json/kling/v1/webhook`
2. Subscribe it to **`checkout.session.completed`**
3. Copy the endpoint's signing secret into **WooCommerce → Settings → Payments → Kling → Webhook secret**

Every delivery is verified with `X-Kling-Signature` (HMAC-SHA256 over the raw
body) and then re-checked against the Kling API before the order is marked paid,
so a forged or replayed request cannot complete an order. Pretty permalinks must be
enabled for `/wp-json/` routes to resolve.

## Subscriptions

Any simple product can be sold as a recurring subscription, billed by Kling. No
WooCommerce Subscriptions extension is needed.

1. Edit the product → **General** → tick **Kling subscription**, choose the
   **billing interval** (week / month / year) and **every N intervals** (e.g. month + 1).
2. The customer buys it like any other product. A subscription checks out on its
   own (one product, quantity one); the cart enforces this.
3. Kling creates a matching subscription product (cached on the WooCommerce
   product; a price change creates a fresh one, existing subscribers keep theirs),
   starts the subscription at checkout, and owns the schedule, card updates and
   failed-payment retries.
4. Every renewal Kling charges arrives as `subscription.renewed` on the webhook and
   becomes a **new, already paid WooCommerce order** (created via `kling-renewal`,
   linked to the original through `_kling_renewal_of`), ready for fulfilment.
   Redeliveries are ignored (idempotent on the payment intent). The charge is
   re-checked against the API before the order is created.
5. The customer gets a **Manage subscription** button on the order (thank-you page
   and My Account) that opens Kling's billing portal: change card, cancel.
   `subscription.canceled` and `subscription.payment_failed` add notes to the
   original order.

Subscribe the webhook to `checkout.session.completed`, `subscription.renewed`,
`subscription.canceled` and `subscription.payment_failed`.

## How an order gets marked paid

Both paths (thank-you page and webhook) run the same check: fetch the session the
order stored at checkout, require it `complete`, take its payment intent, require
`captured` and an amount equal to the order total, then `payment_complete()`.
A bank-claim checkout (`awaiting_claim`) puts the order **on hold** instead.

## Changelog

- **1.4.0** — Subscriptions: per-product Kling subscription flag + interval, subscription
  checkout, renewal orders from `subscription.renewed`, Manage-subscription button
  (billing portal), cancel/failed notes.

- **1.3.0** — Webhook receiver (`/wp-json/kling/v1/webhook`) confirms orders without the
  customer returning; bank-claim checkouts hold the order.
- **1.2.0** — Orders are marked paid again: verification now starts from the stored
  checkout session (works in redirect mode, where Kling appends `session_id`), uses the
  `/v1/payment-intents/` route, and sends the currency code in upper case.
- **1.1.0** — Embedded checkout mode, HPOS compatibility.

A "TEST MODE" badge is shown automatically when using an `sk_test_…` key.

## Building the plugin

```bash
./build.sh
```

Outputs `dist/kling-payments-<version>.zip` ready to distribute.

## Distribution options

- **Direct download** — Host the ZIP on kling.is and link from the dashboard
- **GitHub Releases** — Tag releases, attach the ZIP; users download from there
- **WordPress.org Plugin Directory** — Submit via [wordpress.org/plugins/developers/add](https://wordpress.org/plugins/developers/add/). Requires SVN workflow and a `readme.txt` in WP-style format. Biggest reach — users install it from inside WP Admin with no file upload.

## Local testing (for development)

```bash
docker compose up -d
```

Visit http://localhost:8080, log in as `admin` / `admin`.

> **Note**: The **embedded** checkout does not work on `localhost` because browsers block public→private network access from the Kling iframe. Use **redirect mode** for localhost testing.

## Features

- Hosted redirect checkout or embedded overlay
- Pre-fills customer email, name, and phone from WooCommerce billing fields
- Language selection (Icelandic / English / auto)
- Stores Kling session ID and payment intent ID on the order for traceability
- Server-side payment verification on the thank-you page (fetches the payment intent from Kling and checks status + amount + session match before marking the order paid)
- Idempotency keys on checkout session creation (safe to retry on flaky networks)
- HPOS (High-Performance Order Storage) compatible
- Auto-detects test mode from API key prefix

### Webhooks

This version does **not** consume Kling webhooks — payment confirmation happens synchronously on the thank-you page via a server-side API check. Webhook support will be added in a future version when async flows (e.g. subscriptions) are needed.

## File structure

```
kling-payments.php     — Main plugin file
assets/kling-logo.svg  — Payment method icon
README.md              — This file
build.sh               — Build script (produces dist/*.zip)
docker-compose.yml     — Local dev environment
```
