import {z} from 'zod' export type V2TransactionsComplaintCategory = 'item_not_received' | 'item_not_as_described' | 'other'; export type CreateApiV2TransactionsTransactionIdSubmitComplaintArgs = {'Trustap-User'?: string | undefined, transaction_id: string, body: {category?: V2TransactionsComplaintCategory | undefined, description: string}}; export type CreateApiV2TransactionsTransactionIdSubmitComplaintOptions = {baseUrl?: string | undefined, APIKey?: {username: string, password: string} | undefined, fetch?: typeof fetch | undefined}; export const v2TransactionsUser = z.object({id: z.string(), is_guest: z.boolean()}); export const v2TransactionsComplaintCategory = z.enum(["item_not_received", "item_not_as_described", "other"]); export const v2TransactionsEvents = z.object({by_key: z.object({buyer_handover_confirmed: z.string().optional(), cancelled: z.string().optional(), claimed_by_buyer: z.string().optional(), claimed_by_seller: z.string().optional(), complaint_period_ended: z.string().optional(), complaint_submitted: z.string().optional(), created: z.string(), delivered: z.string().optional(), funds_released: z.string().optional(), joined: z.string().optional(), order_issue_submitted: z.string().optional(), paid: z.string().optional(), payment_accepted: z.string().optional(), refunded: z.string().optional(), rejected: z.string().optional(), review_flagged: z.string().optional(), seller_handover_confirmed: z.string().optional(), tracked: z.string().optional()}), by_time: z.array(z.object({at: z.string(), by: z.string().optional(), code: z.string()}))}); export const v2TransactionsBillingType = z.enum(["one_time", "recurring"]); export const v2TransactionsRecurringPeriod = z.enum(["day", "week", "month", "year"]); export const v2TransactionsTransactionItem = z.object({amount: z.number().int(), amount_extra: z.number().int().optional(), amount_postage: z.number().int().optional(), amount_tax: z.number().int().optional(), billing_type: v2TransactionsBillingType, created: z.string(), description: z.string(), image_url: z.string().max(2047).optional(), item_id: z.string(), quantity: z.number().int().optional(), recurring_period: v2TransactionsRecurringPeriod.optional(), ref_id: z.string().optional(), tax_code: z.string().optional()}); export const v2TransactionsOrderIssueCategory = z.enum(["item_not_received", "other"]); export const v2TransactionsPricing = z.object({amount: z.number().int(), amount_extra: z.number().int(), amount_postage: z.number().int().optional(), currency: z.string(), fees: z.object({buyer: z.number().int(), buyer_client: z.number().int(), international_payment: z.number().int().optional(), seller: z.number().int(), seller_client: z.number().int()}), postage_bearer: z.enum(["buyer", "seller", "client"]).optional()}); export const v2TransactionsStatus = z.enum(["created", "joined", "rejected", "cancelled", "paid", "review_flagged", "payment_accepted", "complaint_submitted", "complaint_period_ended", "refunded", "tracked", "delivered", "funds_released", "claimed_by_buyer", "claimed_by_seller"]); export const v2TransactionsTracking = z.object({carrier: z.string(), tracking_code: z.string()}); export const v2TransactionsTransaction = z.object({buyer: v2TransactionsUser.optional(), cancellation: z.object({description: z.string()}).optional(), client_id: z.string(), complaint: z.object({accepted: z.string().optional(), category: v2TransactionsComplaintCategory, description: z.string()}).optional(), contains_shipping: z.boolean().optional(), deadlines: z.object({complaints: z.string().nullable().optional()}), description: z.string(), events: v2TransactionsEvents, funds_release: z.object({payout_id: z.string().optional(), refunds: z.array(z.object({amount: z.number().int(), id: z.string()})), released_to_seller: z.boolean()}).optional(), id: z.string(), items: z.array(v2TransactionsTransactionItem).optional(), join_code: z.string().optional(), metadata: z.record(z.string(), z.unknown()).optional(), order_issue: z.object({category: v2TransactionsOrderIssueCategory, description: z.string()}).optional(), payment_link: z.string().optional(), pricing: v2TransactionsPricing, review: z.object({approved: z.boolean(), outcome_reason: z.string()}).optional(), seller: v2TransactionsUser.optional(), status: v2TransactionsStatus, tracking: v2TransactionsTracking.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 }; /** * Submit a complaint for this transaction * * POST /v2/transactions/{transaction_id}/submit_complaint * * Also accepts auth: OAuth2 */ export const createApiV2TransactionsTransactionIdSubmitComplaint = async (args: CreateApiV2TransactionsTransactionIdSubmitComplaintArgs, options?: CreateApiV2TransactionsTransactionIdSubmitComplaintOptions) => { const {baseUrl = "https://api.test.trustap.com", fetch: fetchFn = fetch, APIKey} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (args['Trustap-User'] != null) headers.set("Trustap-User", String(args['Trustap-User'])) if (APIKey !== undefined) headers.set('authorization', `Basic ${btoa(`${APIKey.username}:${APIKey.password}`)}`) const url = `${baseUrl.replace(/\/+$/, '')}/v2/transactions/${encodeURIComponent(String(args.transaction_id))}/submit_complaint${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(v2TransactionsTransaction, await res.json()) };