import { chargeMatchesOrder, decideReservation, isBillingKeyOwnedBy, isValidIdempotencyKey, parseCheckoutRequest, planCheckoutFailure, } from './checkout-policy.ts' function assert(condition: boolean, message: string): asserts condition { if (!condition) throw new Error(message) } function assertEquals(actual: unknown, expected: unknown, message: string): void { const a = JSON.stringify(actual) const e = JSON.stringify(expected) if (a !== e) throw new Error(`${message}: expected ${e}, got ${a}`) } Deno.test('parseCheckoutRequest accepts a valid request with or without idempotency key', () => { assertEquals( parseCheckoutRequest({ payer_id: 'payer-12345', tier: 'pro' }), { payerId: 'payer-12345', tier: 'pro', idempotencyKey: undefined }, 'without key', ) assertEquals( parseCheckoutRequest({ payer_id: 'payer-12345', tier: 'pro_plus', idempotency_key: 'payple-checkout:abc-123', }), { payerId: 'payer-12345', tier: 'pro_plus', idempotencyKey: 'payple-checkout:abc-123' }, 'with key', ) }) Deno.test('parseCheckoutRequest rejects malformed bodies', () => { const invalid: unknown[] = [ null, 'string', {}, { payer_id: 'short', tier: 'pro' }, { payer_id: 'x'.repeat(256), tier: 'pro' }, { payer_id: 'payer-12345', tier: 'free' }, { payer_id: 12345678, tier: 'pro' }, { payer_id: 'payer-12345', tier: 'pro', idempotency_key: 'short' }, { payer_id: 'payer-12345', tier: 'pro', idempotency_key: 'has spaces in it!' }, { payer_id: 'payer-12345', tier: 'pro', idempotency_key: null }, ] for (const body of invalid) { assert(parseCheckoutRequest(body) === null, `must reject ${JSON.stringify(body)}`) } }) Deno.test('isValidIdempotencyKey enforces the database key format', () => { assert(isValidIdempotencyKey('payple-checkout:0123'), 'valid key') assert(!isValidIdempotencyKey('a'.repeat(11)), 'too short') assert(!isValidIdempotencyKey('a'.repeat(161)), 'too long') assert(!isValidIdempotencyKey(42), 'not a string') }) Deno.test('decideReservation proceeds only for a freshly created operation', () => { assertEquals( decideReservation({ created: true, operation_id: 'op-1', state: 'reserved' }), { kind: 'proceed', operationId: 'op-1' }, 'created', ) assertEquals( decideReservation({ created: false, operation_id: 'op-1', state: 'applied', reason: 'idempotent_replay' }), { kind: 'reject', status: 409, body: { error: 'idempotent_replay', state: 'applied' } }, 'replay never charges again', ) assertEquals( decideReservation(null), { kind: 'reject', status: 409, body: { error: 'payment_operation_in_progress', state: 'rejected' } }, 'missing reservation', ) assertEquals( decideReservation({ created: true }), { kind: 'reject', status: 409, body: { error: 'payment_operation_in_progress', state: 'rejected' } }, 'created without operation id', ) }) Deno.test('decideReservation surfaces an active paid period without charging (stale-tab double checkout)', () => { const decision = decideReservation({ created: false, state: 'rejected', reason: 'subscription_already_active', owner_provider: 'payple', tier: 'pro', current_period_end: '2026-10-28T00:00:00.000Z', }) assertEquals( decision, { kind: 'reject', status: 409, body: { error: 'subscription_already_active', state: 'rejected' } }, 'active subscriber is rejected before Payple is contacted', ) }) Deno.test('isBillingKeyOwnedBy requires a live key registered to the caller', () => { const owners = ['user-1', 'hashed-user-1'] assert( isBillingKeyOwnedBy({ PCD_PAY_RST: 'success', PCD_PAYER_ID: 'payer-1', PCD_PAYER_NO: 'hashed-user-1' }, 'payer-1', owners), 'owner accepted', ) assert( !isBillingKeyOwnedBy({ PCD_PAY_RST: 'error', PCD_PAYER_ID: 'payer-1', PCD_PAYER_NO: 'user-1' }, 'payer-1', owners), 'failed lookup rejected', ) assert( !isBillingKeyOwnedBy({ PCD_PAY_RST: 'success', PCD_PAYER_ID: 'payer-2', PCD_PAYER_NO: 'user-1' }, 'payer-1', owners), 'different billing key rejected', ) assert( !isBillingKeyOwnedBy({ PCD_PAY_RST: 'success', PCD_PAYER_ID: 'payer-1', PCD_PAYER_NO: '' }, 'payer-1', owners), 'missing payer number rejected', ) assert( !isBillingKeyOwnedBy({ PCD_PAY_RST: 'success', PCD_PAYER_ID: 'payer-1', PCD_PAYER_NO: 'user-2' }, 'payer-1', owners), 'other user rejected', ) }) Deno.test('chargeMatchesOrder binds the charge to the reserved order', () => { const expected = { orderId: 'D3RO-1', amount: 9900, payerId: 'payer-1' } assert(chargeMatchesOrder({ PCD_PAY_OID: 'D3RO-1', PCD_PAY_TOTAL: '9900' }, expected), 'no payer echo') assert( chargeMatchesOrder({ PCD_PAY_OID: 'D3RO-1', PCD_PAY_TOTAL: '9900', PCD_PAYER_ID: 'payer-1' }, expected), 'matching payer echo', ) assert(!chargeMatchesOrder({ PCD_PAY_OID: 'D3RO-2', PCD_PAY_TOTAL: '9900' }, expected), 'order mismatch') assert(!chargeMatchesOrder({ PCD_PAY_OID: 'D3RO-1', PCD_PAY_TOTAL: '100' }, expected), 'amount mismatch') assert( !chargeMatchesOrder({ PCD_PAY_OID: 'D3RO-1', PCD_PAY_TOTAL: '9900', PCD_PAYER_ID: 'payer-x' }, expected), 'payer mismatch', ) }) Deno.test('planCheckoutFailure keeps unknown charges reconcilable and releases safe failures', () => { const base = { hasOperation: true, externalChargeCompleted: false, chargeOutcomeUnknown: false, configurationError: false, } assertEquals( planCheckoutFailure({ ...base, chargeOutcomeUnknown: true }, 'payple_not_configured'), { mark: { state: 'external_created' }, status: 409, error: 'payment_requires_reconciliation' }, 'ambiguous charge', ) assertEquals( planCheckoutFailure(base, 'payple_not_configured'), { mark: { state: 'failed', errorCode: 'payple_checkout_failed' }, status: 502, error: 'payple_checkout_failed' }, 'failure before charge', ) assertEquals( planCheckoutFailure({ ...base, externalChargeCompleted: true }, 'payple_not_configured'), { mark: null, status: 409, error: 'payment_requires_reconciliation' }, 'failure after charge leaves the operation charged', ) assertEquals( planCheckoutFailure({ ...base, hasOperation: false, configurationError: true }, 'payple_not_configured'), { mark: null, status: 503, error: 'payple_not_configured' }, 'configuration error', ) assertEquals( planCheckoutFailure({ ...base, configurationError: true }, 'payple_not_configured'), { mark: { state: 'failed', errorCode: 'payple_not_configured' }, status: 503, error: 'payple_not_configured' }, 'configuration error with operation', ) })