@stewardhq/sdk 0.5.0 → 0.7.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.
@@ -1,4 +1,4 @@
1
- import { A as SubscriptionStatusSchema, B as EmailSettingsPatchSchema, Bt as MeterCreditEntrySchema, C as AccountSchema, Ct as DecimalUnitsStringSchema, D as BillingProfileKindSchema, Fn as CurrencySchema, Gn as IdSchema, Hn as ExternalRefSchema, Ht as MeterDefSchema, I as EMAIL_TEMPLATES, In as DateTimeSchema, Jn as InvoicePaymentStatusSchema, Kn as IntervalSchema, Mn as ActorRefSchema, Nn as AmountMinorSchema, O as BillingProfileSchema, Pn as CodeSchema, Qt as MeteredPriceSchema, V as EmailSettingsSchema, Vt as MeterCreditPropertiesSchema, X as applyEmailSettingsPatch, Zt as MeteredPriceDefSchema, a as EVENT_TYPES, bt as CatalogMeterSchema, cn as plainDecimalOf, dt as CatalogBenefitSchema, en as meterFilterClauseOf, ht as featureValueMatchesType, ln as toMicroUnits, nn as MICRO_UNITS_PER_UNIT, o as EventIdSchema, qn as InvoiceBillingReasonSchema, st as BenefitDefSchema, w as AccountStateSchema, yt as AccountMetersSchema, zn as EntitlementsSchema } from "./events.js";
1
+ import { $t as MeteredPriceSchema, A as SubscriptionStatusSchema, Bn as EntitlementsSchema, C as AccountSchema, D as BillingProfileKindSchema, Et as MAX_METER_UNITS, Fn as CodeSchema, H as EmailSettingsSchema, Ht as MeterCreditPropertiesSchema, In as CurrencySchema, Jn as InvoiceBillingReasonSchema, Kn as IdSchema, L as EMAIL_TEMPLATES, Ln as DateTimeSchema, Nn as ActorRefSchema, O as BillingProfileSchema, Pn as AmountMinorSchema, Qt as MeteredPriceDefSchema, Un as ExternalRefSchema, Ut as MeterDefSchema, V as EmailSettingsPatchSchema, Vt as MeterCreditEntrySchema, X as PriceChangeNoticeMeteredRateSchema, Yn as InvoicePaymentStatusSchema, Z as applyEmailSettingsPatch, a as EVENT_TYPES, bt as AccountMetersSchema, ct as BenefitDefSchema, ft as CatalogBenefitSchema, gt as featureValueMatchesType, ln as plainDecimalOf, o as EventIdSchema, on as isMicroPrecise, qn as IntervalSchema, rn as MICRO_UNITS_PER_UNIT, tn as meterFilterClauseOf, un as toMicroUnits, w as AccountStateSchema, wt as DecimalUnitsStringSchema, xt as CatalogMeterSchema } from "./events.js";
2
2
  import { z } from "zod";
3
3
  //#region ../contract/src/catalog.ts
