@shware/purchase 7.2.0 → 7.5.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.cjs +4 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/stripe/decline.cjs +48 -0
- package/dist/stripe/decline.cjs.map +1 -0
- package/dist/stripe/decline.d.cts +33 -0
- package/dist/stripe/decline.d.cts.map +1 -0
- package/dist/stripe/decline.d.mts +33 -0
- package/dist/stripe/decline.d.mts.map +1 -0
- package/dist/stripe/decline.mjs +46 -0
- package/dist/stripe/decline.mjs.map +1 -0
- package/dist/stripe/index.cjs +12 -0
- package/dist/stripe/index.d.cts +5 -2
- package/dist/stripe/index.d.mts +5 -2
- package/dist/stripe/index.mjs +5 -2
- package/dist/stripe/mapper.cjs +44 -2
- package/dist/stripe/mapper.cjs.map +1 -1
- package/dist/stripe/mapper.d.cts +14 -2
- package/dist/stripe/mapper.d.cts.map +1 -1
- package/dist/stripe/mapper.d.mts +14 -2
- package/dist/stripe/mapper.d.mts.map +1 -1
- package/dist/stripe/mapper.mjs +43 -4
- package/dist/stripe/mapper.mjs.map +1 -1
- package/dist/stripe/payment-method.cjs +34 -0
- package/dist/stripe/payment-method.cjs.map +1 -0
- package/dist/stripe/payment-method.d.cts +22 -0
- package/dist/stripe/payment-method.d.cts.map +1 -0
- package/dist/stripe/payment-method.d.mts +22 -0
- package/dist/stripe/payment-method.d.mts.map +1 -0
- package/dist/stripe/payment-method.mjs +32 -0
- package/dist/stripe/payment-method.mjs.map +1 -0
- package/dist/stripe/subscription.cjs +35 -0
- package/dist/stripe/subscription.cjs.map +1 -0
- package/dist/stripe/subscription.d.cts +33 -0
- package/dist/stripe/subscription.d.cts.map +1 -0
- package/dist/stripe/subscription.d.mts +33 -0
- package/dist/stripe/subscription.d.mts.map +1 -0
- package/dist/stripe/subscription.mjs +33 -0
- package/dist/stripe/subscription.mjs.map +1 -0
- package/dist/subscription/index.cjs +59 -0
- package/dist/subscription/index.cjs.map +1 -1
- package/dist/subscription/index.d.cts +26 -0
- package/dist/subscription/index.d.cts.map +1 -1
- package/dist/subscription/index.d.mts +26 -0
- package/dist/subscription/index.d.mts.map +1 -1
- package/dist/subscription/index.mjs +56 -1
- package/dist/subscription/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -7,9 +7,13 @@ exports.AVAILABLE_STATUSES = require_subscription_index.AVAILABLE_STATUSES;
|
|
|
7
7
|
exports.AppStoreConfig = require_app_store_config.AppStoreConfig;
|
|
8
8
|
exports.CANCELLATION_FEEDBACKS = require_subscription_index.CANCELLATION_FEEDBACKS;
|
|
9
9
|
exports.CANCELLATION_INITIATORS = require_subscription_index.CANCELLATION_INITIATORS;
|
|
10
|
+
exports.CLOSED_DISPUTE_STATUSES = require_subscription_index.CLOSED_DISPUTE_STATUSES;
|
|
11
|
+
exports.DISPUTE_STATUSES = require_subscription_index.DISPUTE_STATUSES;
|
|
10
12
|
exports.GooglePlayConfig = require_google_play_config.GooglePlayConfig;
|
|
11
13
|
exports.PAYMENT_TYPES = require_subscription_index.PAYMENT_TYPES;
|
|
12
14
|
exports.PLATFORMS = require_subscription_index.PLATFORMS;
|
|
15
|
+
exports.REFUND_STATUSES = require_subscription_index.REFUND_STATUSES;
|
|
16
|
+
exports.REFUND_STATUS_TRANSITIONS = require_subscription_index.REFUND_STATUS_TRANSITIONS;
|
|
13
17
|
exports.RESUBSCRIBE_INTENTS = require_subscription_index.RESUBSCRIBE_INTENTS;
|
|
14
18
|
exports.SUBSCRIPTION_STATUSES = require_subscription_index.SUBSCRIPTION_STATUSES;
|
|
15
19
|
exports.StripeConfig = require_stripe_config.StripeConfig;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AppStoreConfig } from "./app-store/config.cjs";
|
|
2
|
-
import { AVAILABLE_STATUSES, CANCELLATION_FEEDBACKS, CANCELLATION_INITIATORS, CancellationDetails, CancellationFeedback, CancellationInitiator, PAYMENT_TYPES, PLATFORMS, PaymentType, Platform, RESUBSCRIBE_INTENTS, ResubscribeIntent, SUBSCRIPTION_STATUSES, SubscriptionStatus } from "./subscription/index.cjs";
|
|
2
|
+
import { AVAILABLE_STATUSES, CANCELLATION_FEEDBACKS, CANCELLATION_INITIATORS, CLOSED_DISPUTE_STATUSES, CancellationDetails, CancellationFeedback, CancellationInitiator, DISPUTE_STATUSES, DisputeStatus, PAYMENT_TYPES, PLATFORMS, PaymentType, Platform, REFUND_STATUSES, REFUND_STATUS_TRANSITIONS, RESUBSCRIBE_INTENTS, RefundStatus, ResubscribeIntent, SUBSCRIPTION_STATUSES, SubscriptionStatus } from "./subscription/index.cjs";
|
|
3
3
|
import { GooglePlayConfig } from "./google-play/config.cjs";
|
|
4
4
|
import { StripeConfig } from "./stripe/config.cjs";
|
|
5
|
-
export { AVAILABLE_STATUSES, AppStoreConfig, CANCELLATION_FEEDBACKS, CANCELLATION_INITIATORS, type CancellationDetails, type CancellationFeedback, type CancellationInitiator, GooglePlayConfig, PAYMENT_TYPES, PLATFORMS, type PaymentType, type Platform, RESUBSCRIBE_INTENTS, type ResubscribeIntent, SUBSCRIPTION_STATUSES, StripeConfig, type SubscriptionStatus };
|
|
5
|
+
export { AVAILABLE_STATUSES, AppStoreConfig, CANCELLATION_FEEDBACKS, CANCELLATION_INITIATORS, CLOSED_DISPUTE_STATUSES, type CancellationDetails, type CancellationFeedback, type CancellationInitiator, DISPUTE_STATUSES, type DisputeStatus, GooglePlayConfig, PAYMENT_TYPES, PLATFORMS, type PaymentType, type Platform, REFUND_STATUSES, REFUND_STATUS_TRANSITIONS, RESUBSCRIBE_INTENTS, type RefundStatus, type ResubscribeIntent, SUBSCRIPTION_STATUSES, StripeConfig, type SubscriptionStatus };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AppStoreConfig } from "./app-store/config.mjs";
|
|
2
|
-
import { AVAILABLE_STATUSES, CANCELLATION_FEEDBACKS, CANCELLATION_INITIATORS, CancellationDetails, CancellationFeedback, CancellationInitiator, PAYMENT_TYPES, PLATFORMS, PaymentType, Platform, RESUBSCRIBE_INTENTS, ResubscribeIntent, SUBSCRIPTION_STATUSES, SubscriptionStatus } from "./subscription/index.mjs";
|
|
2
|
+
import { AVAILABLE_STATUSES, CANCELLATION_FEEDBACKS, CANCELLATION_INITIATORS, CLOSED_DISPUTE_STATUSES, CancellationDetails, CancellationFeedback, CancellationInitiator, DISPUTE_STATUSES, DisputeStatus, PAYMENT_TYPES, PLATFORMS, PaymentType, Platform, REFUND_STATUSES, REFUND_STATUS_TRANSITIONS, RESUBSCRIBE_INTENTS, RefundStatus, ResubscribeIntent, SUBSCRIPTION_STATUSES, SubscriptionStatus } from "./subscription/index.mjs";
|
|
3
3
|
import { GooglePlayConfig } from "./google-play/config.mjs";
|
|
4
4
|
import { StripeConfig } from "./stripe/config.mjs";
|
|
5
|
-
export { AVAILABLE_STATUSES, AppStoreConfig, CANCELLATION_FEEDBACKS, CANCELLATION_INITIATORS, type CancellationDetails, type CancellationFeedback, type CancellationInitiator, GooglePlayConfig, PAYMENT_TYPES, PLATFORMS, type PaymentType, type Platform, RESUBSCRIBE_INTENTS, type ResubscribeIntent, SUBSCRIPTION_STATUSES, StripeConfig, type SubscriptionStatus };
|
|
5
|
+
export { AVAILABLE_STATUSES, AppStoreConfig, CANCELLATION_FEEDBACKS, CANCELLATION_INITIATORS, CLOSED_DISPUTE_STATUSES, type CancellationDetails, type CancellationFeedback, type CancellationInitiator, DISPUTE_STATUSES, type DisputeStatus, GooglePlayConfig, PAYMENT_TYPES, PLATFORMS, type PaymentType, type Platform, REFUND_STATUSES, REFUND_STATUS_TRANSITIONS, RESUBSCRIBE_INTENTS, type RefundStatus, type ResubscribeIntent, SUBSCRIPTION_STATUSES, StripeConfig, type SubscriptionStatus };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AVAILABLE_STATUSES, CANCELLATION_FEEDBACKS, CANCELLATION_INITIATORS, PAYMENT_TYPES, PLATFORMS, RESUBSCRIBE_INTENTS, SUBSCRIPTION_STATUSES } from "./subscription/index.mjs";
|
|
1
|
+
import { AVAILABLE_STATUSES, CANCELLATION_FEEDBACKS, CANCELLATION_INITIATORS, CLOSED_DISPUTE_STATUSES, DISPUTE_STATUSES, PAYMENT_TYPES, PLATFORMS, REFUND_STATUSES, REFUND_STATUS_TRANSITIONS, RESUBSCRIBE_INTENTS, SUBSCRIPTION_STATUSES } from "./subscription/index.mjs";
|
|
2
2
|
import { AppStoreConfig } from "./app-store/config.mjs";
|
|
3
3
|
import { GooglePlayConfig } from "./google-play/config.mjs";
|
|
4
4
|
import { StripeConfig } from "./stripe/config.mjs";
|
|
5
|
-
export { AVAILABLE_STATUSES, AppStoreConfig, CANCELLATION_FEEDBACKS, CANCELLATION_INITIATORS, GooglePlayConfig, PAYMENT_TYPES, PLATFORMS, RESUBSCRIBE_INTENTS, SUBSCRIPTION_STATUSES, StripeConfig };
|
|
5
|
+
export { AVAILABLE_STATUSES, AppStoreConfig, CANCELLATION_FEEDBACKS, CANCELLATION_INITIATORS, CLOSED_DISPUTE_STATUSES, DISPUTE_STATUSES, GooglePlayConfig, PAYMENT_TYPES, PLATFORMS, REFUND_STATUSES, REFUND_STATUS_TRANSITIONS, RESUBSCRIBE_INTENTS, SUBSCRIPTION_STATUSES, StripeConfig };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/stripe/decline.ts
|
|
3
|
+
/**
|
|
4
|
+
* Why a card was refused, in the few buckets a cardholder can act on. Everything else
|
|
5
|
+
* (`do_not_honor`, `fraudulent`, `lost_card`, ...) is DECLINED, which is also what Stripe advises
|
|
6
|
+
* telling the customer in those cases: https://docs.stripe.com/declines/codes
|
|
7
|
+
*
|
|
8
|
+
* - INSUFFICIENT_FUNDS: top up, or use another card.
|
|
9
|
+
* - CARD_EXPIRED: update the card.
|
|
10
|
+
* - CARD_INVALID: a mistyped number, expiry, CVC or postal code.
|
|
11
|
+
* - PROCESSING_ERROR: a transient issuer or network problem; trying again may work.
|
|
12
|
+
* - DECLINED: the bank said no without a reason the customer can fix.
|
|
13
|
+
*/
|
|
14
|
+
const DECLINE_REASONS = [
|
|
15
|
+
"INSUFFICIENT_FUNDS",
|
|
16
|
+
"CARD_EXPIRED",
|
|
17
|
+
"CARD_INVALID",
|
|
18
|
+
"PROCESSING_ERROR",
|
|
19
|
+
"DECLINED"
|
|
20
|
+
];
|
|
21
|
+
const REASON_BY_CODE = {
|
|
22
|
+
insufficient_funds: "INSUFFICIENT_FUNDS",
|
|
23
|
+
expired_card: "CARD_EXPIRED",
|
|
24
|
+
incorrect_cvc: "CARD_INVALID",
|
|
25
|
+
invalid_cvc: "CARD_INVALID",
|
|
26
|
+
incorrect_number: "CARD_INVALID",
|
|
27
|
+
invalid_number: "CARD_INVALID",
|
|
28
|
+
invalid_expiry_month: "CARD_INVALID",
|
|
29
|
+
invalid_expiry_year: "CARD_INVALID",
|
|
30
|
+
incorrect_zip: "CARD_INVALID",
|
|
31
|
+
processing_error: "PROCESSING_ERROR",
|
|
32
|
+
try_again_later: "PROCESSING_ERROR",
|
|
33
|
+
issuer_not_available: "PROCESSING_ERROR",
|
|
34
|
+
reenter_transaction: "PROCESSING_ERROR"
|
|
35
|
+
};
|
|
36
|
+
function mapDecline(failure) {
|
|
37
|
+
const code = failure?.decline_code || failure?.code || null;
|
|
38
|
+
return {
|
|
39
|
+
reason: code && REASON_BY_CODE[code] || "DECLINED",
|
|
40
|
+
code,
|
|
41
|
+
message: failure?.message || null
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
exports.DECLINE_REASONS = DECLINE_REASONS;
|
|
46
|
+
exports.mapDecline = mapDecline;
|
|
47
|
+
|
|
48
|
+
//# sourceMappingURL=decline.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decline.cjs","names":[],"sources":["../../src/stripe/decline.ts"],"sourcesContent":["/**\n * Why a card was refused, in the few buckets a cardholder can act on. Everything else\n * (`do_not_honor`, `fraudulent`, `lost_card`, ...) is DECLINED, which is also what Stripe advises\n * telling the customer in those cases: https://docs.stripe.com/declines/codes\n *\n * - INSUFFICIENT_FUNDS: top up, or use another card.\n * - CARD_EXPIRED: update the card.\n * - CARD_INVALID: a mistyped number, expiry, CVC or postal code.\n * - PROCESSING_ERROR: a transient issuer or network problem; trying again may work.\n * - DECLINED: the bank said no without a reason the customer can fix.\n */\nexport const DECLINE_REASONS = [\n 'INSUFFICIENT_FUNDS',\n 'CARD_EXPIRED',\n 'CARD_INVALID',\n 'PROCESSING_ERROR',\n 'DECLINED',\n] as const;\n\nexport type DeclineReason = (typeof DECLINE_REASONS)[number];\n\nconst REASON_BY_CODE: Partial<Record<string, DeclineReason>> = {\n insufficient_funds: 'INSUFFICIENT_FUNDS',\n expired_card: 'CARD_EXPIRED',\n incorrect_cvc: 'CARD_INVALID',\n invalid_cvc: 'CARD_INVALID',\n incorrect_number: 'CARD_INVALID',\n invalid_number: 'CARD_INVALID',\n invalid_expiry_month: 'CARD_INVALID',\n invalid_expiry_year: 'CARD_INVALID',\n incorrect_zip: 'CARD_INVALID',\n processing_error: 'PROCESSING_ERROR',\n try_again_later: 'PROCESSING_ERROR',\n issuer_not_available: 'PROCESSING_ERROR',\n reenter_transaction: 'PROCESSING_ERROR',\n};\n\n/**\n * A refused charge as Stripe describes it: the shape shared by `Stripe.errors.StripeCardError` and\n * `PaymentIntent.last_payment_error`.\n */\nexport type CardFailure =\n | { code?: string | null; decline_code?: string | null; message?: string | null }\n | null\n | undefined;\n\nexport interface Decline {\n reason: DeclineReason;\n /** Stripe's decline code (or error code when there is none), for logs and error metadata */\n code: string | null;\n /** Stripe's own message, for logs; not meant for the customer */\n message: string | null;\n}\n\nexport function mapDecline(failure: CardFailure): Decline {\n // stripe-node fills `decline_code` with '' when the raw error has none, hence `||`.\n const code = failure?.decline_code || failure?.code || null;\n return {\n reason: (code && REASON_BY_CODE[code]) || 'DECLINED',\n code,\n message: failure?.message || null,\n };\n}\n"],"mappings":";;;;;;;;;;;;;AAWA,MAAa,kBAAkB;CAC7B;CACA;CACA;CACA;CACA;AACF;AAIA,MAAM,iBAAyD;CAC7D,oBAAoB;CACpB,cAAc;CACd,eAAe;CACf,aAAa;CACb,kBAAkB;CAClB,gBAAgB;CAChB,sBAAsB;CACtB,qBAAqB;CACrB,eAAe;CACf,kBAAkB;CAClB,iBAAiB;CACjB,sBAAsB;CACtB,qBAAqB;AACvB;AAmBA,SAAgB,WAAW,SAA+B;CAExD,MAAM,OAAO,SAAS,gBAAgB,SAAS,QAAQ;CACvD,OAAO;EACL,QAAS,QAAQ,eAAe,SAAU;EAC1C;EACA,SAAS,SAAS,WAAW;CAC/B;AACF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//#region src/stripe/decline.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Why a card was refused, in the few buckets a cardholder can act on. Everything else
|
|
4
|
+
* (`do_not_honor`, `fraudulent`, `lost_card`, ...) is DECLINED, which is also what Stripe advises
|
|
5
|
+
* telling the customer in those cases: https://docs.stripe.com/declines/codes
|
|
6
|
+
*
|
|
7
|
+
* - INSUFFICIENT_FUNDS: top up, or use another card.
|
|
8
|
+
* - CARD_EXPIRED: update the card.
|
|
9
|
+
* - CARD_INVALID: a mistyped number, expiry, CVC or postal code.
|
|
10
|
+
* - PROCESSING_ERROR: a transient issuer or network problem; trying again may work.
|
|
11
|
+
* - DECLINED: the bank said no without a reason the customer can fix.
|
|
12
|
+
*/
|
|
13
|
+
export declare const DECLINE_REASONS: readonly ['INSUFFICIENT_FUNDS', 'CARD_EXPIRED', 'CARD_INVALID', 'PROCESSING_ERROR', 'DECLINED'];
|
|
14
|
+
export type DeclineReason = (typeof DECLINE_REASONS)[number];
|
|
15
|
+
/**
|
|
16
|
+
* A refused charge as Stripe describes it: the shape shared by `Stripe.errors.StripeCardError` and
|
|
17
|
+
* `PaymentIntent.last_payment_error`.
|
|
18
|
+
*/
|
|
19
|
+
export type CardFailure = {
|
|
20
|
+
code?: string | null;
|
|
21
|
+
decline_code?: string | null;
|
|
22
|
+
message?: string | null;
|
|
23
|
+
} | null | undefined;
|
|
24
|
+
export interface Decline {
|
|
25
|
+
reason: DeclineReason;
|
|
26
|
+
/** Stripe's decline code (or error code when there is none), for logs and error metadata */
|
|
27
|
+
code: string | null;
|
|
28
|
+
/** Stripe's own message, for logs; not meant for the customer */
|
|
29
|
+
message: string | null;
|
|
30
|
+
}
|
|
31
|
+
export declare function mapDecline(failure: CardFailure): Decline;
|
|
32
|
+
//#endregion
|
|
33
|
+
//# sourceMappingURL=decline.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decline.d.cts","names":[],"sources":["../../src/stripe/decline.ts"],"mappings":";;;;;;;;;;;;qBAWa;YAQD,wBAAwB;;;;;YAsBxB;EACN;EAAsB;EAA8B;;iBAIzC;EACf,QAAQ;;EAER;;EAEA;;wBAGc,WAAW,SAAS,cAAc"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//#region src/stripe/decline.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Why a card was refused, in the few buckets a cardholder can act on. Everything else
|
|
4
|
+
* (`do_not_honor`, `fraudulent`, `lost_card`, ...) is DECLINED, which is also what Stripe advises
|
|
5
|
+
* telling the customer in those cases: https://docs.stripe.com/declines/codes
|
|
6
|
+
*
|
|
7
|
+
* - INSUFFICIENT_FUNDS: top up, or use another card.
|
|
8
|
+
* - CARD_EXPIRED: update the card.
|
|
9
|
+
* - CARD_INVALID: a mistyped number, expiry, CVC or postal code.
|
|
10
|
+
* - PROCESSING_ERROR: a transient issuer or network problem; trying again may work.
|
|
11
|
+
* - DECLINED: the bank said no without a reason the customer can fix.
|
|
12
|
+
*/
|
|
13
|
+
export declare const DECLINE_REASONS: readonly ['INSUFFICIENT_FUNDS', 'CARD_EXPIRED', 'CARD_INVALID', 'PROCESSING_ERROR', 'DECLINED'];
|
|
14
|
+
export type DeclineReason = (typeof DECLINE_REASONS)[number];
|
|
15
|
+
/**
|
|
16
|
+
* A refused charge as Stripe describes it: the shape shared by `Stripe.errors.StripeCardError` and
|
|
17
|
+
* `PaymentIntent.last_payment_error`.
|
|
18
|
+
*/
|
|
19
|
+
export type CardFailure = {
|
|
20
|
+
code?: string | null;
|
|
21
|
+
decline_code?: string | null;
|
|
22
|
+
message?: string | null;
|
|
23
|
+
} | null | undefined;
|
|
24
|
+
export interface Decline {
|
|
25
|
+
reason: DeclineReason;
|
|
26
|
+
/** Stripe's decline code (or error code when there is none), for logs and error metadata */
|
|
27
|
+
code: string | null;
|
|
28
|
+
/** Stripe's own message, for logs; not meant for the customer */
|
|
29
|
+
message: string | null;
|
|
30
|
+
}
|
|
31
|
+
export declare function mapDecline(failure: CardFailure): Decline;
|
|
32
|
+
//#endregion
|
|
33
|
+
//# sourceMappingURL=decline.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decline.d.mts","names":[],"sources":["../../src/stripe/decline.ts"],"mappings":";;;;;;;;;;;;qBAWa;YAQD,wBAAwB;;;;;YAsBxB;EACN;EAAsB;EAA8B;;iBAIzC;EACf,QAAQ;;EAER;;EAEA;;wBAGc,WAAW,SAAS,cAAc"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
//#region src/stripe/decline.ts
|
|
2
|
+
/**
|
|
3
|
+
* Why a card was refused, in the few buckets a cardholder can act on. Everything else
|
|
4
|
+
* (`do_not_honor`, `fraudulent`, `lost_card`, ...) is DECLINED, which is also what Stripe advises
|
|
5
|
+
* telling the customer in those cases: https://docs.stripe.com/declines/codes
|
|
6
|
+
*
|
|
7
|
+
* - INSUFFICIENT_FUNDS: top up, or use another card.
|
|
8
|
+
* - CARD_EXPIRED: update the card.
|
|
9
|
+
* - CARD_INVALID: a mistyped number, expiry, CVC or postal code.
|
|
10
|
+
* - PROCESSING_ERROR: a transient issuer or network problem; trying again may work.
|
|
11
|
+
* - DECLINED: the bank said no without a reason the customer can fix.
|
|
12
|
+
*/
|
|
13
|
+
const DECLINE_REASONS = [
|
|
14
|
+
"INSUFFICIENT_FUNDS",
|
|
15
|
+
"CARD_EXPIRED",
|
|
16
|
+
"CARD_INVALID",
|
|
17
|
+
"PROCESSING_ERROR",
|
|
18
|
+
"DECLINED"
|
|
19
|
+
];
|
|
20
|
+
const REASON_BY_CODE = {
|
|
21
|
+
insufficient_funds: "INSUFFICIENT_FUNDS",
|
|
22
|
+
expired_card: "CARD_EXPIRED",
|
|
23
|
+
incorrect_cvc: "CARD_INVALID",
|
|
24
|
+
invalid_cvc: "CARD_INVALID",
|
|
25
|
+
incorrect_number: "CARD_INVALID",
|
|
26
|
+
invalid_number: "CARD_INVALID",
|
|
27
|
+
invalid_expiry_month: "CARD_INVALID",
|
|
28
|
+
invalid_expiry_year: "CARD_INVALID",
|
|
29
|
+
incorrect_zip: "CARD_INVALID",
|
|
30
|
+
processing_error: "PROCESSING_ERROR",
|
|
31
|
+
try_again_later: "PROCESSING_ERROR",
|
|
32
|
+
issuer_not_available: "PROCESSING_ERROR",
|
|
33
|
+
reenter_transaction: "PROCESSING_ERROR"
|
|
34
|
+
};
|
|
35
|
+
function mapDecline(failure) {
|
|
36
|
+
const code = failure?.decline_code || failure?.code || null;
|
|
37
|
+
return {
|
|
38
|
+
reason: code && REASON_BY_CODE[code] || "DECLINED",
|
|
39
|
+
code,
|
|
40
|
+
message: failure?.message || null
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
export { DECLINE_REASONS, mapDecline };
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=decline.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decline.mjs","names":[],"sources":["../../src/stripe/decline.ts"],"sourcesContent":["/**\n * Why a card was refused, in the few buckets a cardholder can act on. Everything else\n * (`do_not_honor`, `fraudulent`, `lost_card`, ...) is DECLINED, which is also what Stripe advises\n * telling the customer in those cases: https://docs.stripe.com/declines/codes\n *\n * - INSUFFICIENT_FUNDS: top up, or use another card.\n * - CARD_EXPIRED: update the card.\n * - CARD_INVALID: a mistyped number, expiry, CVC or postal code.\n * - PROCESSING_ERROR: a transient issuer or network problem; trying again may work.\n * - DECLINED: the bank said no without a reason the customer can fix.\n */\nexport const DECLINE_REASONS = [\n 'INSUFFICIENT_FUNDS',\n 'CARD_EXPIRED',\n 'CARD_INVALID',\n 'PROCESSING_ERROR',\n 'DECLINED',\n] as const;\n\nexport type DeclineReason = (typeof DECLINE_REASONS)[number];\n\nconst REASON_BY_CODE: Partial<Record<string, DeclineReason>> = {\n insufficient_funds: 'INSUFFICIENT_FUNDS',\n expired_card: 'CARD_EXPIRED',\n incorrect_cvc: 'CARD_INVALID',\n invalid_cvc: 'CARD_INVALID',\n incorrect_number: 'CARD_INVALID',\n invalid_number: 'CARD_INVALID',\n invalid_expiry_month: 'CARD_INVALID',\n invalid_expiry_year: 'CARD_INVALID',\n incorrect_zip: 'CARD_INVALID',\n processing_error: 'PROCESSING_ERROR',\n try_again_later: 'PROCESSING_ERROR',\n issuer_not_available: 'PROCESSING_ERROR',\n reenter_transaction: 'PROCESSING_ERROR',\n};\n\n/**\n * A refused charge as Stripe describes it: the shape shared by `Stripe.errors.StripeCardError` and\n * `PaymentIntent.last_payment_error`.\n */\nexport type CardFailure =\n | { code?: string | null; decline_code?: string | null; message?: string | null }\n | null\n | undefined;\n\nexport interface Decline {\n reason: DeclineReason;\n /** Stripe's decline code (or error code when there is none), for logs and error metadata */\n code: string | null;\n /** Stripe's own message, for logs; not meant for the customer */\n message: string | null;\n}\n\nexport function mapDecline(failure: CardFailure): Decline {\n // stripe-node fills `decline_code` with '' when the raw error has none, hence `||`.\n const code = failure?.decline_code || failure?.code || null;\n return {\n reason: (code && REASON_BY_CODE[code]) || 'DECLINED',\n code,\n message: failure?.message || null,\n };\n}\n"],"mappings":";;;;;;;;;;;;AAWA,MAAa,kBAAkB;CAC7B;CACA;CACA;CACA;CACA;AACF;AAIA,MAAM,iBAAyD;CAC7D,oBAAoB;CACpB,cAAc;CACd,eAAe;CACf,aAAa;CACb,kBAAkB;CAClB,gBAAgB;CAChB,sBAAsB;CACtB,qBAAqB;CACrB,eAAe;CACf,kBAAkB;CAClB,iBAAiB;CACjB,sBAAsB;CACtB,qBAAqB;AACvB;AAmBA,SAAgB,WAAW,SAA+B;CAExD,MAAM,OAAO,SAAS,gBAAgB,SAAS,QAAQ;CACvD,OAAO;EACL,QAAS,QAAQ,eAAe,SAAU;EAC1C;EACA,SAAS,SAAS,WAAW;CAC/B;AACF"}
|
package/dist/stripe/index.cjs
CHANGED
|
@@ -1,32 +1,44 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_stripe_config = require("./config.cjs");
|
|
3
|
+
const require_stripe_decline = require("./decline.cjs");
|
|
3
4
|
const require_stripe_expandable = require("./expandable.cjs");
|
|
4
5
|
const require_stripe_handler = require("./handler.cjs");
|
|
5
6
|
const require_stripe_mapper = require("./mapper.cjs");
|
|
7
|
+
const require_stripe_subscription = require("./subscription.cjs");
|
|
8
|
+
const require_stripe_payment_method = require("./payment-method.cjs");
|
|
6
9
|
const require_stripe_thin_handler = require("./thin-handler.cjs");
|
|
7
10
|
const require_stripe_schema = require("./schema.cjs");
|
|
8
11
|
const require_stripe_metadata = require("./metadata.cjs");
|
|
9
12
|
const require_stripe_pending_checkout = require("./pending-checkout.cjs");
|
|
13
|
+
exports.DECLINE_REASONS = require_stripe_decline.DECLINE_REASONS;
|
|
14
|
+
exports.DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES = require_stripe_payment_method.DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES;
|
|
10
15
|
exports.METADATA_KEYS = require_stripe_metadata.METADATA_KEYS;
|
|
11
16
|
exports.StripeConfig = require_stripe_config.StripeConfig;
|
|
12
17
|
exports.StripeEventHandler = require_stripe_handler.StripeEventHandler;
|
|
13
18
|
exports.StripeThinEventHandler = require_stripe_thin_handler.StripeThinEventHandler;
|
|
14
19
|
exports.addPendingCheckout = require_stripe_pending_checkout.addPendingCheckout;
|
|
20
|
+
exports.cancellationComment = require_stripe_mapper.cancellationComment;
|
|
15
21
|
exports.cancellationDetailsSchema = require_stripe_schema.cancellationDetailsSchema;
|
|
16
22
|
exports.createCheckoutSessionSchema = require_stripe_schema.createCheckoutSessionSchema;
|
|
17
23
|
exports.expanded = require_stripe_expandable.expanded;
|
|
18
24
|
exports.getBeginCheckoutProperties = require_stripe_mapper.getBeginCheckoutProperties;
|
|
19
25
|
exports.getPendingCheckouts = require_stripe_pending_checkout.getPendingCheckouts;
|
|
20
26
|
exports.getPurchaseProperties = require_stripe_mapper.getPurchaseProperties;
|
|
27
|
+
exports.hasDelayedNotification = require_stripe_payment_method.hasDelayedNotification;
|
|
21
28
|
exports.idOf = require_stripe_expandable.idOf;
|
|
22
29
|
exports.mapCancellationDetails = require_stripe_mapper.mapCancellationDetails;
|
|
23
30
|
exports.mapCharge = require_stripe_mapper.mapCharge;
|
|
24
31
|
exports.mapCheckoutSession = require_stripe_mapper.mapCheckoutSession;
|
|
32
|
+
exports.mapDecline = require_stripe_decline.mapDecline;
|
|
33
|
+
exports.mapDisputeStatus = require_stripe_mapper.mapDisputeStatus;
|
|
25
34
|
exports.mapInvoice = require_stripe_mapper.mapInvoice;
|
|
26
35
|
exports.mapLineItem = require_stripe_mapper.mapLineItem;
|
|
36
|
+
exports.mapListPrice = require_stripe_subscription.mapListPrice;
|
|
27
37
|
exports.mapPaymentIntent = require_stripe_mapper.mapPaymentIntent;
|
|
28
38
|
exports.mapPaymentType = require_stripe_mapper.mapPaymentType;
|
|
29
39
|
exports.mapPrice = require_stripe_mapper.mapPrice;
|
|
40
|
+
exports.mapRefundStatus = require_stripe_mapper.mapRefundStatus;
|
|
41
|
+
exports.mapSubscription = require_stripe_subscription.mapSubscription;
|
|
30
42
|
exports.mapSubscriptionStatus = require_stripe_mapper.mapSubscriptionStatus;
|
|
31
43
|
exports.mapTime = require_stripe_mapper.mapTime;
|
|
32
44
|
exports.minorUnits = require_stripe_mapper.minorUnits;
|
package/dist/stripe/index.d.cts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { CancellationDetails } from "../subscription/index.cjs";
|
|
2
2
|
import { PriceId, StripeConfig, StripeMode } from "./config.cjs";
|
|
3
|
+
import { CardFailure, DECLINE_REASONS, Decline, DeclineReason, mapDecline } from "./decline.cjs";
|
|
3
4
|
import { expanded, idOf } from "./expandable.cjs";
|
|
4
5
|
import { StripeEventHandler } from "./handler.cjs";
|
|
5
|
-
import { BeginCheckoutProperties, CheckoutSession, LineItem, Money, PaymentStatus, Price, ProductPrice, PurchaseProperties, getBeginCheckoutProperties, getPurchaseProperties, mapCancellationDetails, mapCharge, mapCheckoutSession, mapInvoice, mapLineItem, mapPaymentIntent, mapPaymentType, mapPrice, mapSubscriptionStatus, mapTime, minorUnits, money, price } from "./mapper.cjs";
|
|
6
|
+
import { BeginCheckoutProperties, CheckoutSession, LineItem, Money, PaymentStatus, Price, ProductPrice, PurchaseProperties, cancellationComment, getBeginCheckoutProperties, getPurchaseProperties, mapCancellationDetails, mapCharge, mapCheckoutSession, mapDisputeStatus, mapInvoice, mapLineItem, mapPaymentIntent, mapPaymentType, mapPrice, mapRefundStatus, mapSubscriptionStatus, mapTime, minorUnits, money, price } from "./mapper.cjs";
|
|
7
|
+
import { StripeSubscriptionState, mapListPrice, mapSubscription } from "./subscription.cjs";
|
|
8
|
+
import { DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES, hasDelayedNotification } from "./payment-method.cjs";
|
|
6
9
|
import { StripeThinEventHandler, StripeThinEventNotificationOf, StripeThinEventType } from "./thin-handler.cjs";
|
|
7
10
|
import { AllowedOrigins, CreateCheckoutSessionDTO, CreateCheckoutSessionSchemaOptions, cancellationDetailsSchema, createCheckoutSessionSchema, returnUrlSchema } from "./schema.cjs";
|
|
8
11
|
import { METADATA_KEYS } from "./metadata.cjs";
|
|
9
12
|
import { addPendingCheckout, getPendingCheckouts, removePendingCheckout } from "./pending-checkout.cjs";
|
|
10
13
|
import { Stripe } from "stripe";
|
|
11
|
-
export { type AllowedOrigins, type BeginCheckoutProperties, type CancellationDetails, type CheckoutSession, type CreateCheckoutSessionDTO, type CreateCheckoutSessionSchemaOptions, type LineItem, METADATA_KEYS, type Money, type PaymentStatus, type Price, type PriceId, type ProductPrice, type PurchaseProperties, type Stripe, StripeConfig, StripeEventHandler, type StripeMode, StripeThinEventHandler, type StripeThinEventNotificationOf, type StripeThinEventType, addPendingCheckout, cancellationDetailsSchema, createCheckoutSessionSchema, expanded, getBeginCheckoutProperties, getPendingCheckouts, getPurchaseProperties, idOf, mapCancellationDetails, mapCharge, mapCheckoutSession, mapInvoice, mapLineItem, mapPaymentIntent, mapPaymentType, mapPrice, mapSubscriptionStatus, mapTime, minorUnits, money, price, removePendingCheckout, returnUrlSchema };
|
|
14
|
+
export { type AllowedOrigins, type BeginCheckoutProperties, type CancellationDetails, type CardFailure, type CheckoutSession, type CreateCheckoutSessionDTO, type CreateCheckoutSessionSchemaOptions, DECLINE_REASONS, DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES, type Decline, type DeclineReason, type LineItem, METADATA_KEYS, type Money, type PaymentStatus, type Price, type PriceId, type ProductPrice, type PurchaseProperties, type Stripe, StripeConfig, StripeEventHandler, type StripeMode, type StripeSubscriptionState, StripeThinEventHandler, type StripeThinEventNotificationOf, type StripeThinEventType, addPendingCheckout, cancellationComment, cancellationDetailsSchema, createCheckoutSessionSchema, expanded, getBeginCheckoutProperties, getPendingCheckouts, getPurchaseProperties, hasDelayedNotification, idOf, mapCancellationDetails, mapCharge, mapCheckoutSession, mapDecline, mapDisputeStatus, mapInvoice, mapLineItem, mapListPrice, mapPaymentIntent, mapPaymentType, mapPrice, mapRefundStatus, mapSubscription, mapSubscriptionStatus, mapTime, minorUnits, money, price, removePendingCheckout, returnUrlSchema };
|
package/dist/stripe/index.d.mts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { CancellationDetails } from "../subscription/index.mjs";
|
|
2
2
|
import { PriceId, StripeConfig, StripeMode } from "./config.mjs";
|
|
3
|
+
import { CardFailure, DECLINE_REASONS, Decline, DeclineReason, mapDecline } from "./decline.mjs";
|
|
3
4
|
import { expanded, idOf } from "./expandable.mjs";
|
|
4
5
|
import { StripeEventHandler } from "./handler.mjs";
|
|
5
|
-
import { BeginCheckoutProperties, CheckoutSession, LineItem, Money, PaymentStatus, Price, ProductPrice, PurchaseProperties, getBeginCheckoutProperties, getPurchaseProperties, mapCancellationDetails, mapCharge, mapCheckoutSession, mapInvoice, mapLineItem, mapPaymentIntent, mapPaymentType, mapPrice, mapSubscriptionStatus, mapTime, minorUnits, money, price } from "./mapper.mjs";
|
|
6
|
+
import { BeginCheckoutProperties, CheckoutSession, LineItem, Money, PaymentStatus, Price, ProductPrice, PurchaseProperties, cancellationComment, getBeginCheckoutProperties, getPurchaseProperties, mapCancellationDetails, mapCharge, mapCheckoutSession, mapDisputeStatus, mapInvoice, mapLineItem, mapPaymentIntent, mapPaymentType, mapPrice, mapRefundStatus, mapSubscriptionStatus, mapTime, minorUnits, money, price } from "./mapper.mjs";
|
|
7
|
+
import { StripeSubscriptionState, mapListPrice, mapSubscription } from "./subscription.mjs";
|
|
8
|
+
import { DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES, hasDelayedNotification } from "./payment-method.mjs";
|
|
6
9
|
import { StripeThinEventHandler, StripeThinEventNotificationOf, StripeThinEventType } from "./thin-handler.mjs";
|
|
7
10
|
import { AllowedOrigins, CreateCheckoutSessionDTO, CreateCheckoutSessionSchemaOptions, cancellationDetailsSchema, createCheckoutSessionSchema, returnUrlSchema } from "./schema.mjs";
|
|
8
11
|
import { METADATA_KEYS } from "./metadata.mjs";
|
|
9
12
|
import { addPendingCheckout, getPendingCheckouts, removePendingCheckout } from "./pending-checkout.mjs";
|
|
10
13
|
import { Stripe } from "stripe";
|
|
11
|
-
export { type AllowedOrigins, type BeginCheckoutProperties, type CancellationDetails, type CheckoutSession, type CreateCheckoutSessionDTO, type CreateCheckoutSessionSchemaOptions, type LineItem, METADATA_KEYS, type Money, type PaymentStatus, type Price, type PriceId, type ProductPrice, type PurchaseProperties, type Stripe, StripeConfig, StripeEventHandler, type StripeMode, StripeThinEventHandler, type StripeThinEventNotificationOf, type StripeThinEventType, addPendingCheckout, cancellationDetailsSchema, createCheckoutSessionSchema, expanded, getBeginCheckoutProperties, getPendingCheckouts, getPurchaseProperties, idOf, mapCancellationDetails, mapCharge, mapCheckoutSession, mapInvoice, mapLineItem, mapPaymentIntent, mapPaymentType, mapPrice, mapSubscriptionStatus, mapTime, minorUnits, money, price, removePendingCheckout, returnUrlSchema };
|
|
14
|
+
export { type AllowedOrigins, type BeginCheckoutProperties, type CancellationDetails, type CardFailure, type CheckoutSession, type CreateCheckoutSessionDTO, type CreateCheckoutSessionSchemaOptions, DECLINE_REASONS, DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES, type Decline, type DeclineReason, type LineItem, METADATA_KEYS, type Money, type PaymentStatus, type Price, type PriceId, type ProductPrice, type PurchaseProperties, type Stripe, StripeConfig, StripeEventHandler, type StripeMode, type StripeSubscriptionState, StripeThinEventHandler, type StripeThinEventNotificationOf, type StripeThinEventType, addPendingCheckout, cancellationComment, cancellationDetailsSchema, createCheckoutSessionSchema, expanded, getBeginCheckoutProperties, getPendingCheckouts, getPurchaseProperties, hasDelayedNotification, idOf, mapCancellationDetails, mapCharge, mapCheckoutSession, mapDecline, mapDisputeStatus, mapInvoice, mapLineItem, mapListPrice, mapPaymentIntent, mapPaymentType, mapPrice, mapRefundStatus, mapSubscription, mapSubscriptionStatus, mapTime, minorUnits, money, price, removePendingCheckout, returnUrlSchema };
|
package/dist/stripe/index.mjs
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { StripeConfig } from "./config.mjs";
|
|
2
|
+
import { DECLINE_REASONS, mapDecline } from "./decline.mjs";
|
|
2
3
|
import { expanded, idOf } from "./expandable.mjs";
|
|
3
4
|
import { StripeEventHandler } from "./handler.mjs";
|
|
4
|
-
import { getBeginCheckoutProperties, getPurchaseProperties, mapCancellationDetails, mapCharge, mapCheckoutSession, mapInvoice, mapLineItem, mapPaymentIntent, mapPaymentType, mapPrice, mapSubscriptionStatus, mapTime, minorUnits, money, price } from "./mapper.mjs";
|
|
5
|
+
import { cancellationComment, getBeginCheckoutProperties, getPurchaseProperties, mapCancellationDetails, mapCharge, mapCheckoutSession, mapDisputeStatus, mapInvoice, mapLineItem, mapPaymentIntent, mapPaymentType, mapPrice, mapRefundStatus, mapSubscriptionStatus, mapTime, minorUnits, money, price } from "./mapper.mjs";
|
|
6
|
+
import { mapListPrice, mapSubscription } from "./subscription.mjs";
|
|
7
|
+
import { DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES, hasDelayedNotification } from "./payment-method.mjs";
|
|
5
8
|
import { StripeThinEventHandler } from "./thin-handler.mjs";
|
|
6
9
|
import { cancellationDetailsSchema, createCheckoutSessionSchema, returnUrlSchema } from "./schema.mjs";
|
|
7
10
|
import { METADATA_KEYS } from "./metadata.mjs";
|
|
8
11
|
import { addPendingCheckout, getPendingCheckouts, removePendingCheckout } from "./pending-checkout.mjs";
|
|
9
|
-
export { METADATA_KEYS, StripeConfig, StripeEventHandler, StripeThinEventHandler, addPendingCheckout, cancellationDetailsSchema, createCheckoutSessionSchema, expanded, getBeginCheckoutProperties, getPendingCheckouts, getPurchaseProperties, idOf, mapCancellationDetails, mapCharge, mapCheckoutSession, mapInvoice, mapLineItem, mapPaymentIntent, mapPaymentType, mapPrice, mapSubscriptionStatus, mapTime, minorUnits, money, price, removePendingCheckout, returnUrlSchema };
|
|
12
|
+
export { DECLINE_REASONS, DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES, METADATA_KEYS, StripeConfig, StripeEventHandler, StripeThinEventHandler, addPendingCheckout, cancellationComment, cancellationDetailsSchema, createCheckoutSessionSchema, expanded, getBeginCheckoutProperties, getPendingCheckouts, getPurchaseProperties, hasDelayedNotification, idOf, mapCancellationDetails, mapCharge, mapCheckoutSession, mapDecline, mapDisputeStatus, mapInvoice, mapLineItem, mapListPrice, mapPaymentIntent, mapPaymentType, mapPrice, mapRefundStatus, mapSubscription, mapSubscriptionStatus, mapTime, minorUnits, money, price, removePendingCheckout, returnUrlSchema };
|
package/dist/stripe/mapper.cjs
CHANGED
|
@@ -131,6 +131,27 @@ function mapPaymentType(invoice) {
|
|
|
131
131
|
return "SUBSCRIPTION_UPDATE";
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
+
/** `refund.status` is an untyped string in stripe-node; these are the documented values. */
|
|
135
|
+
const REFUND_STATUS = {
|
|
136
|
+
pending: "PENDING",
|
|
137
|
+
requires_action: "PENDING",
|
|
138
|
+
succeeded: "SUCCEEDED",
|
|
139
|
+
failed: "FAILED",
|
|
140
|
+
canceled: "CANCELED"
|
|
141
|
+
};
|
|
142
|
+
/** A Stripe refund's status; a refund that has none yet is pending. Throws on an unknown one. */
|
|
143
|
+
function mapRefundStatus(refund) {
|
|
144
|
+
const status = REFUND_STATUS[refund.status ?? "pending"];
|
|
145
|
+
if (!status) throw new Error(`Unknown refund status ${refund.status}: ${refund.id}`);
|
|
146
|
+
return status;
|
|
147
|
+
}
|
|
148
|
+
/** A Stripe dispute's status, upper-cased into {@link DISPUTE_STATUSES}. Throws on an unknown one. */
|
|
149
|
+
function mapDisputeStatus(dispute) {
|
|
150
|
+
const status = dispute.status.toUpperCase();
|
|
151
|
+
const known = require_subscription_index.DISPUTE_STATUSES.find((item) => item === status);
|
|
152
|
+
if (!known) throw new Error(`Unknown dispute status ${dispute.status}: ${dispute.id}`);
|
|
153
|
+
return known;
|
|
154
|
+
}
|
|
134
155
|
/** How many Stripe API amount units make one unit of `currency` (1, 100 or 1000). */
|
|
135
156
|
function minorUnits(currency) {
|
|
136
157
|
return (0, _shware_utils.stripeMinorUnits)(currency);
|
|
@@ -207,10 +228,28 @@ function getBeginCheckoutProperties(p) {
|
|
|
207
228
|
};
|
|
208
229
|
}
|
|
209
230
|
/**
|
|
231
|
+
* The `cancellation_details.comment` to send Stripe for a cancel dialog's answers. Stripe stores
|
|
232
|
+
* reason, feedback and comment, one field short of `resubscribeIntent`, so the intent travels as a
|
|
233
|
+
* `[maybe]` / `[no]` / `[yes]` prefix on the comment, which {@link mapCancellationDetails} takes
|
|
234
|
+
* back out.
|
|
235
|
+
*/
|
|
236
|
+
function cancellationComment({ comment, resubscribeIntent }) {
|
|
237
|
+
return `${resubscribeIntent ? `[${resubscribeIntent}]` : ""}${comment ?? ""}`;
|
|
238
|
+
}
|
|
239
|
+
function parseCancellationComment(comment) {
|
|
240
|
+
const [, intent, rest] = comment && /^\[(\w+)\](.*)$/s.exec(comment) || [];
|
|
241
|
+
if (!intent || !require_subscription_index.RESUBSCRIBE_INTENTS.includes(intent)) return { comment };
|
|
242
|
+
return {
|
|
243
|
+
comment: rest || null,
|
|
244
|
+
resubscribeIntent: intent
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
210
248
|
* Stripe's `cancellation_details` in the shared shape. The object is present on every
|
|
211
249
|
* subscription with all three fields null, so an active one maps to null rather than an empty
|
|
212
250
|
* record. `reason` says who acted: `cancellation_requested` is the customer (or us on their
|
|
213
|
-
* behalf), the payment reasons are Stripe ending it.
|
|
251
|
+
* behalf), the payment reasons are Stripe ending it. A comment written by
|
|
252
|
+
* {@link cancellationComment} is split back into the comment and `resubscribeIntent`.
|
|
214
253
|
*/
|
|
215
254
|
function mapCancellationDetails(subscription) {
|
|
216
255
|
const details = subscription.cancellation_details;
|
|
@@ -219,7 +258,7 @@ function mapCancellationDetails(subscription) {
|
|
|
219
258
|
initiator: details.reason === "payment_failed" || details.reason === "payment_disputed" ? "system" : "user",
|
|
220
259
|
reason: details.reason ?? null,
|
|
221
260
|
feedback: details.feedback ? require_subscription_index.CANCELLATION_FEEDBACKS.includes(details.feedback) ? details.feedback : "other" : null,
|
|
222
|
-
|
|
261
|
+
...parseCancellationComment(details.comment ?? null)
|
|
223
262
|
};
|
|
224
263
|
}
|
|
225
264
|
//#endregion
|
|
@@ -229,16 +268,19 @@ Object.defineProperty(exports, "ZERO_DECIMAL_CURRENCIES", {
|
|
|
229
268
|
return _shware_utils.ZERO_DECIMAL_CURRENCIES;
|
|
230
269
|
}
|
|
231
270
|
});
|
|
271
|
+
exports.cancellationComment = cancellationComment;
|
|
232
272
|
exports.getBeginCheckoutProperties = getBeginCheckoutProperties;
|
|
233
273
|
exports.getPurchaseProperties = getPurchaseProperties;
|
|
234
274
|
exports.mapCancellationDetails = mapCancellationDetails;
|
|
235
275
|
exports.mapCharge = mapCharge;
|
|
236
276
|
exports.mapCheckoutSession = mapCheckoutSession;
|
|
277
|
+
exports.mapDisputeStatus = mapDisputeStatus;
|
|
237
278
|
exports.mapInvoice = mapInvoice;
|
|
238
279
|
exports.mapLineItem = mapLineItem;
|
|
239
280
|
exports.mapPaymentIntent = mapPaymentIntent;
|
|
240
281
|
exports.mapPaymentType = mapPaymentType;
|
|
241
282
|
exports.mapPrice = mapPrice;
|
|
283
|
+
exports.mapRefundStatus = mapRefundStatus;
|
|
242
284
|
exports.mapSubscriptionStatus = mapSubscriptionStatus;
|
|
243
285
|
exports.mapTime = mapTime;
|
|
244
286
|
exports.minorUnits = minorUnits;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mapper.cjs","names":["stripeMinorUnits","CANCELLATION_FEEDBACKS"],"sources":["../../src/stripe/mapper.ts"],"sourcesContent":["import { stripeMinorUnits } from '@shware/utils';\nimport type { Stripe } from 'stripe';\nimport {\n CANCELLATION_FEEDBACKS,\n type CancellationDetails,\n type CancellationFeedback,\n type PaymentType,\n type SubscriptionStatus,\n} from '../subscription/index';\n\nexport function mapTime<T extends number | null>(\n stripeTimestampSeconds: T\n): T extends number ? string : null {\n if (!stripeTimestampSeconds) return null as T extends number ? string : null;\n return new Date(stripeTimestampSeconds * 1000).toISOString() as T extends number ? string : null;\n}\n\nexport type Price = {\n id: string;\n type: Stripe.Price.Type;\n active: boolean;\n billing_scheme: Stripe.Price.BillingScheme;\n currency: Stripe.Price['currency'];\n unit_amount: number | null;\n unit_amount_decimal: string | null;\n recurring: Stripe.Price.Recurring | null;\n};\n\nexport function mapPrice(price: Stripe.Price): Price {\n return {\n id: price.id,\n type: price.type,\n active: price.active,\n billing_scheme: price.billing_scheme,\n currency: price.currency,\n unit_amount: price.unit_amount,\n unit_amount_decimal: price.unit_amount_decimal?.toString() ?? null,\n recurring: price.recurring,\n };\n}\n\nexport interface LineItem {\n id: string;\n currency: string;\n quantity: number | null;\n description: string | null;\n amount_tax: number;\n amount_total: number;\n amount_subtotal: number;\n amount_discount: number;\n price: Price | null;\n}\n\nexport function mapLineItem(item: Stripe.LineItem): LineItem {\n return {\n id: item.price\n ? typeof item.price.product === 'string'\n ? item.price.product\n : item.price.product.id\n : item.id,\n currency: item.currency,\n quantity: item.quantity,\n description: item.description,\n amount_tax: item.amount_tax,\n amount_total: item.amount_total,\n amount_subtotal: item.amount_subtotal,\n amount_discount: item.amount_discount,\n price: item.price ? mapPrice(item.price) : null,\n };\n}\n\n// Re-exported under our own name so consumers need not reach into stripe's namespace.\n// Open-ended since stripe 22.4: a status the API adds later is not a type error.\nexport type PaymentStatus = Stripe.Checkout.Session.PaymentStatus;\n\n// Declared rather than inferred from mapCheckoutSession: an inferred shape is\n// structural, so a consumer's declaration emit has to spell out payment_status\n// through stripe's internal module path — TS2883 in any package that reaches\n// stripe transitively instead of depending on it (see line_items/price too).\nexport interface CheckoutSession {\n id: string;\n url: string | null;\n coupon: string | undefined;\n livemode: boolean;\n expires_at: number;\n payment_status: PaymentStatus;\n currency: string | null;\n amount_total: number | null;\n line_items: LineItem[] | undefined;\n}\n\nexport function mapCheckoutSession(session: Stripe.Checkout.Session): CheckoutSession {\n let coupon: string | undefined = undefined;\n if (Array.isArray(session.discounts) && session.discounts.length !== 0) {\n const discount = session.discounts[0];\n if (discount.coupon && typeof discount.coupon === 'object') {\n coupon = discount.coupon.id;\n } else if (typeof discount.coupon === 'string') {\n coupon = discount.coupon;\n } else {\n coupon = undefined;\n }\n }\n\n return {\n id: session.id,\n url: session.url,\n coupon,\n livemode: session.livemode,\n expires_at: session.expires_at,\n payment_status: session.payment_status,\n currency: session.currency,\n amount_total: session.amount_total,\n line_items: session.line_items?.data.map(mapLineItem),\n };\n}\n\nexport function mapInvoice(i: Stripe.Invoice) {\n return {\n id: i.id,\n number: i.number,\n total: i.total,\n subtotal: i.subtotal,\n amount_due: i.amount_due,\n amount_paid: i.amount_paid,\n amount_remaining: i.amount_remaining,\n currency: i.currency,\n billing_reason: i.billing_reason,\n hosted_invoice_url: i.hosted_invoice_url,\n invoice_pdf: i.invoice_pdf,\n receipt_number: i.receipt_number,\n status: i.status,\n created: i.created,\n period_start: i.period_start,\n period_end: i.period_end,\n };\n}\n\nexport function mapPaymentIntent(intent: Stripe.PaymentIntent) {\n return {\n id: intent.id,\n amount: intent.amount,\n amount_capturable: intent.amount_capturable,\n amount_received: intent.amount_received,\n currency: intent.currency,\n client_secret: intent.client_secret,\n description: intent.description,\n status: intent.status,\n created: intent.created,\n };\n}\n\nexport function mapCharge(charge: Stripe.Charge) {\n return {\n id: charge.id,\n description: charge.description,\n currency: charge.currency,\n amount: charge.amount,\n amount_captured: charge.amount_captured,\n amount_refunded: charge.amount_refunded,\n receipt_email: charge.receipt_email,\n receipt_number: charge.receipt_number,\n receipt_url: charge.receipt_url,\n status: charge.status,\n created: charge.created,\n payment_intent:\n charge.payment_intent && typeof charge.payment_intent === 'object'\n ? mapPaymentIntent(charge.payment_intent)\n : undefined,\n };\n}\n\nexport type ProductPrice = {\n id: string;\n type: Stripe.Price.Type;\n unit_amount: number;\n currency: Stripe.Price['currency'];\n product: {\n id: Stripe.Product['id'];\n name: Stripe.Product['name'];\n description: Stripe.Product['description'];\n livemode: Stripe.Product['livemode'];\n };\n};\n\nexport function mapSubscriptionStatus(status: Stripe.Subscription.Status): SubscriptionStatus {\n switch (status) {\n case 'active':\n return 'ACTIVE';\n case 'canceled':\n return 'CANCELED';\n case 'incomplete':\n return 'INCOMPLETE';\n case 'incomplete_expired':\n return 'INCOMPLETE_EXPIRED';\n case 'past_due':\n return 'PAST_DUE';\n case 'paused':\n return 'PAUSED';\n case 'trialing':\n return 'TRIALING';\n case 'unpaid':\n return 'UNPAID';\n default: {\n console.error(`Invalid stripe status: ${String(status)}`);\n throw new Error(`Invalid stripe status: ${String(status)}`);\n }\n }\n}\n\n/**\n * What a paid subscription invoice was for, by its `billing_reason`. Only `subscription_cycle` is\n * a renewal: a plan change invoices its proration mid-period (`subscription_update`), and counting\n * that as a renewal would inflate the renewal rate by every upgrade.\n */\nexport function mapPaymentType(\n invoice: Pick<Stripe.Invoice, 'id' | 'billing_reason'>\n): Exclude<PaymentType, 'ONE_TIME'> {\n switch (invoice.billing_reason) {\n // Exactly once per subscription: its first invoice (after a trial, the first paid one is a cycle).\n case 'subscription_create':\n return 'SUBSCRIPTION_START';\n case 'subscription_cycle':\n return 'SUBSCRIPTION_RENEWAL';\n case 'subscription_update':\n return 'SUBSCRIPTION_UPDATE';\n // An invoice made by hand on the subscription (dashboard or API): off-cycle money, not a renewal.\n case 'manual':\n return 'SUBSCRIPTION_UPDATE';\n default:\n // subscription_threshold (metered billing) and the rest are not reasons flat-priced\n // subscriptions produce. Off-cycle is the safe reading: it leaves renewals alone.\n console.warn(`Invoice ${invoice.id} has billing_reason ${invoice.billing_reason}`);\n return 'SUBSCRIPTION_UPDATE';\n }\n}\n\nexport { ZERO_DECIMAL_CURRENCIES } from '@shware/utils';\n\n/** How many Stripe API amount units make one unit of `currency` (1, 100 or 1000). */\nexport function minorUnits(currency: string) {\n return stripeMinorUnits(currency);\n}\n\nexport function price(value: number, currency: string) {\n return value / minorUnits(currency);\n}\n\nexport type Money = { amount: number; currency: string };\n\n/** A Stripe amount in minor units (cents, yen, fils) as an amount in `currency` itself. */\nexport function money(value: number, currency: string): Money {\n return { amount: price(value, currency), currency };\n}\n\nexport interface Item {\n item_id: string;\n item_name: string;\n affiliation?: 'Google Store' | (string & {});\n coupon?: string;\n discount?: number;\n index?: number;\n item_brand?: string;\n item_category?: string;\n item_category2?: string;\n item_category3?: string;\n item_category4?: string;\n item_category5?: string;\n item_list_id?: string;\n item_list_name?: string;\n item_variant?: string;\n location_id?: string;\n price?: number;\n quantity?: number;\n}\n\nexport interface PurchaseProperties {\n currency: string;\n value: number;\n transaction_id: string;\n coupon?: string;\n shipping?: number;\n tax?: number;\n items?: Item[];\n}\n\nexport interface BeginCheckoutProperties {\n currency: string;\n value: number;\n coupon?: string;\n items: Item[];\n}\n\n// Google Ads rejects conversion transaction IDs longer than 64 characters.\n// https://support.google.com/google-ads/answer/6386790\nconst GOOGLE_ADS_TRANSACTION_ID_MAX = 64;\n\n/**\n * GA4 purchase events feed Google Ads conversions, whose transaction IDs are\n * capped at 64 characters — but Stripe checkout session ids exceed that:\n * around 2021 they grew from ~32 chars (`cs_live_` + 24 random chars) to ~66\n * (`cs_live_a` + 57), with no announcement. Stripe treats id length/format as\n * opaque and backwards-compatible, guaranteeing only that ids never exceed\n * 255 chars, so they may grow again at any time.\n *\n * Dropping the fixed `cs_live_`/`cs_test_` prefix brings the id under 64\n * while staying reversible: prepend the prefix (livemode tells which) to\n * reconstruct the full session id for Stripe dashboard lookups. The payment\n * intent id (~27 chars) is not a substitute — it only exists on\n * `mode: 'payment'` sessions (subscription-mode sessions carry it on the\n * invoice instead), and its short length is just as unguaranteed as the\n * session id's was.\n *\n * Must stay deterministic: GA4/Google Ads dedupe purchases by\n * transaction_id, and the same session may be tracked from multiple paths.\n */\nfunction toTransactionId(sessionId: string): string {\n const stripped = sessionId.replace(/^cs_(live|test)_/, '');\n if (stripped.length > GOOGLE_ADS_TRANSACTION_ID_MAX) {\n console.warn(\n `transaction_id still exceeds ${GOOGLE_ADS_TRANSACTION_ID_MAX} chars after stripping ` +\n `the prefix — Stripe may have lengthened session ids again; truncating: ${sessionId}`\n );\n }\n return stripped.slice(0, GOOGLE_ADS_TRANSACTION_ID_MAX);\n}\n\nexport function getPurchaseProperties(session: CheckoutSession): PurchaseProperties {\n let value: number;\n let currency: string;\n if (!session.amount_total || !session.currency) {\n value = session.line_items?.reduce((acc, item) => acc + item.amount_total, 0) ?? 0;\n currency = session.line_items?.[0]?.currency ?? 'usd';\n } else {\n value = session.amount_total;\n currency = session.currency;\n }\n\n return {\n transaction_id: toTransactionId(session.id),\n value: price(value, currency),\n currency: currency.toUpperCase(),\n coupon: session.coupon,\n items: session.line_items?.map((item, index) => ({\n index,\n item_id: item.id,\n item_name: item.description ?? '',\n price: price(item.amount_total, item.currency),\n quantity: item.quantity ?? 1,\n discount: price(item.amount_discount, item.currency),\n })),\n };\n}\n\nexport function getBeginCheckoutProperties(p: ProductPrice): BeginCheckoutProperties {\n return {\n currency: p.currency.toUpperCase(),\n value: price(p.unit_amount, p.currency),\n items: [\n {\n item_id: p.product.id,\n item_name: p.product.name,\n price: price(p.unit_amount, p.currency),\n },\n ],\n };\n}\n\n/**\n * Stripe's `cancellation_details` in the shared shape. The object is present on every\n * subscription with all three fields null, so an active one maps to null rather than an empty\n * record. `reason` says who acted: `cancellation_requested` is the customer (or us on their\n * behalf), the payment reasons are Stripe ending it.\n */\nexport function mapCancellationDetails(\n subscription: Pick<Stripe.Subscription, 'cancellation_details'>\n): CancellationDetails | null {\n const details = subscription.cancellation_details;\n if (!details || (!details.reason && !details.feedback && !details.comment)) return null;\n return {\n initiator:\n details.reason === 'payment_failed' || details.reason === 'payment_disputed'\n ? 'system'\n : 'user',\n reason: details.reason ?? null,\n // Stripe's feedback vocabulary is ours; anything it adds later is reported as \"other\".\n feedback: details.feedback\n ? (CANCELLATION_FEEDBACKS as readonly string[]).includes(details.feedback)\n ? (details.feedback as CancellationFeedback)\n : 'other'\n : null,\n comment: details.comment ?? null,\n };\n}\n"],"mappings":";;;;AAUA,SAAgB,QACd,wBACkC;CAClC,IAAI,CAAC,wBAAwB,OAAO;CACpC,wBAAO,IAAI,KAAK,yBAAyB,GAAI,EAAA,CAAE,YAAY;AAC7D;AAaA,SAAgB,SAAS,OAA4B;CACnD,OAAO;EACL,IAAI,MAAM;EACV,MAAM,MAAM;EACZ,QAAQ,MAAM;EACd,gBAAgB,MAAM;EACtB,UAAU,MAAM;EAChB,aAAa,MAAM;EACnB,qBAAqB,MAAM,qBAAqB,SAAS,KAAK;EAC9D,WAAW,MAAM;CACnB;AACF;AAcA,SAAgB,YAAY,MAAiC;CAC3D,OAAO;EACL,IAAI,KAAK,QACL,OAAO,KAAK,MAAM,YAAY,WAC5B,KAAK,MAAM,UACX,KAAK,MAAM,QAAQ,KACrB,KAAK;EACT,UAAU,KAAK;EACf,UAAU,KAAK;EACf,aAAa,KAAK;EAClB,YAAY,KAAK;EACjB,cAAc,KAAK;EACnB,iBAAiB,KAAK;EACtB,iBAAiB,KAAK;EACtB,OAAO,KAAK,QAAQ,SAAS,KAAK,KAAK,IAAI;CAC7C;AACF;AAsBA,SAAgB,mBAAmB,SAAmD;CACpF,IAAI,SAA6B,KAAA;CACjC,IAAI,MAAM,QAAQ,QAAQ,SAAS,KAAK,QAAQ,UAAU,WAAW,GAAG;EACtE,MAAM,WAAW,QAAQ,UAAU;EACnC,IAAI,SAAS,UAAU,OAAO,SAAS,WAAW,UAChD,SAAS,SAAS,OAAO;OACpB,IAAI,OAAO,SAAS,WAAW,UACpC,SAAS,SAAS;OAElB,SAAS,KAAA;CAEb;CAEA,OAAO;EACL,IAAI,QAAQ;EACZ,KAAK,QAAQ;EACb;EACA,UAAU,QAAQ;EAClB,YAAY,QAAQ;EACpB,gBAAgB,QAAQ;EACxB,UAAU,QAAQ;EAClB,cAAc,QAAQ;EACtB,YAAY,QAAQ,YAAY,KAAK,IAAI,WAAW;CACtD;AACF;AAEA,SAAgB,WAAW,GAAmB;CAC5C,OAAO;EACL,IAAI,EAAE;EACN,QAAQ,EAAE;EACV,OAAO,EAAE;EACT,UAAU,EAAE;EACZ,YAAY,EAAE;EACd,aAAa,EAAE;EACf,kBAAkB,EAAE;EACpB,UAAU,EAAE;EACZ,gBAAgB,EAAE;EAClB,oBAAoB,EAAE;EACtB,aAAa,EAAE;EACf,gBAAgB,EAAE;EAClB,QAAQ,EAAE;EACV,SAAS,EAAE;EACX,cAAc,EAAE;EAChB,YAAY,EAAE;CAChB;AACF;AAEA,SAAgB,iBAAiB,QAA8B;CAC7D,OAAO;EACL,IAAI,OAAO;EACX,QAAQ,OAAO;EACf,mBAAmB,OAAO;EAC1B,iBAAiB,OAAO;EACxB,UAAU,OAAO;EACjB,eAAe,OAAO;EACtB,aAAa,OAAO;EACpB,QAAQ,OAAO;EACf,SAAS,OAAO;CAClB;AACF;AAEA,SAAgB,UAAU,QAAuB;CAC/C,OAAO;EACL,IAAI,OAAO;EACX,aAAa,OAAO;EACpB,UAAU,OAAO;EACjB,QAAQ,OAAO;EACf,iBAAiB,OAAO;EACxB,iBAAiB,OAAO;EACxB,eAAe,OAAO;EACtB,gBAAgB,OAAO;EACvB,aAAa,OAAO;EACpB,QAAQ,OAAO;EACf,SAAS,OAAO;EAChB,gBACE,OAAO,kBAAkB,OAAO,OAAO,mBAAmB,WACtD,iBAAiB,OAAO,cAAc,IACtC,KAAA;CACR;AACF;AAeA,SAAgB,sBAAsB,QAAwD;CAC5F,QAAQ,QAAR;EACE,KAAK,UACH,OAAO;EACT,KAAK,YACH,OAAO;EACT,KAAK,cACH,OAAO;EACT,KAAK,sBACH,OAAO;EACT,KAAK,YACH,OAAO;EACT,KAAK,UACH,OAAO;EACT,KAAK,YACH,OAAO;EACT,KAAK,UACH,OAAO;EACT;GACE,QAAQ,MAAM,0BAA0B,OAAO,MAAM,GAAG;GACxD,MAAM,IAAI,MAAM,0BAA0B,OAAO,MAAM,GAAG;CAE9D;AACF;;;;;;AAOA,SAAgB,eACd,SACkC;CAClC,QAAQ,QAAQ,gBAAhB;EAEE,KAAK,uBACH,OAAO;EACT,KAAK,sBACH,OAAO;EACT,KAAK,uBACH,OAAO;EAET,KAAK,UACH,OAAO;EACT;GAGE,QAAQ,KAAK,WAAW,QAAQ,GAAG,sBAAsB,QAAQ,gBAAgB;GACjF,OAAO;CACX;AACF;;AAKA,SAAgB,WAAW,UAAkB;CAC3C,QAAA,GAAOA,cAAAA,iBAAAA,CAAiB,QAAQ;AAClC;AAEA,SAAgB,MAAM,OAAe,UAAkB;CACrD,OAAO,QAAQ,WAAW,QAAQ;AACpC;;AAKA,SAAgB,MAAM,OAAe,UAAyB;CAC5D,OAAO;EAAE,QAAQ,MAAM,OAAO,QAAQ;EAAG;CAAS;AACpD;AA0CA,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;AAqBtC,SAAS,gBAAgB,WAA2B;CAClD,MAAM,WAAW,UAAU,QAAQ,oBAAoB,EAAE;CACzD,IAAI,SAAS,SAAS,+BACpB,QAAQ,KACN,gCAAgC,8BAA8B,gGACc,WAC9E;CAEF,OAAO,SAAS,MAAM,GAAG,6BAA6B;AACxD;AAEA,SAAgB,sBAAsB,SAA8C;CAClF,IAAI;CACJ,IAAI;CACJ,IAAI,CAAC,QAAQ,gBAAgB,CAAC,QAAQ,UAAU;EAC9C,QAAQ,QAAQ,YAAY,QAAQ,KAAK,SAAS,MAAM,KAAK,cAAc,CAAC,KAAK;EACjF,WAAW,QAAQ,aAAa,EAAE,EAAE,YAAY;CAClD,OAAO;EACL,QAAQ,QAAQ;EAChB,WAAW,QAAQ;CACrB;CAEA,OAAO;EACL,gBAAgB,gBAAgB,QAAQ,EAAE;EAC1C,OAAO,MAAM,OAAO,QAAQ;EAC5B,UAAU,SAAS,YAAY;EAC/B,QAAQ,QAAQ;EAChB,OAAO,QAAQ,YAAY,KAAK,MAAM,WAAW;GAC/C;GACA,SAAS,KAAK;GACd,WAAW,KAAK,eAAe;GAC/B,OAAO,MAAM,KAAK,cAAc,KAAK,QAAQ;GAC7C,UAAU,KAAK,YAAY;GAC3B,UAAU,MAAM,KAAK,iBAAiB,KAAK,QAAQ;EACrD,EAAE;CACJ;AACF;AAEA,SAAgB,2BAA2B,GAA0C;CACnF,OAAO;EACL,UAAU,EAAE,SAAS,YAAY;EACjC,OAAO,MAAM,EAAE,aAAa,EAAE,QAAQ;EACtC,OAAO,CACL;GACE,SAAS,EAAE,QAAQ;GACnB,WAAW,EAAE,QAAQ;GACrB,OAAO,MAAM,EAAE,aAAa,EAAE,QAAQ;EACxC,CACF;CACF;AACF;;;;;;;AAQA,SAAgB,uBACd,cAC4B;CAC5B,MAAM,UAAU,aAAa;CAC7B,IAAI,CAAC,WAAY,CAAC,QAAQ,UAAU,CAAC,QAAQ,YAAY,CAAC,QAAQ,SAAU,OAAO;CACnF,OAAO;EACL,WACE,QAAQ,WAAW,oBAAoB,QAAQ,WAAW,qBACtD,WACA;EACN,QAAQ,QAAQ,UAAU;EAE1B,UAAU,QAAQ,WACbC,2BAAAA,uBAA6C,SAAS,QAAQ,QAAQ,IACpE,QAAQ,WACT,UACF;EACJ,SAAS,QAAQ,WAAW;CAC9B;AACF"}
|
|
1
|
+
{"version":3,"file":"mapper.cjs","names":["DISPUTE_STATUSES","stripeMinorUnits","RESUBSCRIBE_INTENTS","CANCELLATION_FEEDBACKS"],"sources":["../../src/stripe/mapper.ts"],"sourcesContent":["import { stripeMinorUnits } from '@shware/utils';\nimport type { Stripe } from 'stripe';\nimport {\n CANCELLATION_FEEDBACKS,\n type CancellationDetails,\n type CancellationFeedback,\n DISPUTE_STATUSES,\n type DisputeStatus,\n type PaymentType,\n RESUBSCRIBE_INTENTS,\n type RefundStatus,\n type ResubscribeIntent,\n type SubscriptionStatus,\n} from '../subscription/index';\n\nexport function mapTime<T extends number | null>(\n stripeTimestampSeconds: T\n): T extends number ? string : null {\n if (!stripeTimestampSeconds) return null as T extends number ? string : null;\n return new Date(stripeTimestampSeconds * 1000).toISOString() as T extends number ? string : null;\n}\n\nexport type Price = {\n id: string;\n type: Stripe.Price.Type;\n active: boolean;\n billing_scheme: Stripe.Price.BillingScheme;\n currency: Stripe.Price['currency'];\n unit_amount: number | null;\n unit_amount_decimal: string | null;\n recurring: Stripe.Price.Recurring | null;\n};\n\nexport function mapPrice(price: Stripe.Price): Price {\n return {\n id: price.id,\n type: price.type,\n active: price.active,\n billing_scheme: price.billing_scheme,\n currency: price.currency,\n unit_amount: price.unit_amount,\n unit_amount_decimal: price.unit_amount_decimal?.toString() ?? null,\n recurring: price.recurring,\n };\n}\n\nexport interface LineItem {\n id: string;\n currency: string;\n quantity: number | null;\n description: string | null;\n amount_tax: number;\n amount_total: number;\n amount_subtotal: number;\n amount_discount: number;\n price: Price | null;\n}\n\nexport function mapLineItem(item: Stripe.LineItem): LineItem {\n return {\n id: item.price\n ? typeof item.price.product === 'string'\n ? item.price.product\n : item.price.product.id\n : item.id,\n currency: item.currency,\n quantity: item.quantity,\n description: item.description,\n amount_tax: item.amount_tax,\n amount_total: item.amount_total,\n amount_subtotal: item.amount_subtotal,\n amount_discount: item.amount_discount,\n price: item.price ? mapPrice(item.price) : null,\n };\n}\n\n// Re-exported under our own name so consumers need not reach into stripe's namespace.\n// Open-ended since stripe 22.4: a status the API adds later is not a type error.\nexport type PaymentStatus = Stripe.Checkout.Session.PaymentStatus;\n\n// Declared rather than inferred from mapCheckoutSession: an inferred shape is\n// structural, so a consumer's declaration emit has to spell out payment_status\n// through stripe's internal module path — TS2883 in any package that reaches\n// stripe transitively instead of depending on it (see line_items/price too).\nexport interface CheckoutSession {\n id: string;\n url: string | null;\n coupon: string | undefined;\n livemode: boolean;\n expires_at: number;\n payment_status: PaymentStatus;\n currency: string | null;\n amount_total: number | null;\n line_items: LineItem[] | undefined;\n}\n\nexport function mapCheckoutSession(session: Stripe.Checkout.Session): CheckoutSession {\n let coupon: string | undefined = undefined;\n if (Array.isArray(session.discounts) && session.discounts.length !== 0) {\n const discount = session.discounts[0];\n if (discount.coupon && typeof discount.coupon === 'object') {\n coupon = discount.coupon.id;\n } else if (typeof discount.coupon === 'string') {\n coupon = discount.coupon;\n } else {\n coupon = undefined;\n }\n }\n\n return {\n id: session.id,\n url: session.url,\n coupon,\n livemode: session.livemode,\n expires_at: session.expires_at,\n payment_status: session.payment_status,\n currency: session.currency,\n amount_total: session.amount_total,\n line_items: session.line_items?.data.map(mapLineItem),\n };\n}\n\nexport function mapInvoice(i: Stripe.Invoice) {\n return {\n id: i.id,\n number: i.number,\n total: i.total,\n subtotal: i.subtotal,\n amount_due: i.amount_due,\n amount_paid: i.amount_paid,\n amount_remaining: i.amount_remaining,\n currency: i.currency,\n billing_reason: i.billing_reason,\n hosted_invoice_url: i.hosted_invoice_url,\n invoice_pdf: i.invoice_pdf,\n receipt_number: i.receipt_number,\n status: i.status,\n created: i.created,\n period_start: i.period_start,\n period_end: i.period_end,\n };\n}\n\nexport function mapPaymentIntent(intent: Stripe.PaymentIntent) {\n return {\n id: intent.id,\n amount: intent.amount,\n amount_capturable: intent.amount_capturable,\n amount_received: intent.amount_received,\n currency: intent.currency,\n client_secret: intent.client_secret,\n description: intent.description,\n status: intent.status,\n created: intent.created,\n };\n}\n\nexport function mapCharge(charge: Stripe.Charge) {\n return {\n id: charge.id,\n description: charge.description,\n currency: charge.currency,\n amount: charge.amount,\n amount_captured: charge.amount_captured,\n amount_refunded: charge.amount_refunded,\n receipt_email: charge.receipt_email,\n receipt_number: charge.receipt_number,\n receipt_url: charge.receipt_url,\n status: charge.status,\n created: charge.created,\n payment_intent:\n charge.payment_intent && typeof charge.payment_intent === 'object'\n ? mapPaymentIntent(charge.payment_intent)\n : undefined,\n };\n}\n\nexport type ProductPrice = {\n id: string;\n type: Stripe.Price.Type;\n unit_amount: number;\n currency: Stripe.Price['currency'];\n product: {\n id: Stripe.Product['id'];\n name: Stripe.Product['name'];\n description: Stripe.Product['description'];\n livemode: Stripe.Product['livemode'];\n };\n};\n\nexport function mapSubscriptionStatus(status: Stripe.Subscription.Status): SubscriptionStatus {\n switch (status) {\n case 'active':\n return 'ACTIVE';\n case 'canceled':\n return 'CANCELED';\n case 'incomplete':\n return 'INCOMPLETE';\n case 'incomplete_expired':\n return 'INCOMPLETE_EXPIRED';\n case 'past_due':\n return 'PAST_DUE';\n case 'paused':\n return 'PAUSED';\n case 'trialing':\n return 'TRIALING';\n case 'unpaid':\n return 'UNPAID';\n default: {\n console.error(`Invalid stripe status: ${String(status)}`);\n throw new Error(`Invalid stripe status: ${String(status)}`);\n }\n }\n}\n\n/**\n * What a paid subscription invoice was for, by its `billing_reason`. Only `subscription_cycle` is\n * a renewal: a plan change invoices its proration mid-period (`subscription_update`), and counting\n * that as a renewal would inflate the renewal rate by every upgrade.\n */\nexport function mapPaymentType(\n invoice: Pick<Stripe.Invoice, 'id' | 'billing_reason'>\n): Exclude<PaymentType, 'ONE_TIME'> {\n switch (invoice.billing_reason) {\n // Exactly once per subscription: its first invoice (after a trial, the first paid one is a cycle).\n case 'subscription_create':\n return 'SUBSCRIPTION_START';\n case 'subscription_cycle':\n return 'SUBSCRIPTION_RENEWAL';\n case 'subscription_update':\n return 'SUBSCRIPTION_UPDATE';\n // An invoice made by hand on the subscription (dashboard or API): off-cycle money, not a renewal.\n case 'manual':\n return 'SUBSCRIPTION_UPDATE';\n default:\n // subscription_threshold (metered billing) and the rest are not reasons flat-priced\n // subscriptions produce. Off-cycle is the safe reading: it leaves renewals alone.\n console.warn(`Invoice ${invoice.id} has billing_reason ${invoice.billing_reason}`);\n return 'SUBSCRIPTION_UPDATE';\n }\n}\n\n/** `refund.status` is an untyped string in stripe-node; these are the documented values. */\nconst REFUND_STATUS: Partial<Record<string, RefundStatus>> = {\n pending: 'PENDING',\n requires_action: 'PENDING',\n succeeded: 'SUCCEEDED',\n failed: 'FAILED',\n canceled: 'CANCELED',\n};\n\n/** A Stripe refund's status; a refund that has none yet is pending. Throws on an unknown one. */\nexport function mapRefundStatus(refund: Pick<Stripe.Refund, 'id' | 'status'>): RefundStatus {\n const status = REFUND_STATUS[refund.status ?? 'pending'];\n if (!status) throw new Error(`Unknown refund status ${refund.status}: ${refund.id}`);\n return status;\n}\n\n/** A Stripe dispute's status, upper-cased into {@link DISPUTE_STATUSES}. Throws on an unknown one. */\nexport function mapDisputeStatus(dispute: Pick<Stripe.Dispute, 'id' | 'status'>): DisputeStatus {\n const status = dispute.status.toUpperCase();\n const known = DISPUTE_STATUSES.find((item) => item === status);\n if (!known) throw new Error(`Unknown dispute status ${dispute.status}: ${dispute.id}`);\n return known;\n}\n\nexport { ZERO_DECIMAL_CURRENCIES } from '@shware/utils';\n\n/** How many Stripe API amount units make one unit of `currency` (1, 100 or 1000). */\nexport function minorUnits(currency: string) {\n return stripeMinorUnits(currency);\n}\n\nexport function price(value: number, currency: string) {\n return value / minorUnits(currency);\n}\n\nexport type Money = { amount: number; currency: string };\n\n/** A Stripe amount in minor units (cents, yen, fils) as an amount in `currency` itself. */\nexport function money(value: number, currency: string): Money {\n return { amount: price(value, currency), currency };\n}\n\nexport interface Item {\n item_id: string;\n item_name: string;\n affiliation?: 'Google Store' | (string & {});\n coupon?: string;\n discount?: number;\n index?: number;\n item_brand?: string;\n item_category?: string;\n item_category2?: string;\n item_category3?: string;\n item_category4?: string;\n item_category5?: string;\n item_list_id?: string;\n item_list_name?: string;\n item_variant?: string;\n location_id?: string;\n price?: number;\n quantity?: number;\n}\n\nexport interface PurchaseProperties {\n currency: string;\n value: number;\n transaction_id: string;\n coupon?: string;\n shipping?: number;\n tax?: number;\n items?: Item[];\n}\n\nexport interface BeginCheckoutProperties {\n currency: string;\n value: number;\n coupon?: string;\n items: Item[];\n}\n\n// Google Ads rejects conversion transaction IDs longer than 64 characters.\n// https://support.google.com/google-ads/answer/6386790\nconst GOOGLE_ADS_TRANSACTION_ID_MAX = 64;\n\n/**\n * GA4 purchase events feed Google Ads conversions, whose transaction IDs are\n * capped at 64 characters — but Stripe checkout session ids exceed that:\n * around 2021 they grew from ~32 chars (`cs_live_` + 24 random chars) to ~66\n * (`cs_live_a` + 57), with no announcement. Stripe treats id length/format as\n * opaque and backwards-compatible, guaranteeing only that ids never exceed\n * 255 chars, so they may grow again at any time.\n *\n * Dropping the fixed `cs_live_`/`cs_test_` prefix brings the id under 64\n * while staying reversible: prepend the prefix (livemode tells which) to\n * reconstruct the full session id for Stripe dashboard lookups. The payment\n * intent id (~27 chars) is not a substitute — it only exists on\n * `mode: 'payment'` sessions (subscription-mode sessions carry it on the\n * invoice instead), and its short length is just as unguaranteed as the\n * session id's was.\n *\n * Must stay deterministic: GA4/Google Ads dedupe purchases by\n * transaction_id, and the same session may be tracked from multiple paths.\n */\nfunction toTransactionId(sessionId: string): string {\n const stripped = sessionId.replace(/^cs_(live|test)_/, '');\n if (stripped.length > GOOGLE_ADS_TRANSACTION_ID_MAX) {\n console.warn(\n `transaction_id still exceeds ${GOOGLE_ADS_TRANSACTION_ID_MAX} chars after stripping ` +\n `the prefix — Stripe may have lengthened session ids again; truncating: ${sessionId}`\n );\n }\n return stripped.slice(0, GOOGLE_ADS_TRANSACTION_ID_MAX);\n}\n\nexport function getPurchaseProperties(session: CheckoutSession): PurchaseProperties {\n let value: number;\n let currency: string;\n if (!session.amount_total || !session.currency) {\n value = session.line_items?.reduce((acc, item) => acc + item.amount_total, 0) ?? 0;\n currency = session.line_items?.[0]?.currency ?? 'usd';\n } else {\n value = session.amount_total;\n currency = session.currency;\n }\n\n return {\n transaction_id: toTransactionId(session.id),\n value: price(value, currency),\n currency: currency.toUpperCase(),\n coupon: session.coupon,\n items: session.line_items?.map((item, index) => ({\n index,\n item_id: item.id,\n item_name: item.description ?? '',\n price: price(item.amount_total, item.currency),\n quantity: item.quantity ?? 1,\n discount: price(item.amount_discount, item.currency),\n })),\n };\n}\n\nexport function getBeginCheckoutProperties(p: ProductPrice): BeginCheckoutProperties {\n return {\n currency: p.currency.toUpperCase(),\n value: price(p.unit_amount, p.currency),\n items: [\n {\n item_id: p.product.id,\n item_name: p.product.name,\n price: price(p.unit_amount, p.currency),\n },\n ],\n };\n}\n\n/**\n * The `cancellation_details.comment` to send Stripe for a cancel dialog's answers. Stripe stores\n * reason, feedback and comment, one field short of `resubscribeIntent`, so the intent travels as a\n * `[maybe]` / `[no]` / `[yes]` prefix on the comment, which {@link mapCancellationDetails} takes\n * back out.\n */\nexport function cancellationComment({\n comment,\n resubscribeIntent,\n}: Pick<CancellationDetails, 'comment' | 'resubscribeIntent'>): string {\n return `${resubscribeIntent ? `[${resubscribeIntent}]` : ''}${comment ?? ''}`;\n}\n\nfunction parseCancellationComment(\n comment: string | null\n): Pick<CancellationDetails, 'comment' | 'resubscribeIntent'> {\n const [, intent, rest] = (comment && /^\\[(\\w+)\\](.*)$/s.exec(comment)) || [];\n if (!intent || !(RESUBSCRIBE_INTENTS as readonly string[]).includes(intent)) return { comment };\n return { comment: rest || null, resubscribeIntent: intent as ResubscribeIntent };\n}\n\n/**\n * Stripe's `cancellation_details` in the shared shape. The object is present on every\n * subscription with all three fields null, so an active one maps to null rather than an empty\n * record. `reason` says who acted: `cancellation_requested` is the customer (or us on their\n * behalf), the payment reasons are Stripe ending it. A comment written by\n * {@link cancellationComment} is split back into the comment and `resubscribeIntent`.\n */\nexport function mapCancellationDetails(\n subscription: Pick<Stripe.Subscription, 'cancellation_details'>\n): CancellationDetails | null {\n const details = subscription.cancellation_details;\n if (!details || (!details.reason && !details.feedback && !details.comment)) return null;\n return {\n initiator:\n details.reason === 'payment_failed' || details.reason === 'payment_disputed'\n ? 'system'\n : 'user',\n reason: details.reason ?? null,\n // Stripe's feedback vocabulary is ours; anything it adds later is reported as \"other\".\n feedback: details.feedback\n ? (CANCELLATION_FEEDBACKS as readonly string[]).includes(details.feedback)\n ? (details.feedback as CancellationFeedback)\n : 'other'\n : null,\n ...parseCancellationComment(details.comment ?? null),\n };\n}\n"],"mappings":"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"}
|
package/dist/stripe/mapper.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CancellationDetails, PaymentType, SubscriptionStatus } from "../subscription/index.cjs";
|
|
1
|
+
import { CancellationDetails, DisputeStatus, PaymentType, RefundStatus, SubscriptionStatus } from "../subscription/index.cjs";
|
|
2
2
|
import { Stripe } from "stripe";
|
|
3
3
|
import { ZERO_DECIMAL_CURRENCIES } from "@shware/utils";
|
|
4
4
|
//#region src/stripe/mapper.d.ts
|
|
@@ -111,6 +111,10 @@ export declare function mapSubscriptionStatus(status: Stripe.Subscription.Status
|
|
|
111
111
|
* that as a renewal would inflate the renewal rate by every upgrade.
|
|
112
112
|
*/
|
|
113
113
|
export declare function mapPaymentType(invoice: Pick<Stripe.Invoice, 'id' | 'billing_reason'>): Exclude<PaymentType, 'ONE_TIME'>;
|
|
114
|
+
/** A Stripe refund's status; a refund that has none yet is pending. Throws on an unknown one. */
|
|
115
|
+
export declare function mapRefundStatus(refund: Pick<Stripe.Refund, 'id' | 'status'>): RefundStatus;
|
|
116
|
+
/** A Stripe dispute's status, upper-cased into {@link DISPUTE_STATUSES}. Throws on an unknown one. */
|
|
117
|
+
export declare function mapDisputeStatus(dispute: Pick<Stripe.Dispute, 'id' | 'status'>): DisputeStatus;
|
|
114
118
|
/** How many Stripe API amount units make one unit of `currency` (1, 100 or 1000). */
|
|
115
119
|
export declare function minorUnits(currency: string): 1 | 100 | 1000;
|
|
116
120
|
export declare function price(value: number, currency: string): number;
|
|
@@ -157,11 +161,19 @@ export interface BeginCheckoutProperties {
|
|
|
157
161
|
}
|
|
158
162
|
export declare function getPurchaseProperties(session: CheckoutSession): PurchaseProperties;
|
|
159
163
|
export declare function getBeginCheckoutProperties(p: ProductPrice): BeginCheckoutProperties;
|
|
164
|
+
/**
|
|
165
|
+
* The `cancellation_details.comment` to send Stripe for a cancel dialog's answers. Stripe stores
|
|
166
|
+
* reason, feedback and comment, one field short of `resubscribeIntent`, so the intent travels as a
|
|
167
|
+
* `[maybe]` / `[no]` / `[yes]` prefix on the comment, which {@link mapCancellationDetails} takes
|
|
168
|
+
* back out.
|
|
169
|
+
*/
|
|
170
|
+
export declare function cancellationComment({ comment, resubscribeIntent }: Pick<CancellationDetails, 'comment' | 'resubscribeIntent'>): string;
|
|
160
171
|
/**
|
|
161
172
|
* Stripe's `cancellation_details` in the shared shape. The object is present on every
|
|
162
173
|
* subscription with all three fields null, so an active one maps to null rather than an empty
|
|
163
174
|
* record. `reason` says who acted: `cancellation_requested` is the customer (or us on their
|
|
164
|
-
* behalf), the payment reasons are Stripe ending it.
|
|
175
|
+
* behalf), the payment reasons are Stripe ending it. A comment written by
|
|
176
|
+
* {@link cancellationComment} is split back into the comment and `resubscribeIntent`.
|
|
165
177
|
*/
|
|
166
178
|
export declare function mapCancellationDetails(subscription: Pick<Stripe.Subscription, 'cancellation_details'>): CancellationDetails | null;
|
|
167
179
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mapper.d.cts","names":[],"sources":["../../src/stripe/mapper.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"mapper.d.cts","names":[],"sources":["../../src/stripe/mapper.ts"],"mappings":";;;;wBAegB,QAAQ,yBACtB,wBAAwB,IACvB;YAKS;EACV;EACA,MAAM,OAAO,MAAM;EACnB;EACA,gBAAgB,OAAO,MAAM;EAC7B,UAAU,OAAO;EACjB;EACA;EACA,WAAW,OAAO,MAAM;;wBAGV,SAAS,OAAO,OAAO,QAAQ;iBAa9B;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,OAAO;;wBAGO,YAAY,MAAM,OAAO,WAAW;YAoBxC,gBAAgB,OAAO,SAAS,QAAQ;iBAMnC;EACf;EACA;EACA;EACA;EACA;EACA,gBAAgB;EAChB;EACA;EACA,YAAY;;wBAGE,mBAAmB,SAAS,OAAO,SAAS,UAAU;wBA0BtD,WAAW,GAAG,OAAO;EAEjC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,gBAAc,OAAA,QAAA;EACd;EACA;EACA;EACA,QAAM,OAAA,QAAA;EACN;EACA;EACA;;wBAIY,iBAAiB,QAAQ,OAAO;EAE5C;EACA;EACA;EACA;EACA;EACA;EACA;EACA,QAAM,OAAA,cAAA;EACN;;wBAIY,UAAU,QAAQ,OAAO;EAErC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,QAAM,OAAA,OAAA;EACN;EACA;;;;;;;;;;;;YAOQ;EACV;EACA,MAAM,OAAO,MAAM;EACnB;EACA,UAAU,OAAO;EACjB;IACE,IAAI,OAAO;IACX,MAAM,OAAO;IACb,aAAa,OAAO;IACpB,UAAU,OAAO;;;wBAIL,sBAAsB,QAAQ,OAAO,aAAa,SAAS;;;;;;wBA8B3D,eACd,SAAS,KAAK,OAAO,oCACpB,QAAQ;;wBA8BK,gBAAgB,QAAQ,KAAK,OAAO,2BAA2B;;wBAO/D,iBAAiB,SAAS,KAAK,OAAO,4BAA4B;;wBAUlE,WAAW;wBAIX,MAAM,eAAe;YAIzB;EAAU;EAAgB;;;wBAGtB,MAAM,eAAe,mBAAmB;iBAIvC;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;iBAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA,QAAQ;;iBAGO;EACf;EACA;EACA;EACA,OAAO;;wBAqCO,sBAAsB,SAAS,kBAAkB;wBA2BjD,2BAA2B,GAAG,eAAe;;;;;;;wBAoB7C,sBACd,SACA,qBACC,KAAK;;;;;;;;wBAmBQ,uBACd,cAAc,KAAK,OAAO,wCACzB"}
|
package/dist/stripe/mapper.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CancellationDetails, PaymentType, SubscriptionStatus } from "../subscription/index.mjs";
|
|
1
|
+
import { CancellationDetails, DisputeStatus, PaymentType, RefundStatus, SubscriptionStatus } from "../subscription/index.mjs";
|
|
2
2
|
import { ZERO_DECIMAL_CURRENCIES } from "@shware/utils";
|
|
3
3
|
import { Stripe } from "stripe";
|
|
4
4
|
//#region src/stripe/mapper.d.ts
|
|
@@ -111,6 +111,10 @@ export declare function mapSubscriptionStatus(status: Stripe.Subscription.Status
|
|
|
111
111
|
* that as a renewal would inflate the renewal rate by every upgrade.
|
|
112
112
|
*/
|
|
113
113
|
export declare function mapPaymentType(invoice: Pick<Stripe.Invoice, 'id' | 'billing_reason'>): Exclude<PaymentType, 'ONE_TIME'>;
|
|
114
|
+
/** A Stripe refund's status; a refund that has none yet is pending. Throws on an unknown one. */
|
|
115
|
+
export declare function mapRefundStatus(refund: Pick<Stripe.Refund, 'id' | 'status'>): RefundStatus;
|
|
116
|
+
/** A Stripe dispute's status, upper-cased into {@link DISPUTE_STATUSES}. Throws on an unknown one. */
|
|
117
|
+
export declare function mapDisputeStatus(dispute: Pick<Stripe.Dispute, 'id' | 'status'>): DisputeStatus;
|
|
114
118
|
/** How many Stripe API amount units make one unit of `currency` (1, 100 or 1000). */
|
|
115
119
|
export declare function minorUnits(currency: string): 1 | 100 | 1000;
|
|
116
120
|
export declare function price(value: number, currency: string): number;
|
|
@@ -157,11 +161,19 @@ export interface BeginCheckoutProperties {
|
|
|
157
161
|
}
|
|
158
162
|
export declare function getPurchaseProperties(session: CheckoutSession): PurchaseProperties;
|
|
159
163
|
export declare function getBeginCheckoutProperties(p: ProductPrice): BeginCheckoutProperties;
|
|
164
|
+
/**
|
|
165
|
+
* The `cancellation_details.comment` to send Stripe for a cancel dialog's answers. Stripe stores
|
|
166
|
+
* reason, feedback and comment, one field short of `resubscribeIntent`, so the intent travels as a
|
|
167
|
+
* `[maybe]` / `[no]` / `[yes]` prefix on the comment, which {@link mapCancellationDetails} takes
|
|
168
|
+
* back out.
|
|
169
|
+
*/
|
|
170
|
+
export declare function cancellationComment({ comment, resubscribeIntent }: Pick<CancellationDetails, 'comment' | 'resubscribeIntent'>): string;
|
|
160
171
|
/**
|
|
161
172
|
* Stripe's `cancellation_details` in the shared shape. The object is present on every
|
|
162
173
|
* subscription with all three fields null, so an active one maps to null rather than an empty
|
|
163
174
|
* record. `reason` says who acted: `cancellation_requested` is the customer (or us on their
|
|
164
|
-
* behalf), the payment reasons are Stripe ending it.
|
|
175
|
+
* behalf), the payment reasons are Stripe ending it. A comment written by
|
|
176
|
+
* {@link cancellationComment} is split back into the comment and `resubscribeIntent`.
|
|
165
177
|
*/
|
|
166
178
|
export declare function mapCancellationDetails(subscription: Pick<Stripe.Subscription, 'cancellation_details'>): CancellationDetails | null;
|
|
167
179
|
//#endregion
|