import {z} from 'zod' export type GsmDecision = 'retry' | 'do_default'; export type ErrorCategory = 'frm_decline' | 'processor_downtime' | 'processor_decline_unauthorized' | 'issue_with_payment_method' | 'processor_decline_incorrect_data' | 'hard_decline' | 'soft_decline'; export type GsmFeature = 'retry'; export type RetryFeatureData = {step_up_possible: boolean, clear_pan_possible: boolean, alternate_network_possible: boolean, decision: GsmDecision}; export type GsmFeatureData = {retry: RetryFeatureData}; export type StandardisedCode = 'account_closed_or_invalid' | 'authentication_failed' | 'authentication_required' | 'authorization_missing_or_revoked' | 'card_lost_or_stolen' | 'card_not_supported_restricted' | 'cfg_pm_not_enabled_or_misconfigured' | 'compliance_or_sanctions_restriction' | 'configuration_issue' | 'credit_limit_exceeded' | 'currency_or_corridor_not_enabled' | 'do_not_honor' | 'downstream_technical_issue' | 'duplicate_request' | 'generic_unknown_error' | 'incorrect_authentication_code' | 'insufficient_funds' | 'integ_cryptographic_issue' | 'integration_issue' | 'invalid_card_number' | 'invalid_credentials' | 'invalid_cvv' | 'invalid_expiry_date' | 'invalid_state' | 'issuer_unavailable' | 'merchant_inactive' | 'missing_or_invalid_param' | 'operation_not_allowed' | 'payment_cancelled_by_user' | 'payment_method_issue' | 'payment_session_timeout' | 'pm_address_mismatch' | 'psp_acquirer_error' | 'psp_fraud_engine_decline' | 'rate_limit' | 'stored_credential_or_mit_not_enabled' | 'subscription_plan_inactive' | 'suspected_fraud' | 'three_ds_authentication_service_issue' | 'three_ds_configuration_issue' | 'three_ds_data_or_protocol_invalid' | 'transaction_not_permitted' | 'transaction_timed_out' | 'velocity_limit_exceeded' | 'wallet_or_token_config_issue'; export type GsmUpdateRequest = {connector: string, flow: string, sub_flow: string, code: string, message: string, status?: (string | null) | undefined, router_error?: (string | null) | undefined, decision?: (GsmDecision | null) | undefined, step_up_possible?: (boolean | null) | undefined, unified_code?: (string | null) | undefined, unified_message?: (string | null) | undefined, error_category?: (ErrorCategory | null) | undefined, clear_pan_possible?: (boolean | null) | undefined, feature?: (GsmFeature | null) | undefined, feature_data?: (GsmFeatureData | null) | undefined, standardised_code?: (StandardisedCode | null) | undefined, description?: (string | null) | undefined, user_guidance_message?: (string | null) | undefined}; export type CreateApiGsmUpdateArgs = {body: GsmUpdateRequest}; export type CreateApiGsmUpdateOptions = {baseUrl: string, adminApiKey?: string | undefined, fetch?: typeof fetch | undefined}; export const gsmDecision = z.enum(["retry", "do_default"]); export const errorCategory = z.enum(["frm_decline", "processor_downtime", "processor_decline_unauthorized", "issue_with_payment_method", "processor_decline_incorrect_data", "hard_decline", "soft_decline"]); export const gsmFeature = z.literal("retry"); export const retryFeatureData = z.object({step_up_possible: z.boolean(), clear_pan_possible: z.boolean(), alternate_network_possible: z.boolean(), decision: gsmDecision}); export const gsmFeatureData = z.object({retry: retryFeatureData}); export const standardisedCode = z.enum(["account_closed_or_invalid", "authentication_failed", "authentication_required", "authorization_missing_or_revoked", "card_lost_or_stolen", "card_not_supported_restricted", "cfg_pm_not_enabled_or_misconfigured", "compliance_or_sanctions_restriction", "configuration_issue", "credit_limit_exceeded", "currency_or_corridor_not_enabled", "do_not_honor", "downstream_technical_issue", "duplicate_request", "generic_unknown_error", "incorrect_authentication_code", "insufficient_funds", "integ_cryptographic_issue", "integration_issue", "invalid_card_number", "invalid_credentials", "invalid_cvv", "invalid_expiry_date", "invalid_state", "issuer_unavailable", "merchant_inactive", "missing_or_invalid_param", "operation_not_allowed", "payment_cancelled_by_user", "payment_method_issue", "payment_session_timeout", "pm_address_mismatch", "psp_acquirer_error", "psp_fraud_engine_decline", "rate_limit", "stored_credential_or_mit_not_enabled", "subscription_plan_inactive", "suspected_fraud", "three_ds_authentication_service_issue", "three_ds_configuration_issue", "three_ds_data_or_protocol_invalid", "transaction_not_permitted", "transaction_timed_out", "velocity_limit_exceeded", "wallet_or_token_config_issue"]); export const gsmResponse = z.object({connector: z.string(), flow: z.string(), sub_flow: z.string(), code: z.string(), message: z.string(), status: z.string(), router_error: z.string().nullable().optional(), decision: gsmDecision, step_up_possible: z.boolean(), unified_code: z.string().nullable().optional(), unified_message: z.string().nullable().optional(), error_category: errorCategory.nullable().optional(), clear_pan_possible: z.boolean(), feature: gsmFeature, feature_data: gsmFeatureData, standardised_code: standardisedCode.nullable().optional(), description: z.string().nullable().optional(), user_guidance_message: z.string().nullable().optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Gsm - Update * * POST /gsm/update */ export const createApiGsmUpdate = async (args: CreateApiGsmUpdateArgs, options: CreateApiGsmUpdateOptions) => { const {baseUrl, fetch: fetchFn = fetch, adminApiKey} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (adminApiKey !== undefined) headers.set("api-key", adminApiKey) const url = `${baseUrl.replace(/\/+$/, '')}/gsm/update${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(gsmResponse, await res.json()) };