@fire-spark/payments 0.3.5 → 0.4.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.
package/dist/index.d.ts CHANGED
@@ -9,7 +9,7 @@ type AllocateTenderInput = {
9
9
  sequence: number;
10
10
  method: PaymentMethod;
11
11
  allocation: TenderAllocationInput | null;
12
- /** Value a REDEMPTION tender covers (`details.points_value`). */
12
+ /** Value a REDEMPTION tender covers (`details.amount`). */
13
13
  redemption_amount?: number;
14
14
  };
15
15
  type AllocateTendersInput = {
@@ -472,16 +472,14 @@ type RedemptionDetails = Extract<TenderDetails, {
472
472
  /** One reward inside a grouped REDEMPTION tender (entry totals). */
473
473
  type RedemptionReward = RedemptionDetails["rewards"][number];
474
474
  /**
475
- * Payment redeem as stored in `orders.redeem`. `amount` and `points` are
476
- * totals of the entry (every unit); `quantity` is informational.
475
+ * Payment redeem as stored in `orders.redeem`. `amount` is the total of
476
+ * the entry (every unit); `quantity` is informational.
477
477
  */
478
478
  type PaymentRedeemLike = {
479
479
  reward_id: string;
480
480
  quantity?: number;
481
481
  payment_id?: string | null;
482
482
  amount?: number;
483
- points?: number;
484
- program?: string;
485
483
  };
486
484
  /** Payment redeems of one `payment_id`, ready to seed its tender. */
487
485
  type RedemptionGroup = {
@@ -491,7 +489,7 @@ type RedemptionGroup = {
491
489
  details: RedemptionDetails;
492
490
  };
493
491
  /**
494
- * Points / balance paid with a REDEMPTION tender, not a discount (D16):
492
+ * Reward (voucher, balance…) paid with a REDEMPTION tender, not a discount (D16):
495
493
  * it never discounts lines nor has a `redemption_steps` entry.
496
494
  */
497
495
  declare const isPaymentRedeem: (redeem: {
@@ -529,16 +527,16 @@ declare const paymentRedeemsCoverTotal: (redeem: readonly PaymentRedeemLike[], t
529
527
  */
530
528
  declare const groupPaymentRedeems: (redeem: readonly PaymentRedeemLike[]) => RedemptionGroup[];
531
529
  /**
532
- * REDEMPTION `details` in the grouped shape, or null for other methods.
533
- * Single-reward details written before grouping read as one reward.
530
+ * REDEMPTION `details` in the current shape, or null for other methods.
531
+ * Details persisted earlier (one `reward_id`, or money as `points_value`)
532
+ * read as the same shape; their old keys are dropped.
534
533
  */
535
534
  declare const redemptionDetailsOf: (details: unknown) => RedemptionDetails | null;
536
535
  /** Rewards of a REDEMPTION tender; empty for other methods. */
537
536
  declare const redemptionRewardsOf: (details: unknown) => {
538
537
  reward_id: string;
539
538
  quantity: number;
540
- points: number;
541
- points_value: number;
539
+ amount: number;
542
540
  }[];
543
541
  //#endregion
544
542
  //#region src/reference.d.ts
@@ -624,7 +622,7 @@ declare const primaryTender: <T extends TenderLike>(intent: {
624
622
  primary_tender_id: string | null;
625
623
  tenders: readonly T[];
626
624
  } | null | undefined) => T | null;
627
- /** A REDEMPTION tender whose points are held for the order (L2 / D30). */
625
+ /** A REDEMPTION tender whose reward is held for the order (L2 / D30). */
628
626
  declare const isRedemptionReserved: (tender: TenderLike) => boolean;
629
627
  /** Paid, or a reserved REDEMPTION (confirmed later, §3.3). */
630
628
  declare const isTenderSettled: (tender: TenderLike) => boolean;
@@ -635,7 +633,7 @@ declare const isIntentCovered: (intent: IntentLike | null | undefined, orderTota
635
633
  /**
636
634
  * Order `payment_status` from the live tenders of the current intent
637
635
  * (D32). Reserved REDEMPTION tenders count as settled, so a redemption-only
638
- * intent is `PAID` once its points are held (D30).
636
+ * intent is `PAID` once its rewards are held (D30).
639
637
  */
640
638
  declare const derivePaymentStatus: (intent: IntentLike | null | undefined) => PaymentStatus;
641
639
  /** Live tenders a `PAYING` node waits for (§7.3); no scope = all. */
package/dist/index.js CHANGED
@@ -137,7 +137,7 @@ const primaryTender = (intent) => {
137
137
  const id = intent.primary_tender_id;
138
138
  return intent.tenders.find((tender) => tender.id === id) ?? null;
139
139
  };
140
- /** A REDEMPTION tender whose points are held for the order (L2 / D30). */
140
+ /** A REDEMPTION tender whose reward is held for the order (L2 / D30). */
141
141
  const isRedemptionReserved = (tender) => {
142
142
  if (isRealPaymentMethod(tender.method)) return false;
143
143
  return typeof tender.metadata?.reserved_at === "string";
@@ -167,7 +167,7 @@ const isIntentCovered = (intent, orderTotal) => {
167
167
  /**
168
168
  * Order `payment_status` from the live tenders of the current intent
169
169
  * (D32). Reserved REDEMPTION tenders count as settled, so a redemption-only
170
- * intent is `PAID` once its points are held (D30).
170
+ * intent is `PAID` once its rewards are held (D30).
171
171
  */
172
172
  const derivePaymentStatus = (intent) => {
173
173
  const tenders = liveTenders(intent);
@@ -1174,7 +1174,7 @@ const batchCloseDay = (now) => localDay(now);
1174
1174
  const SUM_DECIMALS = 6;
1175
1175
  const add = (a, b) => roundTo(a + b, SUM_DECIMALS);
1176
1176
  /**
1177
- * Points / balance paid with a REDEMPTION tender, not a discount (D16):
1177
+ * Reward (voucher, balance…) paid with a REDEMPTION tender, not a discount (D16):
1178
1178
  * it never discounts lines nor has a `redemption_steps` entry.
1179
1179
  */
1180
1180
  const isPaymentRedeem = (redeem) => {
@@ -1206,32 +1206,22 @@ const paymentRedeemsCoverTotal = (redeem, totals) => {
1206
1206
  return roundTo(paid, decimals) >= roundTo(totals.total, decimals);
1207
1207
  };
1208
1208
  const rewardOf = (redeem) => {
1209
- const r1 = {
1210
- reward_id: redeem.reward_id,
1211
- quantity: redeem.quantity ?? 1
1212
- };
1213
- const r2 = {
1214
- points: redeem.points ?? 0,
1215
- points_value: redeem.amount ?? 0
1216
- };
1217
1209
  return {
1218
- ...r1,
1219
- ...r2
1210
+ reward_id: redeem.reward_id,
1211
+ quantity: redeem.quantity ?? 1,
1212
+ amount: redeem.amount ?? 0
1220
1213
  };
1221
1214
  };
1222
- const detailsOf = (rewards, program, loyalty_transaction_id) => {
1215
+ const detailsOf = (rewards, loyalty_transaction_id) => {
1223
1216
  const d1 = {
1224
1217
  method: REDEMPTION_METHOD,
1225
1218
  rewards,
1226
- points: rewards.reduce((sum, item) => add(sum, item.points), 0),
1227
- points_value: rewards.reduce((sum, item) => add(sum, item.points_value), 0)
1219
+ amount: rewards.reduce((sum, item) => add(sum, item.amount), 0)
1228
1220
  };
1229
- const d2 = program === void 0 ? {} : { program };
1230
- const d3 = loyalty_transaction_id ? { loyalty_transaction_id } : {};
1221
+ const d2 = loyalty_transaction_id ? { loyalty_transaction_id } : {};
1231
1222
  return {
1232
1223
  ...d1,
1233
- ...d2,
1234
- ...d3
1224
+ ...d2
1235
1225
  };
1236
1226
  };
1237
1227
  /**
@@ -1248,11 +1238,10 @@ const groupPaymentRedeems = (redeem) => {
1248
1238
  groups.set(payment_id, list);
1249
1239
  }
1250
1240
  return [...groups].map(([payment_id, items]) => {
1251
- const program = items.find((item) => item.program)?.program;
1252
- const details = detailsOf(items.map(rewardOf), program);
1241
+ const details = detailsOf(items.map(rewardOf));
1253
1242
  return {
1254
1243
  payment_id,
1255
- amount: details.points_value,
1244
+ amount: details.amount,
1256
1245
  details
1257
1246
  };
1258
1247
  });
@@ -1260,27 +1249,41 @@ const groupPaymentRedeems = (redeem) => {
1260
1249
  const isRecord = (value) => {
1261
1250
  return typeof value === "object" && value !== null;
1262
1251
  };
1252
+ const numberOr = (value, fallback) => {
1253
+ return typeof value === "number" && Number.isFinite(value) ? value : fallback;
1254
+ };
1255
+ /** Money of a persisted reward: `amount`, or `points_value` before it. */
1256
+ const rewardAmountOf = (reward) => {
1257
+ return numberOr(reward.amount, numberOr(reward.points_value, 0));
1258
+ };
1259
+ const persistedRewardOf = (value) => {
1260
+ if (!isRecord(value) || typeof value.reward_id !== "string") return null;
1261
+ const quantity = numberOr(value.quantity, 1);
1262
+ return {
1263
+ reward_id: value.reward_id,
1264
+ quantity,
1265
+ amount: rewardAmountOf(value)
1266
+ };
1267
+ };
1263
1268
  /**
1264
- * REDEMPTION `details` in the grouped shape, or null for other methods.
1265
- * Single-reward details written before grouping read as one reward.
1269
+ * REDEMPTION `details` in the current shape, or null for other methods.
1270
+ * Details persisted earlier (one `reward_id`, or money as `points_value`)
1271
+ * read as the same shape; their old keys are dropped.
1266
1272
  */
1267
1273
  const redemptionDetailsOf = (details) => {
1268
1274
  if (!isRecord(details) || details.method !== "REDEMPTION") return null;
1269
- if (Array.isArray(details.rewards)) return details;
1270
- if (typeof details.reward_id !== "string") return null;
1271
- const legacy = details;
1272
- const r1 = {
1273
- reward_id: legacy.reward_id,
1275
+ const id = details.loyalty_transaction_id;
1276
+ const reference = typeof id === "string" ? id : void 0;
1277
+ if (Array.isArray(details.rewards)) {
1278
+ const rewards = details.rewards.map(persistedRewardOf);
1279
+ if (rewards.some((reward) => reward === null)) return null;
1280
+ return detailsOf(rewards, reference);
1281
+ }
1282
+ const reward = persistedRewardOf({
1283
+ ...details,
1274
1284
  quantity: 1
1275
- };
1276
- const r2 = { points: legacy.points ?? 0 };
1277
- const reward = {
1278
- ...r1,
1279
- ...r2,
1280
- points_value: legacy.points_value ?? 0
1281
- };
1282
- const id = legacy.loyalty_transaction_id;
1283
- return detailsOf([reward], legacy.program, id);
1285
+ });
1286
+ return reward ? detailsOf([reward], reference) : null;
1284
1287
  };
1285
1288
  /** Rewards of a REDEMPTION tender; empty for other methods. */
1286
1289
  const redemptionRewardsOf = (details) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fire-spark/payments",
3
- "version": "0.3.5",
3
+ "version": "0.4.0",
4
4
  "description": "Fire Spark payments contract: adapters, errors, amounts and policy",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -17,7 +17,7 @@
17
17
  }
18
18
  },
19
19
  "dependencies": {
20
- "@fire-spark/types": "^0.3.5"
20
+ "@fire-spark/types": "^0.4.0"
21
21
  },
22
22
  "devDependencies": {
23
23
  "tsdown": "^0.22.14",