Moonbase Documentation

Backend Plugin Context

What the backend ctx object provides.

Every backend plugin gets a PluginContext object.

Context map

  • app: Express app instance.
  • env: process.env.
  • logger: Moonbase logger.
  • hooks: backend hooks including onRoutesReady, onPurchaseFulfilled, and onShutdown.
  • paths: rootDir, pluginsDir.
  • routers.api
  • routers.dashboard
  • routers.purchase
  • services.API (database access)
  • services.stripe
  • services.coinbaseCommerce
  • services.paypalCheckout
  • services.emailService
  • modules.purchase (route module; can still be wrapped or patched)
  • core.controllers, core.models, core.helpers, core.utils

Preferred purchase integration point

If your plugin only needs to run after a checkout is fulfilled, use ctx.hooks.onPurchaseFulfilled(...). Reach for ctx.modules.purchase only when you truly need to wrap provider-specific behavior.

Examples

module.exports = {
  name: 'status-endpoint',
  register(ctx) {
    ctx.routers.api.get('/plugins/status', (_req, res) => {
      res.json({ status_overview: 'success', status_message: 'OK' });
    });
  }
};
module.exports = {
  name: 'provisioner',
  register(ctx) {
    ctx.hooks.onPurchaseFulfilled(async (payload) => {
      for (const item of payload.items) {
        if (item.product.slug !== 'game-server-basic') continue;

        ctx.logger.info('provisioning server', {
          user: payload.user.email,
          product: item.product.slug,
          plan: item.plan,
          quantity: item.quantity
        });
      }
    });
  }
};
module.exports = {
  name: 'stripe-tagger',
  register(ctx) {
    const original = ctx.services.stripe.checkout.sessions.create.bind(
      ctx.services.stripe.checkout.sessions
    );
    ctx.services.stripe.checkout.sessions.create = async (params, options) => {
      return original({ ...params, metadata: { ...params.metadata, tag: 'plugin' } }, options);
    };
  }
};

On this page