import {z} from 'zod' export type SdkEphemeralPublicKey = {kty?: 'EC' | undefined, crv?: string | undefined, x?: string | undefined, y?: string | undefined}; export type ChannelData = {channel: 'browser', three_ds_method_completion?: ('Y' | 'N' | 'U') | undefined, accept_header: string, java_enabled: boolean, javascript_enabled: boolean, language: string, color_depth: string, screen_height: string, screen_width: string, timezone: string, user_agent: string, ip_address: string, iframe_payment_allowed?: boolean | undefined, user_agent_client_hint?: string | undefined} | {channel: 'app', sdk_app_id: string, sdk_max_timeout: number, sdk_ephem_pub_key: SdkEphemeralPublicKey, sdk_reference_number: string, sdk_encrypted_data: string, sdk_transaction_id: string, sdk_interface_type: 'native' | 'html' | 'both', sdk_ui_elements: Array<'text' | 'single_select' | 'multi_select' | 'oob' | 'html_other'>} | {channel: 'merchant_initiated', request_type: 'recurring_transaction' | 'installment_transaction' | 'add_card' | 'maintain_card_information' | 'account_verification' | 'split_or_delayed_shipment' | 'top_up' | 'mail_order' | 'telephone_order' | 'whitelist_status_check' | 'other_payment'}; export type UpdateApiSessionsIdCollectDataArgs = {id: string, body: ChannelData}; export type UpdateApiSessionsIdCollectDataOptions = {baseUrl: string, OAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const sessionId = z.string().min(30).max(30); export const sessionSecret = z.string().min(48).max(48); export const amount = z.number().int().gte(0).lte(9007199254740991); export const currency = z.string(); export const authenticationType = z.enum(["regular", "recurring", "installment", "maintain_card", "add_card"]); export const category = z.enum(["payment", "non_payment"]); export const dsPublicKeys = z.object({ds_public: z.string().max(1024), ca_public: z.string().max(1024).optional(), ca_public_all: z.array(z.string().max(1024)).optional()}); export const status = z.enum(["challenged", "pending", "processing", "challenge_abandoned", "expired", "approved", "attempted", "unavailable", "declined", "rejected"]); export const statusReason = z.enum(["ares_status", "ares_error", "rreq_error", "rreq_status", "risk_declined"]); export const approved = z.boolean(); export const protocolVersion = z.string().max(50); export const threeDsRequestorAuthenticationInfo = z.object({three_ds_req_auth_method: z.enum(["no_threeds_requestor_authentication_occurred", "three3ds_requestor_own_credentials", "federated_id", "issuer_credentials", "third_party_authentication", "fido_authenticator", "fido_authenticator_fido_assurance_data_signed", "src_assurance_data"]).optional(), three_ds_req_auth_timestamp: z.string().optional(), three_ds_req_auth_data: z.string().max(20000).optional()}); export const cardholderAccountInfo = z.object({purchase_count: z.number().gte(0).lte(9999).optional(), account_age: z.enum(["no_account", "created_during_transaction", "less_than_thirty_days", "thirty_to_sixty_days", "more_than_sixty_days"]).optional(), add_card_attempts: z.number().gte(0).lte(999).optional(), shipping_address_age: z.enum(["this_transaction", "less_than_thirty_days", "thirty_to_sixty_days", "more_than_sixty_days"]).optional(), account_name_matches_shipping_name: z.boolean().optional(), suspicious_account_activity: z.boolean().optional(), transactions_today: z.number().gte(0).lte(999).optional(), authentication_method: z.enum(["no_authentication", "own_credentials", "federated_id", "issuer_credentials", "third_party_authentication", "fido"]).optional(), cardholder_account_age_indicator: z.enum(["no_account,", "this_transaction", "less_than_thirty_days", "thirty_to_sixty_days", "more_than_sixty_days"]).optional(), account_change: z.string().optional(), account_change_indicator: z.enum(["this_transaction", "less_than_thirty_days", "thirty_to_sixty_days", "more_than_sixty_days"]).optional(), account_date: z.string().optional(), account_password_change: z.string().optional(), account_password_change_indicator: z.enum(["no_change", "this_transaction", "less_than_thirty_days", "thirty_to_sixty_days", "more_than_sixty_days"]).optional(), transactions_per_year: z.number().int().lte(999).optional(), payment_account_age: z.string().optional(), shipping_address_usage: z.string().optional(), account_type: z.enum(["not_applicable", "credit", "debit"]).optional(), account_id: z.string().max(64).optional(), three_ds_requestor_authentication_info: threeDsRequestorAuthenticationInfo.optional()}); export const merchantRiskInfo = z.object({delivery_email: z.string().max(254).optional(), delivery_timeframe: z.enum(["electronic_delivery", "same_day", "overnight", "two_day_or_more"]).optional(), is_preorder: z.boolean().optional(), is_reorder: z.boolean().optional(), shipping_indicator: z.enum(["billing_address", "another_address_on_file", "not_on_file", "store_pick_up", "digital_goods", "travel_and_event_no_shipping", "other"]).optional(), reorder_items_indicator: z.enum(["first_time_ordered", "reordered"]).optional(), pre_order_purchase_indicator: z.enum(["merchandise_available", "future_availability"]).optional(), pre_order_date: z.string().optional(), gift_card_amount: z.string().max(15).optional(), gift_card_currency: z.string().min(3).max(3).optional(), gift_card_count: z.string().min(2).max(2).optional()}); export const reference = z.string().max(100); export const transactionType = z.enum(["goods_service", "check_acceptance", "account_funding", "quasi_card_transaction", "prepaid_activation_and_load"]).max(50); export const nextActions = z.array(z.enum(["redirect_cardholder", "collect_channel_data", "issuer_fingerprint", "challenge_cardholder", "complete"])); export const ds = z.object({ds_id: z.string().max(32).optional(), reference_number: z.string().max(32).optional(), transaction_id: z.string().min(36).max(36).optional()}); export const acs = z.object({reference_number: z.string().max(32), transaction_id: z.string().min(36).max(36), operator_id: z.string().max(32), url: z.string().max(2048).optional(), signed_content: z.string().max(512).optional(), challenge_mandated: z.boolean(), authentication_type: z.string().optional(), challenge_cancel_reason: z.enum(["cardholder_cancel", "transaction_timed_out", "challenge_timed_out", "transaction_error", "unknown", "sdk_timed_out"]).optional(), interface: z.enum(["native_ui", "html"]).optional(), ui_template: z.enum(["text", "single_select", "multi_select", "oob", "html_other"]).optional(), challenge_cancel_reason_code: z.string().optional()}); export const responseCode = z.enum(["Y", "N", "U", "A", "C", "D", "R", "I"]); export const responseStatusReason = z.string(); export const cryptogram = z.string().min(28).max(28); export const eci = z.string().min(2).max(2); export const cardInfo = z.object({instrument_id: z.string(), fingerprint: z.string(), metadata: z.object({card_type: z.enum(["CREDIT", "DEBIT", "PREPAID", "CHARGE", "DEFERRED DEBIT"]).optional(), card_category: z.enum(["CONSUMER", "COMMERCIAL"]).optional(), issuer_name: z.string().optional(), issuer_country: z.string().optional(), product_id: z.string().optional(), product_type: z.string().optional()}).optional()}); export const recurring = z.object({days_between_payments: z.number().int().optional(), expiry: z.string().optional()}); export const installment = z.object({number_of_payments: z.number().int().gte(2), days_between_payments: z.number().int().optional(), expiry: z.string().optional()}); export const initialTransaction = z.object({acs_transaction_id: z.string().min(36).optional(), authentication_method: z.enum(["frictionless_authentication", "challenge_occurred", "avs_verified", "other_issuer_methods"]).optional(), authentication_timestamp: z.string().optional(), authentication_data: z.string().max(2048).optional(), initial_session_id: z.string().min(30).max(30).optional()}); export const getSessionLinks = z.object({self: z.object({href: z.string().max(100)})}); export const trustedBeneficiary = z.object({status: z.enum(["Y", "N", "E", "P", "R", "U"]).optional(), source: z.string().optional()}); export const optimizedProperty = z.object({field: z.string().optional(), original_value: z.string().optional(), optimized_value: z.string().optional()}); export const errorDetails = z.object({error_code: z.string().optional(), error_component: z.string().optional(), error_detail: z.string().max(2048).optional(), error_description: z.string().max(2048).optional()}); export const preferredExperiences = z.object({google_spa: z.object({status: z.enum(["available", "unprocessed", "processed", "unavailable"]).optional(), reason: z.array(z.string()).optional()}).optional(), "3ds": z.object({status: z.enum(["available", "unprocessed", "processed", "unavailable"]).optional(), reason: z.array(z.string()).optional()}).optional()}); export const experience = z.enum(["3ds", "google_spa"]); export const googleSpaToken = z.object({number: z.string().optional(), expiry_month: z.number().optional(), expiry_year: z.number().optional()}); export const hostedGoogleSpaInfo = z.object({token: googleSpaToken.optional()}); export const nonHostedGoogleSpaInfo = z.object({challenge_url: z.string().optional(), initial_timeout: z.string().optional(), max_timeout: z.string().optional(), iframe: z.object({height: z.string().optional(), width: z.string().optional()}).optional(), token: googleSpaToken.optional()}); export const googleSpaInfo = z.union([hostedGoogleSpaInfo, nonHostedGoogleSpaInfo]); export const getSessionResponse = z.object({id: sessionId, session_secret: sessionSecret.optional(), transaction_id: z.string().min(36).max(36), scheme: z.enum(["visa", "mastercard", "jcb", "amex", "diners", "cartes_bancaires", "discover", "upi"]), amount: amount, currency: currency, completed: z.boolean().optional(), challenged: z.boolean().optional(), authentication_type: authenticationType, authentication_category: category, certificates: dsPublicKeys.optional(), status: status, status_reason: statusReason.optional(), approved: approved.optional(), protocol_version: protocolVersion, account_info: cardholderAccountInfo.optional(), merchant_risk_info: merchantRiskInfo.optional(), reference: reference.optional(), transaction_type: transactionType.optional(), next_actions: nextActions.optional(), ds: ds.optional(), acs: acs.optional(), response_code: responseCode.optional(), response_status_reason: responseStatusReason.optional(), cryptogram: cryptogram.optional(), eci: eci.optional(), xid: z.string().optional(), cardholder_info: z.string().optional(), card: cardInfo.optional(), recurring: recurring.optional(), installment: installment.optional(), initial_transaction: initialTransaction.optional(), customer_ip: z.string().optional(), _links: getSessionLinks, authentication_date: z.string().optional(), exemption: z.object({requested: z.literal("none").optional(), applied: z.enum(["none", "low_value", "transaction_risk_assessment", "secure_corporate_payment", "trusted_listing", "3ds_outage", "sca_delegation", "out_of_sca_scope", "other", "low_risk_program"]).optional(), code: z.string().optional(), trusted_beneficiary: trustedBeneficiary.optional()}).optional(), flow_type: z.enum(["challenged", "frictionless", "frictionless_delegated"]).optional(), challenge_indicator: z.enum(["no_preference", "no_challenge_requested", "challenge_requested", "challenge_requested_mandate"]), optimization: z.object({optimized: z.boolean().optional(), framework: z.literal("acceptance_rates").optional(), optimized_properties: z.array(optimizedProperty).optional()}).optional(), scheme_info: z.object({name: z.enum(["cartes_bancaires", "visa", "mastercard"]).optional(), score: z.string().optional(), avalgo: z.string().optional()}).optional(), "3ds": z.object({challenge_request: z.string().optional(), interaction_counter: z.string().max(2).optional(), error_details: errorDetails.optional()}).optional(), preferred_experiences: preferredExperiences.optional(), experience: experience.optional(), google_spa: googleSpaInfo.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 }; /** * Update a session * * PUT /sessions/{id}/collect-data * * Also accepts auth: SessionSecret */ export const updateApiSessionsIdCollectData = async (args: UpdateApiSessionsIdCollectDataArgs, options: UpdateApiSessionsIdCollectDataOptions) => { const {baseUrl, fetch: fetchFn = fetch, OAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (OAuth !== undefined) headers.set('authorization', `Bearer ${OAuth}`) const url = `${baseUrl.replace(/\/+$/, '')}/sessions/${encodeURIComponent(String(args.id))}/collect-data${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "PUT", 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(getSessionResponse, await res.json()) };