Stable Terminal

@stable_payments/medusa-payment

Public Medusa v2 provider. The buyer pays on hosted checkout (USDC or local rails). The merchant receives USDC. This package does not move crypto or fiat.

Integrator agent prompt: https://doc.stableterminal.co/adapters/medusa/prompt/ (raw prompt.md).

Install

npm install @stable_payments/medusa-payment

Peer: @medusajs/framework ^2.21.2.

apiUrl

Production is only https://checkout.stableterminal.co (no trailing slash). Set STABLETERM_API_URL to that origin. Do not use the apex https://stableterminal.co as apiUrl.

Hitting the checkout origin without a merchant API key returns {"error":{"code":"unauthorized","message":"La llave no corresponde a un comercio."}}. That is expected. It is not a health check.

medusa-config.ts

module.exports = defineConfig({
  modules: [
    {
      resolve: "@medusajs/medusa/payment",
      options: {
        providers: [
          {
            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,
            },
          },
        ],
      },
    },
  ],
})

initiatePayment

Posts data.payer or data.customer on POST /v1/checkout/sessions. If both are set, payer wins. Fields: name, last_name, id_number, email, address. If neither object is present, Medusa context.customer is sent as customer with email and name.

Webhook

https://<your-medusa-host>/hooks/payment/stableterm_stableterm

Confirmed funds arrive as checkout.session.confirmed, signed with Stable-Signature. Until then authorizePayment stays pending_authorization.