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
// 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
Validates configuration and creates a reusable client targeting https://obhco.ir/api/v1. Throws if run in a browser.
Creates a payment. Sends POST https://obhco.ir/api/v1/payments with an idempotency key.
Lists the gateways OBH offers for your checkout page. Sends GET https://obhco.ir/api/v1/gateways.
Retrieves one payment. Sends GET https://obhco.ir/api/v1/payments/{reference}.
Extracts the reference from return query params or a return URL and calls getPayment(reference).
Class OBHPaymentsError
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 OBHPaymentsErrorTypeScript types
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.
| Header | Value | Notes |
|---|---|---|
Authorization | Bearer svc_... | Required on every request. |
Content-Type | application/json | Required for POST. |
Accept | application/json | Set by the SDK. |
Idempotency-Key | 1–191 printable ASCII characters | Required for POST; scoped to the service. |
User-Agent | @obhco/payments/0.2.0 | Set by the SDK for diagnostics. |
Responses include a request identifier for support correlation. Errors use a single envelope, described below.
Create endpoint
/api/v1/payments{ "externalOrderId": "IG-8821", "amount": "245000000", "currency": "IRR", "description": "Annual design workspace", "returnUrl": "https://igraphical.ir/payments/return", "metadata": { "plan": "annual" }, "gateway": "sadad"}{ "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. checkoutUrlmay benullwhen the adapter does not use a redirect.- Pass
"simulator": true(or setOBH_SIMULATOR="true"when using the SDK) to route the payment to the OBH Sadad simulator instead of the live Sadad IPG. gatewayis optional and defaults to"sadad". Use a code fromGET /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.
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
/api/v1/payments/{reference}{ "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
{ "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.0targets APIv1.
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.