import {z} from 'zod' export type CreateApiVrpConsentsIdReconfirmArgs = {id: string}; export type CreateApiVrpConsentsIdReconfirmOptions = {baseUrl?: string | undefined, Bearer?: string | undefined, fetch?: typeof fetch | undefined}; export const memberId = z.string(); export const bankId = z.string(); export const refId = z.string(); export const remittanceInformationPrimary = z.string(); export const remittanceInformationSecondary = z.string(); export const address = z.object({addressLine: z.array(z.string()).optional(), streetName: z.string().optional(), buildingNumber: z.string().optional(), postCode: z.string().optional(), townName: z.string().optional(), state: z.string().optional(), district: z.string().optional(), country: z.string().optional()}); export const vRPDebtorInformation = z.object({accountNumber: z.string(), sortCode: z.string(), name: z.string().optional(), ultimateDebtorName: z.string().optional(), address: address.optional()}); export const vRPCreditorInformation = z.object({accountNumber: z.string(), sortCode: z.string(), name: z.string(), ultimateCreditorName: z.string().optional(), address: address.optional(), bankName: z.string().optional()}); export const periodicLimit = z.object({maximumAmount: z.string(), periodType: z.enum(["DAY", "WEEK", "MONTH", "YEAR"]), periodAlignment: z.enum(["CONSENT", "CALENDAR"]).optional()}); export const callbackUrl = z.string(); export const callbackStatev2 = z.string(); export const paymentContextCode = z.enum(["INVALID_PAYMENT_CONTEXT_CODE", "BILLING_GOODS_AND_SERVICES_IN_ADVANCE", "BILLING_GOODS_AND_SERVICES_IN_ARREARS", "PISP_PAYEE", "ECOMMERCE_MERCHANT_INITIATED_PAYMENT", "FACE_TO_FACE_POINT_OF_SALE", "TRANSFER_TO_SELF", "TRANSFER_TO_THIRD_PARTY"]); export const deliveryAddress = z.object({addressLine: z.array(z.string()).optional(), addressType: z.enum(["INVALID_ADDRESS_TYPE", "BUSINESS", "CORRESPONDENCE", "DELIVERYTO", "MAILTO", "POBOX", "POSTAL", "RESIDENTIAL", "STATEMENT"]).optional(), buildingNumber: z.string().optional(), country: z.string().optional(), countrySubDivision: z.array(z.string()).optional(), department: z.string().optional(), postCode: z.string().optional(), streetName: z.string().optional(), subDepartment: z.string().optional(), townName: z.string().optional()}); export const risk = z.object({psuId: z.string().optional(), paymentContextCode: paymentContextCode.optional(), paymentPurposeCode: z.enum(["CASH", "CORT", "DVPM", "INTC", "TREA", "SUPP"]).optional(), merchantCategoryCode: z.string().optional(), beneficiaryAccountType: z.enum(["PERSONAL", "JOINT_PERSONAL", "PERSONAL_SAVINGS_ACCOUNT", "BUSINESS", "BUSINESS_SAVINGS_ACCOUNT", "CHARITY", "COLLECTION", "CORPORATE", "GOVERNMENT", "EWALLET", "INVESTMENT", "ISA", "PREMIER", "WEALTH", "PENSION"]).optional(), contractPresentIndicator: z.boolean().optional(), beneficiaryPrepopulatedIndicator: z.boolean().optional(), deliveryAddress: deliveryAddress.optional()}); export const vrpConsentInitiation = z.object({bankId: bankId.optional(), refId: refId, remittanceInformationPrimary: remittanceInformationPrimary.optional(), remittanceInformationSecondary: remittanceInformationSecondary.optional(), startDateTime: z.string().optional(), endDateTime: z.string().optional(), onBehalfOfId: z.string().optional(), scheme: z.literal("VRP_SWEEPING"), localInstrument: z.literal("FASTER_PAYMENTS"), debtor: vRPDebtorInformation.optional(), creditor: vRPCreditorInformation, currency: z.string(), minimumIndividualAmount: z.string().optional(), maximumIndividualAmount: z.string(), periodicLimits: z.array(periodicLimit), maximumOccurrences: z.number().int().optional(), callbackUrl: callbackUrl, callbackState: callbackStatev2, returnRefundAccount: z.boolean().optional(), risk: risk.optional(), flowType: z.enum(["API_ONLY", "FULL_HOSTED_PAGES"]).optional()}); export const vrpConsentStatus = z.enum(["PENDING", "PENDING_MORE_INFO", "PENDING_REDIRECT_AUTH", "PENDING_REDIRECT_AUTH_VERIFICATION", "AUTHORIZED", "REJECTED", "REVOKED", "FAILED"]); export const authentication = z.object({redirectUrl: z.string()}); export const vrpConsent = z.object({id: z.string(), memberId: memberId, initiation: vrpConsentInitiation, createdDateTime: z.string(), updatedDateTime: z.string(), status: vrpConsentStatus, bankVrpConsentId: z.string().optional(), bankVrpConsentStatus: z.string().optional(), statusReasonInformation: z.string().optional(), authentication: authentication.optional(), lastUsedAt: z.string().optional(), inactivityRevocationDueAt: z.string().optional()}); export const vrpConsentResponse = z.object({vrpConsent: vrpConsent}); 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 }; /** * Reconfirm a VRP consent * * POST /vrp-consents/{id}/reconfirm * * Also accepts auth: BasicAuth */ export const createApiVrpConsentsIdReconfirm = async (args: CreateApiVrpConsentsIdReconfirmArgs, options?: CreateApiVrpConsentsIdReconfirmOptions) => { const {baseUrl = "https://api.token.io", fetch: fetchFn = fetch, Bearer} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (Bearer !== undefined) headers.set('authorization', `Bearer ${Bearer}`) const url = `${baseUrl.replace(/\/+$/, '')}/vrp-consents/${encodeURIComponent(String(args.id))}/reconfirm${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(vrpConsentResponse, await res.json()) };