# Integrate StableTerm into a Medusa v2 marketplace

You are an agent wiring a merchant Medusa app to **StableTerm hosted checkout**. Do only this. Do not invent a payment backend.

## Install the public package

```bash
npm install @stable_payments/medusa-payment
```

Access is the **merchant API key**, not a private npm org. There is no public SDK package yet.

## Register the provider

In `medusa-config.ts` (or `medusa-config.js`):

```ts
{
  resolve: "@stable_payments/medusa-payment",
  id: "stableterm",
  options: {
    apiKey: process.env.STABLETERM_API_KEY,
    webhookSecret: process.env.STABLETERM_WEBHOOK_SECRET,
    apiUrl: process.env.STABLETERM_API_URL, // https://checkout.stableterminal.co (no trailing slash)
    // Without a merchant API key this origin returns
    // {"error":{"code":"unauthorized","message":"La llave no corresponde a un comercio."}}
    // That is expected; it is not a health check.
  },
}
```

Set env (never commit secrets):

- `STABLETERM_API_KEY` — merchant secret (`st_test_…` or `st_live_…`)
- `STABLETERM_WEBHOOK_SECRET` — HMAC secret for `Stable-Signature`
- `STABLETERM_API_URL` — `https://checkout.stableterminal.co` (no trailing slash)

## Hosted checkout, not an in-cart rail

`initiatePayment` creates a session and returns `session.url`. The buyer pays on that **hosted** page (local rails or Celo USDC). The storefront labels the method **Pago con métodos locales**, opens that URL, and shows **Pago en proceso** until capture.

Pass Medusa `amount` and `currency_code` through unchanged. Optional `data.theme` styles the hosted page; omit it to keep the StableTerm look.

On `POST /v1/checkout/sessions` the marketplace **may** send `customer` or `payer` with `name`, `last_name`, `id_number`, `email`, and `address` (if both objects are present, `payer` wins). They are stored on `checkout_sessions`. The hosted page does not collect them. Omit the object or a field and that value is empty. `email` is included on the operator mismatch mail when the COP amount does not match.

## Webhooks

Point StableTerm at:

```text
https://<medusa-host>/hooks/payment/stableterm_stableterm
```

Until `checkout.session.confirmed`, `authorizePayment` stays `pending_authorization`. Then Medusa captures. Refunds are recorded; this package does not send funds.

## Do not

- Do not put API keys in git, chat, or the storefront bundle.
- Do not use `https://stableterminal.co` as `apiUrl`. Production checkout is `https://checkout.stableterminal.co`.

Package details: https://doc.stableterminal.co/adapters/medusa/
npm: https://www.npmjs.com/package/@stable_payments/medusa-payment
