OBHPayments
↑↓ navigate↵ openSearches titles and topics
Documentation

Reference

API reference

The SDK is a thin, typed layer over two HTTP endpoints. This page is the exhaustive reference for both layers — useful when you need a detail, or when you cannot use the SDK.

SDK surface

ts
// Package exportsexport { OBHPayments } from "@obhco/payments"export { OBHPaymentsError, isOBHPaymentsError } from "@obhco/payments"export type {  APIErrorDetail,  APIErrorEnvelope,  ListGatewaysOptions,  OBHPaymentsOptions,  Payment,  PaymentEnvironment,  PaymentGateway,  PaymentGatewayCode,  PaymentGatewayKind,  PaymentReceipt,  PaymentStatus,  StartPaymentInput,  VerifyReturnInput,} from "@obhco/payments"

Class OBHPayments

new OBHPayments(options)

Validates configuration and creates a reusable client targeting https://obhco.ir/api/v1. Throws if run in a browser.

startPayment(input): Promise<Payment>

Creates a payment. Sends POST https://obhco.ir/api/v1/payments with an idempotency key.

listGateways(options?): Promise<PaymentGateway[]>

Lists the gateways OBH offers for your checkout page. Sends GET https://obhco.ir/api/v1/gateways.

getPayment(reference): Promise<Payment>

Retrieves one payment. Sends GET https://obhco.ir/api/v1/payments/{reference}.

verifyReturn(input): Promise<Payment>

Extracts the reference from return query params or a return URL and calls getPayment(reference).

Class OBHPaymentsError

ts
class OBHPaymentsError extends Error {  readonly code: string  readonly status?: number  readonly requestId?: string  readonly details?: APIErrorDetail[]  readonly retryable: boolean  cause?: unknown} function isOBHPaymentsError(error: unknown): error is OBHPaymentsError

TypeScript types

