TypeScript SDK

The official TypeScript client — @crylabsorg/suward-sdk. A typed client over the full merchant API, plus WebhooksHelper for signature verification.

Install

terminal
npm install @crylabsorg/suward-sdk

Create a client

suward.ts
import { SuwardSDKClient } from "@crylabsorg/suward-sdk";
 
export const suward = new SuwardSDKClient({
  apiKey: process.env.SUWARD_API_KEY,   // server-side only
});

The quickstart flow, in TypeScript

checkout.ts
// 1 — create a payment for one order
const payment = await suward.payments.createPayment({
  amount: "100000000",                  // integer string, smallest unit
  asset: "TESTSTABLECOIN_OPTIMISM",
  externalId: order.id,                 // makes the call idempotent
});
 
// 2 — projects with an activation flow start the payment in pending/created,
//     with no address and no way into accepted until it is activated
if (payment.subStatus === "created") {
  await suward.payments.activatePayment({ paymentId: payment.id });
}
 
// 3 — send the customer to the hosted checkout
redirect(payment.paymentPageUrl);
 
// 4 — drive the lifecycle while you write the handler (test assets only)
await suward.payments.simulatePayment({
  paymentId: payment.id,
  status: "accepted",
  subStatus: "completed",
});
 
// 5 — read the authoritative state whenever you need it
const fresh = await suward.payments.getPayment({ paymentId: payment.id });

Quote before you create

quote.ts
const quote = await suward.payments.quotePaymentFees({
  asset: "USDT_ARBITRUM",
  amount: "100000000",
  serviceFeePayer: "customer",
  networkFeePayer: "customer",
  complianceLevel: "basic",
});
 
console.log(quote.gross, quote.netAmount, quote.fee, quote.networkFee);

Static wallets

wallets.ts
const wallet = await suward.staticWallets.createStaticWallet({
  externalId: `customer-${user.id}`,
  allowedAssets: ["USDT_ETHEREUM", "USDT_ARBITRUM"],
});
 
const deposits = await suward.staticWallets.listStaticWalletDeposits({ staticWalletId: wallet.id, limit: 100 });

Verify webhooks

webhook.ts
import { webhooks } from "@crylabsorg/suward-sdk";
 
const ok = await webhooks.WebhooksHelper.verifySignature(
  rawBody,                                 // string — never the parsed object
  headers["x-suward-signature"],
  process.env.SUWARD_WEBHOOK_PUBLIC_KEY,
  headers["x-suward-timestamp"]
);

The helper checks the X-Suward-Timestamp header against a 300-second tolerance as well as the signature, so pass the header through as received. Full handler, including the required deduplication on eventId → Webhooks.

Errors

errors.ts
import { SuwardSDKError } from "@crylabsorg/suward-sdk";
 
try {
  await suward.payments.createPayment({ amount: "0", asset: "USDT_ARBITRUM" });
} catch (e) {
  if (e instanceof SuwardSDKError) {
    const body = e.body as { errorCode?: number; message?: string } | undefined;
    console.error(e.statusCode, body?.errorCode, body?.message);
    if (e.statusCode === 409) { /* externalId already used — fetch it instead */ }
  }
  throw e;
}

Codes and retry rules → Errors & limits.

Something unclear? payments@suward.com — we treat every integration question as a documentation defect.