Moosyl logo

TypeScript SDK

Use moosyl-sdk in TypeScript and Node.js to create checkout sessions, manage subscriptions and verify webhook signatures.

moosyl-sdk is the official client for Node.js and other TypeScript/JavaScript servers. It wraps the Moosyl API with typed methods.

Install

npm install moosyl-sdk

Set up the client

Create one client with your API key. Use your secret key on your server; most methods need it.

import { Moosyl } from "moosyl-sdk";

const moosyl = new Moosyl(process.env.MOOSYL_SECRET_KEY!);

The key decides the environment: a key from your Sandbox environment talks to the sandbox, a Production key to production. See API keys.

Accept a payment

The quickest way is a hosted checkout session. Create it on your server and redirect the customer to checkoutUrl:

const { data: session, checkoutUrl } = await moosyl.createCheckoutSession({
  transactionId: "order_1043",
  amount: 2500,
  phoneNumber: "22222222",
  successUrl: "https://example.com/orders/1043/paid",
  cancelUrl: "https://example.com/orders/1043",
  expiresInMinutes: 30,
});

To use an existing payment request instead, pass paymentRequestId in place of transactionId, amount and phoneNumber. See Checkout Session for all the options.

Creating a payment request

The SDK has no method for POST /payment-request. If you show the payment UI in your own app (Flutter or React Native) instead of hosted checkout, create the payment request with an HTTP call:

const res = await fetch("https://api.moosyl.com/payment-request", {
  method: "POST",
  headers: {
    Authorization: process.env.MOOSYL_SECRET_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ transactionId: "order_1043", amount: 2500 }),
});
const { data: paymentRequest } = await res.json();

Handle webhooks

constructWebhookEvent verifies the x-webhook-signature header against your webhook secret and returns a typed { event, data }. Pass the raw request body.

import { WebhookSignatureError } from "moosyl-sdk";

try {
  const { event, data } = moosyl.constructWebhookEvent(
    rawBody,
    signatureHeader,
    process.env.MOOSYL_WEBHOOK_SECRET!
  );
  // event: "payment-created" | "payment-updated" | "payment-request-created"
  //   | "payment-request-updated" | "subscription-created" | "subscription-updated"
} catch (error) {
  if (error instanceof WebhookSignatureError) {
    // reject with 401
  }
}

If you only need a yes/no answer, verifyWebhookSignature(rawBody, signatureHeader, secret) returns a boolean. See Webhooks for a full Express example.

Methods

Payments

MethodKeyWhat it does
createCheckoutSession(request)SecretCreates a hosted checkout session. Returns { data, checkoutUrl }.
getPayment(paymentId)SecretFetches a payment. The payment is in the response's data.
getPaymentRequest(transactionId)EitherFetches a payment request by your transactionId: id, amount, phoneNumber.
getPaymentMethods(isTestingMode)EitherLists the bank apps enabled for your environment. The environment comes from your key, so the argument has no effect.
pay(transactionId, phoneNumber, passCode, paymentMethodId)EitherSubmits a payment with a method ID from getPaymentMethods. passCode is only used by Bankily; pass "" for other methods. Mostly used by in-app payment UIs.

Subscriptions

All of these need your secret key. See Subscriptions for how billing works.

MethodWhat it does
listProducts({ id?, page?, limit? })Products with their prices, paginated.
getProduct(id)One product with its prices.
createProduct({ name, description? })Creates a product.
updateProduct(id, { name?, description?, active? })Updates a product.
archiveProduct(id)Archives a product.
listCustomers({ id?, externalUserId?, page?, limit? })Customers, paginated.
createCustomer({ externalUserId, phone? })Creates a customer for one of your users.
updateCustomer(id, { externalUserId?, phone? })Updates a customer.
listSubscriptions({ status?, page?, limit? })Subscriptions, paginated.
getSubscription(id)One subscription.
createSubscription({ customerId, priceId, trial?, trialPeriod?, trialEnd?, startedAt?, expiresAt? })Subscribes a customer to a price.
createSubscriptionByExternalUser({ externalUserId, priceId, phone?, ... })Same, creating the customer if needed.
getSubscriptionByExternalUser(externalUserId)A user's subscription.
cancelSubscription(id)Cancels a subscription.
listInvoices({ id?, externalUserId?, subscriptionId?, page?, limit? })Invoices, paginated.

Prices have no SDK methods yet. Create them in the dashboard or with POST /prices (see Subscriptions).

List methods return { data, pagination }, where pagination has page, limit, total and totalPages.

Webhooks

MethodWhat it does
constructWebhookEvent(payload, signature, secret)Verifies and parses a webhook. Throws WebhookSignatureError.
verifyWebhookSignature(payload, signature, secret)Returns true if the signature is valid.

Errors

When a request fails, the SDK throws an error with:

  • message: what went wrong
  • status: the HTTP status, when the API responded
  • code: for example connection_error, timeout or invalid_api_key
try {
  await moosyl.getSubscription(id);
} catch (error) {
  const { status, message } = error as { status?: number; message: string };
  console.error("Moosyl request failed", status, message);
}

Next steps