// Handler-level regression tests with in-memory ports: no Supabase, no Payple. import { createPaypleWebhookHandler, type IgnoredProviderEvent, type PaypleWebhookPorts, type ProviderApplyResult, } from './index.ts' import type { CorrelatedPayment, PaypleProviderEventArgs } from './webhook-policy.ts' import { type PayplePaymentLookupResult, TIER_PRICE } from '../_shared/payple.ts' function assert(condition: boolean, message: string): asserts condition { if (!condition) throw new Error(message) } const OLD_ORDER = 'D3RO-20260801090000-user-oid1' const CURRENT_ORDER = 'D3RO-20260901090000-user-oid2' const PAYER = 'payer-billing-key' interface FakeState { applied: Array ignored: IgnoredProviderEvent[] } function fakePorts( state: FakeState, lookups: Record>, ): PaypleWebhookPorts { // Both orders were registered on the same billing key; oid2 (the renewal) // funds the current period. const operations: Record = { [OLD_ORDER]: { user_id: '00000000-0000-4000-8000-000000000001', tier: 'pro', operation_id: '00000000-0000-4000-8000-0000000000a1', payer_id: PAYER, current_order_id: CURRENT_ORDER, }, [CURRENT_ORDER]: { user_id: '00000000-0000-4000-8000-000000000001', tier: 'pro', operation_id: '00000000-0000-4000-8000-0000000000a2', payer_id: PAYER, current_order_id: CURRENT_ORDER, }, } return { correlatePayment: (orderId) => Promise.resolve(operations[orderId] ?? null), lookupPayment: ({ orderId, payType }) => Promise.resolve({ PCD_PAY_RST: 'success', PCD_PAY_CODE: 'PCHK0000', PCD_PAY_MSG: 'ok', PCD_PAY_OID: orderId, PCD_PAY_TYPE: payType, PCD_PAYER_ID: PAYER, PCD_PAY_TOTAL: String(TIER_PRICE.pro), PCD_PAY_TIME: '20260901090000', ...lookups[orderId], }), applyProviderEvent: (args): Promise => { state.applied.push(args) return Promise.resolve({ applied: true, duplicate: false }) }, recordIgnoredEvent: (event) => { state.ignored.push(event) return Promise.resolve() }, now: () => new Date('2026-09-15T00:00:00.000Z'), } } function cancellationRequest(orderId: string): Request { return new Request('http://localhost/payple-webhook', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ PCD_PAY_RST: 'success', PCD_PAY_CODE: 'PAYC0000', PCD_PAYCANCEL_FLAG: 'Y', PCD_PAY_OID: orderId, PCD_PAY_TYPE: 'card', PCD_PAYER_ID: PAYER, }), }) } Deno.test('refund of a past Payple order does not revoke the current paid subscription', async () => { const state: FakeState = { applied: [], ignored: [] } const handler = createPaypleWebhookHandler(() => fakePorts(state, { [OLD_ORDER]: { PCD_PAY_STATE: '승인취소완료', PCD_PAY_TIME: '20260801090000' }, })) const response = await handler(cancellationRequest(OLD_ORDER)) const body = await response.json() as Record assert(response.status === 200, `acknowledged, got ${response.status}`) assert(body.ignored === 'canceled_order_not_current', `ignored reason, got ${JSON.stringify(body)}`) assert(state.applied.length === 0, 'no entitlement change is applied') assert(state.ignored.length === 1, 'the ignored event is recorded') assert(state.ignored[0].eventId === `cancel:${OLD_ORDER}:승인취소완료`, 'event id recorded') assert(/^[0-9a-f]{64}$/.test(state.ignored[0].payloadDigest), 'digest recorded') }) Deno.test('refund of the current Payple order still revokes entitlement', async () => { const state: FakeState = { applied: [], ignored: [] } const handler = createPaypleWebhookHandler(() => fakePorts(state, { [CURRENT_ORDER]: { PCD_PAY_STATE: '승인취소완료' }, })) const response = await handler(cancellationRequest(CURRENT_ORDER)) assert(response.status === 200, `acknowledged, got ${response.status}`) assert(state.ignored.length === 0, 'nothing ignored') assert(state.applied.length === 1, 'revocation applied') const args = state.applied[0] assert(args.p_entitled === false && args.p_tier === 'free', 'revokes entitlement') assert(args.p_provider_order_id === CURRENT_ORDER, 'scoped to the current order') assert(/^[0-9a-f]{64}$/.test(args.p_payload_digest), 'digest attached') })