@commercejs/payment-tap 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tap-provider.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tap-provider.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/tap-provider.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,259 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { TapPaymentProvider } from '../tap-provider.js';
3
+ // ---------------------------------------------------------------------------
4
+ // Helpers
5
+ // ---------------------------------------------------------------------------
6
+ function makeTapCharge(overrides = {}) {
7
+ return {
8
+ id: 'chg_test_abc123',
9
+ status: 'INITIATED',
10
+ amount: 99.99,
11
+ currency: 'SAR',
12
+ threeDSecure: true,
13
+ source: { id: 'src_card', type: 'CARD_NOT_PRESENT' },
14
+ transaction: {
15
+ url: 'https://tap.company/3ds/abc123',
16
+ created: '2026-02-09T12:00:00Z',
17
+ },
18
+ redirect: { url: 'https://store.com/checkout/confirm' },
19
+ created: '2026-02-09T12:00:00Z',
20
+ ...overrides,
21
+ };
22
+ }
23
+ function mockFetchResponse(data, status = 200) {
24
+ return vi.fn().mockResolvedValue({
25
+ ok: status >= 200 && status < 300,
26
+ status,
27
+ json: () => Promise.resolve(data),
28
+ text: () => Promise.resolve(JSON.stringify(data)),
29
+ });
30
+ }
31
+ // ---------------------------------------------------------------------------
32
+ // Tests
33
+ // ---------------------------------------------------------------------------
34
+ describe('TapPaymentProvider', () => {
35
+ let provider;
36
+ beforeEach(() => {
37
+ provider = new TapPaymentProvider({
38
+ secretKey: 'sk_test_xxx',
39
+ webhookSecret: 'whsec_test',
40
+ });
41
+ });
42
+ // ---- Constructor -------------------------------------------------------
43
+ describe('constructor', () => {
44
+ it('sets id and name', () => {
45
+ expect(provider.id).toBe('tap');
46
+ expect(provider.name).toBe('Tap Payments');
47
+ });
48
+ });
49
+ // ---- createSession ----------------------------------------------------
50
+ describe('createSession', () => {
51
+ it('creates a charge and returns a PaymentSession with redirectUrl', async () => {
52
+ const charge = makeTapCharge();
53
+ globalThis.fetch = mockFetchResponse(charge);
54
+ const session = await provider.createSession({
55
+ amount: 99.99,
56
+ currency: 'SAR',
57
+ sourceToken: 'tok_test_123',
58
+ returnUrl: 'https://store.com/checkout/confirm',
59
+ });
60
+ expect(session.id).toBe('chg_test_abc123');
61
+ expect(session.providerId).toBe('tap');
62
+ expect(session.status).toBe('pending');
63
+ expect(session.amount).toBe(99.99);
64
+ expect(session.currency).toBe('SAR');
65
+ expect(session.redirectUrl).toBe('https://tap.company/3ds/abc123');
66
+ // Verify correct API call
67
+ expect(globalThis.fetch).toHaveBeenCalledWith('https://api.tap.company/v2/charges', expect.objectContaining({
68
+ method: 'POST',
69
+ headers: expect.objectContaining({
70
+ 'Authorization': 'Bearer sk_test_xxx',
71
+ }),
72
+ }));
73
+ });
74
+ it('passes orderId as reference.order', async () => {
75
+ const charge = makeTapCharge();
76
+ globalThis.fetch = mockFetchResponse(charge);
77
+ await provider.createSession({
78
+ amount: 50,
79
+ currency: 'SAR',
80
+ orderId: 'order-123',
81
+ returnUrl: 'https://store.com/confirm',
82
+ });
83
+ const callBody = JSON.parse(globalThis.fetch.mock.calls[0][1].body);
84
+ expect(callBody.reference).toEqual({ order: 'order-123' });
85
+ });
86
+ it('uses src_all when no sourceToken is provided', async () => {
87
+ const charge = makeTapCharge();
88
+ globalThis.fetch = mockFetchResponse(charge);
89
+ await provider.createSession({
90
+ amount: 10,
91
+ currency: 'SAR',
92
+ returnUrl: 'https://store.com/confirm',
93
+ });
94
+ const callBody = JSON.parse(globalThis.fetch.mock.calls[0][1].body);
95
+ expect(callBody.source).toEqual({ id: 'src_all' });
96
+ });
97
+ it('throws on Tap API error', async () => {
98
+ globalThis.fetch = mockFetchResponse({ error: 'invalid' }, 400);
99
+ await expect(provider.createSession({ amount: 10, currency: 'SAR' })).rejects.toThrow('Tap API error (400)');
100
+ });
101
+ });
102
+ // ---- confirmSession ---------------------------------------------------
103
+ describe('confirmSession', () => {
104
+ it('re-fetches charge to get final status after 3DS', async () => {
105
+ const captured = makeTapCharge({ status: 'CAPTURED' });
106
+ globalThis.fetch = mockFetchResponse(captured);
107
+ const session = await provider.confirmSession('chg_test_abc123');
108
+ expect(session.status).toBe('captured');
109
+ expect(globalThis.fetch).toHaveBeenCalledWith('https://api.tap.company/v2/charges/chg_test_abc123', expect.objectContaining({ method: 'GET' }));
110
+ });
111
+ });
112
+ // ---- getSession -------------------------------------------------------
113
+ describe('getSession', () => {
114
+ it('fetches charge by ID', async () => {
115
+ const charge = makeTapCharge({ status: 'IN_PROGRESS' });
116
+ globalThis.fetch = mockFetchResponse(charge);
117
+ const session = await provider.getSession('chg_test_abc123');
118
+ expect(session.status).toBe('processing');
119
+ expect(session.id).toBe('chg_test_abc123');
120
+ });
121
+ });
122
+ // ---- refund -----------------------------------------------------------
123
+ describe('refund', () => {
124
+ it('creates a refund and returns updated session', async () => {
125
+ const fetchMock = vi.fn()
126
+ // First call: getSession to get current amount/currency
127
+ .mockResolvedValueOnce({
128
+ ok: true, status: 200,
129
+ json: () => Promise.resolve(makeTapCharge({ status: 'CAPTURED' })),
130
+ text: () => Promise.resolve(''),
131
+ })
132
+ // Second call: POST /refunds
133
+ .mockResolvedValueOnce({
134
+ ok: true, status: 200,
135
+ json: () => Promise.resolve({ id: 'ref_123', status: 'REFUNDED' }),
136
+ text: () => Promise.resolve(''),
137
+ })
138
+ // Third call: getSession to get updated status
139
+ .mockResolvedValueOnce({
140
+ ok: true, status: 200,
141
+ json: () => Promise.resolve(makeTapCharge({ status: 'REFUNDED' })),
142
+ text: () => Promise.resolve(''),
143
+ });
144
+ globalThis.fetch = fetchMock;
145
+ const session = await provider.refund({
146
+ sessionId: 'chg_test_abc123',
147
+ reason: 'requested_by_customer',
148
+ });
149
+ expect(session.status).toBe('refunded');
150
+ expect(fetchMock).toHaveBeenCalledTimes(3);
151
+ // Verify refund POST body
152
+ const refundCall = fetchMock.mock.calls[1];
153
+ expect(refundCall[0]).toBe('https://api.tap.company/v2/refunds');
154
+ const refundBody = JSON.parse(refundCall[1].body);
155
+ expect(refundBody.charge_id).toBe('chg_test_abc123');
156
+ expect(refundBody.amount).toBe(99.99); // full refund
157
+ });
158
+ it('supports partial refund with explicit amount', async () => {
159
+ const fetchMock = vi.fn()
160
+ .mockResolvedValueOnce({
161
+ ok: true, status: 200,
162
+ json: () => Promise.resolve(makeTapCharge({ status: 'CAPTURED' })),
163
+ text: () => Promise.resolve(''),
164
+ })
165
+ .mockResolvedValueOnce({
166
+ ok: true, status: 200,
167
+ json: () => Promise.resolve({ id: 'ref_456', status: 'REFUNDED' }),
168
+ text: () => Promise.resolve(''),
169
+ })
170
+ .mockResolvedValueOnce({
171
+ ok: true, status: 200,
172
+ json: () => Promise.resolve(makeTapCharge({ status: 'CAPTURED' })),
173
+ text: () => Promise.resolve(''),
174
+ });
175
+ globalThis.fetch = fetchMock;
176
+ await provider.refund({
177
+ sessionId: 'chg_test_abc123',
178
+ amount: 25.00,
179
+ });
180
+ const refundBody = JSON.parse(fetchMock.mock.calls[1][1].body);
181
+ expect(refundBody.amount).toBe(25.00);
182
+ });
183
+ });
184
+ // ---- Status mapping ---------------------------------------------------
185
+ describe('status mapping', () => {
186
+ const cases = [
187
+ ['INITIATED', 'pending'],
188
+ ['IN_PROGRESS', 'processing'],
189
+ ['CAPTURED', 'captured'],
190
+ ['FAILED', 'failed'],
191
+ ['DECLINED', 'failed'],
192
+ ['RESTRICTED', 'failed'],
193
+ ['VOID', 'cancelled'],
194
+ ['CANCELLED', 'cancelled'],
195
+ ['TIMEDOUT', 'cancelled'],
196
+ ['ABANDONED', 'cancelled'],
197
+ ['REFUNDED', 'refunded'],
198
+ ];
199
+ it.each(cases)('maps Tap "%s" → "%s"', async (tapStatus, expected) => {
200
+ const charge = makeTapCharge({ status: tapStatus });
201
+ globalThis.fetch = mockFetchResponse(charge);
202
+ const session = await provider.getSession('chg_test_abc123');
203
+ expect(session.status).toBe(expected);
204
+ });
205
+ });
206
+ // ---- cancelSession ----------------------------------------------------
207
+ describe('cancelSession', () => {
208
+ it('returns current session state', async () => {
209
+ const charge = makeTapCharge({ status: 'CANCELLED' });
210
+ globalThis.fetch = mockFetchResponse(charge);
211
+ const session = await provider.cancelSession('chg_test_abc123');
212
+ expect(session.status).toBe('cancelled');
213
+ });
214
+ });
215
+ // ---- verifyWebhook ----------------------------------------------------
216
+ describe('verifyWebhook', () => {
217
+ it('throws on invalid hashstring', async () => {
218
+ const payload = JSON.stringify({
219
+ id: 'chg_test_abc123',
220
+ amount: 99.99,
221
+ currency: 'SAR',
222
+ status: 'CAPTURED',
223
+ reference: { gateway: 'gw_ref', payment: 'pay_ref' },
224
+ transaction: { created: '2026-02-09T12:00:00Z' },
225
+ });
226
+ await expect(provider.verifyWebhook(payload, 'invalid_sig')).rejects.toThrow('invalid webhook hashstring');
227
+ });
228
+ it('returns parsed event on valid hashstring', async () => {
229
+ const event = {
230
+ id: 'chg_test_abc123',
231
+ amount: 99.99,
232
+ currency: 'SAR',
233
+ status: 'CAPTURED',
234
+ reference: { gateway: 'gw_ref', payment: 'pay_ref' },
235
+ transaction: { created: '2026-02-09T12:00:00Z' },
236
+ };
237
+ const payload = JSON.stringify(event);
238
+ // Build the hashstring the same way the implementation does
239
+ const toBeHashed = `x_id${event.id}` +
240
+ `x_amount${event.amount}` +
241
+ `x_currency${event.currency}` +
242
+ `x_gateway_reference${event.reference.gateway}` +
243
+ `x_payment_reference${event.reference.payment}` +
244
+ `x_status${event.status}` +
245
+ `x_created${event.transaction.created}`;
246
+ // HMAC with secretKey (not webhookSecret — matches implementation)
247
+ const encoder = new TextEncoder();
248
+ const key = await globalThis.crypto.subtle.importKey('raw', encoder.encode('sk_test_xxx'), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
249
+ const sig = await globalThis.crypto.subtle.sign('HMAC', key, encoder.encode(toBeHashed));
250
+ const validSignature = Array.from(new Uint8Array(sig))
251
+ .map(b => b.toString(16).padStart(2, '0'))
252
+ .join('');
253
+ const result = await provider.verifyWebhook(payload, validSignature);
254
+ expect(result.type).toBe('payment.captured');
255
+ expect(result.sessionId).toBe('chg_test_abc123');
256
+ });
257
+ });
258
+ });
259
+ //# sourceMappingURL=tap-provider.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tap-provider.test.js","sourceRoot":"","sources":["../../src/__tests__/tap-provider.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { TapPaymentProvider } from './tap-provider.js';
2
+ export type { TapConfig, TapRawCharge, TapChargeStatus, TapRawRefund } from './types.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AACtD,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ // ---------------------------------------------------------------------------
2
+ // @commercejs/payment-tap — Tap Payments provider for CommerceJS
3
+ // ---------------------------------------------------------------------------
4
+ export { TapPaymentProvider } from './tap-provider.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,iEAAiE;AACjE,8EAA8E;AAE9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA"}
@@ -0,0 +1,42 @@
1
+ import type { PaymentProvider, PaymentSession, CreatePaymentSessionInput, RefundInput, PaymentWebhookEvent } from '@commercejs/types';
2
+ import type { TapConfig } from './types.js';
3
+ /**
4
+ * Tap Payments provider — redirect-based, PCI-free.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * const tap = new TapPaymentProvider({ secretKey: 'sk_test_...' })
9
+ *
10
+ * // 1. Create charge with token from goSell.js
11
+ * const session = await tap.createSession({
12
+ * amount: 99.99,
13
+ * currency: 'SAR',
14
+ * sourceToken: 'tok_xxx',
15
+ * returnUrl: 'https://store.com/checkout/confirm',
16
+ * })
17
+ *
18
+ * // 2. Redirect customer to session.redirectUrl for 3DS
19
+ *
20
+ * // 3. After redirect, confirm the payment
21
+ * const confirmed = await tap.confirmSession(session.id)
22
+ * // confirmed.status === 'captured'
23
+ * ```
24
+ */
25
+ export declare class TapPaymentProvider implements PaymentProvider {
26
+ readonly id = "tap";
27
+ readonly name = "Tap Payments";
28
+ private readonly secretKey;
29
+ private readonly baseUrl;
30
+ private readonly webhookSecret;
31
+ constructor(config: TapConfig);
32
+ createSession(input: CreatePaymentSessionInput): Promise<PaymentSession>;
33
+ confirmSession(sessionId: string): Promise<PaymentSession>;
34
+ getSession(sessionId: string): Promise<PaymentSession>;
35
+ refund(input: RefundInput): Promise<PaymentSession>;
36
+ cancelSession(sessionId: string): Promise<PaymentSession>;
37
+ verifyWebhook(payload: string | Uint8Array, signature: string): Promise<PaymentWebhookEvent>;
38
+ /** Map Tap charge status to a webhook event type */
39
+ private mapChargeStatusToEventType;
40
+ private request;
41
+ }
42
+ //# sourceMappingURL=tap-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tap-provider.d.ts","sourceRoot":"","sources":["../src/tap-provider.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAEd,yBAAyB,EACzB,WAAW,EACX,mBAAmB,EACpB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,KAAK,EAAE,SAAS,EAAiC,MAAM,YAAY,CAAA;AAgD1E;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,kBAAmB,YAAW,eAAe;IACxD,QAAQ,CAAC,EAAE,SAAQ;IACnB,QAAQ,CAAC,IAAI,kBAAiB;IAE9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;gBAEjC,MAAM,EAAE,SAAS;IAUvB,aAAa,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,cAAc,CAAC;IA+BxE,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAK1D,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAKtD,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC;IAmBnD,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAOzD,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA6DlG,oDAAoD;IACpD,OAAO,CAAC,0BAA0B;YAmBpB,OAAO;CAqBtB"}
@@ -0,0 +1,230 @@
1
+ // ---------------------------------------------------------------------------
2
+ // TapPaymentProvider — Tap Payments gateway (redirect-based, PCI-free)
3
+ // ---------------------------------------------------------------------------
4
+ //
5
+ // Flow: tokenize client-side (goSell.js) → create charge server-side →
6
+ // redirect for 3DS → confirm after redirect → done.
7
+ //
8
+ // Tap auto-captures charges, so captureSession is not implemented.
9
+ // ---------------------------------------------------------------------------
10
+ const TAP_API_BASE = 'https://api.tap.company/v2';
11
+ /** Map Tap charge status → PaymentSessionStatus */
12
+ function mapTapStatus(status) {
13
+ switch (status) {
14
+ case 'INITIATED':
15
+ return 'pending';
16
+ case 'IN_PROGRESS':
17
+ return 'processing';
18
+ case 'CAPTURED':
19
+ return 'captured';
20
+ case 'VOID':
21
+ case 'CANCELLED':
22
+ case 'TIMEDOUT':
23
+ case 'ABANDONED':
24
+ return 'cancelled';
25
+ case 'FAILED':
26
+ case 'DECLINED':
27
+ case 'RESTRICTED':
28
+ return 'failed';
29
+ case 'REFUNDED':
30
+ return 'refunded';
31
+ default:
32
+ return 'pending';
33
+ }
34
+ }
35
+ /** Build a PaymentSession from a Tap charge */
36
+ function chargeToSession(charge, providerId) {
37
+ return {
38
+ id: charge.id,
39
+ providerId,
40
+ status: mapTapStatus(charge.status),
41
+ amount: charge.amount,
42
+ currency: charge.currency,
43
+ providerData: {
44
+ tapChargeId: charge.id,
45
+ tapStatus: charge.status,
46
+ source: charge.source,
47
+ reference: charge.reference,
48
+ },
49
+ redirectUrl: charge.transaction?.url ?? null,
50
+ createdAt: charge.created ?? new Date().toISOString(),
51
+ };
52
+ }
53
+ /**
54
+ * Tap Payments provider — redirect-based, PCI-free.
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * const tap = new TapPaymentProvider({ secretKey: 'sk_test_...' })
59
+ *
60
+ * // 1. Create charge with token from goSell.js
61
+ * const session = await tap.createSession({
62
+ * amount: 99.99,
63
+ * currency: 'SAR',
64
+ * sourceToken: 'tok_xxx',
65
+ * returnUrl: 'https://store.com/checkout/confirm',
66
+ * })
67
+ *
68
+ * // 2. Redirect customer to session.redirectUrl for 3DS
69
+ *
70
+ * // 3. After redirect, confirm the payment
71
+ * const confirmed = await tap.confirmSession(session.id)
72
+ * // confirmed.status === 'captured'
73
+ * ```
74
+ */
75
+ export class TapPaymentProvider {
76
+ id = 'tap';
77
+ name = 'Tap Payments';
78
+ secretKey;
79
+ baseUrl;
80
+ webhookSecret;
81
+ constructor(config) {
82
+ this.secretKey = config.secretKey;
83
+ this.baseUrl = config.baseUrl ?? TAP_API_BASE;
84
+ this.webhookSecret = config.webhookSecret ?? null;
85
+ }
86
+ // ---------------------------------------------------------------------------
87
+ // Core methods (required by PaymentProvider)
88
+ // ---------------------------------------------------------------------------
89
+ async createSession(input) {
90
+ const body = {
91
+ amount: input.amount,
92
+ currency: input.currency,
93
+ threeDSecure: true,
94
+ source: { id: input.sourceToken ?? 'src_all' },
95
+ redirect: { url: input.returnUrl ?? '' },
96
+ ...(input.orderId ? { reference: { order: input.orderId } } : {}),
97
+ ...(input.customerId ? { customer: { id: input.customerId } } : {}),
98
+ // Include customer details if provided (and no customerId)
99
+ ...(!input.customerId && input.customer
100
+ ? {
101
+ customer: {
102
+ first_name: input.customer.firstName ?? '',
103
+ last_name: input.customer.lastName ?? '',
104
+ email: input.customer.email ?? '',
105
+ phone: input.customer.phone
106
+ ? { country_code: '966', number: input.customer.phone.replace(/^\+?966\s?/, '') }
107
+ : undefined,
108
+ },
109
+ }
110
+ : {}),
111
+ ...(input.metadata ? { metadata: input.metadata } : {}),
112
+ // Tap sends charge results to this URL asynchronously
113
+ ...(input.webhookUrl ? { post: { url: input.webhookUrl } } : {}),
114
+ };
115
+ const charge = await this.request('POST', '/charges', body);
116
+ return chargeToSession(charge, this.id);
117
+ }
118
+ async confirmSession(sessionId) {
119
+ // After 3DS redirect, re-fetch the charge to get the final status
120
+ return this.getSession(sessionId);
121
+ }
122
+ async getSession(sessionId) {
123
+ const charge = await this.request('GET', `/charges/${sessionId}`);
124
+ return chargeToSession(charge, this.id);
125
+ }
126
+ async refund(input) {
127
+ // First get the current charge to know the amount/currency
128
+ const current = await this.getSession(input.sessionId);
129
+ await this.request('POST', '/refunds', {
130
+ charge_id: input.sessionId,
131
+ amount: input.amount ?? current.amount,
132
+ currency: current.currency,
133
+ reason: input.reason ?? 'requested_by_customer',
134
+ });
135
+ // Re-fetch to get updated status
136
+ return this.getSession(input.sessionId);
137
+ }
138
+ // ---------------------------------------------------------------------------
139
+ // Optional methods
140
+ // ---------------------------------------------------------------------------
141
+ async cancelSession(sessionId) {
142
+ // Tap doesn't have a dedicated cancel endpoint.
143
+ // For authorized (not captured) transactions, we could void.
144
+ // For now, re-fetch and return current state.
145
+ return this.getSession(sessionId);
146
+ }
147
+ async verifyWebhook(payload, signature) {
148
+ // Tap's webhook verification uses a "hashstring" — NOT raw body HMAC.
149
+ // The hashstring is built by concatenating specific fields from the charge
150
+ // body with x_ prefixes, then HMAC-SHA256'd with the secret API key.
151
+ //
152
+ // Format for charges/authorizes:
153
+ // x_id{id}x_amount{amount}x_currency{currency}x_gateway_reference{ref}
154
+ // x_payment_reference{ref}x_status{status}x_created{created}
155
+ //
156
+ // See: https://developers.tap.company/docs/webhook#validate-the-webhook-hashstring
157
+ const bodyStr = typeof payload === 'string' ? payload : new TextDecoder().decode(payload);
158
+ const event = JSON.parse(bodyStr);
159
+ // Extract fields for hashstring
160
+ const id = event.id ?? '';
161
+ const amount = event.amount ?? '';
162
+ const currency = event.currency ?? '';
163
+ const gatewayRef = event.reference?.gateway ?? '';
164
+ const paymentRef = event.reference?.payment ?? '';
165
+ const status = event.status ?? '';
166
+ const created = event.transaction?.created ?? '';
167
+ // Build the hashstring input
168
+ const toBeHashed = `x_id${id}` +
169
+ `x_amount${amount}` +
170
+ `x_currency${currency}` +
171
+ `x_gateway_reference${gatewayRef}` +
172
+ `x_payment_reference${paymentRef}` +
173
+ `x_status${status}` +
174
+ `x_created${created}`;
175
+ // HMAC-SHA256 with the secret API key
176
+ const encoder = new TextEncoder();
177
+ const key = await globalThis.crypto.subtle.importKey('raw', encoder.encode(this.secretKey), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
178
+ const sig = await globalThis.crypto.subtle.sign('HMAC', key, encoder.encode(toBeHashed));
179
+ const computed = Array.from(new Uint8Array(sig))
180
+ .map(b => b.toString(16).padStart(2, '0'))
181
+ .join('');
182
+ if (computed !== signature) {
183
+ throw new Error('TapPaymentProvider: invalid webhook hashstring');
184
+ }
185
+ // Map Tap status to a normalized event type
186
+ const eventType = this.mapChargeStatusToEventType(event.status);
187
+ return {
188
+ type: eventType,
189
+ sessionId: String(event.id ?? ''),
190
+ data: event,
191
+ };
192
+ }
193
+ /** Map Tap charge status to a webhook event type */
194
+ mapChargeStatusToEventType(status) {
195
+ switch (status) {
196
+ case 'CAPTURED': return 'payment.captured';
197
+ case 'FAILED':
198
+ case 'DECLINED':
199
+ case 'RESTRICTED': return 'payment.failed';
200
+ case 'VOID':
201
+ case 'CANCELLED': return 'payment.cancelled';
202
+ case 'REFUNDED': return 'payment.refunded';
203
+ case 'TIMEDOUT':
204
+ case 'ABANDONED': return 'payment.expired';
205
+ default: return 'payment.updated';
206
+ }
207
+ }
208
+ // ---------------------------------------------------------------------------
209
+ // HTTP helper
210
+ // ---------------------------------------------------------------------------
211
+ async request(method, path, body) {
212
+ const url = `${this.baseUrl}${path}`;
213
+ const headers = {
214
+ 'Authorization': `Bearer ${this.secretKey}`,
215
+ 'Content-Type': 'application/json',
216
+ 'Accept': 'application/json',
217
+ };
218
+ const res = await fetch(url, {
219
+ method,
220
+ headers,
221
+ ...(body ? { body: JSON.stringify(body) } : {}),
222
+ });
223
+ if (!res.ok) {
224
+ const errorBody = await res.text();
225
+ throw new Error(`Tap API error (${res.status}): ${errorBody}`);
226
+ }
227
+ return res.json();
228
+ }
229
+ }
230
+ //# sourceMappingURL=tap-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tap-provider.js","sourceRoot":"","sources":["../src/tap-provider.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,uEAAuE;AACvE,8EAA8E;AAC9E,EAAE;AACF,uEAAuE;AACvE,0DAA0D;AAC1D,EAAE;AACF,mEAAmE;AACnE,8EAA8E;AAa9E,MAAM,YAAY,GAAG,4BAA4B,CAAA;AAEjD,mDAAmD;AACnD,SAAS,YAAY,CAAC,MAAuB;IAC3C,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,WAAW;YACd,OAAO,SAAS,CAAA;QAClB,KAAK,aAAa;YAChB,OAAO,YAAY,CAAA;QACrB,KAAK,UAAU;YACb,OAAO,UAAU,CAAA;QACnB,KAAK,MAAM,CAAC;QACZ,KAAK,WAAW,CAAC;QACjB,KAAK,UAAU,CAAC;QAChB,KAAK,WAAW;YACd,OAAO,WAAW,CAAA;QACpB,KAAK,QAAQ,CAAC;QACd,KAAK,UAAU,CAAC;QAChB,KAAK,YAAY;YACf,OAAO,QAAQ,CAAA;QACjB,KAAK,UAAU;YACb,OAAO,UAAU,CAAA;QACnB;YACE,OAAO,SAAS,CAAA;IACpB,CAAC;AACH,CAAC;AAED,+CAA+C;AAC/C,SAAS,eAAe,CAAC,MAAoB,EAAE,UAAkB;IAC/D,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,UAAU;QACV,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC;QACnC,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,YAAY,EAAE;YACZ,WAAW,EAAE,MAAM,CAAC,EAAE;YACtB,SAAS,EAAE,MAAM,CAAC,MAAM;YACxB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE,MAAM,CAAC,SAAS;SAC5B;QACD,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,GAAG,IAAI,IAAI;QAC5C,SAAS,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACtD,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,OAAO,kBAAkB;IACpB,EAAE,GAAG,KAAK,CAAA;IACV,IAAI,GAAG,cAAc,CAAA;IAEb,SAAS,CAAQ;IACjB,OAAO,CAAQ;IACf,aAAa,CAAe;IAE7C,YAAY,MAAiB;QAC3B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAA;QACjC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,YAAY,CAAA;QAC7C,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa,IAAI,IAAI,CAAA;IACnD,CAAC;IAED,8EAA8E;IAC9E,6CAA6C;IAC7C,8EAA8E;IAE9E,KAAK,CAAC,aAAa,CAAC,KAAgC;QAClD,MAAM,IAAI,GAA4B;YACpC,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,WAAW,IAAI,SAAS,EAAE;YAC9C,QAAQ,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,SAAS,IAAI,EAAE,EAAE;YACxC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjE,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnE,2DAA2D;YAC3D,GAAG,CAAC,CAAC,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,QAAQ;gBACrC,CAAC,CAAC;oBACE,QAAQ,EAAE;wBACR,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,SAAS,IAAI,EAAE;wBAC1C,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE;wBACxC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE;wBACjC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK;4BACzB,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,EAAE;4BACjF,CAAC,CAAC,SAAS;qBACd;iBACF;gBACH,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvD,sDAAsD;YACtD,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjE,CAAA;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAe,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,CAAA;QACzE,OAAO,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAA;IACzC,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,SAAiB;QACpC,kEAAkE;QAClE,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;IACnC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,SAAiB;QAChC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAe,KAAK,EAAE,YAAY,SAAS,EAAE,CAAC,CAAA;QAC/E,OAAO,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAA;IACzC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAkB;QAC7B,2DAA2D;QAC3D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QAEtD,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE;YACrC,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM;YACtC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,uBAAuB;SAChD,CAAC,CAAA;QAEF,iCAAiC;QACjC,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IACzC,CAAC;IAED,8EAA8E;IAC9E,mBAAmB;IACnB,8EAA8E;IAE9E,KAAK,CAAC,aAAa,CAAC,SAAiB;QACnC,gDAAgD;QAChD,6DAA6D;QAC7D,8CAA8C;QAC9C,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;IACnC,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,OAA4B,EAAE,SAAiB;QACjE,sEAAsE;QACtE,2EAA2E;QAC3E,qEAAqE;QACrE,EAAE;QACF,iCAAiC;QACjC,yEAAyE;QACzE,+DAA+D;QAC/D,EAAE;QACF,mFAAmF;QAEnF,MAAM,OAAO,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QACzF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAEjC,gCAAgC;QAChC,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;QACzB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,CAAA;QACjC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAA;QACrC,MAAM,UAAU,GAAG,KAAK,CAAC,SAAS,EAAE,OAAO,IAAI,EAAE,CAAA;QACjD,MAAM,UAAU,GAAG,KAAK,CAAC,SAAS,EAAE,OAAO,IAAI,EAAE,CAAA;QACjD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,CAAA;QACjC,MAAM,OAAO,GAAG,KAAK,CAAC,WAAW,EAAE,OAAO,IAAI,EAAE,CAAA;QAEhD,6BAA6B;QAC7B,MAAM,UAAU,GACd,OAAO,EAAE,EAAE;YACX,WAAW,MAAM,EAAE;YACnB,aAAa,QAAQ,EAAE;YACvB,sBAAsB,UAAU,EAAE;YAClC,sBAAsB,UAAU,EAAE;YAClC,WAAW,MAAM,EAAE;YACnB,YAAY,OAAO,EAAE,CAAA;QAEvB,sCAAsC;QACtC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;QACjC,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAClD,KAAK,EACL,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAC9B,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EACjC,KAAK,EACL,CAAC,MAAM,CAAC,CACT,CAAA;QACD,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAA;QACxF,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;aAC7C,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;aACzC,IAAI,CAAC,EAAE,CAAC,CAAA;QAEX,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAA;QACnE,CAAC;QAED,4CAA4C;QAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAE/D,OAAO;YACL,IAAI,EAAE,SAAS;YACf,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;YACjC,IAAI,EAAE,KAAK;SACZ,CAAA;IACH,CAAC;IAED,oDAAoD;IAC5C,0BAA0B,CAAC,MAAuB;QACxD,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,UAAU,CAAC,CAAC,OAAO,kBAAkB,CAAA;YAC1C,KAAK,QAAQ,CAAC;YACd,KAAK,UAAU,CAAC;YAChB,KAAK,YAAY,CAAC,CAAC,OAAO,gBAAgB,CAAA;YAC1C,KAAK,MAAM,CAAC;YACZ,KAAK,WAAW,CAAC,CAAC,OAAO,mBAAmB,CAAA;YAC5C,KAAK,UAAU,CAAC,CAAC,OAAO,kBAAkB,CAAA;YAC1C,KAAK,UAAU,CAAC;YAChB,KAAK,WAAW,CAAC,CAAC,OAAO,iBAAiB,CAAA;YAC1C,OAAO,CAAC,CAAC,OAAO,iBAAiB,CAAA;QACnC,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,cAAc;IACd,8EAA8E;IAEtE,KAAK,CAAC,OAAO,CAAI,MAAc,EAAE,IAAY,EAAE,IAAc;QACnE,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,CAAA;QACpC,MAAM,OAAO,GAA2B;YACtC,eAAe,EAAE,UAAU,IAAI,CAAC,SAAS,EAAE;YAC3C,cAAc,EAAE,kBAAkB;YAClC,QAAQ,EAAE,kBAAkB;SAC7B,CAAA;QAED,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC3B,MAAM;YACN,OAAO;YACP,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChD,CAAC,CAAA;QAEF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;YAClC,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,CAAC,MAAM,MAAM,SAAS,EAAE,CAAC,CAAA;QAChE,CAAC;QAED,OAAO,GAAG,CAAC,IAAI,EAAgB,CAAA;IACjC,CAAC;CACF"}
@@ -0,0 +1,60 @@
1
+ /** Configuration for TapPaymentProvider */
2
+ export interface TapConfig {
3
+ /** Tap secret API key (sk_test_... or sk_live_...) */
4
+ secretKey: string;
5
+ /** Tap webhook secret for signature verification (optional) */
6
+ webhookSecret?: string;
7
+ /** Use live mode (defaults to auto-detect from key prefix) */
8
+ liveMode?: boolean;
9
+ /** API base URL override (for testing) */
10
+ baseUrl?: string;
11
+ }
12
+ /** Tap charge object (subset of fields we use) */
13
+ export interface TapRawCharge {
14
+ id: string;
15
+ status: TapChargeStatus;
16
+ amount: number;
17
+ currency: string;
18
+ threeDSecure: boolean;
19
+ description?: string;
20
+ reference?: {
21
+ transaction?: string;
22
+ order?: string;
23
+ };
24
+ transaction?: {
25
+ url?: string;
26
+ created?: string;
27
+ authorization_id?: string;
28
+ };
29
+ redirect?: {
30
+ status?: string;
31
+ url?: string;
32
+ };
33
+ source?: {
34
+ id: string;
35
+ type: string;
36
+ payment_method?: string;
37
+ payment_type?: string;
38
+ };
39
+ customer?: {
40
+ id?: string;
41
+ first_name?: string;
42
+ last_name?: string;
43
+ email?: string;
44
+ };
45
+ metadata?: Record<string, unknown>;
46
+ created: string;
47
+ }
48
+ /** Known Tap charge status values */
49
+ export type TapChargeStatus = 'INITIATED' | 'IN_PROGRESS' | 'ABANDONED' | 'CAPTURED' | 'VOID' | 'CANCELLED' | 'FAILED' | 'DECLINED' | 'RESTRICTED' | 'REFUNDED' | 'TIMEDOUT';
50
+ /** Tap refund response */
51
+ export interface TapRawRefund {
52
+ id: string;
53
+ status: string;
54
+ amount: number;
55
+ currency: string;
56
+ charge_id: string;
57
+ reason?: string;
58
+ created: string;
59
+ }
60
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAIA,2CAA2C;AAC3C,MAAM,WAAW,SAAS;IACxB,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAA;IACjB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAID,kDAAkD;AAClD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,eAAe,CAAA;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,OAAO,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE;QACV,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,CAAA;IACD,WAAW,CAAC,EAAE;QACZ,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAC1B,CAAA;IACD,QAAQ,CAAC,EAAE;QACT,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,GAAG,CAAC,EAAE,MAAM,CAAA;KACb,CAAA;IACD,MAAM,CAAC,EAAE;QACP,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB,YAAY,CAAC,EAAE,MAAM,CAAA;KACtB,CAAA;IACD,QAAQ,CAAC,EAAE;QACT,EAAE,CAAC,EAAE,MAAM,CAAA;QACX,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,CAAA;IACD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,qCAAqC;AACrC,MAAM,MAAM,eAAe,GACvB,WAAW,GACX,aAAa,GACb,WAAW,GACX,UAAU,GACV,MAAM,GACN,WAAW,GACX,QAAQ,GACR,UAAU,GACV,YAAY,GACZ,UAAU,GACV,UAAU,CAAA;AAEd,0BAA0B;AAC1B,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAChB"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Tap Payments — config and raw API response types
3
+ // ---------------------------------------------------------------------------
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,mDAAmD;AACnD,8EAA8E"}
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@commercejs/payment-tap",
3
+ "version": "0.1.0",
4
+ "description": "Tap Payments provider for CommerceJS — redirect-based, PCI-free",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "dependencies": {
20
+ "@commercejs/types": "0.1.0"
21
+ },
22
+ "devDependencies": {
23
+ "typescript": "^5.7.0",
24
+ "vitest": "^4.0.0"
25
+ },
26
+ "scripts": {
27
+ "build": "tsc",
28
+ "typecheck": "tsc --noEmit",
29
+ "test": "vitest run",
30
+ "clean": "rm -rf dist"
31
+ }
32
+ }