npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

bog-payments-sdk

v0.1.0

Published

Unofficial TypeScript SDK for the Bank of Georgia (BOG) E-Commerce Payments API

Downloads

38

Readme

bog-payments-sdk

Unofficial TypeScript SDK for the Bank of Georgia (BOG) E-Commerce Payments API.

Covers:

  • OAuth2 client-credentials authentication (token fetch + caching + auto-refresh)
  • Creating orders (POST /payments/v1/ecommerce/orders)
  • Fetching payment/receipt details (GET /payments/v1/receipt/:order_id)
  • Verifying and parsing async payment callbacks (RSA/SHA256 signature check)

Install

npm install bog-payments-sdk

Usage

import { BogClient } from "bog-payments-sdk";

const bog = new BogClient({
  clientId: process.env.BOG_CLIENT_ID!,
  clientSecret: process.env.BOG_CLIENT_SECRET!,
});

const order = await bog.orders.createOrder({
  callback_url: "https://example.com/bog/callback",
  external_order_id: "id123",
  purchase_units: {
    currency: "GEL",
    total_amount: 1,
    basket: [{ product_id: "product123", quantity: 1, unit_price: 1 }],
  },
  redirect_urls: {
    success: "https://example.com/success",
    fail: "https://example.com/fail",
  },
});

// Redirect the customer here to complete payment:
order._links.redirect.href;

Fetching payment details

const details = await bog.orders.getPaymentDetails(order.id);
details.order_status.key; // "completed" | "rejected" | ...

Handling callbacks

Verify the Callback-Signature header against the raw, unparsed request body before trusting the payload. Use your framework's raw-body middleware (do not let it be re-serialized — field order must be preserved).

import { parseVerifiedCallback } from "bog-payments-sdk";

// Express example, with a raw-body parser mounted only on this route:
app.post("/bog/callback", express.raw({ type: "application/json" }), (req, res) => {
  const signature = req.header("Callback-Signature");
  if (!signature) return res.sendStatus(400);

  try {
    const callback = parseVerifiedCallback(req.body, signature);
    // callback.body.order_id, callback.body.order_status, ...
  } catch {
    return res.sendStatus(400);
  }

  res.sendStatus(200);
});

If you only need a boolean check (e.g. you're parsing the body separately), use verifyCallbackSignature(rawBody, signature) instead.

Idempotency, locale, and theme

createOrder accepts a third options argument for the optional request headers:

await bog.orders.createOrder(request, {
  idempotencyKey: crypto.randomUUID(),
  acceptLanguage: "en",
  theme: "dark",
});

Buy Now Pay Later / Installment plan modal

The installment plan "loan calculator" modal (BOG.Calculator.open(...)) is a separate browser widget, loaded directly on your page — it is not part of this SDK:

<script src="https://webstatic.bog.ge/bog-sdk/bog-sdk.js?version=2&client_id={client_id}"></script>

This SDK covers the backend leg: once the customer picks an installment plan in the modal, its onRequest(selected, successCb, closeCb) callback fires with { amount, month, discount_code }. POST that to your backend, create the order via createLoanOrder, and return the resulting order id so the modal can continue:

// Frontend
BOG.Calculator.open({
  amount: 500,
  onRequest: (selected, successCb, closeCb) => {
    fetch("/api/bog/loan-order", {
      method: "POST",
      body: JSON.stringify(selected),
    })
      .then((res) => res.json())
      .then((data) => successCb(data.orderId))
      .catch(() => closeCb());
  },
  onComplete: ({ redirectUrl }) => {
    // customer is auto-redirected unless you return false here
  },
});
// Backend route (e.g. POST /api/bog/loan-order)
const order = await bog.orders.createLoanOrder(
  selected, // { amount, month, discount_code } from the modal
  {
    callback_url: "https://example.com/bog/callback",
    purchase_units: {
      basket: [{ product_id: "product123", quantity: 1, unit_price: selected.amount }],
    },
    redirect_urls: {
      success: "https://example.com/success",
      fail: "https://example.com/fail",
    },
  },
);

res.json({ orderId: order.id });

createLoanOrder sets config.loan = { type: discount_code, month } and defaults payment_method to ["bog_loan"] and purchase_units.total_amount to selected.amount — pass payment_method: ["bnpl"] in the request to use the Buy Now Pay Later plan instead, or override any other field as needed.

Google Pay™ on your own webpage

If you render the Google Pay button on your own webpage (instead of redirecting to the bank's hosted payment page), configure Google's PaymentRequest with:

{
  "type": "PAYMENT_GATEWAY",
  "parameters": {
    "gateway": "georgiancard",
    "gatewayMerchantId": "BCR2DN4TXKPITITV"
  }
}

Once the customer authorizes the payment, Google's SDK returns an encrypted payment token (paymentMethodData.tokenizationData.token). Pass it — full and unmodified — to createGooglePayOrder:

const order = await bog.orders.createGooglePayOrder(
  googlePayToken, // raw token string from the Google Pay SDK response
  {
    callback_url: "https://example.com/bog/callback",
    purchase_units: {
      currency: "GEL",
      total_amount: 1,
      basket: [{ product_id: "product123", quantity: 1, unit_price: 1 }],
    },
  },
);

if (order._links.redirect) {
  // 3DS authentication is required — redirect the customer to complete it
  order._links.redirect.href;
} else {
  // payment is already finalized
  order.status;
  order.order_details;
}

createGooglePayOrder sets payment_method: ["google_pay"] and config.google_pay = { external: true, google_pay_token: googlePayToken }. The response's _links.redirect is only present when 3DS authentication is required; otherwise the order completes immediately and status/order_details describe the result.

Response codes

payment_detail.code/code_description (and actions[].code/code_description) are bank-defined codes. The SDK ships lookup tables and helpers so you don't have to hardcode them:

import {
  isSuccessfulPaymentCode,
  getPaymentResponseCodeDescription,
  getActionResponseCodeDescription,
} from "bog-payments-sdk";

const details = await bog.orders.getPaymentDetails(orderId);

isSuccessfulPaymentCode(details.payment_detail?.code); // true for code "100"
getPaymentResponseCodeDescription(details.payment_detail?.code); // { en, ka } or undefined

details.actions?.forEach((action) => {
  getActionResponseCodeDescription(action.code); // { en, ka } or undefined, e.g. for refund failures
});

PAYMENT_RESPONSE_CODES and ACTION_RESPONSE_CODES are also exported directly if you need the full maps (e.g. to render a description in the customer's own response, server-side logging, etc).

Error handling

  • BogAuthError — thrown when the OAuth token request fails.
  • BogApiError — thrown when an Orders API call returns a non-2xx response. Carries status, body, and (when present) requestId.

Custom endpoints / sandbox

new BogClient({
  clientId,
  clientSecret,
  tokenUrl: "https://oauth2.bog.ge/auth/realms/bog/protocol/openid-connect/token",
  apiBaseUrl: "https://api.bog.ge/payments/v1",
});

License

MIT