@proxy-checkout/stripe-server-js 0.1.0-prx-146.162.1 → 0.1.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/README.md +15 -113
- package/dist/cjs/errors.d.cts +1 -68
- package/dist/cjs/errors.d.ts +1 -68
- package/dist/cjs/errors.js +1 -86
- package/dist/cjs/index.d.cts +4 -10
- package/dist/cjs/index.d.ts +4 -10
- package/dist/cjs/index.js +1 -24
- package/dist/cjs/metadata.d.cts +2 -26
- package/dist/cjs/metadata.d.ts +2 -26
- package/dist/cjs/metadata.js +3 -73
- package/dist/cjs/open-checkout.d.cts +0 -21
- package/dist/cjs/open-checkout.d.ts +0 -21
- package/dist/cjs/open-checkout.js +38 -310
- package/dist/cjs/sync-checkout-cart.d.cts +3 -3
- package/dist/cjs/sync-checkout-cart.d.ts +3 -3
- package/dist/cjs/sync-checkout-cart.js +22 -92
- package/dist/cjs/types.d.cts +0 -199
- package/dist/cjs/types.d.ts +0 -199
- package/dist/cjs/version.d.cts +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/errors.d.ts +1 -68
- package/dist/esm/errors.js +0 -80
- package/dist/esm/index.d.ts +4 -10
- package/dist/esm/index.js +2 -7
- package/dist/esm/metadata.d.ts +2 -26
- package/dist/esm/metadata.js +2 -69
- package/dist/esm/open-checkout.d.ts +0 -21
- package/dist/esm/open-checkout.js +40 -312
- package/dist/esm/sync-checkout-cart.d.ts +3 -3
- package/dist/esm/sync-checkout-cart.js +23 -93
- package/dist/esm/types.d.ts +0 -199
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +3 -3
- package/dist/cjs/acquisition.d.cts +0 -189
- package/dist/cjs/acquisition.d.ts +0 -189
- package/dist/cjs/acquisition.js +0 -789
- package/dist/cjs/compatibility.d.cts +0 -66
- package/dist/cjs/compatibility.d.ts +0 -66
- package/dist/cjs/compatibility.js +0 -174
- package/dist/cjs/open-payment-intent.d.cts +0 -35
- package/dist/cjs/open-payment-intent.d.ts +0 -35
- package/dist/cjs/open-payment-intent.js +0 -157
- package/dist/cjs/open-setup-intent.d.cts +0 -49
- package/dist/cjs/open-setup-intent.d.ts +0 -49
- package/dist/cjs/open-setup-intent.js +0 -157
- package/dist/cjs/open-subscription.d.cts +0 -75
- package/dist/cjs/open-subscription.d.ts +0 -75
- package/dist/cjs/open-subscription.js +0 -307
- package/dist/cjs/subscription-params.d.cts +0 -33
- package/dist/cjs/subscription-params.d.ts +0 -33
- package/dist/cjs/subscription-params.js +0 -237
- package/dist/esm/acquisition.d.ts +0 -189
- package/dist/esm/acquisition.js +0 -763
- package/dist/esm/compatibility.d.ts +0 -66
- package/dist/esm/compatibility.js +0 -168
- package/dist/esm/open-payment-intent.d.ts +0 -35
- package/dist/esm/open-payment-intent.js +0 -154
- package/dist/esm/open-setup-intent.d.ts +0 -49
- package/dist/esm/open-setup-intent.js +0 -153
- package/dist/esm/open-subscription.d.ts +0 -75
- package/dist/esm/open-subscription.js +0 -304
- package/dist/esm/subscription-params.d.ts +0 -33
- package/dist/esm/subscription-params.js +0 -232
package/dist/cjs/metadata.js
CHANGED
|
@@ -8,22 +8,17 @@
|
|
|
8
8
|
* provides assertions that a Stripe object actually belongs to a Proxy session.
|
|
9
9
|
*/
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.
|
|
11
|
+
exports.PROXY_INTEGRATION_PATH_METADATA_KEY = exports.PROXY_SESSION_METADATA_KEY = void 0;
|
|
12
12
|
exports.requiredMetadata = requiredMetadata;
|
|
13
13
|
exports.injectRequiredCheckoutSessionMetadata = injectRequiredCheckoutSessionMetadata;
|
|
14
|
-
exports.assertCheckoutSessionMetadataPreflight = assertCheckoutSessionMetadataPreflight;
|
|
15
|
-
exports.injectRequiredPaymentIntentMetadata = injectRequiredPaymentIntentMetadata;
|
|
16
14
|
exports.assertCheckoutSessionBelongsToProxy = assertCheckoutSessionBelongsToProxy;
|
|
17
15
|
exports.assertSubscriptionBelongsToProxy = assertSubscriptionBelongsToProxy;
|
|
18
16
|
exports.assertPaymentIntentBelongsToProxy = assertPaymentIntentBelongsToProxy;
|
|
19
|
-
exports.assertProviderObjectBelongsToAcquisition = assertProviderObjectBelongsToAcquisition;
|
|
20
17
|
const server_js_1 = require("@proxy-checkout/server-js");
|
|
21
18
|
/** The single metadata key Proxy reads to correlate a Stripe object to a session. */
|
|
22
19
|
exports.PROXY_SESSION_METADATA_KEY = "proxy_session_id";
|
|
23
20
|
/** Server-owned marker that distinguishes Checkout-created child objects from direct objects. */
|
|
24
21
|
exports.PROXY_INTEGRATION_PATH_METADATA_KEY = "proxy_integration_path";
|
|
25
|
-
exports.PROXY_ACQUISITION_ATTEMPT_METADATA_KEY = "proxy_acquisition_attempt_id";
|
|
26
|
-
exports.PROXY_CONTRACT_VERSION_METADATA_KEY = "proxy_contract_version";
|
|
27
22
|
/** Build the required Stripe metadata placements for a Proxy session. */
|
|
28
23
|
function requiredMetadata(proxySession) {
|
|
29
24
|
const metadata = { proxy_session_id: proxySession.id };
|
|
@@ -40,8 +35,8 @@ function requiredMetadata(proxySession) {
|
|
|
40
35
|
* every object Proxy may later need to correlate. Conflicting merchant-provided
|
|
41
36
|
* proxy metadata fails before any Stripe side effect.
|
|
42
37
|
*/
|
|
43
|
-
function injectRequiredCheckoutSessionMetadata(params, proxySessionId
|
|
44
|
-
const metadata =
|
|
38
|
+
function injectRequiredCheckoutSessionMetadata(params, proxySessionId) {
|
|
39
|
+
const metadata = { proxy_session_id: proxySessionId };
|
|
45
40
|
const checkoutMetadata = {
|
|
46
41
|
...metadata,
|
|
47
42
|
[exports.PROXY_INTEGRATION_PATH_METADATA_KEY]: "checkout_session",
|
|
@@ -67,44 +62,6 @@ function injectRequiredCheckoutSessionMetadata(params, proxySessionId, acquisiti
|
|
|
67
62
|
: {}),
|
|
68
63
|
};
|
|
69
64
|
}
|
|
70
|
-
/**
|
|
71
|
-
* Validate merchant-authored Checkout metadata before reserving an acquisition.
|
|
72
|
-
* The acquisition ID does not exist yet, so those reservation-owned keys must
|
|
73
|
-
* be absent until the shared create owner injects their exact values.
|
|
74
|
-
*/
|
|
75
|
-
function assertCheckoutSessionMetadataPreflight(params, proxySessionId) {
|
|
76
|
-
for (const [field, metadata] of [
|
|
77
|
-
["metadata", params.metadata],
|
|
78
|
-
["payment_intent_data.metadata", metadataFromNestedParams(params.payment_intent_data)],
|
|
79
|
-
["subscription_data.metadata", metadataFromNestedParams(params.subscription_data)],
|
|
80
|
-
]) {
|
|
81
|
-
for (const key of [
|
|
82
|
-
exports.PROXY_ACQUISITION_ATTEMPT_METADATA_KEY,
|
|
83
|
-
exports.PROXY_CONTRACT_VERSION_METADATA_KEY,
|
|
84
|
-
]) {
|
|
85
|
-
if (metadata?.[key] !== undefined) {
|
|
86
|
-
throw new server_js_1.ProxyCheckoutValidationError(`Stripe ${field}.${key} is owned by the Proxy acquisition reservation and must not be supplied by the merchant.`, { code: "provider_binding_mismatch", field: `${field}.${key}` });
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
// Pure construction performs every session/path conflict check without
|
|
91
|
-
// contacting Proxy or Stripe. The returned params are intentionally ignored;
|
|
92
|
-
// the reservation-derived injection still happens exactly once in create.
|
|
93
|
-
injectRequiredCheckoutSessionMetadata(params, proxySessionId);
|
|
94
|
-
}
|
|
95
|
-
/** Inject the server-owned acquisition identity into a direct PaymentIntent. */
|
|
96
|
-
function injectRequiredPaymentIntentMetadata(params, input) {
|
|
97
|
-
const required = {
|
|
98
|
-
[exports.PROXY_ACQUISITION_ATTEMPT_METADATA_KEY]: input.acquisitionAttemptId,
|
|
99
|
-
[exports.PROXY_CONTRACT_VERSION_METADATA_KEY]: "2",
|
|
100
|
-
[exports.PROXY_INTEGRATION_PATH_METADATA_KEY]: "payment_intent",
|
|
101
|
-
[exports.PROXY_SESSION_METADATA_KEY]: input.proxySessionId,
|
|
102
|
-
};
|
|
103
|
-
return {
|
|
104
|
-
...params,
|
|
105
|
-
metadata: mergeProxyMetadata(params.metadata, required, "metadata"),
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
65
|
/** Assert a Stripe Checkout Session carries the expected `proxy_session_id` metadata. */
|
|
109
66
|
function assertCheckoutSessionBelongsToProxy(checkoutSession, proxySessionId) {
|
|
110
67
|
assertProxyMetadata(checkoutSession.metadata, proxySessionId, "Stripe checkout session");
|
|
@@ -117,39 +74,12 @@ function assertSubscriptionBelongsToProxy(subscription, proxySessionId) {
|
|
|
117
74
|
function assertPaymentIntentBelongsToProxy(paymentIntent, proxySessionId) {
|
|
118
75
|
assertProxyMetadata(paymentIntent.metadata, proxySessionId, "Stripe payment intent");
|
|
119
76
|
}
|
|
120
|
-
/** Assert the provider root carries the exact reserved acquisition identity. */
|
|
121
|
-
function assertProviderObjectBelongsToAcquisition(object, input) {
|
|
122
|
-
assertProxyMetadata(object.metadata, input.proxySessionId, "Stripe provider object");
|
|
123
|
-
const acquisitionId = object.metadata?.[exports.PROXY_ACQUISITION_ATTEMPT_METADATA_KEY];
|
|
124
|
-
const contractVersion = object.metadata?.[exports.PROXY_CONTRACT_VERSION_METADATA_KEY];
|
|
125
|
-
const integrationPath = object.metadata?.[exports.PROXY_INTEGRATION_PATH_METADATA_KEY];
|
|
126
|
-
if (acquisitionId !== input.acquisitionAttemptId) {
|
|
127
|
-
throw new server_js_1.ProxyCheckoutValidationError(`Stripe provider object metadata.${exports.PROXY_ACQUISITION_ATTEMPT_METADATA_KEY} does not match the reserved Proxy acquisition.`, { code: "provider_binding_mismatch", field: exports.PROXY_ACQUISITION_ATTEMPT_METADATA_KEY });
|
|
128
|
-
}
|
|
129
|
-
if (contractVersion !== "2") {
|
|
130
|
-
throw new server_js_1.ProxyCheckoutValidationError(`Stripe provider object metadata.${exports.PROXY_CONTRACT_VERSION_METADATA_KEY} must be 2.`, { code: "provider_binding_mismatch", field: exports.PROXY_CONTRACT_VERSION_METADATA_KEY });
|
|
131
|
-
}
|
|
132
|
-
if (integrationPath !== input.integrationPath) {
|
|
133
|
-
throw new server_js_1.ProxyCheckoutValidationError(`Stripe provider object metadata.${exports.PROXY_INTEGRATION_PATH_METADATA_KEY} does not match ${input.integrationPath}.`, { code: "provider_binding_mismatch", field: exports.PROXY_INTEGRATION_PATH_METADATA_KEY });
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
77
|
function assertProxyMetadata(metadata, proxySessionId, objectLabel) {
|
|
137
78
|
const value = metadata?.[exports.PROXY_SESSION_METADATA_KEY];
|
|
138
79
|
if (value !== proxySessionId) {
|
|
139
80
|
throw new server_js_1.ProxyCheckoutValidationError(`${objectLabel} metadata.${exports.PROXY_SESSION_METADATA_KEY} (${value ?? "missing"}) does not match Proxy session ${proxySessionId}.`, { code: "provider_binding_mismatch", field: `metadata.${exports.PROXY_SESSION_METADATA_KEY}` });
|
|
140
81
|
}
|
|
141
82
|
}
|
|
142
|
-
function acquisitionMetadata(proxySessionId, acquisition) {
|
|
143
|
-
return {
|
|
144
|
-
...(acquisition
|
|
145
|
-
? {
|
|
146
|
-
[exports.PROXY_ACQUISITION_ATTEMPT_METADATA_KEY]: acquisition.id,
|
|
147
|
-
[exports.PROXY_CONTRACT_VERSION_METADATA_KEY]: acquisition.contractVersion,
|
|
148
|
-
}
|
|
149
|
-
: {}),
|
|
150
|
-
[exports.PROXY_SESSION_METADATA_KEY]: proxySessionId,
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
83
|
function mergeProxyMetadata(existing, required, field) {
|
|
154
84
|
for (const [key, requiredValue] of Object.entries(required)) {
|
|
155
85
|
const existingValue = existing?.[key];
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
* metadata placement, idempotency, and binding reconciliation.
|
|
8
8
|
*/
|
|
9
9
|
import type { JsonObject, PayerOpenedResult, ProxyCartValidator, ProxyCheckoutServerClient, ProxySessionProviderBinding } from "@proxy-checkout/server-js";
|
|
10
|
-
import { type StripeCompatibilityDescriptor } from "./compatibility.js";
|
|
11
10
|
import type { StripeCheckoutSessionCreateParams, StripeCheckoutSessionLike, StripeClientLike, StripeRequestOptionsWithoutIdempotencyLike } from "./types.js";
|
|
12
11
|
export interface OpenCheckoutOptions<TStripe extends StripeClientLike, TCart, TOffer> {
|
|
13
12
|
/** Builds app-specific Stripe Checkout Session params. Proxy metadata is injected by the SDK. */
|
|
@@ -19,13 +18,8 @@ export interface OpenCheckoutOptions<TStripe extends StripeClientLike, TCart, TO
|
|
|
19
18
|
}) => Promise<StripeCheckoutSessionCreateParams> | StripeCheckoutSessionCreateParams;
|
|
20
19
|
/** Optional schema validating the session cart snapshot into a typed cart. */
|
|
21
20
|
readonly cartSchema?: ProxyCartValidator<TCart>;
|
|
22
|
-
/** New acquisition contract. Omit with the other acquisition fields only for 0.0.x compatibility. */
|
|
23
|
-
readonly commercialMode?: "one_time" | "subscription";
|
|
24
|
-
readonly compatibility?: StripeCompatibilityDescriptor;
|
|
25
21
|
/** Optional extractor used to assert the cart buyer reference matches the session. */
|
|
26
22
|
readonly getCartBuyerReference?: (cart: TCart) => string | null | undefined;
|
|
27
|
-
/** New acquisition contract. Defaults are intentionally not guessed for explicit callers. */
|
|
28
|
-
readonly pricingMode?: "fixed" | "provider_finalized";
|
|
29
23
|
/** A Proxy server SDK client. */
|
|
30
24
|
readonly proxy: ProxyCheckoutServerClient;
|
|
31
25
|
readonly proxySessionId: string;
|
|
@@ -40,12 +34,8 @@ export interface OpenCheckoutOptions<TStripe extends StripeClientLike, TCart, TO
|
|
|
40
34
|
readonly requestId?: string;
|
|
41
35
|
/** The merchant's Stripe instance. */
|
|
42
36
|
readonly stripe: TStripe;
|
|
43
|
-
/** Convenience alias for compatibility.apiVersion. */
|
|
44
|
-
readonly stripeApiVersion?: string;
|
|
45
37
|
/** Optional Stripe request options. The SDK owns the deterministic idempotency key. */
|
|
46
38
|
readonly stripeRequestOptions?: StripeRequestOptionsWithoutIdempotencyLike;
|
|
47
|
-
/** Semantic Checkout presentation. Provider aliases are normalized per Stripe generation. */
|
|
48
|
-
readonly uiMode?: "custom" | "embedded" | "hosted";
|
|
49
39
|
/** Optional merchant cart validation that derives an app-specific offer. */
|
|
50
40
|
readonly validateCart?: (input: {
|
|
51
41
|
cart: TCart;
|
|
@@ -59,26 +49,15 @@ export interface OpenCheckoutReconciledCart<TCart> {
|
|
|
59
49
|
readonly currency: string;
|
|
60
50
|
}
|
|
61
51
|
export interface OpenCheckoutResult<TCart, TOffer, TSession> {
|
|
62
|
-
readonly acquisitionAttemptId?: string;
|
|
63
52
|
readonly binding: ProxySessionProviderBinding;
|
|
64
53
|
readonly cart: TCart;
|
|
65
54
|
readonly checkoutSession: TSession;
|
|
66
|
-
readonly checkoutSessionId?: string;
|
|
67
55
|
readonly clientSecret: string | null;
|
|
68
56
|
readonly offer: TOffer;
|
|
69
57
|
readonly outcome: "ready";
|
|
70
|
-
readonly presentation?: {
|
|
71
|
-
readonly kind: "client_secret";
|
|
72
|
-
readonly clientSecret: string;
|
|
73
|
-
readonly uiMode: "custom" | "embedded";
|
|
74
|
-
} | {
|
|
75
|
-
readonly kind: "redirect";
|
|
76
|
-
readonly url: string;
|
|
77
|
-
};
|
|
78
58
|
readonly proxySession: PayerOpenedResult;
|
|
79
59
|
readonly proxySessionId: string;
|
|
80
60
|
}
|
|
81
|
-
export type OpenCheckoutPresentation = NonNullable<OpenCheckoutResult<unknown, unknown, unknown>["presentation"]>;
|
|
82
61
|
export type OpenCheckoutTerminalResult<TCart> = {
|
|
83
62
|
readonly cart: TCart;
|
|
84
63
|
readonly outcome: "already_paid";
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
* metadata placement, idempotency, and binding reconciliation.
|
|
8
8
|
*/
|
|
9
9
|
import type { JsonObject, PayerOpenedResult, ProxyCartValidator, ProxyCheckoutServerClient, ProxySessionProviderBinding } from "@proxy-checkout/server-js";
|
|
10
|
-
import { type StripeCompatibilityDescriptor } from "./compatibility.js";
|
|
11
10
|
import type { StripeCheckoutSessionCreateParams, StripeCheckoutSessionLike, StripeClientLike, StripeRequestOptionsWithoutIdempotencyLike } from "./types.js";
|
|
12
11
|
export interface OpenCheckoutOptions<TStripe extends StripeClientLike, TCart, TOffer> {
|
|
13
12
|
/** Builds app-specific Stripe Checkout Session params. Proxy metadata is injected by the SDK. */
|
|
@@ -19,13 +18,8 @@ export interface OpenCheckoutOptions<TStripe extends StripeClientLike, TCart, TO
|
|
|
19
18
|
}) => Promise<StripeCheckoutSessionCreateParams> | StripeCheckoutSessionCreateParams;
|
|
20
19
|
/** Optional schema validating the session cart snapshot into a typed cart. */
|
|
21
20
|
readonly cartSchema?: ProxyCartValidator<TCart>;
|
|
22
|
-
/** New acquisition contract. Omit with the other acquisition fields only for 0.0.x compatibility. */
|
|
23
|
-
readonly commercialMode?: "one_time" | "subscription";
|
|
24
|
-
readonly compatibility?: StripeCompatibilityDescriptor;
|
|
25
21
|
/** Optional extractor used to assert the cart buyer reference matches the session. */
|
|
26
22
|
readonly getCartBuyerReference?: (cart: TCart) => string | null | undefined;
|
|
27
|
-
/** New acquisition contract. Defaults are intentionally not guessed for explicit callers. */
|
|
28
|
-
readonly pricingMode?: "fixed" | "provider_finalized";
|
|
29
23
|
/** A Proxy server SDK client. */
|
|
30
24
|
readonly proxy: ProxyCheckoutServerClient;
|
|
31
25
|
readonly proxySessionId: string;
|
|
@@ -40,12 +34,8 @@ export interface OpenCheckoutOptions<TStripe extends StripeClientLike, TCart, TO
|
|
|
40
34
|
readonly requestId?: string;
|
|
41
35
|
/** The merchant's Stripe instance. */
|
|
42
36
|
readonly stripe: TStripe;
|
|
43
|
-
/** Convenience alias for compatibility.apiVersion. */
|
|
44
|
-
readonly stripeApiVersion?: string;
|
|
45
37
|
/** Optional Stripe request options. The SDK owns the deterministic idempotency key. */
|
|
46
38
|
readonly stripeRequestOptions?: StripeRequestOptionsWithoutIdempotencyLike;
|
|
47
|
-
/** Semantic Checkout presentation. Provider aliases are normalized per Stripe generation. */
|
|
48
|
-
readonly uiMode?: "custom" | "embedded" | "hosted";
|
|
49
39
|
/** Optional merchant cart validation that derives an app-specific offer. */
|
|
50
40
|
readonly validateCart?: (input: {
|
|
51
41
|
cart: TCart;
|
|
@@ -59,26 +49,15 @@ export interface OpenCheckoutReconciledCart<TCart> {
|
|
|
59
49
|
readonly currency: string;
|
|
60
50
|
}
|
|
61
51
|
export interface OpenCheckoutResult<TCart, TOffer, TSession> {
|
|
62
|
-
readonly acquisitionAttemptId?: string;
|
|
63
52
|
readonly binding: ProxySessionProviderBinding;
|
|
64
53
|
readonly cart: TCart;
|
|
65
54
|
readonly checkoutSession: TSession;
|
|
66
|
-
readonly checkoutSessionId?: string;
|
|
67
55
|
readonly clientSecret: string | null;
|
|
68
56
|
readonly offer: TOffer;
|
|
69
57
|
readonly outcome: "ready";
|
|
70
|
-
readonly presentation?: {
|
|
71
|
-
readonly kind: "client_secret";
|
|
72
|
-
readonly clientSecret: string;
|
|
73
|
-
readonly uiMode: "custom" | "embedded";
|
|
74
|
-
} | {
|
|
75
|
-
readonly kind: "redirect";
|
|
76
|
-
readonly url: string;
|
|
77
|
-
};
|
|
78
58
|
readonly proxySession: PayerOpenedResult;
|
|
79
59
|
readonly proxySessionId: string;
|
|
80
60
|
}
|
|
81
|
-
export type OpenCheckoutPresentation = NonNullable<OpenCheckoutResult<unknown, unknown, unknown>["presentation"]>;
|
|
82
61
|
export type OpenCheckoutTerminalResult<TCart> = {
|
|
83
62
|
readonly cart: TCart;
|
|
84
63
|
readonly outcome: "already_paid";
|
|
@@ -10,15 +10,10 @@
|
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
11
|
exports.openCheckout = openCheckout;
|
|
12
12
|
const server_js_1 = require("@proxy-checkout/server-js");
|
|
13
|
-
const acquisition_js_1 = require("./acquisition.js");
|
|
14
|
-
const compatibility_js_1 = require("./compatibility.js");
|
|
15
13
|
const errors_js_1 = require("./errors.js");
|
|
16
14
|
const metadata_js_1 = require("./metadata.js");
|
|
17
15
|
const psp_js_1 = require("./psp.js");
|
|
18
16
|
async function openCheckout(options) {
|
|
19
|
-
if (usesAcquisitionContract(options)) {
|
|
20
|
-
return openAcquisitionCheckout(options);
|
|
21
|
-
}
|
|
22
17
|
// Normalize the same way the API does on store, so the binding is recorded
|
|
23
18
|
// under the normalized psp and later syncCheckoutCart validations compare
|
|
24
19
|
// normalized-to-normalized.
|
|
@@ -138,7 +133,7 @@ async function openCheckout(options) {
|
|
|
138
133
|
const checkoutSession = (await options.stripe.checkout.sessions.create((0, metadata_js_1.injectRequiredCheckoutSessionMetadata)(params, proxySession.id), buildStripeRequestOptions(options, proxySession.id, psp)));
|
|
139
134
|
// Fail closed if the merchant forgot to place proxy_session_id metadata.
|
|
140
135
|
(0, metadata_js_1.assertCheckoutSessionBelongsToProxy)(checkoutSession, proxySession.id);
|
|
141
|
-
const binding = await (
|
|
136
|
+
const binding = await recordOrReconcileProviderBinding({
|
|
142
137
|
checkoutSessionId: checkoutSession.id,
|
|
143
138
|
expectedCartVersion: proxySession.cartVersion,
|
|
144
139
|
commercialMode,
|
|
@@ -160,310 +155,6 @@ async function openCheckout(options) {
|
|
|
160
155
|
proxySessionId: proxySession.id,
|
|
161
156
|
};
|
|
162
157
|
}
|
|
163
|
-
async function openAcquisitionCheckout(options) {
|
|
164
|
-
if (options.commercialMode !== "one_time" ||
|
|
165
|
-
(options.uiMode !== "hosted" && options.uiMode !== "embedded" && options.uiMode !== "custom") ||
|
|
166
|
-
options.pricingMode === undefined) {
|
|
167
|
-
throw new errors_js_1.UnsupportedStripeOptionError("The explicit Checkout acquisition contract supports one_time hosted, embedded, and custom presentations only.", "uiMode");
|
|
168
|
-
}
|
|
169
|
-
if ((0, psp_js_1.normalizePsp)(options.psp ?? "stripe") !== "stripe") {
|
|
170
|
-
throw new errors_js_1.UnsupportedStripeOptionError("The Stripe acquisition helper cannot route provider creation through another PSP.", "psp");
|
|
171
|
-
}
|
|
172
|
-
(0, acquisition_js_1.assertNoConnectRequestOptions)(options.stripeRequestOptions);
|
|
173
|
-
const compatibility = compatibilityDescriptor(options);
|
|
174
|
-
(0, compatibility_js_1.assertStripePathCompatibility)(checkoutCompatibilityPath(options.uiMode), compatibility);
|
|
175
|
-
let proxySession = await options.proxy.sessions.payerOpened(options.proxySessionId, {
|
|
176
|
-
requestId: options.requestId,
|
|
177
|
-
});
|
|
178
|
-
let cart = parseCheckoutCart(options, proxySession);
|
|
179
|
-
if (proxySession.presentationState !== "checkout_available") {
|
|
180
|
-
return terminalResultFromSession(proxySession, cart);
|
|
181
|
-
}
|
|
182
|
-
let offer = options.validateCart
|
|
183
|
-
? await options.validateCart({ cart, session: proxySession })
|
|
184
|
-
: undefined;
|
|
185
|
-
const reconciledCart = await options.reconcileCart?.({ cart, offer, session: proxySession });
|
|
186
|
-
if (reconciledCart) {
|
|
187
|
-
if (options.getCartBuyerReference) {
|
|
188
|
-
(0, server_js_1.assertCartBuyerReference)(options.getCartBuyerReference(reconciledCart.cart), proxySession);
|
|
189
|
-
}
|
|
190
|
-
try {
|
|
191
|
-
const updated = await options.proxy.sessions.cart.set(proxySession.id, {
|
|
192
|
-
amountMinor: reconciledCart.amountMinor,
|
|
193
|
-
cartSnapshot: reconciledCart.cartSnapshot,
|
|
194
|
-
currency: reconciledCart.currency,
|
|
195
|
-
expectedCartVersion: proxySession.cartVersion,
|
|
196
|
-
requestId: options.requestId,
|
|
197
|
-
});
|
|
198
|
-
proxySession = {
|
|
199
|
-
...proxySession,
|
|
200
|
-
amountMinor: updated.amountMinor,
|
|
201
|
-
cartSnapshot: updated.cartSnapshot,
|
|
202
|
-
cartVersion: updated.cartVersion,
|
|
203
|
-
currency: updated.currency,
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
catch (cause) {
|
|
207
|
-
if (!isProxyConflict(cause))
|
|
208
|
-
throw cause;
|
|
209
|
-
const joined = await options.proxy.sessions.payerOpened(proxySession.id, {
|
|
210
|
-
requestId: options.requestId,
|
|
211
|
-
});
|
|
212
|
-
if (!sameCheckoutCart(joined, reconciledCart))
|
|
213
|
-
throw cause;
|
|
214
|
-
proxySession = joined;
|
|
215
|
-
}
|
|
216
|
-
cart = reconciledCart.cart;
|
|
217
|
-
if (options.validateCart)
|
|
218
|
-
offer = await options.validateCart({ cart, session: proxySession });
|
|
219
|
-
}
|
|
220
|
-
const current = await options.proxy.sessions.payerOpened(proxySession.id, {
|
|
221
|
-
requestId: options.requestId,
|
|
222
|
-
});
|
|
223
|
-
if (current.presentationState !== "checkout_available") {
|
|
224
|
-
return terminalResultFromSession(current, cart);
|
|
225
|
-
}
|
|
226
|
-
if (!sameCheckoutCart(current, proxySession)) {
|
|
227
|
-
throw new server_js_1.ProxyCheckoutValidationError(`Proxy session ${proxySession.id} cart changed while Checkout was being prepared.`, { code: "cart_version_conflict", field: "cart_version" });
|
|
228
|
-
}
|
|
229
|
-
proxySession = current;
|
|
230
|
-
const builtParams = await options.buildCheckoutSessionParams({
|
|
231
|
-
cart,
|
|
232
|
-
offer,
|
|
233
|
-
proxySession,
|
|
234
|
-
stripe: options.stripe,
|
|
235
|
-
});
|
|
236
|
-
validateAcquisitionCheckoutParams(builtParams, options, proxySession);
|
|
237
|
-
(0, metadata_js_1.assertCheckoutSessionMetadataPreflight)(builtParams, proxySession.id);
|
|
238
|
-
// Stripe 12 has no hosted ui_mode create field, while newer Stripe responses
|
|
239
|
-
// name the same provider value hosted_page. Omit only the hosted provider
|
|
240
|
-
// alias; client-secret paths must send their exact generation-specific mode.
|
|
241
|
-
const params = options.uiMode === "hosted" ? withoutHostedProviderUiMode(builtParams) : builtParams;
|
|
242
|
-
if (options.pricingMode === "fixed" && proxySession.amountMinor === 0) {
|
|
243
|
-
(0, compatibility_js_1.assertHostedNoCostCompatibility)(compatibility);
|
|
244
|
-
}
|
|
245
|
-
const providerOptionsFingerprint = (0, acquisition_js_1.fingerprintHostedCheckoutProviderOptions)(params);
|
|
246
|
-
const acquisitionResult = await (0, acquisition_js_1.acquireStripeRoot)({
|
|
247
|
-
checkoutUiMode: options.uiMode,
|
|
248
|
-
commercialMode: "one_time",
|
|
249
|
-
integrationPath: "checkout_session",
|
|
250
|
-
objectType: "checkout_session",
|
|
251
|
-
pricingMode: options.pricingMode,
|
|
252
|
-
create: async (reservation) => {
|
|
253
|
-
const created = (await options.stripe.checkout.sessions.create((0, metadata_js_1.injectRequiredCheckoutSessionMetadata)(params, proxySession.id, {
|
|
254
|
-
contractVersion: "2",
|
|
255
|
-
id: reservation.acquisitionAttempt.id,
|
|
256
|
-
}), {
|
|
257
|
-
...options.stripeRequestOptions,
|
|
258
|
-
idempotencyKey: reservation.stripe.idempotencyKeys.root,
|
|
259
|
-
}));
|
|
260
|
-
return (await (0, acquisition_js_1.retrieveCheckoutSessionWithLineEvidence)({
|
|
261
|
-
id: created.id,
|
|
262
|
-
initial: created,
|
|
263
|
-
requestOptions: options.stripeRequestOptions,
|
|
264
|
-
stripe: options.stripe,
|
|
265
|
-
}));
|
|
266
|
-
},
|
|
267
|
-
providerOptionsFingerprint,
|
|
268
|
-
proxy: options.proxy,
|
|
269
|
-
proxySession,
|
|
270
|
-
requestId: options.requestId,
|
|
271
|
-
retrieve: async (id) => (await (0, acquisition_js_1.retrieveCheckoutSessionWithLineEvidence)({
|
|
272
|
-
id,
|
|
273
|
-
requestOptions: options.stripeRequestOptions,
|
|
274
|
-
stripe: options.stripe,
|
|
275
|
-
})),
|
|
276
|
-
toConfirmation: (session) => (0, acquisition_js_1.checkoutCartConfirmation)({
|
|
277
|
-
cartVersion: proxySession.cartVersion,
|
|
278
|
-
checkoutSession: session,
|
|
279
|
-
expectedLineItems: params.line_items,
|
|
280
|
-
}),
|
|
281
|
-
validateObject: (session, acquisition) => {
|
|
282
|
-
(0, metadata_js_1.assertProviderObjectBelongsToAcquisition)(session, {
|
|
283
|
-
acquisitionAttemptId: acquisition.id,
|
|
284
|
-
integrationPath: "checkout_session",
|
|
285
|
-
proxySessionId: proxySession.id,
|
|
286
|
-
});
|
|
287
|
-
assertCheckoutProviderCart(session, proxySession, options.pricingMode ?? "fixed", params.line_items, options.uiMode ?? "hosted");
|
|
288
|
-
},
|
|
289
|
-
});
|
|
290
|
-
if (acquisitionResult.outcome === "terminal") {
|
|
291
|
-
return terminalResultFromSession(acquisitionResult.proxySession, cart);
|
|
292
|
-
}
|
|
293
|
-
const acquired = acquisitionResult;
|
|
294
|
-
const presentation = checkoutPresentation(acquired.object, options.uiMode);
|
|
295
|
-
return {
|
|
296
|
-
acquisitionAttemptId: acquired.acquisition.id,
|
|
297
|
-
binding: {
|
|
298
|
-
providerCheckoutSessionId: acquired.object.id,
|
|
299
|
-
proxySessionId: proxySession.id,
|
|
300
|
-
psp: "stripe",
|
|
301
|
-
updatedAt: acquired.acquisition.updatedAt,
|
|
302
|
-
},
|
|
303
|
-
cart,
|
|
304
|
-
checkoutSession: acquired.object,
|
|
305
|
-
checkoutSessionId: acquired.object.id,
|
|
306
|
-
clientSecret: presentation.kind === "client_secret" ? presentation.clientSecret : null,
|
|
307
|
-
offer,
|
|
308
|
-
outcome: "ready",
|
|
309
|
-
presentation,
|
|
310
|
-
proxySession,
|
|
311
|
-
proxySessionId: proxySession.id,
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
function usesAcquisitionContract(options) {
|
|
315
|
-
const values = [options.commercialMode, options.pricingMode, options.uiMode];
|
|
316
|
-
const count = values.filter((value) => value !== undefined).length;
|
|
317
|
-
if (count !== 0 && count !== values.length) {
|
|
318
|
-
throw new server_js_1.ProxyCheckoutValidationError("commercialMode, pricingMode, and uiMode must be supplied together for the acquisition contract.", { code: "unsupported_provider_option", field: "commercialMode" });
|
|
319
|
-
}
|
|
320
|
-
return count === values.length;
|
|
321
|
-
}
|
|
322
|
-
function parseCheckoutCart(options, proxySession) {
|
|
323
|
-
return options.cartSchema || options.getCartBuyerReference
|
|
324
|
-
? options.proxy.sessions.parseCart(proxySession, options.cartSchema ?? ((value) => value), { getBuyerReference: options.getCartBuyerReference })
|
|
325
|
-
: proxySession.cartSnapshot;
|
|
326
|
-
}
|
|
327
|
-
function compatibilityDescriptor(options) {
|
|
328
|
-
if (!options.compatibility && !options.stripeApiVersion)
|
|
329
|
-
return undefined;
|
|
330
|
-
return {
|
|
331
|
-
...options.compatibility,
|
|
332
|
-
...(options.stripeApiVersion ? { apiVersion: options.stripeApiVersion } : {}),
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
function validateAcquisitionCheckoutParams(params, options, proxySession) {
|
|
336
|
-
assertCheckoutAutomaticRecoveryDisabled(params, proxySession.id);
|
|
337
|
-
if (checkoutCommercialMode(params, proxySession.id) !== options.commercialMode) {
|
|
338
|
-
throw new errors_js_1.UnsupportedStripeOptionError("Stripe Checkout mode does not match commercialMode.", "mode");
|
|
339
|
-
}
|
|
340
|
-
const uiMode = normalizeProviderUiMode(params.ui_mode);
|
|
341
|
-
if (uiMode !== options.uiMode) {
|
|
342
|
-
throw new errors_js_1.UnsupportedStripeOptionError(`Stripe Checkout ui_mode ${uiMode} does not match requested ${options.uiMode}.`, "ui_mode");
|
|
343
|
-
}
|
|
344
|
-
if (uiMode === "hosted" && !params.success_url) {
|
|
345
|
-
throw new errors_js_1.UnsupportedStripeOptionError("Hosted Stripe Checkout requires success_url.", "success_url");
|
|
346
|
-
}
|
|
347
|
-
if (uiMode === "hosted" && params.return_url !== undefined) {
|
|
348
|
-
throw new errors_js_1.UnsupportedStripeOptionError("Hosted Stripe Checkout uses success_url and must not set return_url.", "return_url");
|
|
349
|
-
}
|
|
350
|
-
if (uiMode !== "hosted" && !params.return_url) {
|
|
351
|
-
throw new errors_js_1.UnsupportedStripeOptionError(`${uiMode} Stripe Checkout requires return_url.`, "return_url");
|
|
352
|
-
}
|
|
353
|
-
if (uiMode !== "hosted" && params.success_url !== undefined) {
|
|
354
|
-
throw new errors_js_1.UnsupportedStripeOptionError(`${uiMode} Stripe Checkout uses return_url and must not set success_url.`, "success_url");
|
|
355
|
-
}
|
|
356
|
-
const paymentIntentData = objectRecord(params.payment_intent_data);
|
|
357
|
-
for (const field of [
|
|
358
|
-
"application_fee_amount",
|
|
359
|
-
"application_fee_percent",
|
|
360
|
-
"capture_method",
|
|
361
|
-
"on_behalf_of",
|
|
362
|
-
"transfer_data",
|
|
363
|
-
"transfer_group",
|
|
364
|
-
]) {
|
|
365
|
-
if (paymentIntentData[field] !== undefined) {
|
|
366
|
-
throw new errors_js_1.UnsupportedStripeOptionError(`One-time Checkout does not support payment_intent_data.${field}.`, `payment_intent_data.${field}`);
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
if (options.pricingMode === "fixed") {
|
|
370
|
-
for (const field of [
|
|
371
|
-
"allow_promotion_codes",
|
|
372
|
-
"shipping_address_collection",
|
|
373
|
-
"shipping_options",
|
|
374
|
-
]) {
|
|
375
|
-
const value = params[field];
|
|
376
|
-
if (value !== undefined && value !== false) {
|
|
377
|
-
throw new errors_js_1.UnsupportedStripeOptionError(`Fixed-price Checkout cannot use provider-finalized option ${field}.`, field);
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
for (const field of ["adaptive_pricing", "automatic_tax"]) {
|
|
381
|
-
const value = objectRecord(params[field]);
|
|
382
|
-
if (value.enabled === true) {
|
|
383
|
-
throw new errors_js_1.UnsupportedStripeOptionError(`Fixed-price Checkout cannot enable provider-finalized option ${field}.`, `${field}.enabled`);
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
const lineItems = Array.isArray(params.line_items) ? params.line_items : [];
|
|
387
|
-
if (lineItems.some((line) => objectRecord(objectRecord(line).adjustable_quantity).enabled === true)) {
|
|
388
|
-
throw new errors_js_1.UnsupportedStripeOptionError("Fixed-price Checkout cannot enable adjustable line-item quantities.", "line_items.adjustable_quantity.enabled");
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
function assertCheckoutProviderCart(checkoutSession, proxySession, pricingMode, expectedLineItems, requestedUiMode) {
|
|
393
|
-
const confirmation = (0, acquisition_js_1.checkoutCartConfirmation)({
|
|
394
|
-
cartVersion: 0,
|
|
395
|
-
checkoutSession,
|
|
396
|
-
expectedLineItems,
|
|
397
|
-
});
|
|
398
|
-
if (checkoutSession.mode !== undefined &&
|
|
399
|
-
checkoutSession.mode !== null &&
|
|
400
|
-
checkoutSession.mode !== "payment") {
|
|
401
|
-
throw new errors_js_1.StripeResponseShapeError("Stripe Checkout response is not payment mode.", "mode");
|
|
402
|
-
}
|
|
403
|
-
if (normalizeProviderUiMode(checkoutSession.ui_mode) !== requestedUiMode) {
|
|
404
|
-
throw new errors_js_1.StripeResponseShapeError(`Stripe Checkout response is not ${requestedUiMode} UI mode.`, "ui_mode");
|
|
405
|
-
}
|
|
406
|
-
if (confirmation.currency !== proxySession.currency ||
|
|
407
|
-
(pricingMode === "fixed" && confirmation.amountMinor !== proxySession.amountMinor)) {
|
|
408
|
-
throw new server_js_1.ProxyCheckoutValidationError(`Stripe Checkout Session ${checkoutSession.id} does not represent the current Proxy cart amount and currency.`, { code: "cart_version_conflict", field: "provider_amount" });
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
function normalizeProviderUiMode(value) {
|
|
412
|
-
if (value === undefined || value === null || value === "hosted" || value === "hosted_page") {
|
|
413
|
-
return "hosted";
|
|
414
|
-
}
|
|
415
|
-
if (value === "embedded" || value === "embedded_page")
|
|
416
|
-
return "embedded";
|
|
417
|
-
if (value === "custom" || value === "elements")
|
|
418
|
-
return "custom";
|
|
419
|
-
return value;
|
|
420
|
-
}
|
|
421
|
-
function checkoutCompatibilityPath(uiMode) {
|
|
422
|
-
return `one_time.checkout.${uiMode}`;
|
|
423
|
-
}
|
|
424
|
-
function checkoutPresentation(checkoutSession, uiMode) {
|
|
425
|
-
const clientSecret = checkoutSession.client_secret;
|
|
426
|
-
const url = checkoutSession.url;
|
|
427
|
-
if (uiMode === "hosted") {
|
|
428
|
-
if (!isSafeHostedCheckoutUrl(url)) {
|
|
429
|
-
throw new errors_js_1.StripeResponseShapeError("Hosted Stripe Checkout response did not contain a safe HTTPS redirect URL.", "url");
|
|
430
|
-
}
|
|
431
|
-
if (clientSecret !== undefined && clientSecret !== null) {
|
|
432
|
-
throw new errors_js_1.StripeResponseShapeError("Hosted Stripe Checkout response unexpectedly contained a client secret.", "client_secret");
|
|
433
|
-
}
|
|
434
|
-
return { kind: "redirect", url };
|
|
435
|
-
}
|
|
436
|
-
if (!isCheckoutSessionClientSecret(clientSecret)) {
|
|
437
|
-
throw new errors_js_1.StripeResponseShapeError(`${uiMode} Stripe Checkout response did not contain a valid Checkout Session client secret.`, "client_secret");
|
|
438
|
-
}
|
|
439
|
-
if (url !== undefined && url !== null) {
|
|
440
|
-
throw new errors_js_1.StripeResponseShapeError(`${uiMode} Stripe Checkout response unexpectedly contained a hosted redirect URL.`, "url");
|
|
441
|
-
}
|
|
442
|
-
return { clientSecret, kind: "client_secret", uiMode };
|
|
443
|
-
}
|
|
444
|
-
function isCheckoutSessionClientSecret(value) {
|
|
445
|
-
return typeof value === "string" && /^cs_(?:test|live)_[A-Za-z0-9_]+$/.test(value);
|
|
446
|
-
}
|
|
447
|
-
function isSafeHostedCheckoutUrl(value) {
|
|
448
|
-
if (typeof value !== "string" || value !== value.trim())
|
|
449
|
-
return false;
|
|
450
|
-
try {
|
|
451
|
-
const parsed = new URL(value);
|
|
452
|
-
return parsed.protocol === "https:" && parsed.username === "" && parsed.password === "";
|
|
453
|
-
}
|
|
454
|
-
catch {
|
|
455
|
-
return false;
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
function withoutHostedProviderUiMode(params) {
|
|
459
|
-
if (params.ui_mode === undefined)
|
|
460
|
-
return params;
|
|
461
|
-
const { ui_mode: _providerUiMode, ...providerParams } = params;
|
|
462
|
-
return providerParams;
|
|
463
|
-
}
|
|
464
|
-
function objectRecord(value) {
|
|
465
|
-
return typeof value === "object" && value !== null ? value : {};
|
|
466
|
-
}
|
|
467
158
|
function terminalResultFromSession(proxySession, cart) {
|
|
468
159
|
const common = {
|
|
469
160
|
cart,
|
|
@@ -523,6 +214,31 @@ function bindingFromSession(proxySession) {
|
|
|
523
214
|
updatedAt: proxySession.updatedAt,
|
|
524
215
|
};
|
|
525
216
|
}
|
|
217
|
+
async function recordOrReconcileProviderBinding(input) {
|
|
218
|
+
try {
|
|
219
|
+
return await input.proxy.sessions.recordProviderBinding(input.proxySessionId, {
|
|
220
|
+
commercialMode: input.commercialMode,
|
|
221
|
+
expectedCartVersion: input.expectedCartVersion,
|
|
222
|
+
providerCheckoutSessionId: input.checkoutSessionId,
|
|
223
|
+
psp: input.psp,
|
|
224
|
+
requestId: input.requestId,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
catch (cause) {
|
|
228
|
+
const reconciled = await readReconciledBinding(input).catch(() => undefined);
|
|
229
|
+
if (reconciled) {
|
|
230
|
+
return reconciled;
|
|
231
|
+
}
|
|
232
|
+
if (isProxyConflict(cause)) {
|
|
233
|
+
throw cause;
|
|
234
|
+
}
|
|
235
|
+
throw new errors_js_1.ProxyStripeOpenCheckoutError("Stripe Checkout Session was created but Proxy provider binding could not be recorded.", {
|
|
236
|
+
cause,
|
|
237
|
+
code: "provider_binding_failed",
|
|
238
|
+
providerCheckoutSessionId: input.checkoutSessionId,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|
|
526
242
|
function sameCheckoutCart(actual, expected) {
|
|
527
243
|
return (actual.amountMinor === expected.amountMinor &&
|
|
528
244
|
actual.currency === expected.currency &&
|
|
@@ -554,6 +270,18 @@ function assertCheckoutAutomaticRecoveryDisabled(params, proxySessionId) {
|
|
|
554
270
|
throw new server_js_1.ProxyCheckoutValidationError(`Proxy session ${proxySessionId} does not allow Stripe Checkout automatic recovery because replacement roots require explicit Proxy supersession.`, { code: "unsupported_provider_option", field: "after_expiration.recovery.enabled" });
|
|
555
271
|
}
|
|
556
272
|
}
|
|
273
|
+
async function readReconciledBinding(input) {
|
|
274
|
+
const current = await input.proxy.sessions.retrieve(input.proxySessionId, {
|
|
275
|
+
requestId: input.requestId,
|
|
276
|
+
});
|
|
277
|
+
if (current.providerCheckoutSessionId !== input.checkoutSessionId ||
|
|
278
|
+
current.providerCheckoutSessionPsp !== input.psp) {
|
|
279
|
+
return undefined;
|
|
280
|
+
}
|
|
281
|
+
const checkoutSession = await input.stripe.checkout.sessions.retrieve(input.checkoutSessionId, undefined, input.stripeRequestOptions);
|
|
282
|
+
(0, metadata_js_1.assertCheckoutSessionBelongsToProxy)(checkoutSession, input.proxySessionId);
|
|
283
|
+
return bindingFromSession(current);
|
|
284
|
+
}
|
|
557
285
|
function isProxyConflict(error) {
|
|
558
286
|
return (typeof error === "object" &&
|
|
559
287
|
error !== null &&
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* safest order with deterministic rollback/reconciliation on failure.
|
|
7
7
|
*/
|
|
8
8
|
import { type JsonObject, type MerchantProxySession, type ProxyCartValidator, type ProxyCheckoutServerClient } from "@proxy-checkout/server-js";
|
|
9
|
-
import type { StripeCheckoutSessionLike,
|
|
9
|
+
import type { StripeCheckoutSessionLike, StripeClientLike, StripeRequestOptionsWithoutIdempotencyLike } from "./types.js";
|
|
10
10
|
/** The next cart, expressed both as Proxy state and the typed merchant cart. */
|
|
11
11
|
export interface SyncedCart<TCart> {
|
|
12
12
|
readonly amountMinor: number;
|
|
@@ -14,7 +14,7 @@ export interface SyncedCart<TCart> {
|
|
|
14
14
|
readonly cartSnapshot: JsonObject;
|
|
15
15
|
readonly currency: string;
|
|
16
16
|
}
|
|
17
|
-
export interface SyncCheckoutCartOptions<TStripe extends
|
|
17
|
+
export interface SyncCheckoutCartOptions<TStripe extends StripeClientLike, TCart, TInput> {
|
|
18
18
|
/** Compute the next cart from current state and the merchant input. */
|
|
19
19
|
readonly buildNextCart: (input: {
|
|
20
20
|
currentCart: TCart;
|
|
@@ -44,4 +44,4 @@ export interface SyncCheckoutCartResult<TCart> {
|
|
|
44
44
|
readonly checkoutSession: StripeCheckoutSessionLike;
|
|
45
45
|
readonly currency: string;
|
|
46
46
|
}
|
|
47
|
-
export declare function syncCheckoutCart<TStripe extends
|
|
47
|
+
export declare function syncCheckoutCart<TStripe extends StripeClientLike, TCart, TInput>(options: SyncCheckoutCartOptions<TStripe, TCart, TInput>): Promise<SyncCheckoutCartResult<TCart>>;
|