@proxy-checkout/stripe-server-js 0.0.0-pr-76.20.1 → 0.0.0-pr-76.21.1
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 +1 -1
- package/dist/open-checkout.js +75 -31
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Server-side Stripe adapter for Proxy Checkout. It owns the Stripe-specific integ
|
|
|
4
4
|
|
|
5
5
|
- **`requiredMetadata(proxySession)`** — the `proxy_session_id` metadata Proxy needs on the Checkout Session, Subscription, and PaymentIntent.
|
|
6
6
|
- **`assertCheckoutSessionBelongsToProxy` / `assertSubscriptionBelongsToProxy` / `assertPaymentIntentBelongsToProxy`** — provider-object ownership checks.
|
|
7
|
-
- **`openCheckout(...)`** — records payer-opened, validates the typed cart, injects required metadata, creates the Stripe Checkout Session with deterministic idempotency, records the Proxy provider binding, and returns the client secret. The merchant only supplies app-specific Stripe params.
|
|
7
|
+
- **`openCheckout(...)`** — records payer-opened, validates/reconciles the typed cart with rollback, injects required metadata, creates the Stripe Checkout Session with deterministic idempotency, records the Proxy provider binding, and returns the client secret. The merchant only supplies app-specific Stripe params.
|
|
8
8
|
- **`syncCheckoutCart(...)`** — validates the stored Proxy provider binding, then updates the Proxy cart and the Stripe Checkout `line_items` in the safest order with deterministic rollback/reconciliation (`ProxyStripeCartSyncError`).
|
|
9
9
|
|
|
10
10
|
PSP-agnostic primitives (sessions, subscriptions, webhooks, lifecycle) live in [`@proxy-checkout/server-js`](https://www.npmjs.com/package/@proxy-checkout/server-js). This package is an additive adapter on top and is dependency-free: you inject your own `Stripe` instance and your `@proxy-checkout/server-js` client.
|
package/dist/open-checkout.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* metadata placement, idempotency, and binding reconciliation.
|
|
8
8
|
*/
|
|
9
9
|
import { ProxyCheckoutValidationError } from "@proxy-checkout/server-js";
|
|
10
|
-
import { ProxyStripeOpenCheckoutError } from "./errors.js";
|
|
10
|
+
import { ProxyStripeCartSyncError, ProxyStripeOpenCheckoutError } from "./errors.js";
|
|
11
11
|
import { assertCheckoutSessionBelongsToProxy, injectRequiredCheckoutSessionMetadata, } from "./metadata.js";
|
|
12
12
|
import { normalizePsp } from "./psp.js";
|
|
13
13
|
export async function openCheckout(options) {
|
|
@@ -27,8 +27,29 @@ export async function openCheckout(options) {
|
|
|
27
27
|
const offer = options.validateCart
|
|
28
28
|
? await options.validateCart({ cart, session: proxySession })
|
|
29
29
|
: undefined;
|
|
30
|
+
if (proxySession.providerCheckoutSessionId !== null) {
|
|
31
|
+
assertExistingBindingMatches(proxySession, psp);
|
|
32
|
+
const checkoutSession = (await options.stripe.checkout.sessions.retrieve(proxySession.providerCheckoutSessionId));
|
|
33
|
+
assertCheckoutSessionBelongsToProxy(checkoutSession, proxySession.id);
|
|
34
|
+
return {
|
|
35
|
+
binding: bindingFromSession(proxySession),
|
|
36
|
+
cart,
|
|
37
|
+
checkoutSession,
|
|
38
|
+
clientSecret: checkoutSession.client_secret ?? null,
|
|
39
|
+
offer,
|
|
40
|
+
proxySession,
|
|
41
|
+
proxySessionId: proxySession.id,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
let rollbackCart;
|
|
30
45
|
const reconciledCart = await options.reconcileCart?.({ cart, offer, session: proxySession });
|
|
31
46
|
if (reconciledCart) {
|
|
47
|
+
const priorCart = {
|
|
48
|
+
amountMinor: proxySession.amountMinor,
|
|
49
|
+
cartSnapshot: proxySession.cartSnapshot,
|
|
50
|
+
cartVersion: proxySession.cartVersion,
|
|
51
|
+
currency: proxySession.currency,
|
|
52
|
+
};
|
|
32
53
|
const updatedCart = await options.proxy.sessions.cart.set(proxySession.id, {
|
|
33
54
|
amountMinor: reconciledCart.amountMinor,
|
|
34
55
|
cartSnapshot: reconciledCart.cartSnapshot,
|
|
@@ -36,6 +57,10 @@ export async function openCheckout(options) {
|
|
|
36
57
|
expectedCartVersion: proxySession.cartVersion,
|
|
37
58
|
requestId: options.requestId,
|
|
38
59
|
});
|
|
60
|
+
rollbackCart = {
|
|
61
|
+
...priorCart,
|
|
62
|
+
expectedCartVersion: updatedCart.cartVersion,
|
|
63
|
+
};
|
|
39
64
|
proxySession = {
|
|
40
65
|
...proxySession,
|
|
41
66
|
amountMinor: updatedCart.amountMinor,
|
|
@@ -46,12 +71,26 @@ export async function openCheckout(options) {
|
|
|
46
71
|
};
|
|
47
72
|
cart = reconciledCart.cart;
|
|
48
73
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
74
|
+
try {
|
|
75
|
+
const params = await options.buildCheckoutSessionParams({
|
|
76
|
+
cart,
|
|
77
|
+
offer,
|
|
78
|
+
proxySession,
|
|
79
|
+
stripe: options.stripe,
|
|
80
|
+
});
|
|
81
|
+
const checkoutSession = (await options.stripe.checkout.sessions.create(injectRequiredCheckoutSessionMetadata(params, proxySession.id), buildStripeRequestOptions(options, proxySession.id, psp)));
|
|
82
|
+
// Fail closed if the merchant forgot to place proxy_session_id metadata.
|
|
52
83
|
assertCheckoutSessionBelongsToProxy(checkoutSession, proxySession.id);
|
|
84
|
+
const binding = await recordOrReconcileProviderBinding({
|
|
85
|
+
checkoutSessionId: checkoutSession.id,
|
|
86
|
+
proxy: options.proxy,
|
|
87
|
+
proxySessionId: proxySession.id,
|
|
88
|
+
psp,
|
|
89
|
+
requestId: options.requestId,
|
|
90
|
+
stripe: options.stripe,
|
|
91
|
+
});
|
|
53
92
|
return {
|
|
54
|
-
binding
|
|
93
|
+
binding,
|
|
55
94
|
cart,
|
|
56
95
|
checkoutSession,
|
|
57
96
|
clientSecret: checkoutSession.client_secret ?? null,
|
|
@@ -60,32 +99,18 @@ export async function openCheckout(options) {
|
|
|
60
99
|
proxySessionId: proxySession.id,
|
|
61
100
|
};
|
|
62
101
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
proxySessionId: proxySession.id,
|
|
76
|
-
psp,
|
|
77
|
-
requestId: options.requestId,
|
|
78
|
-
stripe: options.stripe,
|
|
79
|
-
});
|
|
80
|
-
return {
|
|
81
|
-
binding,
|
|
82
|
-
cart,
|
|
83
|
-
checkoutSession,
|
|
84
|
-
clientSecret: checkoutSession.client_secret ?? null,
|
|
85
|
-
offer,
|
|
86
|
-
proxySession,
|
|
87
|
-
proxySessionId: proxySession.id,
|
|
88
|
-
};
|
|
102
|
+
catch (cause) {
|
|
103
|
+
if (rollbackCart) {
|
|
104
|
+
await rollbackReconciledCart({
|
|
105
|
+
cause,
|
|
106
|
+
proxy: options.proxy,
|
|
107
|
+
proxySessionId: proxySession.id,
|
|
108
|
+
requestId: options.requestId,
|
|
109
|
+
rollbackCart,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
throw cause;
|
|
113
|
+
}
|
|
89
114
|
}
|
|
90
115
|
function buildStripeRequestOptions(options, proxySessionId, psp) {
|
|
91
116
|
return {
|
|
@@ -113,6 +138,25 @@ function bindingFromSession(proxySession) {
|
|
|
113
138
|
updatedAt: proxySession.updatedAt,
|
|
114
139
|
};
|
|
115
140
|
}
|
|
141
|
+
async function rollbackReconciledCart(input) {
|
|
142
|
+
try {
|
|
143
|
+
await input.proxy.sessions.cart.set(input.proxySessionId, {
|
|
144
|
+
amountMinor: input.rollbackCart.amountMinor,
|
|
145
|
+
cartSnapshot: input.rollbackCart.cartSnapshot,
|
|
146
|
+
currency: input.rollbackCart.currency,
|
|
147
|
+
expectedCartVersion: input.rollbackCart.expectedCartVersion,
|
|
148
|
+
requestId: input.requestId,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
catch (rollbackCause) {
|
|
152
|
+
throw new ProxyStripeCartSyncError("openCheckout failed after reconciling the Proxy cart, and the rollback failed; carts may be out of sync.", {
|
|
153
|
+
cause: input.cause,
|
|
154
|
+
code: "reconciliation_failed",
|
|
155
|
+
reconciled: false,
|
|
156
|
+
rollbackCause,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
116
160
|
async function recordOrReconcileProviderBinding(input) {
|
|
117
161
|
try {
|
|
118
162
|
return await input.proxy.sessions.recordProviderBinding(input.proxySessionId, {
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const proxyCheckoutStripeServerSdkName = "@proxy-checkout/stripe-server-js";
|
|
2
|
-
export declare const proxyCheckoutStripeServerSdkVersion = "0.0.0-pr-76.
|
|
2
|
+
export declare const proxyCheckoutStripeServerSdkVersion = "0.0.0-pr-76.21.1";
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export const proxyCheckoutStripeServerSdkName = "@proxy-checkout/stripe-server-js";
|
|
2
|
-
export const proxyCheckoutStripeServerSdkVersion = "0.0.0-pr-76.
|
|
2
|
+
export const proxyCheckoutStripeServerSdkVersion = "0.0.0-pr-76.21.1";
|
package/package.json
CHANGED
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
"sideEffects": false,
|
|
8
8
|
"type": "module",
|
|
9
9
|
"types": "./dist/index.d.ts",
|
|
10
|
-
"version": "0.0.0-pr-76.
|
|
10
|
+
"version": "0.0.0-pr-76.21.1",
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"@types/node": "^24.12.4",
|
|
13
13
|
"@vitest/coverage-v8": "4.1.7",
|
|
14
14
|
"typescript": "^6.0.3",
|
|
15
15
|
"vitest": "4.1.7",
|
|
16
|
-
"@proxy-checkout/server-js": "0.0.4-pr-76.
|
|
16
|
+
"@proxy-checkout/server-js": "0.0.4-pr-76.21.1"
|
|
17
17
|
},
|
|
18
18
|
"exports": {
|
|
19
19
|
".": {
|