@hypay/typescript-sdk
v1.0.1
Published
TypeScript SDK for the Hypay API
Maintainers
Readme
@hypay/typescript-sdk
A fully typed, production-ready TypeScript SDK for the Hyp Pay payment gateway API (Israel).
Features
- Pay Protocol — Generate signed payment page URLs with tamper-proof signatures
- Signature Verification — Verify transactions from success/failure redirect pages
- Soft Protocol — Server-side transactions with tokens, Apple Pay, and Google Pay
- Token Management — Obtain and reuse tokens for recurring charges (auto-parses Tokef)
- J5 Transactions — Reserve and later charge credit lines
- Postpone Transactions — Create delayed charges and commit them within 72 hours
- Cancel & Refund — Cancel same-day transactions or refund by transaction ID / token
- Subscriptions (HK) — Create standing orders with initial payments, terminate/activate
- EzCount Invoices — Generate signed invoice URLs, build item strings with validation
- Offline Invoices — Cash, Check, and Multi-check invoice creation
- Error Handling — Typed errors with full Hypay + Shva EMV error code mappings
- Production Ready — Timeouts, custom fetch, lifecycle hooks, Israeli ID validation
- Tree-shakable — ESM + CJS dual output, zero runtime dependencies
Installation
npm install @hypay/typescript-sdkRequirements: Node.js >= 18 (uses native fetch)
Quick Start
import { HypayClient, Coin, PageLang } from "@hypay/typescript-sdk";
const client = new HypayClient({
masof: "0010131918", // Terminal number (10 digits)
apiKey: "your-api-key", // API key from Settings > Terminal Settings
passP: "your-password", // PassP from terminal settings
});Pay Protocol — Payment Page
Step 1 + 2: Create a Signed Payment Page URL
const url = await client.createPaymentPageUrl({
Info: "Order #12345",
Amount: 100,
UserId: "203269535",
ClientName: "Israel",
ClientLName: "Israeli",
email: "[email protected]",
phone: "098610338",
cell: "0505555555",
street: "Levanon 3",
city: "Netanya",
zip: "42361",
Tash: 2,
Coin: Coin.ILS,
PageLang: PageLang.HEB,
tmp: 1,
MoreData: true,
Sign: true,
UTF8: true,
UTF8out: true,
sendemail: true,
});
// Redirect the customer to `url`Step 1 only: Sign Parameters (for custom URL building)
const result = await client.sign({
Info: "Order #123",
Amount: 100,
// ...
});
console.log(result.signature); // The signature hash
console.log(result.raw); // Full signed query string
// Build the URL yourself
const paymentUrl = client.buildPaymentPageUrl(result.raw);Step 3: Handle Success Redirect
When the customer completes payment, they're redirected to your success page with transaction parameters in the URL.
import { parsePaymentPageResponse } from "@hypay/typescript-sdk";
// In your success page handler:
const response = parsePaymentPageResponse(req.url);
console.log(response.Id); // Transaction ID
console.log(response.CCode); // "0" = success
console.log(response.Amount); // Amount charged
console.log(response.ACode); // Confirmation code
console.log(response.L4digit); // Last 4 digits (when MoreData=True)
console.log(response.Bank); // Acquirer (when MoreData=True)Step 4: Verify Transaction Signature
// Option A: Verify from parsed parameters
import { parseRedirectUrl } from "@hypay/typescript-sdk";
const params = parseRedirectUrl(req.url);
const result = await client.verify(params);
if (result.verified) {
// Transaction is legitimate — process the order
} else {
// CCode=902 — verification failed, do NOT process
}
// Option B: Verify directly from URL
const result = await client.verifyRedirectUrl(req.url);
if (result.verified) { /* OK */ }Soft Protocol — Server-Side Transactions
Token-Based Transaction
const result = await client.soft({
CC: "1315872608557940000", // Token (19 digits)
Tmonth: "04",
Tyear: "2025",
Amount: 50,
Info: "Subscription renewal",
UserId: "203269535",
ClientName: "Israel",
ClientLName: "Israeli",
email: "[email protected]",
Coin: Coin.ILS,
Token: true,
MoreData: true,
UTF8: true,
UTF8out: true,
sendemail: true,
});
console.log(result.Id); // Transaction ID
console.log(result.ACode); // Confirmation code
console.log(result.UID); // UID for J5 charge
// Access MoreData fields via result.params:
console.log(result.params.Bank); // Acquirer
console.log(result.params.Brand); // Card brand
console.log(result.params.L4digit); // Last 4 digitsApple Pay / Google Pay
const result = await client.soft({
WalletToken: walletTokenJsonString, // From Apple Pay / Google Pay SDK
Amount: 100,
Info: "Purchase",
UserId: "203269535",
ClientName: "Israel",
Coin: Coin.ILS,
MoreData: true,
UTF8: true,
UTF8out: true,
});Token Management
Get a Token
const token = await client.getToken({
TransId: "12788261",
Fild1: "customer-123", // Your reference (not saved in Hypay)
});
console.log(token.Token); // "1315872608557940000" (19 digits)
console.log(token.Tokef); // "2504" (YYMM format)
console.log(token.Tmonth); // "04" (auto-parsed)
console.log(token.Tyear); // "2025" (auto-parsed)
// Save token.Token, token.Tmonth, token.Tyear, and customer details
// (Hypay does NOT store user info or card validity with the token)Use Token in a Soft Transaction
await client.soft({
CC: token.Token,
Tmonth: token.Tmonth,
Tyear: token.Tyear,
Token: true,
Amount: 50,
Info: "Monthly charge",
UserId: savedUserId,
ClientName: savedName,
});Cross-Terminal Token Usage
await client.soft({
CC: token.Token,
Tmonth: token.Tmonth,
Tyear: token.Tyear,
Token: true,
tOwner: "0010020610", // Terminal that owns the token
Amount: 50,
Info: "Cross-terminal charge",
UserId: "203269535",
ClientName: "Israel",
});Manual Tokef Parsing
import { parseTokef } from "@hypay/typescript-sdk";
const { Tmonth, Tyear } = parseTokef("2504");
// Tmonth = "04", Tyear = "2025"J5 Transaction — Credit Line Reservation
Reserve a Credit Line
const reservation = await client.soft({
CC: token.Token,
Tmonth: token.Tmonth,
Tyear: token.Tyear,
Token: true,
J5: true, // Reserve credit line
MoreData: true, // Required to get UID
Amount: 100,
Info: "Hotel reservation",
UserId: "203269535",
ClientName: "Israel",
});
// Save reservation.UID and reservation.ACodeCharge the Reservation (amount <= original)
const charge = await client.chargeJ5(
{
CC: token.Token,
Tmonth: token.Tmonth,
Tyear: token.Tyear,
Token: true,
Amount: 80,
Info: "Hotel checkout",
UserId: "203269535",
ClientName: "Israel",
},
{
"inputObj.originalUid": reservation.UID!,
"inputObj.originalAmount": 8000, // 80 ILS in agorot
AuthNum: reservation.ACode,
"inputObj.authorizationCodeManpik": 7,
}
);Postpone Transaction
Create a Postponed Transaction
const postponed = await client.soft({
CC: token.Token,
Tmonth: token.Tmonth,
Tyear: token.Tyear,
Token: true,
Postpone: true,
Amount: 100,
Info: "Pending order verification",
UserId: "203269535",
ClientName: "Israel",
MoreData: true,
});
// postponed.CCode === "800" (valid postpone)Commit Within 72 Hours
const result = await client.commitTransaction({
TransId: postponed.Id,
SendHesh: true,
heshDesc: "Payment for order 1234",
UTF8: true,
UTF8out: true,
});
console.log(result.HeshASM); // Invoice number createdCancel & Refund
Cancel (Same Day, Before 23:20)
const result = await client.cancelTransaction({
TransId: "5890796",
});Refund by Transaction ID
const result = await client.refund({
TransId: "12290620",
Amount: 10,
Tash: 1,
SendHesh: true,
UTF8: true,
UTF8out: true,
});
console.log(result.Id); // New refund transaction ID
console.log(result.HeshASM); // Credit invoice numberRefund by Token (PAYout)
const result = await client.refundByToken({
CC: "6907500685494032346",
Tmonth: "04",
Tyear: "2023",
Amount: 2,
Info: "Refund for order 123",
zPass: "1234", // Secret refund password (sent to terminal owner's phone)
Token: true,
UserId: "000000000",
ClientName: "Israel",
SendHesh: true,
sendemail: true,
UTF8: true,
UTF8out: true,
});Subscriptions (HK Module)
Create a Subscription
const url = await client.createSubscriptionUrl({
Info: "Monthly subscription",
Amount: 120,
HK: true,
Tash: 999, // Unlimited payments
freq: 1, // Monthly
FirstDate: "2025-06-01",
OnlyOnApprove: true,
UserId: "203269535",
ClientName: "Israel",
email: "[email protected]",
Coin: Coin.ILS,
UTF8: true,
UTF8out: true,
Sign: true,
MoreData: true,
sendemail: true,
SendHesh: true,
});
// The success redirect URL will include HKId (agreement number)Subscription with Initial Payment
const url = await client.createSubscriptionWithInitialPayment({
Info: "Plan with setup fee",
Amount: 120, // Monthly recurring amount
HK: true,
Tash: 999,
freq: 1,
TashFirstPayment: 50, // Setup fee amount
FirstPaymentTash: 3, // Charge setup fee for 3 months
FixTash: true,
OnlyOnApprove: true,
UserId: "203269535",
ClientName: "Israel",
Coin: Coin.ILS,
UTF8: true,
UTF8out: true,
Sign: true,
MoreData: true,
});Terminate / Activate an Agreement
import { HKNewStatus } from "@hypay/typescript-sdk";
// Terminate
await client.terminateSubscription("64239");
// or: await client.updateHKStatus({ HKId: "64239", NewStat: HKNewStatus.Terminate });
// Reactivate
await client.activateSubscription("64239");
// or: await client.updateHKStatus({ HKId: "64239", NewStat: HKNewStatus.Activate });EzCount Invoices
Build Invoice Items
import { buildItemsString, calculateItemsTotal } from "@hypay/typescript-sdk";
const items = [
{ code: "001", description: "Widget A", quantity: 2, price: 50 },
{ code: "002", description: "Widget B", quantity: 1, price: 100 },
];
const heshDesc = buildItemsString(items);
// "[001~Widget A~2~50][002~Widget B~1~100]"
const total = calculateItemsTotal(items);
// 200 (must match Amount parameter)Get a Signed Invoice URL
const invoiceUrl = await client.getInvoiceUrl({
TransId: "55373520",
type: "EZCOUNT",
});
// Or for old system:
const pdfUrl = await client.getInvoiceUrl({
TransId: "55373520",
type: "PDF",
HeshORCopy: true, // Authentic copy
});Offline Invoices
Cash Invoice
const result = await client.createOfflineInvoice({
TransType: "Cash",
Info: "Cash payment",
Amount: 200,
UserId: "203269535",
ClientName: "Israel",
email: "[email protected]",
Pritim: true,
heshDesc: buildItemsString([
{ code: "001", description: "Product A", quantity: 2, price: 50 },
{ code: "002", description: "Product B", quantity: 1, price: 100 },
]),
SendHesh: true,
UTF8: true,
UTF8out: true,
});Check Invoice
const result = await client.createOfflineInvoice({
TransType: "Check",
Info: "Check payment",
Amount: 200,
Bank: "10",
Snif: "912",
PAN: "1234456",
CheckNum: "11111111",
Date: "20250211",
UserId: "203269535",
ClientName: "Israel",
SendHesh: true,
UTF8: true,
UTF8out: true,
});Multi-Check Invoice
const result = await client.createOfflineInvoice({
TransType: "Multi",
Info: "Multi-check payment",
Amount: 200, // Total
Bank: "10,12,11",
Snif: "912,826,921",
PAN: "1234456,1111111,222222",
CheckNum: "11111111,112223,3554568",
Date: "20250211,20250911,20251012",
UserId: "203269535",
ClientName: "Israel",
SendHesh: true,
UTF8: true,
UTF8out: true,
});Error Handling
Typed Errors
import { HypayError, HypayNetworkError, HypayTimeoutError } from "@hypay/typescript-sdk";
try {
await client.soft({ /* ... */ });
} catch (error) {
if (error instanceof HypayError) {
console.error(`CCode: ${error.code}`); // e.g., "902"
console.error(`Message: ${error.message}`); // "Authentication error..."
console.error(`Raw: ${error.raw}`); // Full response string
console.error(`Params:`, error.params); // Parsed response
} else if (error instanceof HypayTimeoutError) {
console.error(`Timeout after ${error.timeoutMs}ms`);
} else if (error instanceof HypayNetworkError) {
console.error(`Network error: ${error.message}`);
console.error(`Cause:`, error.cause);
}
}Error Code Utilities
import {
isSuccessCode,
isShvaError,
isHypayError,
getErrorMessage,
ALL_ERROR_CODES,
} from "@hypay/typescript-sdk";
isSuccessCode("0"); // true — Approved
isSuccessCode("800"); // true — Postponed (valid)
isSuccessCode("902"); // false — Authentication error
isShvaError("6"); // true — Incorrect CVV (Shva)
isHypayError("902"); // true — Authentication error (Hypay)
getErrorMessage("902"); // "Authentication error — reference differs from configured method"
getErrorMessage("6"); // "Incorrect ID or CVV"Validation Helpers
import {
isValidMasof,
isTestMasof,
isValidToken,
isValidEmail,
isValidIsraeliId,
} from "@hypay/typescript-sdk";
isValidMasof("0010131918"); // true (10 digits)
isTestMasof("0010131918"); // true (starts with 00100)
isTestMasof("1234567890"); // false
isValidToken("1315872608557940000"); // true (19 digits)
isValidEmail("[email protected]"); // true
isValidIsraeliId("203269535"); // true (valid Teudat Zehut)
isValidIsraeliId("000000000"); // true (special test value)Advanced Configuration
Custom Timeout
const client = new HypayClient({
masof: "0010131918",
apiKey: "your-key",
timeout: 60_000, // 60 seconds
});Custom Fetch (Node.js < 18 or test mocks)
import nodeFetch from "node-fetch";
const client = new HypayClient({
masof: "0010131918",
apiKey: "your-key",
fetch: nodeFetch as unknown as typeof fetch,
});Lifecycle Hooks (Logging, Metrics)
const client = new HypayClient({
masof: "0010131918",
apiKey: "your-key",
hooks: {
onRequest: (ctx) => {
console.log(`[Hypay] ${ctx.method} ${ctx.action}`, ctx.params);
},
onResponse: (ctx) => {
console.log(`[Hypay] ${ctx.action} responded in ${ctx.durationMs}ms`, {
status: ctx.statusCode,
CCode: ctx.parsedParams.CCode,
});
},
onError: (error, ctx) => {
console.error(`[Hypay] ${ctx.action} failed: ${error.code} — ${error.message}`);
// Send to your error tracking (Sentry, Datadog, etc.)
},
},
});Testing
Use a test terminal (Masof starting with 00100) for development:
| Parameter | Test Value |
|-----------|-----------|
| Masof | 0010131918 |
| PassP | yaad |
| API Key | 7110eda4d09e062aa5e4a390b0a572ac0d2c0220 |
Test Credit Card:
| Field | Value |
|-------|-------|
| Number | 5326107300020772 |
| Expiry | 05/31 |
| CVV | 033 |
| ID | 890108558 or 000000000 |
Use low amounts (5-10 ILS) for testing. To simulate failures, use a real credit card on a test terminal.
API Reference
Client Methods
| Method | Description |
|--------|-------------|
| sign(params) | Sign payment page parameters (APISign) |
| buildPaymentPageUrl(qs) | Build payment page URL from signed query string |
| createPaymentPageUrl(params) | Sign + build URL in one call |
| verify(params) | Verify transaction from success page params |
| verifyRedirectUrl(url) | Parse URL + verify in one call |
| soft(params) | Server-side transaction (token, wallet, card) |
| getToken(params) | Get reusable token from a transaction |
| chargeJ5(tokenParams, j5Params) | Charge a J5 credit line reservation |
| commitTransaction(params) | Commit a postponed (800) transaction |
| cancelTransaction(params) | Cancel a same-day transaction |
| refund(params) | Refund by transaction ID (zikoyAPI) |
| refundByToken(params) | Refund via token + zPass (PAYout) |
| createSubscriptionUrl(params) | Create HK subscription payment page |
| createSubscriptionWithInitialPayment(params) | Subscription with setup fee |
| updateHKStatus(params) | Change standing order status |
| terminateSubscription(hkId) | Terminate a standing order |
| activateSubscription(hkId) | Activate a standing order |
| getInvoiceUrl(params) | Get signed EzCount invoice URL |
| createOfflineInvoice(params) | Create Cash/Check/Multi invoice |
Helper Functions
| Function | Description |
|----------|-------------|
| parseQueryString(qs) | Parse URL query string to Record |
| parseRedirectUrl(url) | Parse success/failure redirect URL |
| parsePaymentPageResponse(url) | Parse redirect URL to typed response |
| parseTokef(tokef) | Parse YYMM token expiry to Tmonth/Tyear |
| buildItemsString(items) | Build heshDesc invoice items string |
| calculateItemsTotal(items) | Calculate total from invoice items |
| isValidMasof(masof) | Validate terminal number format |
| isTestMasof(masof) | Check if terminal is a test terminal |
| isValidToken(token) | Validate 19-digit token format |
| isValidEmail(email) | Basic email validation |
| isValidIsraeliId(id) | Validate Israeli ID (Teudat Zehut) |
| isSuccessCode(ccode) | Check if CCode is success (0/600/700/800) |
| isShvaError(ccode) | Check if CCode is Shva error (1-200) |
| isHypayError(ccode) | Check if CCode is Hypay error (201-999) |
| getErrorMessage(ccode) | Get human-readable error description |
License
MIT