@obhco/paymentsts
type PaymentStatus =  | "pending"  | "completed"  | "failed"  | "cancelled"  | "expired" type PaymentEnvironment = "test" | "live" type PaymentGatewayCode = "sadad" | "zarinpal" | "mellat" | "digipay" | (string & {}) type PaymentGatewayKind = "card" | "installment" type PaymentGateway = {  code: PaymentGatewayCode  name: string  displayName: string // Persian label for checkout  description: string  kind: PaymentGatewayKind  requiresCustomerMobile: boolean  minAmount: string | null  isDefault: boolean  environment: PaymentEnvironment} type ListGatewaysOptions = {  simulator?: boolean} type PaymentReceipt = {  orderNumber: string | null  traceNumber: string | null  referenceNumber: string | null  maskedCardNumber: string | null  resultCode: string | null  resultMessage: string | null} type Payment = {  id: string  reference: string  service: string  externalOrderId: string | null  amount: string  currency: string  environment: PaymentEnvironment  gateway: PaymentGatewayCode  status: PaymentStatus  description: string  checkoutUrl: string | null  receipt: PaymentReceipt  createdAt: string  completedAt: string | null  verifiedAt: string | null} type StartPaymentInput = {  externalOrderId: string  amount: string  currency?: "IRR"  description: string  returnUrl?: string  metadata?: Record<string, unknown>  gateway?: PaymentGatewayCode // default "sadad"  customerMobile?: string // required by Digipay  idempotencyKey?: string  simulator?: boolean} type VerifyReturnInput =  | string  | URL  | URLSearchParams  | Record<string, string | string[] | undefined> type OBHPaymentsOptions = {  secretKey: string  /** Optional override. Defaults to "https://obhco.ir/api/v1". */  baseUrl?: string  timeoutMs?: number  fetch?: typeof fetch  simulator?: boolean} type APIErrorDetail = {  field?: string  message: string} type APIErrorEnvelope = {  error?: {    code?: string    message?: string    requestId?: string    details?: APIErrorDetail[]  }}

Runtime validation is intentionally shallow

The SDK checks that a successful response looks like a Payment — required strings, a known status, a known environment. It does not do full schema validation. Unknown fields are passed through and should be ignored.

HTTP API

Base URL: https://obhco.ir/api/v1. Transport is HTTPS and content is UTF-8 JSON.

HeaderValueNotes
AuthorizationBearer svc_...Required on every request.
Content-Typeapplication/jsonRequired for POST.
Acceptapplication/jsonSet by the SDK.
Idempotency-Key1–191 printable ASCII charactersRequired for POST; scoped to the service.
User-Agent@obhco/payments/0.2.0Set by the SDK for diagnostics.

Responses include a request identifier for support correlation. Errors use a single envelope, described below.

Create endpoint

POST/api/v1/payments
Requestjson
{  "externalOrderId": "IG-8821",  "amount": "245000000",  "currency": "IRR",  "description": "Annual design workspace",  "returnUrl": "https://igraphical.ir/payments/return",  "metadata": { "plan": "annual" },  "gateway": "sadad"}
201 Createdjson
{  "data": {    "id": "018f0000-0000-7000-8000-000000000001",    "reference": "OBH-8B30F9C07A52D1E4",    "service": "igraphical",    "externalOrderId": "IG-8821",    "amount": "245000000",    "currency": "IRR",    "environment": "live",    "gateway": "sadad",    "status": "pending",    "description": "Annual design workspace",    "checkoutUrl": "https://sadad.shaparak.ir/VPG/Purchase?Token=...",    "receipt": {      "orderNumber": "1042",      "traceNumber": null,      "referenceNumber": null,      "maskedCardNumber": null,      "resultCode": "0",      "resultMessage": null    },    "createdAt": "2026-10-18T08:00:00.000Z",    "completedAt": null,    "verifiedAt": null  }}
  • 201 — a new payment was created.
  • 200 — idempotent replay. The response includes Idempotent-Replayed: true.
  • checkoutUrl may be null when the adapter does not use a redirect.
  • Pass "simulator": true (or set OBH_SIMULATOR="true" when using the SDK) to route the payment to the OBH Sadad simulator instead of the live Sadad IPG.
  • gateway is optional and defaults to "sadad". Use a code from GET /api/v1/gateways. Digipay ("digipay") also needs "customer": { "mobile": "09121234567" }. See Gateways & installments.
  • The OBH reference is generated by OBH and sent to the provider only through server-side integration.
curlbash
curl -sS https://obhco.ir/api/v1/payments \  -H "Authorization: Bearer $OBH_SERVICE_KEY" \  -H "Content-Type: application/json" \  -H "Idempotency-Key: order-IG-8821-attempt-1" \  -d '{    "externalOrderId": "IG-8821",    "amount": "245000000",    "currency": "IRR",    "description": "Annual design workspace"  }'

Retrieve endpoint

GET/api/v1/payments/{reference}
200 OKjson
{  "data": {    "reference": "OBH-8B30F9C07A52D1E4",    "status": "completed",    "completedAt": "2026-10-18T08:04:10.000Z",    "verifiedAt": "2026-10-18T08:04:10.000Z"  }}
  • Returns only payments belonging to the authenticated service.
  • Unknown references and other services’ references both return 404 PAYMENT_NOT_FOUND.
  • The status is authoritative only after server-side provider verification.
  • The SDK encodes the reference before building the URL. Encode it yourself if you call the API directly.

Error envelope

Any non-2xxjson
{  "error": {    "code": "VALIDATION_ERROR",    "message": "The request could not be validated.",    "requestId": "req_01J9Z6K3T4QW8M2",    "details": [      {        "field": "amount",        "message": "Amount must be greater than zero."      }    ]  }}

The SDK maps this envelope to OBHPaymentsError. See Errors for every code and the retry rules.

Versioning

  • The base path carries the major version: /api/v1.
  • Adding response fields is backward-compatible and does not require a new version.
  • Breaking changes require a new API version.
  • The SDK version is independent of the API version. Package 0.1.0 targets API v1.

Not implemented yet

There is no endpoint for cancellation, refunds, captures, or listing payments. Do not design around them. Rate limiting is reserved (429) but not enforced.