Skip to main content

Contracts and Kurv integration

Single source of truth​

@payofy/contracts defines all API endpoints and asynchronous webhook payloads with Zod schemas.

The build pipeline exports these schemas to OpenAPI 3.1 definitions. Consuming packages, including @payofy/node and @payofy/js, consume types generated from these contracts. When a contract changes, client types update automatically during the build step.

Kurv isolation​

Direct communication with Kurv exists solely within @payofy/kurv. Other modules interact with the PaymentRail interface.

export interface PaymentRail {
tokenizePaymentMethod(params: TokenizePaymentMethodParams): Promise<{ vaultToken: string }>;
charge(params: ChargeParams): Promise<RailChargeResult>;
refund(params: RefundParams): Promise<{ refundId: string; status: "succeeded" | "failed" }>;
void(params: VoidParams): Promise<{ voidId: string; status: "succeeded" | "failed" }>;
createMerchantApplication(params: MerchantApplicationParams): Promise<RailMerchantResult>;
getMerchantStatus(kurvMid: string): Promise<RailMerchantResult>;
verifyWebhookSignature(rawBody: string, signature: string, secret: string): boolean;
}

This boundary prevents payment processor details from leaking into domain entities or transaction accounting.