diff --git a/src/v0/configurations.ts b/src/v0/configurations.ts index c3445cf85ab..25460b00413 100644 --- a/src/v0/configurations.ts +++ b/src/v0/configurations.ts @@ -54,12 +54,24 @@ export interface BulkUpdateResponse { metadata?: Record } +export type PaymentLinkDefaultUsageMode = 'single_use' | 'multi_use' + +export interface PaymentLinksConfigurationSettings { + default_expiry_days?: number + default_usage_mode?: PaymentLinkDefaultUsageMode +} + +export interface ConfigurationSettings { + payment_links?: PaymentLinksConfigurationSettings + [key: string]: unknown +} + export interface Configuration { id?: string vouchers?: Record scan_prefixes?: Array> voucher_actions?: Array> - settings?: Record + settings?: ConfigurationSettings hooks?: Array> themes?: Record name?: string diff --git a/src/v0/payment_links.ts b/src/v0/payment_links.ts index c617e8ff5ff..dec14b0a45d 100644 --- a/src/v0/payment_links.ts +++ b/src/v0/payment_links.ts @@ -13,8 +13,9 @@ import { } from '../errors' declare type PaymentLinkType = 'items_sale' | 'quick_charge' -declare type PaymentLinkStatus = 'open' | 'expired' | 'closed' +declare type PaymentLinkStatus = 'sent' | 'paid' | 'expired' | 'authorized' | 'cancelled' | 'refunded' | 'failed' declare type BasketItemType = 'goods' | 'shipment' | 'voucher' | 'digital' +declare type PaymentLinkSolutionType = 'BNPL_INSTORE' | 'LINKPAY' export interface PaymentLinkDto { id?: string | null @@ -23,6 +24,7 @@ export interface PaymentLinkDto { linkedOrderId?: string | null branch?: string | null branchId?: string | null + branchName?: string | null businessUnitUnzerId: string externalInvoiceId?: string externalOrderId?: string @@ -33,12 +35,18 @@ export interface PaymentLinkDto { currency?: string | null customer?: PaymentLinkCustomer | null items?: PaymentLinkItem[] | null + paymentPageId?: string | null paymentPageUrl?: string | null createdAt: string | { start: Date end: Date } | null updatedAt?: string | null + solutionType?: PaymentLinkSolutionType + multiUse?: boolean + expiresAt?: string | Date | null + alias?: string | null + orderCount?: number } export interface PaymentLinksOptions { @@ -95,14 +103,19 @@ export interface CreatePaymentLinkRequest { export interface PaymentLinkQuery { branch?: string | null + branchId?: string | null customerEmail?: string | null createdBy?: string | null createdAt?: string | { start: Date end: Date } | null - status?: string | null + status?: PaymentLinkStatus | null amount?: number | null + paymentLinkDescription?: string | null + linkedOrderId?: string | null + externalOrderId?: string | null + deleted?: boolean | null } export interface SendSmsRequest { @@ -128,6 +141,12 @@ export interface PaymentLinksResponse { next?: () => Promise } +export interface PaymentLinkDetailResponse { + results?: PaymentLinkDto[] + msg?: string + count?: number +} + export interface PaymentPageResponse { paymentPageUrl: string id: string @@ -308,7 +327,7 @@ export class PaymentLinks extends ThBaseHandler { } } - async getById (id: string): Promise { + async getById (id: string): Promise { try { const base = this.uriHelper.generateBaseUri() const uri = `${base}/${id}` @@ -318,7 +337,7 @@ export class PaymentLinks extends ThBaseHandler { throw new PaymentLinksGetByIdFailed(undefined, { status: response.status }) } - return response.data as PaymentLinkDto + return response.data as PaymentLinkDetailResponse } catch (error: any) { throw new PaymentLinksGetByIdFailed(error.message, { error }) } diff --git a/test/payment_links/get-by-id.test.ts b/test/payment_links/get-by-id.test.ts new file mode 100644 index 00000000000..affde5b265b --- /dev/null +++ b/test/payment_links/get-by-id.test.ts @@ -0,0 +1,134 @@ +import * as dotenv from 'dotenv' +import axios from 'axios' +import MockAdapter from 'axios-mock-adapter' +import { TillhubClient, v0 } from '../../src/tillhub-js' +dotenv.config() + +const user = { + username: 'test@example.com', + password: '12345678', + clientAccount: 'someuuid', + apiKey: '12345678' +} + +if (process.env.SYSTEM_TEST) { + user.username = process.env.SYSTEM_TEST_USERNAME ?? user.username + user.password = process.env.SYSTEM_TEST_PASSWORD ?? user.password + user.clientAccount = process.env.SYSTEM_TEST_CLIENT_ACCOUNT_ID ?? user.clientAccount + user.apiKey = process.env.SYSTEM_TEST_API_KEY ?? user.apiKey +} + +describe('v0: paymentLinks: can get payment link by id', () => { + const legacyId = '4564' + const paymentLinkId = 'pl-1' + const mock = new MockAdapter(axios) + afterEach(() => { + mock.reset() + }) + + const paymentLink = { + id: paymentLinkId, + paymentLinkType: 'quick_charge', + businessUnitUnzerId: 'bu-1', + createdBy: 'test@example.com', + createdAt: '2026-08-01T00:00:00.000Z', + solutionType: 'LINKPAY', + multiUse: true, + expiresAt: '2026-09-01T00:00:00.000Z', + alias: 'summer-sale', + orderCount: 3 + } + + it('returns the extended detail envelope', async () => { + if (process.env.SYSTEM_TEST !== 'true') { + mock.onPost('https://api.tillhub.com/api/v0/users/login').reply(() => { + return [ + 200, + { + token: '', + user: { + id: '123', + legacy_id: legacyId + } + } + ] + }) + + mock.onGet(`https://api.tillhub.com/api/v0/payment-links/${legacyId}/${paymentLinkId}`).reply(() => { + return [ + 200, + { + msg: 'Success', + count: 1, + results: [paymentLink] + } + ] + }) + } + + const options = { + credentials: { + username: user.username, + password: user.password + }, + base: process.env.TILLHUB_BASE + } + + const th = new TillhubClient() + + th.init(options) + await th.auth.loginUsername({ + username: user.username, + password: user.password + }) + + const paymentLinks = th.paymentLinks() + + expect(paymentLinks).toBeInstanceOf(v0.PaymentLinks) + + const result = await paymentLinks.getById(paymentLinkId) + + expect(result).toEqual(paymentLink) + }) + + it('rejects on status codes that are not 200', async () => { + if (process.env.SYSTEM_TEST !== 'true') { + mock.onPost('https://api.tillhub.com/api/v0/users/login').reply(() => { + return [ + 200, + { + token: '', + user: { + id: '123', + legacy_id: legacyId + } + } + ] + }) + + mock.onGet(`https://api.tillhub.com/api/v0/payment-links/${legacyId}/${paymentLinkId}`).reply(() => { + return [404] + }) + } + + const options = { + credentials: { + username: user.username, + password: user.password + }, + base: process.env.TILLHUB_BASE + } + + const th = new TillhubClient() + + th.init(options) + await th.auth.loginUsername({ + username: user.username, + password: user.password + }) + + await expect(th.paymentLinks().getById(paymentLinkId)).rejects.toMatchObject({ + name: 'PaymentLinksGetByIdFailed' + }) + }) +})