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-sdkSet 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
| Method | Key | What it does |
|---|---|---|
createCheckoutSession(request) | Secret | Creates a hosted checkout session. Returns { data, checkoutUrl }. |
getPayment(paymentId) | Secret | Fetches a payment. The payment is in the response's data. |
getPaymentRequest(transactionId) | Either | Fetches a payment request by your transactionId: id, amount, phoneNumber. |
getPaymentMethods(isTestingMode) | Either | Lists the bank apps enabled for your environment. The environment comes from your key, so the argument has no effect. |
pay(transactionId, phoneNumber, passCode, paymentMethodId) | Either | Submits 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.
| Method | What 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
| Method | What 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 wrongstatus: the HTTP status, when the API respondedcode: for exampleconnection_error,timeoutorinvalid_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);
}