Skip to Content
Core ConceptsProviders

Providers

Hoikka uses a provider pattern for payments and shipping, making it easy to add new integrations.

Payment Providers

Interface

interface PaymentProvider { code: string; createPayment(order: Order): Promise<PaymentInfo>; confirmPayment(transactionId: string): Promise<PaymentStatus>; refundPayment?(transactionId: string, amount: number): Promise<RefundInfo>; }

Adding a Provider

src/lib/server/services/payments/providers/klarna.ts
export class KlarnaProvider implements PaymentProvider { code = "klarna"; async createPayment(order: Order): Promise<PaymentInfo> { // Create Klarna payment session const session = await klarnaClient.createSession({ amount: order.total, currency: "EUR" // ... }); return { transactionId: session.id, redirectUrl: session.redirect_url, status: "pending" }; } async confirmPayment(transactionId: string): Promise<PaymentStatus> { const payment = await klarnaClient.getPayment(transactionId); return payment.status === "CAPTURED" ? "settled" : "pending"; } }

Register it:

src/lib/server/services/payments/index.ts
import { KlarnaProvider } from "./providers/klarna"; PROVIDERS.set("klarna", new KlarnaProvider());

Enabling Stripe

Stripe is the built-in real payment provider. To enable it:

  1. Get API keys from Stripe Dashboard 
  2. Set environment variables:
STRIPE_SECRET_KEY="sk_test_..." PUBLIC_STRIPE_PUBLISHABLE_KEY="pk_test_..."

Stripe is already registered in the provider map and seeded in the database. Once the env vars are set, customers will see a card form powered by Stripe Elements at checkout.

Without Stripe keys, the mock payment provider is used instead. Mock payments complete the order immediately without a separate confirmation step.

Shipping Providers

Interface

interface ShippingProvider { code: string; getRates(order: Order): Promise<ShippingRate[]>; createShipment(order: Order): Promise<ShipmentInfo>; trackShipment?(trackingNumber: string): Promise<ShipmentStatus>; }

Adding a Provider

src/lib/server/services/shipping/providers/dhl.ts
export class DhlProvider implements ShippingProvider { code = "dhl"; async getRates(order: Order): Promise<ShippingRate[]> { const rates = await dhlClient.getRates({ from: WAREHOUSE_ADDRESS, to: order.shippingAddress, weight: calculateWeight(order) }); return rates.map((rate) => ({ id: rate.serviceCode, name: rate.serviceName, price: rate.totalPrice, estimatedDays: rate.transitDays })); } // ... other methods }

Register it:

src/lib/server/services/shipping/index.ts
import { DhlProvider } from "./providers/dhl"; PROVIDERS.set("dhl", new DhlProvider());

Then add a matching row to the shipping_methods table (or add it to initializeDefaultMethods()).

Built-in Providers

Payments

  • Stripe - Full integration with Payment Intents and Stripe Elements
  • Mock - For development/testing (auto-completes orders immediately)

Shipping

  • Flat Rate - Simple flat-rate shipping for development and demos
Last updated on