OBHPayments
↑↓ navigate↵ openSearches titles and topics
Documentation

Documentation

OBH Payments SDK

A small, server-side TypeScript SDK for the versioned OBH payment API. It creates a payment, gives your customer a checkout URL, and tells you — authoritatively — whether that payment succeeded.

What this package is

@obhco/payments is the official client for talking to OBH from one of the connected services in the OBH ecosystem. If your application needs to charge a customer and record the result, this package is the supported path.

It is deliberately small. There are two operations, one response shape, and one error class. Everything else — provider accounts, credentials, verification, webhook delivery, accounting — lives on the OBH server, behind the API.

Create a payment

Send an order id, an amount, and a description. Receive a payment with a reference and, usually, a checkout URL.

Check the result

Fetch the payment by its OBH reference and read a status that was verified on the server, not in the browser.

Project status

Read this before planning an integration. The SDK is complete enough to review and to integrate in a test environment, but it has not been used for a real payment.

Package version0.1.0
Published to npmYes — @obhco/payments@0.1.0
EnvironmentTEST only
Real provider testedNo
RuntimeNode.js 20+
DependenciesNone at runtime

Do not treat this as production-ready

Version 0.1.0 has been tested against the local OBH API and the development adapter only. No real payment provider has been contacted, and LIVE credentials are not issued. Do not publish the package or promise live payments without an authorized environment test.

Sixty-second example

This is the entire integration in miniature. Create a client once at startup, create a payment when an order is placed, then verify the status on your server before fulfilling anything.

checkout.tsts
import { OBHPayments, isOBHPaymentsError } from "@obhco/payments" const obh = new OBHPayments({  secretKey: process.env.OBH_SERVICE_KEY!,}) export async function beginCheckout(orderId: string) {  try {    const payment = await obh.startPayment({      externalOrderId: orderId,      amount: "245000000",      currency: "IRR",      description: "Annual design workspace",      returnUrl: "https://igraphical.ir/payments/return",      metadata: { plan: "annual" },      // Stable per order attempt, so a retry cannot double-charge.      idempotencyKey: `order-${orderId}-attempt-1`,    })     // Store payment.reference with the order.    return payment.checkoutUrl  } catch (error) {    if (isOBHPaymentsError(error)) {      console.error(error.code, error.status, error.requestId)    }    throw error  }}
return-page.tsts
// Never trust ?status=completed in the return URL.const payment = await obh.getPayment(storedReference) if (payment.status === "completed") {  await markOrderPaid(payment.externalOrderId!)}

The two calls map to two HTTP endpoints: POST /api/v1/payments and GET /api/v1/payments/{reference}. You can use the SDK or call them directly — see the API reference.

The one rule: the server decides

A customer returning to your site does not prove that money moved. A query parameter does not prove it either. Only OBH’s server-side verification can set a payment to completed.

That is why the SDK has no browser build and refuses to construct in a browser. Your client-side code should redirect to checkoutUrl and then show a waiting screen; the authoritative decision happens in a server process.

A useful habit

Write your return page as if it were an untrusted stranger: read the stored reference, call getPayment, and branch only on the returned status. Treat the URL as a hint about which order to look at, never as evidence.

Design principles

Server-side by default

The constructor throws in a browser. Credentials never leave your backend.

Verification beats redirects

Statuses come from OBH after provider verification, not from the return URL.

Safe retries

Every create request carries an idempotency key, so retries return the original payment.

Small, typed surface

Two methods, explicit types, and one error class with machine-readable codes.

What is in the box

  • OBHPayments — the client, configured once with your service credential.
  • startPayment() — creates a payment and returns a checkout URL when the provider needs one.
  • getPayment() — reads one payment by its OBH reference.
  • OBHPaymentsError and isOBHPaymentsError() — typed failures with code, status, requestId, details, and retryable.
  • Types: Payment, StartPaymentInput, OBHPaymentsOptions, and PaymentStatus.

Runtime dependencies: none. It uses the platform fetch, AbortController, and crypto.randomUUID.

What is not in the box

  • Provider adapters, provider credentials, or provider SDKs.
  • Database access, refunds, subscriptions, or invoices.
  • Webhook signature verification — that is your job, with your secret.
  • Cancellation, capture, or partial refunds. The API exposes none of these.
  • Browser support. There is no browser entrypoint.

Those boundaries are intentional: they keep provider secrets and financial state on the OBH server, where they can be verified and audited.

Next steps