4
4
  const FeatureTypeSchema = z.enum([
@@ -346,17 +346,34 @@ const BrandingSchema = z.object({
346
346
  });
347
347
  const DEFAULT_PAYMENT_DUE_DAYS = 7;
348
348
  const DEFAULT_MIN_INVOICE_MINOR = 1e3;
349
+ const DEFAULT_BANK_TRANSFER_PAYMENT_DAYS = 5;
349
350
  const PaymentDueDaysSchema = z.number().int().min(1).max(60);
351
+ const BankTransferPaymentDaysSchema = z.number().int().min(1).max(14);
352
+ const BankTransferSettingsSchema = z.object({
353
+ enabled: z.boolean().default(false),
354
+ paymentDays: BankTransferPaymentDaysSchema.default(5)
355
+ });
350
356
  const BillingSettingsSchema = z.object({
351
357
  paymentDueDays: PaymentDueDaysSchema.default(7),
352
358
  minInvoiceMinor: AmountMinorSchema.default(DEFAULT_MIN_INVOICE_MINOR),
353
- allowMultipleSubscriptions: z.boolean().default(false)
359
+ allowMultipleSubscriptions: z.boolean().default(false),
360
+ bankTransfer: BankTransferSettingsSchema.default({
361
+ enabled: false,
362
+ paymentDays: 5
363
+ })
354
364
  });
365
+ /** Patch of `settings.billing.bankTransfer`: an omitted field is unchanged, `null` restores its default. */
366
+ const BankTransferSettingsPatchSchema = z.object({
367
+ enabled: z.boolean().nullable().optional(),
368
+ paymentDays: BankTransferPaymentDaysSchema.nullable().optional()
369
+ }).strict();
355
370
  /** Patch of `settings.billing`: an omitted field is unchanged, `null` restores its default. */
356
371
  const BillingSettingsPatchSchema = z.object({
357
372
  paymentDueDays: PaymentDueDaysSchema.nullable().optional(),
358
373
  minInvoiceMinor: AmountMinorSchema.nullable().optional(),
359
- allowMultipleSubscriptions: z.boolean().nullable().optional()
374
+ allowMultipleSubscriptions: z.boolean().nullable().optional(),
375
+ /** Merges per field; `bankTransfer: null` restores its defaults (off). */
376
+ bankTransfer: BankTransferSettingsPatchSchema.nullable().optional()
360
377
  }).strict();
361
378
  const DEFAULT_EVENT_RETENTION_DAYS = 120;
362
379
  const DEFAULT_LATE_GRACE_MINUTES = 60;
@@ -423,6 +440,12 @@ const BrandingPatchSchema = z.object({
423
440
  }).strict();
424
441
  /** `PATCH /v1/admin/settings` gövdesi. */
425
442
  const ProductSettingsPatchSchema = z.object({
443
+ /**
444
+ * The payment provider for NEW checkouts and payment sessions (issue #57 decision 2; an open
445
+ * session keeps the provider it was opened with). Steward refuses a provider this deployment
446
+ * has not configured (422 `provider_not_available`).
447
+ */
448
+ provider: z.string().regex(/^[a-z][a-z0-9_-]{0,39}$/, "a provider id (lowercase)").optional(),
426
449
  appUrl: WebUrlSchema.nullable().optional(),
427
450
  defaultCurrency: CurrencySchema.optional(),
428
451
  defaultLocale: SettingsLocaleSchema.optional(),
@@ -446,6 +469,17 @@ const MERGED_SECTIONS = /* @__PURE__ */ new Set([
446
469
  "events",
447
470
  "metering"
448
471
  ]);
472
+ /** Objects inside a merged section that merge one level deeper (`billing.bankTransfer`). */
473
+ const NESTED_MERGED_FIELDS = /* @__PURE__ */ new Set(["bankTransfer"]);
474
+ /** Field-by-field merge: `null` deletes a field (its default comes back), `undefined` keeps it. */
475
+ function mergeFields(current, patch, nested = /* @__PURE__ */ new Set()) {
476
+ const merged = { ...current };
477
+ for (const [field, value] of Object.entries(patch)) if (value === null) delete merged[field];
478
+ else if (value === void 0) continue;
479
+ else if (nested.has(field)) merged[field] = mergeFields(current[field] ?? {}, value);
480
+ else merged[field] = value;
481
+ return merged;
482
+ }
449
483
  /**
450
484
  * Doğrulanmış yamayı ayarlara uygular (saf). Sonuç şemadan geçer; alan kuralları
451
485
  * yamada zaten denetlendiği için yalnızca programlama hatasında fırlatır.
@@ -464,12 +498,7 @@ function applySettingsPatch(current, patch) {
464
498
  } else if (key === "emails") next.emails = applyEmailSettingsPatch(current.emails, value);
465
499
  else if (MERGED_SECTIONS.has(key)) {
466
500
  if (value === null) delete next[key];
467
- else {
468
- const section = { ...current[key] ?? {} };
469
- for (const [field, fieldValue] of Object.entries(value)) if (fieldValue === null) delete section[field];
470
- else if (fieldValue !== void 0) section[field] = fieldValue;
471
- next[key] = section;
472
- }
501
+ else next[key] = mergeFields(current[key] ?? {}, value, NESTED_MERGED_FIELDS);
473
502
  } else if (value === null) delete next[key];
474
503
  else next[key] = value;
475
504
  }
@@ -540,7 +569,15 @@ const CheckoutSessionCreateInputSchema = z.object({
540
569
  /** Opens the account with this name if it does not exist; never renames an existing account. */
541
570
  displayName: z.string().min(1).max(200).optional(),
542
571
  prefill: CheckoutPrefillSchema.optional(),
543
- consents: z.array(CheckoutConsentInputSchema).max(20).optional()
572
+ consents: z.array(CheckoutConsentInputSchema).max(20).optional(),
573
+ /**
574
+ * Upgrade (bank transfer plan H16): a live subscription of the account this checkout replaces.
575
+ * It does not block the session (`already_subscribed`) and keeps running until the payment is
576
+ * recorded; in the transaction that records it (card or bank transfer) it is canceled
577
+ * immediately and the new subscription starts. An abandoned, expired or canceled session leaves
578
+ * it untouched. Not a live subscription of the account → 422 `replaces_subscription_invalid`.
579
+ */
580
+ replacesSubscriptionId: IdSchema.optional()
544
581
  }).superRefine((body, ctx) => {
545
582
  const seen = /* @__PURE__ */ new Set();
546
583
  body.consents?.forEach((consent, i) => {
@@ -567,7 +604,18 @@ const CheckoutStatusSchema = z.enum([
567
604
  "expired",
568
605
  "canceled"
569
606
  ]);
570
- /** Provider form shown on steward's hosted checkout page (never returned to the product). */
607
+ /**
608
+ * How the customer chose to pay on the hosted page (bank transfer plan H5): `card` (the provider's
609
+ * form) or `bank_transfer` (the session stays `open` until an operator records the transfer).
610
+ * Absent/null: not chosen yet. The session status set does not change for it.
611
+ */
612
+ const PAYMENT_METHODS = ["card", "bank_transfer"];
613
+ const PaymentMethodSchema = z.enum(PAYMENT_METHODS);
614
+ /**
615
+ * Provider form shown on steward's hosted checkout page (never returned to the product).
616
+ * @deprecated Ürün yüzeyinde kullanılmıyor; yalnızca servis içi. Bir sonraki minor sürümde paketin
617
+ * dış yüzeyinden çıkarılacak (temizlik planı C9).
618
+ */
571
619
  const ProviderPayloadSchema = z.discriminatedUnion("type", [z.object({
572
620
  type: z.literal("html_snippet"),
573
621
  html: z.string()
@@ -595,7 +643,11 @@ const CheckoutSessionSchema = z.object({
595
643
  subscriptionId: IdSchema.nullable(),
596
644
  expiresAt: DateTimeSchema,
597
645
  createdAt: DateTimeSchema,
598
- completedAt: DateTimeSchema.nullable()
646
+ completedAt: DateTimeSchema.nullable(),
647
+ /** Payment method chosen on the page (H6); absent (or null): not chosen yet, or an older steward. */
648
+ paymentMethod: PaymentMethodSchema.nullable().optional(),
649
+ /** The subscription this checkout replaces (H16); absent (or null): none, or an older steward. */
650
+ replacesSubscriptionId: IdSchema.nullable().optional()
599
651
  });
600
652
  /**
601
653
  * `POST /v1/accounts/{ref}/checkout-sessions` response: `url` is steward's checkout page
@@ -640,9 +692,227 @@ const CHECKOUT_ERRORS = [
640
692
  "provider_not_configured",
641
693
  "provider_error",
642
694
  "account_deleted",
643
- "meter_already_billed"
695
+ "meter_already_billed",
696
+ "replaces_subscription_invalid"
644
697
  ];
645
698
  //#endregion
699
+ //#region ../contract/src/bank-transfers.ts
700
+ const BankTransferRecordInputSchema = z.object({
701
+ /** The account's order code as written in the transfer description (`K7M2-QX9D-4`; case and separators are forgiven). */
702
+ code: z.string().min(1).max(40),
703
+ /** The amount received, minor units (kuruş, cent); must equal what the item waits for. */
704
+ amountMinor: z.number().int().positive(),
705
+ currency: CurrencySchema,
706
+ /** When the money reached the account. */
707
+ receivedAt: DateTimeSchema,
708
+ /** The bank's transaction / receipt number; one payment per reference. */
709
+ bankRef: z.string().trim().min(1).max(100),
710
+ /** Settle this checkout (required when several items match, and with `acceptExpired`). */
711
+ checkoutSessionId: IdSchema.optional(),
712
+ /** Pay this invoice (a checkout matches too, or a written-off invoice the transfer pays). */
713
+ invoiceId: IdSchema.optional(),
714
+ /** H10: settle the named checkout although it expired (a late transfer the operator accepts). */
715
+ acceptExpired: z.boolean().optional()
716
+ }).strict().refine((input) => !input.acceptExpired || input.checkoutSessionId !== void 0, {
717
+ path: ["checkoutSessionId"],
718
+ message: "acceptExpired needs checkoutSessionId"
719
+ }).refine((input) => input.checkoutSessionId === void 0 || input.invoiceId === void 0, {
720
+ path: ["invoiceId"],
721
+ message: "name either checkoutSessionId or invoiceId"
722
+ });
723
+ const BankTransferRecordedSchema = z.object({
724
+ accountRef: ExternalRefSchema,
725
+ code: z.string(),
726
+ /** The checkout the transfer completed; null when it paid an invoice. */
727
+ checkoutSessionId: IdSchema.nullable(),
728
+ /** The invoice the transfer paid; null when it completed a checkout. */
729
+ invoiceId: IdSchema.nullable(),
730
+ subscriptionId: IdSchema,
731
+ paymentId: IdSchema,
732
+ /** The subscription the upgrade replaced (canceled in the same transaction, H16); null: none. */
733
+ replacedSubscriptionId: IdSchema.nullable(),
734
+ /** The checkout had expired and the operator accepted the transfer (H10). */
735
+ acceptedAfterExpiry: z.boolean(),
736
+ /** The paid invoice had been written off (waived / uncollectible). */
737
+ paidAfterWriteoff: z.boolean(),
738
+ /** The account's state after the recording. */
739
+ account: AccountStateSchema.optional()
740
+ });
741
+ //#endregion
742
+ //#region ../contract/src/admin.ts
743
+ const API_KEY_SCOPES = [
744
+ "product",
745
+ "admin",
746
+ "checkout"
747
+ ];
748
+ const ApiKeyScopeSchema = z.enum(API_KEY_SCOPES);
749
+ /** The public part of a key: the 12 hex characters after `stw_` (in logs, audit rows and `doctor`). */
750
+ const ApiKeyPrefixSchema = z.string().regex(/^[0-9a-f]{12}$/, "12 lowercase hex characters");
751
+ /**
752
+ * `stw_<prefix: 12 hex>_<secret: 43 base64url>`. A low-variety secret (e.g. one character
753
+ * repeated) is refused; `generateApiKeyToken` draws 32 random bytes.
754
+ */
755
+ const ApiKeyTokenSchema = z.string().regex(/^stw_[0-9a-f]{12}_[A-Za-z0-9_-]{43}$/, "stw_ + 12 hex + _ + 43 base64url characters").refine((token) => new Set(token.slice(17)).size >= 16, "the secret is not random enough");
756
+ /** Longest expiry a key can be given, in days (about ten years). */
757
+ const MAX_API_KEY_TTL_DAYS = 3650;
758
+ const ApiKeyCreateInputSchema = z.object({
759
+ /** Generated by the client (`generateApiKeyToken`); never echoed back. */
760
+ token: ApiKeyTokenSchema,
761
+ name: z.string().trim().min(1).max(100),
762
+ scope: ApiKeyScopeSchema,
763
+ /**
764
+ * Whole days until the key expires. Omitted: the scope's default (admin 90 days, others never).
765
+ * null: never expires, refused for an admin key (issue #57 decision 1).
766
+ */
767
+ expiresInDays: z.number().int().min(1).max(MAX_API_KEY_TTL_DAYS).nullable().optional()
768
+ }).strict().refine((input) => !(input.scope === "admin" && input.expiresInDays === null), {
769
+ path: ["expiresInDays"],
770
+ message: "an admin key must expire"
771
+ });
772
+ const ApiKeySchema = z.object({
773
+ prefix: ApiKeyPrefixSchema,
774
+ name: z.string(),
775
+ scope: ApiKeyScopeSchema,
776
+ createdAt: DateTimeSchema,
777
+ /** Updated at most once a minute. */
778
+ lastUsedAt: DateTimeSchema.nullable(),
779
+ expiresAt: DateTimeSchema.nullable(),
780
+ revokedAt: DateTimeSchema.nullable()
781
+ });
782
+ /** `GET /v1/admin/api-keys`: the product's keys, revoked and expired ones included, oldest first. */
783
+ const ApiKeyListSchema = z.object({ items: z.array(ApiKeySchema) });
784
+ /** A new API key token (`stw_…`), Web Crypto; Node ≥22, edge and workerd. Store it once, send it once. */
785
+ function generateApiKeyToken() {
786
+ const random = (n) => globalThis.crypto.getRandomValues(new Uint8Array(n));
787
+ return `stw_${[...random(6)].map((b) => b.toString(16).padStart(2, "0")).join("")}_${btoa(String.fromCharCode(...random(32))).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "")}`;
788
+ }
789
+ const DUNNING_ACTIONS = [
790
+ "retry_payment",
791
+ "suspend",
792
+ "terminate"
793
+ ];
794
+ /**
795
+ * `products.dunning_policy`: steps by days after the first failed payment; `dryRun` only audits.
796
+ * Not strict: stored policies are read through it too (an unknown field must not turn a stored
797
+ * policy into the default).
798
+ */
799
+ const DunningPolicySchema = z.object({
800
+ steps: z.array(z.object({
801
+ afterDays: z.number().min(0).max(365),
802
+ action: z.enum(DUNNING_ACTIONS)
803
+ })).refine((steps) => steps.every((s, i) => i === 0 || s.afterDays >= steps[i - 1].afterDays), "steps must be in order of days"),
804
+ dryRun: z.boolean().default(true)
805
+ });
806
+ /** `POST /v1/admin/events/:id/redeliver`: every delivery of the event requeued, attempts reset. */
807
+ const RedeliveredEventSchema = z.object({
808
+ eventId: EventIdSchema,
809
+ type: z.string(),
810
+ deliveries: z.array(z.object({
811
+ endpointId: IdSchema,
812
+ status: z.enum([
813
+ "pending",
814
+ "delivered",
815
+ "dead"
816
+ ]),
817
+ attempts: z.number().int().nonnegative(),
818
+ nextAttemptAt: DateTimeSchema
819
+ }))
820
+ });
821
+ const MAX_NOTICE_DAYS = 3650;
822
+ const RepriceInputSchema = z.object({
823
+ planCode: CodeSchema,
824
+ /** The move takes effect from the first period boundary at least this many days away. */
825
+ noticeDays: z.number().int().min(0).max(MAX_NOTICE_DAYS),
826
+ /** true: the same list, nothing written and no e-mail. Required so a real run is never implicit. */
827
+ dryRun: z.boolean()
828
+ }).strict();
829
+ const RepriceItemSchema = z.object({
830
+ subscriptionId: IdSchema,
831
+ accountRef: ExternalRefSchema,
832
+ interval: IntervalSchema,
833
+ currency: CurrencySchema,
834
+ oldAmountMinor: z.number().int(),
835
+ newAmountMinor: z.number().int(),
836
+ taxInclusive: z.boolean(),
837
+ /** The boundary the current amount applies from; null for a skipped subscription. */
838
+ effectiveAt: DateTimeSchema.nullable(),
839
+ action: z.enum([
840
+ "schedule",
841
+ "already_scheduled",
842
+ "skip"
843
+ ]),
844
+ reason: z.enum([
845
+ "cancel_scheduled",
846
+ "change_scheduled",
847
+ "legacy_provider",
848
+ "no_period"
849
+ ]).optional(),
850
+ /** The metered rates that change (locked → current); absent when none does. */
851
+ meteredRates: z.array(PriceChangeNoticeMeteredRateSchema).optional()
852
+ });
853
+ const RepriceResultSchema = z.object({
854
+ dryRun: z.boolean(),
855
+ /** The earliest boundary a move can take effect at (now + notice days). */
856
+ effectiveNotBefore: DateTimeSchema,
857
+ /** Subscriptions scheduled by this run (one notice e-mail each); 0 on a dry run. */
858
+ scheduled: z.number().int().nonnegative(),
859
+ items: z.array(RepriceItemSchema)
860
+ });
861
+ /** `POST /v1/admin/accounts/:ref/meters/recompute`: every meter, or one. */
862
+ const MeterRecomputeInputSchema = z.object({ meter: CodeSchema.optional() }).strict();
863
+ const MeterRecomputeResultSchema = z.object({ items: z.array(z.object({
864
+ meter: CodeSchema,
865
+ /** The open period rebuilt; null when the account has no open period of the meter. */
866
+ periodStart: DateTimeSchema.nullable(),
867
+ periodEnd: DateTimeSchema.nullable(),
868
+ /** Consumption before and after (decimal strings). */
869
+ before: z.string().nullable(),
870
+ after: z.string().nullable()
871
+ })) });
872
+ /** `POST /v1/admin/accounts/:ref/meters/close-periods`: `force` does not wait for unrolled events. */
873
+ const MeterClosePeriodsInputSchema = z.object({
874
+ meter: CodeSchema.optional(),
875
+ force: z.boolean().optional()
876
+ }).strict();
877
+ const MeterClosePeriodsResultSchema = z.object({
878
+ closed: z.number().int().nonnegative(),
879
+ /** `meter.period_closed` events written. */
880
+ events: z.number().int().nonnegative(),
881
+ /** Closing periods left (not ended yet, or waiting for the rollup). */
882
+ pending: z.number().int().nonnegative()
883
+ });
884
+ /**
885
+ * `POST /v1/admin/accounts/:ref/credits`: positive units = `manual_grant` (as the product route),
886
+ * negative = `adjustment` (a correction; admin only, issue #57 decision 3). Response:
887
+ * `CreditGrantResponseSchema`.
888
+ */
889
+ const CreditAdjustmentInputSchema = z.object({
890
+ meter: CodeSchema,
891
+ units: z.number().min(-MAX_METER_UNITS).max(MAX_METER_UNITS).refine((value) => value !== 0, "must not be zero").refine((value) => isMicroPrecise(value), "at most 6 decimal places"),
892
+ reason: z.string().trim().min(3).max(500)
893
+ }).strict();
894
+ const BANK_TRANSFER_LIST_STATUSES = ["pending", "expired"];
895
+ const BankTransferListStatusSchema = z.enum(BANK_TRANSFER_LIST_STATUSES);
896
+ const BankTransferListItemSchema = z.object({
897
+ kind: z.enum(["checkout", "invoice"]),
898
+ id: IdSchema,
899
+ /** The session status, or the invoice's payment status. */
900
+ status: z.string(),
901
+ /** The checkout's plan, or the invoice's subscription plan (null: none). */
902
+ planCode: z.string().nullable(),
903
+ totalMinor: z.number().int(),
904
+ currency: CurrencySchema,
905
+ /** The session's expiry, or the invoice's due date (null: none). */
906
+ deadline: DateTimeSchema.nullable(),
907
+ /** The account's order code (in the transfer description). */
908
+ code: z.string().nullable(),
909
+ accountRef: ExternalRefSchema,
910
+ /** When bank transfer was chosen (checkouts); null for invoices. */
911
+ selectedAt: DateTimeSchema.nullable()
912
+ });
913
+ /** `GET /v1/admin/bank-transfers`: `pending` by deadline; `expired`: expired in the last 30 days. */
914
+ const BankTransferListSchema = z.object({ items: z.array(BankTransferListItemSchema) });
915
+ //#endregion
646
916
  //#region ../contract/src/portal.ts
647
917
  const PortalSessionCreateInputSchema = z.object({
648
918
  /** Sayfa dili; verilmezse ürün ayarı `defaultLocale`. */
@@ -1034,6 +1304,11 @@ const ERROR_CODES = Object.freeze({
1034
1304
  actor_ref_required: spec(400, "validation"),
1035
1305
  idempotency_key_required: spec(400, "validation"),
1036
1306
  invalid_idempotency_key: spec(400, "validation"),
1307
+ /**
1308
+ * The request body is over the route's limit (`/v1`: 64 KiB; catalog sync 1 MiB; invoice issue
1309
+ * 10 MiB). Event ingest keeps its own code (`batch_too_large`).
1310
+ */
1311
+ payload_too_large: spec(413, "validation"),
1037
1312
  /** Anahtar yok / iptal / yanlış — neden ayrıştırılmaz. */
1038
1313
  unauthorized: spec(401, "config"),
1039
1314
  /** Admin kapsamı gereken uç. */
@@ -1052,6 +1327,22 @@ const ERROR_CODES = Object.freeze({
1052
1327
  checkout_session_not_found: spec(404, "not_found"),
1053
1328
  /** Yönetim ucu: endpoint yok ya da başka ürünün. */
1054
1329
  webhook_endpoint_not_found: spec(404, "not_found"),
1330
+ /** Admin endpoint (issue #57): no API key of the product has this prefix. */
1331
+ api_key_not_found: spec(404, "not_found"),
1332
+ /** Admin endpoint (issue #57): no event of the product has this id. */
1333
+ event_not_found: spec(404, "not_found"),
1334
+ /**
1335
+ * `POST /v1/admin/webhook-endpoints`: the URL fails the SSRF policy (through the Ingress only public
1336
+ * `https://` names resolving to public addresses; cluster addresses only from inside the cluster).
1337
+ * The message says which rule.
1338
+ */
1339
+ webhook_url_not_allowed: spec(422, "validation"),
1340
+ /** `POST /v1/admin/api-keys`: a key with this prefix already exists (generate a new token). */
1341
+ api_key_exists: spec(409, "conflict"),
1342
+ /** `POST /v1/admin/api-keys/:prefix/revoke`: a key cannot revoke itself (revoke it with another admin key). */
1343
+ api_key_self_revoke: spec(409, "conflict"),
1344
+ /** `PATCH /v1/admin/settings`: the `provider` is not configured in this deployment. */
1345
+ provider_not_available: spec(422, "validation"),
1055
1346
  /** Ürün için henüz katalog senkronlanmadı (404 ama kurulum eksiği). */
1056
1347
  catalog_not_configured: spec(404, "config"),
1057
1348
  plan_missing_feature: spec(422, "validation"),
@@ -1065,12 +1356,14 @@ const ERROR_CODES = Object.freeze({
1065
1356
  already_subscribed: spec(409, "conflict"),
1066
1357
  already_canceled: spec(409, "conflict"),
1067
1358
  /**
1068
- * LEGACY — no longer produced (billing core, M35: no plan rank). Steward before the billing core
1359
+ * @deprecated LEGACY — no longer produced (billing core, M35: no plan rank). Steward before the billing core
1069
1360
  * answered `PUT …/plan` `mode: "strict"` with it when a live subscription's plan outranked the
1070
1361
  * target. Kept so clients that handle it keep compiling.
1071
1362
  */
1072
1363
  subscription_plan_higher: spec(409, "conflict"),
1073
1364
  plan_not_sellable: spec(422, "validation"),
1365
+ /** Checkout `replacesSubscriptionId` (bank transfer plan H16): not a live subscription of the account. */
1366
+ replaces_subscription_invalid: spec(422, "validation"),
1074
1367
  /**
1075
1368
  * F4e: hesap silinmiş (anonimleştirilmiş). `/v1/accounts/:ref` altındaki her uç (tekrar
1076
1369
  * `DELETE` ve aynı ref'le `PUT` dahil) 410 döner; hesap geri açılmaz.
@@ -1078,13 +1371,26 @@ const ERROR_CODES = Object.freeze({
1078
1371
  account_deleted: spec(410, "not_found"),
1079
1372
  /** `DELETE /v1/accounts/:ref`: canlı abonelik (dönem sonunda iptali planlı dahil) var; önce hemen iptal. */
1080
1373
  subscription_active: spec(409, "conflict"),
1081
- /** `DELETE /v1/accounts/:ref`: sağlayıcı formu açık checkout oturumu var; süresi dolup kapanınca tekrar dene. */
1374
+ /**
1375
+ * `DELETE /v1/accounts/:ref`: sağlayıcı formu açık ya da havale bekleyen (bank transfer plan H5) checkout
1376
+ * oturumu var; kapanınca (süre dolumu, ödeme kaydı) tekrar dene.
1377
+ */
1082
1378
  checkout_in_progress: spec(409, "conflict", true),
1083
1379
  /** `successUrl`, `cancelUrl` or portal `returnUrl` is not in the product's allowed origins: product misconfiguration. */
1084
1380
  return_url_not_allowed: spec(422, "config"),
1085
1381
  /** Bu deployment'ta sağlayıcı yapılandırılmamış (503 ama beklemekle düzelmez). */
1086
1382
  provider_not_configured: spec(503, "config"),
1087
1383
  provider_error: spec(502, "provider"),
1384
+ /** Not an order code, or its check symbol does not match (a typo in the transfer description). */
1385
+ bank_transfer_code_invalid: spec(422, "validation"),
1386
+ /** No account of the product has this order code. */
1387
+ bank_transfer_code_not_found: spec(404, "not_found"),
1388
+ /** This bank reference is already recorded. */
1389
+ bank_transfer_duplicate: spec(409, "conflict"),
1390
+ /** Nothing of the account waits for exactly this amount, or several items do (name one), or the named checkout is not one. */
1391
+ bank_transfer_unmatched: spec(422, "conflict"),
1392
+ /** The checkout expired (only `acceptExpired` settles it), is closed or cannot be completed: refund the transfer. */
1393
+ bank_transfer_rejected: spec(409, "conflict"),
1088
1394
  already_issued: spec(409, "conflict"),
1089
1395
  number_taken: spec(409, "conflict"),
1090
1396
  invalid_document: spec(422, "validation"),
@@ -1126,14 +1432,21 @@ const ERROR_CODES = Object.freeze({
1126
1432
  internal_error: spec(500, "unavailable", true),
1127
1433
  /** `/health`: veritabanına ulaşılamıyor. */
1128
1434
  database_unavailable: spec(503, "unavailable", true),
1129
- /** F2c (K26): anahtar prefix'i başına bütçe aşıldı; `Retry-After` başlığı taşır. */
1435
+ /**
1436
+ * Always with `Retry-After` (seconds). `/v1`: the key's budget for the route is spent, or the client
1437
+ * IP is blocked after too many rejected keys (`service/src/http/rate-limit.ts`, issue #43). Hosted
1438
+ * pages: wrong page key / action limit (`hosted/routes.ts`, `hosted/portal-routes.ts`).
1439
+ */
1130
1440
  rate_limited: spec(429, "unavailable", true),
1131
1441
  unknown_provider: spec(404, "not_found"),
1132
1442
  bad_signature: spec(401, "config"),
1133
1443
  invalid_payload: spec(400, "validation"),
1134
1444
  stale_event: spec(400, "validation"),
1135
1445
  not_configured: spec(503, "config"),
1136
- /** Yalnızca sahte sağlayıcı (yerel/test). */
1446
+ /**
1447
+ * @deprecated Üretilmiyor: sağlayıcı abonelik yolu silindi (M30) ve sahte sağlayıcı da bu kodu
1448
+ * döndürmüyor. Eski istemciler derlensin diye duruyor; bir sonraki minor sürümde kaldırılacak.
1449
+ */
1137
1450
  unknown_subscription: spec(404, "not_found")
1138
1451
  });
1139
1452
  function isKnownErrorCode(code) {
@@ -1502,25 +1815,26 @@ const LOOPBACK_HOSTS = /* @__PURE__ */ new Set([
1502
1815
  ]);
1503
1816
  const CLUSTER_SUFFIX = ".svc.cluster.local";
1504
1817
  /**
1505
- * Adres politikası; uygunsa null, değilse nedeni. `allowLoopback` üretimde false.
1506
- * Şemadan ayrıdır: üretim bilgisi yalnızca serviste var (servis ve sahte steward
1507
- * gövde şemasına `superRefine` ile ekler).
1818
+ * Address SYNTAX policy; null when acceptable, otherwise the reason. `allowLoopback` is false in
1819
+ * production. Separate from the schema: only the service knows whether it runs in production. The
1820
+ * service adds the SSRF rules on top (who may register a cluster address, public names only, DNS
1821
+ * resolving to public addresses; `service/src/domain/webhook-url-policy.ts`).
1508
1822
  */
1509
1823
  function webhookEndpointUrlProblem(value, options) {
1510
1824
  let url;
1511
1825
  try {
1512
1826
  url = new URL(value);
1513
1827
  } catch {
1514
- return "geçerli bir adres değil";
1828
+ return "not a valid url";
1515
1829
  }
1516
- if (url.username !== "" || url.password !== "") return "adreste kullanıcı bilgisi olamaz";
1830
+ if (url.username !== "" || url.password !== "") return "url must not contain credentials";
1517
1831
  if (url.protocol === "https:") return null;
1518
1832
  const host = url.hostname.toLowerCase();
1519
1833
  if (url.protocol === "http:") {
1520
1834
  if (host.endsWith(CLUSTER_SUFFIX) && host.length > 18) return null;
1521
1835
  if (options.allowLoopback && LOOPBACK_HOSTS.has(host)) return null;
1522
1836
  }
1523
- return options.allowLoopback ? "https://, cluster içi http://*.svc.cluster.local ya da http://localhost olmalı" : "https:// ya da cluster içi http://*.svc.cluster.local olmalı";
1837
+ return options.allowLoopback ? "must be https://, cluster-internal http://*.svc.cluster.local or http://localhost" : "must be https:// or cluster-internal http://*.svc.cluster.local";
1524
1838
  }
1525
1839
  const EndpointUrlSchema = z.url({ protocol: /^https?$/ }).max(2e3).refine((value) => !hasSecretMarker(value), "adres sır içeremez");
1526
1840
  const DescriptionSchema = z.string().trim().min(1).max(200).refine((value) => !hasSecretMarker(value), "açıklama sır içeremez");
@@ -1546,7 +1860,10 @@ const WebhookLastDeliverySchema = z.object({
1546
1860
  "dead"
1547
1861
  ]),
1548
1862
  httpStatus: z.number().int().nullable(),
1549
- /** `http_<kod>`, `timeout`, `network_error`, `endpoint_inactive`; başarıda null. */
1863
+ /**
1864
+ * `http_<kod>`, `timeout`, `network_error`, `endpoint_inactive`, `url_not_allowed` (the URL or the
1865
+ * address it resolves to fails the SSRF policy at send time); başarıda null.
1866
+ */
1550
1867
  error: z.string().nullable(),
1551
1868
  attempts: z.number().int().nonnegative(),
1552
1869
  at: DateTimeSchema
@@ -1559,6 +1876,11 @@ const WebhookEndpointSchema = z.object({
1559
1876
  /** null: filtre yok, yalnızca 0.1'in 15 eski tipi (`LEGACY_EVENT_TYPES`). */
1560
1877
  eventTypes: z.array(EventTypeSchema).nullable(),
1561
1878
  description: z.string().nullable(),
1879
+ /**
1880
+ * A cluster address registered from inside the cluster (`*.svc.cluster.local`); every other
1881
+ * endpoint must be public `https://`. Absent from stewards before issue #43.
1882
+ */
1883
+ internal: z.boolean().optional(),
1562
1884
  createdAt: DateTimeSchema,
1563
1885
  rotatedAt: DateTimeSchema.nullable(),
1564
1886
  lastDelivery: WebhookLastDeliverySchema.nullable()
@@ -1740,6 +2062,23 @@ const DoctorEmailsSchema = z.object({
1740
2062
  /** Emails are sent: transport and sender configured, at least one template on. */
1741
2063
  ready: z.boolean()
1742
2064
  });
2065
+ /** An active `api_keys` row (not revoked, not expired); issue #43. Never the secret. */
2066
+ const DoctorApiKeySchema = z.object({
2067
+ name: z.string(),
2068
+ /** Public prefix (`stw_<prefix>_…`): what `revoke-api-key` takes. */
2069
+ prefix: z.string(),
2070
+ /** `product` | `admin` | `checkout`; open set. */
2071
+ scope: z.string(),
2072
+ createdAt: DateTimeSchema,
2073
+ /** Updated at most once a minute. */
2074
+ lastUsedAt: DateTimeSchema.nullable(),
2075
+ /** null: never expires. */
2076
+ expiresAt: DateTimeSchema.nullable(),
2077
+ /** Whole days since creation. */
2078
+ ageDays: z.number().int().nonnegative()
2079
+ });
2080
+ /** A key expiring within this many days is a warning. */
2081
+ const DOCTOR_KEY_EXPIRY_WARN_DAYS = 14;
1743
2082
  const DoctorReportSchema = z.object({
1744
2083
  /** `error` önemde uyarı yok. */
1745
2084
  ok: z.boolean(),
@@ -1765,6 +2104,8 @@ dryRun: z.boolean() }),
1765
2104
  events: DoctorEventsSchema.optional(),
1766
2105
  /** Metering MF5; absent without metered prices and from older steward. */
1767
2106
  overage: DoctorOverageSchema.optional(),
2107
+ /** The product's active API keys, oldest first; absent from steward versions before issue #43. */
2108
+ apiKeys: z.array(DoctorApiKeySchema).optional(),
1768
2109
  warnings: z.array(DoctorWarningSchema)
1769
2110
  });
1770
2111
  /** Email readiness from settings and the deployment's transport (pure). */
@@ -1846,7 +2187,9 @@ function buildDoctorReport(facts) {
1846
2187
  if (drift > 0) warn("info", "price_drift", `${drift} live subscription(s) keep a locked amount that differs from the current price; moving them to the current price is an explicit operation`);
1847
2188
  const legacy = facts.billing?.legacyProviderSubscriptions ?? 0;
1848
2189
  if (legacy > 0) warn("error", "legacy_provider_subscription", `${legacy} live subscription(s) still have a provider subscription: steward never invoices them and the provider may still charge them; cancel each in the provider panel, then immediately in steward`);
1849
- if (!provider.configured) warn("error", "provider_not_configured", `ödeme sağlayıcısı ${provider.id} bu deployment'ta yapılandırılmamış`);
2190
+ const transferCurrencies = facts.bankTransfer?.currencies ?? [];
2191
+ if (!provider.configured && transferCurrencies.length > 0) warn("warning", "card_payments_unavailable", `payment provider ${provider.id} is not configured in this deployment: card payments are off, checkout offers bank transfer only (${transferCurrencies.join(", ")})`);
2192
+ else if (!provider.configured) warn("error", "provider_not_configured", `ödeme sağlayıcısı ${provider.id} bu deployment'ta yapılandırılmamış`);
1850
2193
  else if (provider.healthy === false) warn("warning", "provider_unhealthy", `ödeme sağlayıcısı ${provider.id} art arda erişilemedi (yanıtı veren pod'un gözlemi)`);
1851
2194
  const returnOrigins = returnOriginsOf(settings);
1852
2195
  if (returnOrigins.length === 0) warn("error", "no_return_origin", "checkout dönüşüne izinli origin yok: `appUrl` ayarlanmalı (her checkout return_url_not_allowed alır)");
@@ -1888,6 +2231,15 @@ function buildDoctorReport(facts) {
1888
2231
  else if (overage.chargeMode === "dry_run") warn("info", "overage_dry_run", "metering.chargeMode is dry_run: overage is priced into meter charges (GET /v1/accounts/:ref/meter-charges) but not invoiced; switch to live after one full cycle");
1889
2232
  }
1890
2233
  if (overage && overage.unratedSubscriptions > 0) warn("info", "overage_unrated_subscriptions", `${overage.unratedSubscriptions} live subscription(s) have no locked rate for a metered price of their plan (added after they started, M20): their overage is not billed until they move to the current terms`);
2234
+ const DAY_MS = 864e5;
2235
+ const apiKeys = facts.apiKeys?.map((key) => ({
2236
+ ...key,
2237
+ ageDays: Math.max(0, Math.floor((facts.checkedAt.getTime() - Date.parse(key.createdAt)) / DAY_MS))
2238
+ }));
2239
+ for (const key of apiKeys ?? []) if (key.expiresAt !== null) {
2240
+ const daysLeft = (Date.parse(key.expiresAt) - facts.checkedAt.getTime()) / DAY_MS;
2241
+ if (daysLeft <= 14) warn("warning", "api_key_expiring", `${key.scope} key "${key.name}" (${key.prefix}) expires in ${Math.max(0, Math.ceil(daysLeft))} day(s): create a new key and revoke this one`);
2242
+ } else if (key.scope === "admin") warn("info", "admin_key_without_expiry", `admin key "${key.name}" (${key.prefix}) never expires: replace it with a key created with an expiry`);
1891
2243
  return {
1892
2244
  ok: !warnings.some((w) => w.severity === "error"),
1893
2245
  checkedAt: facts.checkedAt.toISOString(),
@@ -1905,8 +2257,9 @@ function buildDoctorReport(facts) {
1905
2257
  ...facts.billing ? { billing: facts.billing } : {},
1906
2258
  ...facts.events ? { events: facts.events } : {},
1907
2259
  ...overage ? { overage } : {},
2260
+ ...apiKeys ? { apiKeys } : {},
1908
2261
  warnings
1909
2262
  };
1910
2263
  }
1911
2264
  //#endregion
1912
- export { rolloverOf as $, CheckoutStatusSchema as $t, WebhookEndpointRotateInputSchema as A, TtlMinutesSchema as An, InvoiceWaiveInputSchema as At, PlanSetResponseSchema as B, CatalogSchema as Bn, PaymentSchema as Bt, hostedReadinessOf as C, MeteringSettingsSchema as Cn, InvoiceIssueInputSchema as Ct, WEBHOOK_SECRET_PREFIX as D, ReturnOriginSchema as Dn, InvoiceSchema as Dt, WEBHOOK_ENDPOINT_STATUSES as E, ProductSettingsSchema as En, InvoicePaymentSessionSchema as Et, generateWebhookSecret as F, isReturnUrlAllowed as Fn, splitInclusiveTax as Ft, contributionOf as G, MAX_CATALOG_BENEFITS as Gn, PortalSessionCreateInputSchema as Gt, ResyncResultSchema as H, CatalogSyncResultSchema as Hn, SubscriptionChangeInputSchema as Ht, webhookEndpointUrlProblem as I, meteringSettingsOf as In, CancelSubscriptionInputSchema as It, meterCreditsOf as J, MAX_PLAN_BENEFITS as Jn, CheckoutConsentInputSchema as Jt, matchesFilter as K, MAX_CATALOG_METERED_PRICES as Kn, PortalSessionSchema as Kt, PLAN_SET_MODES as L, returnOriginsOf as Ln, GrantCreateInputSchema as Lt, WebhookEndpointStatusSchema as M, applySettingsPatch as Mn, ManualInvoiceInputSchema as Mt, WebhookLastDeliverySchema as N, billingSettingsOf as Nn, ManualInvoiceLineInputSchema as Nt, WebhookEndpointCreateInputSchema as O, SETTINGS_LOCALES as On, InvoiceStatusSchema as Ot, WebhookSecretSchema as P, eventsSettingsOf as Pn, manualInvoiceTotals as Pt, rateOverage as Q, PriceSchema as Qn, CheckoutSessionSchema as Qt, PlanSetInputSchema as R, AccountsRefreshResultSchema as Rn, GrantSchema as Rt, endpointDiagnosisOf as S, MeteringSettingsPatchSchema as Sn, UncancelSubscriptionResponseSchema as St, EventTypeSchema as T, ProductSettingsPatchSchema as Tn, InvoicePaymentSessionCreateInputSchema as Tt, addUtcMonths as U, FeatureDefSchema as Un, SubscriptionSchema as Ut, PlanSetWarningSchema as V, CatalogSyncInputSchema as Vn, StatsSchema as Vt, consumptionOf as W, FeatureTypeSchema as Wn, PORTAL_SESSION_ERRORS as Wt, overageOf as X, PlanDefSchema as Xn, CheckoutSessionCreateInputSchema as Xt, overageCapReached as Y, METERED_PRICE_TAX_MISMATCH as Yn, CheckoutPrefillSchema as Yt, periodBoundsOf as Z, PriceDefSchema as Zn, CheckoutSessionCreatedSchema as Zt, DoctorSeveritySchema as _, EventsSettingsPatchSchema as _n, InvoiceVoidResponseSchema as _t, DOCTOR_ROLLUP_LAG_WARN_SECONDS as a, BillingSettingsPatchSchema as an, AccountUpsertResponseSchema as at, buildDoctorReport as b, METER_CHARGE_MODES as bn, MeResponseSchema as bt, DoctorCatalogSchema as c, BrandingSchema as cn, CheckoutSessionResponseSchema as ct, DoctorEventsSchema as d, DEFAULT_LATE_GRACE_MINUTES as dn, HEADER_ACTOR_REF as dt, ConsentSchema as en, standingOf as et, DoctorHostedSchema as f, DEFAULT_METER_CHARGE_MODE as fn, HEADER_API_VERSION as ft, DoctorSettingsSchema as g, EventRetentionDaysSchema as gn, InvoiceIssueResponseSchema as gt, DoctorReportSchema as h, DEFAULT_PORTAL_TTL_MINUTES as hn, HEADER_SDK as ht, DOCTOR_REQUIRED_LEGAL_LINKS as i, checkoutRedirectUrl as in, AccountDetailSchema as it, WebhookEndpointSchema as j, WebUrlSchema as jn, MANUAL_INVOICE_MAX_AMOUNT_MINOR as jt, WebhookEndpointListSchema as k, SettingsLocaleSchema as kn, InvoiceVoidInputSchema as kt, DoctorEmailsSchema as l, DEFAULT_CHECKOUT_TTL_MINUTES as ln, CreditGrantResponseSchema as lt, DoctorProviderSchema as m, DEFAULT_PAYMENT_DUE_DAYS as mn, HEADER_REQUEST_ID as mt, DOCTOR_PROVIDER_ENVIRONMENTS as n, MAX_CHECKOUT_CONSENT_DOCS as nn, errorCodeSpec as nt, DOCTOR_SEVERITIES as o, BillingSettingsSchema as on, CancelSubscriptionResponseSchema as ot, DoctorOverageSchema as p, DEFAULT_MIN_INVOICE_MINOR as pn, HEADER_IDEMPOTENCY_KEY as pt, meterChargeTotals as q, MAX_CATALOG_METERS as qn, CHECKOUT_ERRORS as qt, DOCTOR_REQUIRED_BRANDING as r, ProviderPayloadSchema as rn, isKnownErrorCode as rt, DoctorBillingSchema as s, BrandingPatchSchema as sn, ChangeSubscriptionResponseSchema as st, DOCTOR_PENDING_BACKLOG_MS as t, INDIVIDUAL_IDENTITY_PLACEHOLDER as tn, ERROR_CODES as tt, DoctorEndpointSchema as u, DEFAULT_EVENT_RETENTION_DAYS as un, GrantCreateResponseSchema as ut, DoctorUnsellablePriceSchema as v, EventsSettingsSchema as vn, InvoiceWaiveResponseSchema as vt, DEFAULT_ENDPOINT_EVENT_TYPES as w, PaymentDueDaysSchema as wn, InvoiceLineSchema as wt, emailReadinessOf as x, MeterChargeModeSchema as xn, STEWARD_CAPABILITIES as xt, DoctorWarningSchema as y, LateGraceMinutesSchema as yn, ManualInvoiceResponseSchema as yt, PlanSetModeSchema as z, CatalogPlanSchema as zn, MAX_GRANT_BENEFITS as zt };
2265
+ export { periodBoundsOf as $, EventsSettingsSchema as $n, ApiKeySchema as $t, WebhookEndpointCreateInputSchema as A, INDIVIDUAL_IDENTITY_PLACEHOLDER as An, METERED_PRICE_TAX_MISMATCH as Ar, InvoiceStatusSchema as At, PlanSetInputSchema as B, BillingSettingsSchema as Bn, GrantSchema as Bt, emailReadinessOf as C, CheckoutConsentInputSchema as Cn, CatalogSyncResultSchema as Cr, STEWARD_CAPABILITIES as Ct, EventTypeSchema as D, CheckoutSessionSchema as Dn, MAX_CATALOG_METERED_PRICES as Dr, InvoicePaymentSessionCreateInputSchema as Dt, DEFAULT_ENDPOINT_EVENT_TYPES as E, CheckoutSessionCreatedSchema as En, MAX_CATALOG_BENEFITS as Er, InvoiceLineSchema as Et, WebhookLastDeliverySchema as F, checkoutRedirectUrl as Fn, ManualInvoiceLineInputSchema as Ft, addUtcMonths as G, DEFAULT_EVENT_RETENTION_DAYS as Gn, SubscriptionSchema as Gt, PlanSetResponseSchema as H, BrandingSchema as Hn, PaymentSchema as Ht, WebhookSecretSchema as I, BankTransferPaymentDaysSchema as In, manualInvoiceTotals as It, matchesFilter as J, DEFAULT_MIN_INVOICE_MINOR as Jn, PortalSessionSchema as Jt, consumptionOf as K, DEFAULT_LATE_GRACE_MINUTES as Kn, PORTAL_SESSION_ERRORS as Kt, generateWebhookSecret as L, BankTransferSettingsPatchSchema as Ln, splitInclusiveTax as Lt, WebhookEndpointRotateInputSchema as M, PAYMENT_METHODS as Mn, PriceDefSchema as Mr, InvoiceWaiveInputSchema as Mt, WebhookEndpointSchema as N, PaymentMethodSchema as Nn, PriceSchema as Nr, MANUAL_INVOICE_MAX_AMOUNT_MINOR as Nt, WEBHOOK_ENDPOINT_STATUSES as O, CheckoutStatusSchema as On, MAX_CATALOG_METERS as Or, InvoicePaymentSessionSchema as Ot, WebhookEndpointStatusSchema as P, ProviderPayloadSchema as Pn, ManualInvoiceInputSchema as Pt, overageOf as Q, EventsSettingsPatchSchema as Qn, ApiKeyPrefixSchema as Qt, webhookEndpointUrlProblem as R, BankTransferSettingsSchema as Rn, CancelSubscriptionInputSchema as Rt, buildDoctorReport as S, CHECKOUT_ERRORS as Sn, CatalogSyncInputSchema as Sr, MeResponseSchema as St, hostedReadinessOf as T, CheckoutSessionCreateInputSchema as Tn, FeatureTypeSchema as Tr, InvoiceIssueInputSchema as Tt, PlanSetWarningSchema as U, DEFAULT_BANK_TRANSFER_PAYMENT_DAYS as Un, StatsSchema as Ut, PlanSetModeSchema as V, BrandingPatchSchema as Vn, MAX_GRANT_BENEFITS as Vt, ResyncResultSchema as W, DEFAULT_CHECKOUT_TTL_MINUTES as Wn, SubscriptionChangeInputSchema as Wt, meterCreditsOf as X, DEFAULT_PORTAL_TTL_MINUTES as Xn, ApiKeyCreateInputSchema as Xt, meterChargeTotals as Y, DEFAULT_PAYMENT_DUE_DAYS as Yn, API_KEY_SCOPES as Yt, overageCapReached as Z, EventRetentionDaysSchema as Zn, ApiKeyListSchema as Zt, DoctorReportSchema as _, RepriceItemSchema as _n, meteringSettingsOf as _r, HEADER_SDK as _t, DOCTOR_REQUIRED_LEGAL_LINKS as a, BankTransferListStatusSchema as an, PaymentDueDaysSchema as ar, isKnownErrorCode as at, DoctorUnsellablePriceSchema as b, BankTransferRecordInputSchema as bn, CatalogPlanSchema as br, InvoiceWaiveResponseSchema as bt, DoctorApiKeySchema as c, DunningPolicySchema as cn, ReturnOriginSchema as cr, CancelSubscriptionResponseSchema as ct, DoctorEmailsSchema as d, MeterClosePeriodsInputSchema as dn, TtlMinutesSchema as dr, CreditGrantResponseSchema as dt, ApiKeyScopeSchema as en, LateGraceMinutesSchema as er, rateOverage as et, DoctorEndpointSchema as f, MeterClosePeriodsResultSchema as fn, WebUrlSchema as fr, GrantCreateResponseSchema as ft, DoctorProviderSchema as g, RepriceInputSchema as gn, isReturnUrlAllowed as gr, HEADER_REQUEST_ID as gt, DoctorOverageSchema as h, RedeliveredEventSchema as hn, eventsSettingsOf as hr, HEADER_IDEMPOTENCY_KEY as ht, DOCTOR_REQUIRED_BRANDING as i, BankTransferListSchema as in, MeteringSettingsSchema as ir, errorCodeSpec as it, WebhookEndpointListSchema as j, MAX_CHECKOUT_CONSENT_DOCS as jn, PlanDefSchema as jr, InvoiceVoidInputSchema as jt, WEBHOOK_SECRET_PREFIX as k, ConsentSchema as kn, MAX_PLAN_BENEFITS as kr, InvoiceSchema as kt, DoctorBillingSchema as l, MAX_API_KEY_TTL_DAYS as ln, SETTINGS_LOCALES as lr, ChangeSubscriptionResponseSchema as lt, DoctorHostedSchema as m, MeterRecomputeResultSchema as mn, billingSettingsOf as mr, HEADER_API_VERSION as mt, DOCTOR_PENDING_BACKLOG_MS as n, BANK_TRANSFER_LIST_STATUSES as nn, MeterChargeModeSchema as nr, standingOf as nt, DOCTOR_ROLLUP_LAG_WARN_SECONDS as o, CreditAdjustmentInputSchema as on, ProductSettingsPatchSchema as or, AccountDetailSchema as ot, DoctorEventsSchema as p, MeterRecomputeInputSchema as pn, applySettingsPatch as pr, HEADER_ACTOR_REF as pt, contributionOf as q, DEFAULT_METER_CHARGE_MODE as qn, PortalSessionCreateInputSchema as qt, DOCTOR_PROVIDER_ENVIRONMENTS as r, BankTransferListItemSchema as rn, MeteringSettingsPatchSchema as rr, ERROR_CODES as rt, DOCTOR_SEVERITIES as s, DUNNING_ACTIONS as sn, ProductSettingsSchema as sr, AccountUpsertResponseSchema as st, DOCTOR_KEY_EXPIRY_WARN_DAYS as t, ApiKeyTokenSchema as tn, METER_CHARGE_MODES as tr, rolloverOf as tt, DoctorCatalogSchema as u, MAX_NOTICE_DAYS as un, SettingsLocaleSchema as ur, CheckoutSessionResponseSchema as ut, DoctorSettingsSchema as v, RepriceResultSchema as vn, returnOriginsOf as vr, InvoiceIssueResponseSchema as vt, endpointDiagnosisOf as w, CheckoutPrefillSchema as wn, FeatureDefSchema as wr, UncancelSubscriptionResponseSchema as wt, DoctorWarningSchema as x, BankTransferRecordedSchema as xn, CatalogSchema as xr, ManualInvoiceResponseSchema as xt, DoctorSeveritySchema as y, generateApiKeyToken as yn, AccountsRefreshResultSchema as yr, InvoiceVoidResponseSchema as yt, PLAN_SET_MODES as z, BillingSettingsPatchSchema as zn, GrantCreateInputSchema as zt };
@@ -5,7 +5,7 @@ declare const UNIT_DECIMALS = 6;
5
5
  declare const MICRO_UNITS_PER_UNIT = 1000000n;
6
6
  /** A unit value that is not a finite, non-negative decimal (M4 `invalid_value`). */
7
7
  declare class InvalidUnitValueError extends RangeError {
8
- readonly code: "invalid_value";
8
+ readonly code: 'invalid_value';
9
9
  constructor(value: unknown);
10
10
  }
11
11
  /**
@@ -61,7 +61,7 @@ declare function isValidVkn(value: unknown): boolean;
61
61
  * (iyzico'nun istediği biçim).
62
62
  */
63
63
  declare function isE164(value: unknown, options?: {
64
- country?: "TR";
64
+ country?: 'TR';
65
65
  }): boolean;
66
66
  //#endregion
67
67
  export { MICRO_UNITS_PER_UNIT as a, isMicroPrecise as c, plainDecimalOf as d, toMicroUnits as f, InvalidUnitValueError as i, microToDecimalString as l, isValidTckn as n, UNIT_DECIMALS as o, isValidVkn as r, fromMicroUnits as s, isE164 as t, parseMicroUnits as u };