mppx 0.9.1 → 0.9.3
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/CHANGELOG.md +28 -0
- package/README.md +26 -0
- package/dist/Method.d.ts +2 -0
- package/dist/cli/Extension.d.ts +20 -0
- package/dist/cli/Extension.js +5 -0
- package/dist/cli/cli.d.ts +1 -0
- package/dist/cli/cli.js +135 -135
- package/dist/cli/config.d.ts +4 -0
- package/dist/cli/config.js +1 -0
- package/dist/cli/internal.d.ts +3 -0
- package/dist/cli/internal.js +15 -2
- package/dist/cli/plugins/evm.js +2 -0
- package/dist/cli/plugins/index.d.ts +1 -0
- package/dist/cli/plugins/index.js +13 -13
- package/dist/cli/plugins/plugin.d.ts +2 -2
- package/dist/cli/plugins/x402.d.ts +3 -0
- package/dist/cli/plugins/x402.js +61 -0
- package/dist/cli/sessions/request.d.ts +1 -0
- package/dist/cli/sessions/request.js +1 -0
- package/dist/cli/validate/payment.js +14 -8
- package/dist/evm/client/Charge.d.ts +2 -2
- package/dist/evm/client/Charge.js +1 -1
- package/dist/evm/server/Charge.d.ts +7 -2
- package/dist/evm/server/Charge.js +28 -2
- package/dist/evm/server/Methods.d.ts +1 -1
- package/dist/internal/version.d.ts +5 -0
- package/dist/internal/version.js +6 -0
- package/dist/middlewares/internal/mppx.js +17 -3
- package/dist/server/Mppx.d.ts +7 -6
- package/dist/server/Mppx.js +84 -2
- package/dist/server/internal/html/config.js +1 -3
- package/dist/stripe/Methods.d.ts +24 -5
- package/dist/stripe/Methods.js +14 -11
- package/dist/stripe/client/Charge.d.ts +23 -5
- package/dist/stripe/client/Methods.d.ts +23 -5
- package/dist/stripe/internal/constants.d.ts +4 -0
- package/dist/stripe/internal/constants.js +2 -0
- package/dist/stripe/internal/parse-units.d.ts +8 -0
- package/dist/stripe/internal/parse-units.js +20 -0
- package/dist/stripe/internal/payment-intent.d.ts +39 -1
- package/dist/stripe/internal/payment-intent.js +16 -1
- package/dist/stripe/internal/types.d.ts +4 -0
- package/dist/stripe/server/Charge.d.ts +25 -5
- package/dist/stripe/server/Charge.js +35 -23
- package/dist/stripe/server/Methods.d.ts +8 -0
- package/dist/stripe/server/Methods.js +54 -9
- package/dist/stripe/server/internal/analytics.d.ts +6 -0
- package/dist/stripe/server/internal/analytics.js +16 -0
- package/dist/stripe/server/internal/hosted-fee-payer.d.ts +10 -0
- package/dist/stripe/server/internal/hosted-fee-payer.js +54 -0
- package/dist/stripe/server/internal/html.gen.d.ts +1 -1
- package/dist/stripe/server/internal/html.gen.js +1 -1
- package/dist/stripe/server/internal/record-payment.d.ts +4 -1
- package/dist/stripe/server/internal/record-payment.js +35 -5
- package/dist/tempo/client/Subscription.js +6 -2
- package/dist/tempo/internal/account.d.ts +1 -0
- package/dist/tempo/internal/fee-payer.d.ts +2 -0
- package/dist/tempo/internal/fee-payer.js +4 -0
- package/dist/tempo/internal/remote-fee-payer.d.ts +2 -0
- package/dist/tempo/server/Subscription.js +1 -0
- package/dist/tempo/server/internal/html.gen.d.ts +1 -1
- package/dist/tempo/server/internal/html.gen.js +1 -1
- package/dist/tempo/session/client/SessionManager.d.ts +5 -0
- package/dist/tempo/session/client/SessionManager.js +16 -2
- package/dist/tempo/session/precompile/Chain.js +3 -0
- package/dist/tempo/subscription/KeyAuthorization.d.ts +7 -1
- package/dist/tempo/subscription/KeyAuthorization.js +21 -3
- package/dist/viem/Client.js +1 -0
- package/dist/x402/client/Exact.d.ts +2 -2
- package/dist/x402/client/Exact.js +1 -1
- package/dist/x402/server/EvmCharge.d.ts +2 -0
- package/dist/x402/server/EvmCharge.js +34 -26
- package/package.json +1 -1
|
@@ -55,9 +55,18 @@ export declare function charge(parameters: charge.Parameters): Method.Client<{
|
|
|
55
55
|
externalId: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
56
56
|
metadata: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
|
|
57
57
|
networkId: z.ZodMiniString<string>;
|
|
58
|
-
paymentIntentOptions: z.ZodMiniOptional<z.ZodMiniObject<{
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
paymentIntentOptions: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniObject<{
|
|
59
|
+
customer: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
60
|
+
hooks: z.ZodMiniOptional<z.ZodMiniObject<{
|
|
61
|
+
inputs: z.ZodMiniObject<{
|
|
62
|
+
tax: z.ZodMiniObject<{
|
|
63
|
+
calculation: z.ZodMiniString<string>;
|
|
64
|
+
}, z.core.$strip>;
|
|
65
|
+
}, z.core.$strip>;
|
|
66
|
+
}, z.core.$strip>>;
|
|
67
|
+
metadata: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
|
|
68
|
+
receipt_email: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
69
|
+
}, z.core.$strip>, z.ZodMiniCustom<import("../internal/payment-intent.js").ResolveOptions, import("../internal/payment-intent.js").ResolveOptions>]>>;
|
|
61
70
|
paymentMethodTypes: z.ZodMiniArray<z.ZodMiniString<string>>;
|
|
62
71
|
recipient: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
63
72
|
}, z.core.$strip>, z.ZodMiniTransform<{
|
|
@@ -79,8 +88,17 @@ export declare function charge(parameters: charge.Parameters): Method.Client<{
|
|
|
79
88
|
externalId?: string | undefined;
|
|
80
89
|
metadata?: Record<string, string> | undefined;
|
|
81
90
|
networkId: string;
|
|
82
|
-
paymentIntentOptions?: {
|
|
83
|
-
|
|
91
|
+
paymentIntentOptions?: import("../internal/payment-intent.js").ResolveOptions | {
|
|
92
|
+
customer?: string | undefined;
|
|
93
|
+
hooks?: {
|
|
94
|
+
inputs: {
|
|
95
|
+
tax: {
|
|
96
|
+
calculation: string;
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
} | undefined;
|
|
100
|
+
metadata?: Record<string, string> | undefined;
|
|
101
|
+
receipt_email?: string | undefined;
|
|
84
102
|
} | undefined;
|
|
85
103
|
paymentMethodTypes: string[];
|
|
86
104
|
recipient?: string | undefined;
|
|
@@ -42,9 +42,18 @@ export declare function stripe(parameters: stripe.Parameters): readonly [import(
|
|
|
42
42
|
externalId: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
43
43
|
metadata: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniRecord<import("zod/mini").ZodMiniString<string>, import("zod/mini").ZodMiniString<string>>>;
|
|
44
44
|
networkId: import("zod/mini").ZodMiniString<string>;
|
|
45
|
-
paymentIntentOptions: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniObject<{
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
paymentIntentOptions: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniUnion<readonly [import("zod/mini").ZodMiniObject<{
|
|
46
|
+
customer: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
47
|
+
hooks: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniObject<{
|
|
48
|
+
inputs: import("zod/mini").ZodMiniObject<{
|
|
49
|
+
tax: import("zod/mini").ZodMiniObject<{
|
|
50
|
+
calculation: import("zod/mini").ZodMiniString<string>;
|
|
51
|
+
}, import("zod/v4/core").$strip>;
|
|
52
|
+
}, import("zod/v4/core").$strip>;
|
|
53
|
+
}, import("zod/v4/core").$strip>>;
|
|
54
|
+
metadata: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniRecord<import("zod/mini").ZodMiniString<string>, import("zod/mini").ZodMiniString<string>>>;
|
|
55
|
+
receipt_email: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
56
|
+
}, import("zod/v4/core").$strip>, import("zod/mini").ZodMiniCustom<import("../internal/payment-intent.js").ResolveOptions, import("../internal/payment-intent.js").ResolveOptions>]>>;
|
|
48
57
|
paymentMethodTypes: import("zod/mini").ZodMiniArray<import("zod/mini").ZodMiniString<string>>;
|
|
49
58
|
recipient: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
50
59
|
}, import("zod/v4/core").$strip>, import("zod/mini").ZodMiniTransform<{
|
|
@@ -66,8 +75,17 @@ export declare function stripe(parameters: stripe.Parameters): readonly [import(
|
|
|
66
75
|
externalId?: string | undefined;
|
|
67
76
|
metadata?: Record<string, string> | undefined;
|
|
68
77
|
networkId: string;
|
|
69
|
-
paymentIntentOptions?: {
|
|
70
|
-
|
|
78
|
+
paymentIntentOptions?: import("../internal/payment-intent.js").ResolveOptions | {
|
|
79
|
+
customer?: string | undefined;
|
|
80
|
+
hooks?: {
|
|
81
|
+
inputs: {
|
|
82
|
+
tax: {
|
|
83
|
+
calculation: string;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
} | undefined;
|
|
87
|
+
metadata?: Record<string, string> | undefined;
|
|
88
|
+
receipt_email?: string | undefined;
|
|
71
89
|
} | undefined;
|
|
72
90
|
paymentMethodTypes: string[];
|
|
73
91
|
recipient?: string | undefined;
|
|
@@ -5,4 +5,8 @@
|
|
|
5
5
|
* Bump this when upgrading to a newer Stripe API version.
|
|
6
6
|
*/
|
|
7
7
|
export declare const stripePreviewVersion = "2026-07-29.preview";
|
|
8
|
+
/** Metadata identifying a Stripe PaymentIntent as a machine payment. */
|
|
9
|
+
export declare const machinePaymentMetadata: {
|
|
10
|
+
readonly machine_payment: 'true';
|
|
11
|
+
};
|
|
8
12
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -5,4 +5,6 @@
|
|
|
5
5
|
* Bump this when upgrading to a newer Stripe API version.
|
|
6
6
|
*/
|
|
7
7
|
export const stripePreviewVersion = '2026-07-29.preview';
|
|
8
|
+
/** Metadata identifying a Stripe PaymentIntent as a machine payment. */
|
|
9
|
+
export const machinePaymentMetadata = { machine_payment: 'true' };
|
|
8
10
|
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a decimal string to its integer representation at the given precision.
|
|
3
|
+
* Fractional digits beyond the precision are rounded half away from zero.
|
|
4
|
+
*
|
|
5
|
+
* @see https://github.com/wevm/viem/pull/4859
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseUnits(value: string, decimals: number): bigint;
|
|
8
|
+
//# sourceMappingURL=parse-units.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a decimal string to its integer representation at the given precision.
|
|
3
|
+
* Fractional digits beyond the precision are rounded half away from zero.
|
|
4
|
+
*
|
|
5
|
+
* @see https://github.com/wevm/viem/pull/4859
|
|
6
|
+
*/
|
|
7
|
+
export function parseUnits(value, decimals) {
|
|
8
|
+
if (!Number.isInteger(decimals) || decimals < 0)
|
|
9
|
+
throw new RangeError('Decimals must be a non-negative integer.');
|
|
10
|
+
if (!/^-?(?:\d+(?:\.\d*)?|\.\d+)$/.test(value))
|
|
11
|
+
throw new TypeError(`Value \`${value}\` is not a valid decimal number.`);
|
|
12
|
+
const negative = value.startsWith('-');
|
|
13
|
+
const [integer = '0', fraction = ''] = (negative ? value.slice(1) : value).split('.');
|
|
14
|
+
const keptFraction = fraction.slice(0, decimals).padEnd(decimals, '0');
|
|
15
|
+
let result = BigInt(`${integer || '0'}${keptFraction}`);
|
|
16
|
+
if (fraction.length > decimals && fraction[decimals] >= '5')
|
|
17
|
+
result += 1n;
|
|
18
|
+
return negative ? -result : result;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=parse-units.js.map
|
|
@@ -1,7 +1,45 @@
|
|
|
1
|
+
import type * as Challenge from '../../Challenge.js';
|
|
2
|
+
import type * as Credential from '../../Credential.js';
|
|
3
|
+
import type { MaybePromise } from '../../internal/types.js';
|
|
4
|
+
import type * as Method from '../../Method.js';
|
|
1
5
|
import * as z from '../../zod.js';
|
|
2
6
|
/** Stripe PaymentIntent options accepted only by server-side method input. */
|
|
3
7
|
export declare const Schema: z.ZodMiniObject<{
|
|
4
|
-
|
|
8
|
+
customer: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
9
|
+
hooks: z.ZodMiniOptional<z.ZodMiniObject<{
|
|
10
|
+
inputs: z.ZodMiniObject<{
|
|
11
|
+
tax: z.ZodMiniObject<{
|
|
12
|
+
calculation: z.ZodMiniString<string>;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
}, z.core.$strip>;
|
|
15
|
+
}, z.core.$strip>>;
|
|
16
|
+
metadata: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
|
|
17
|
+
receipt_email: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
5
18
|
}, z.core.$strip>;
|
|
6
19
|
export type Options = z.infer<typeof Schema>;
|
|
20
|
+
/** Context provided when resolving request-scoped PaymentIntent options. */
|
|
21
|
+
export type ResolveOptionsContext = {
|
|
22
|
+
challenge: Challenge.Challenge;
|
|
23
|
+
credential: Credential.Credential;
|
|
24
|
+
envelope?: Method.VerifiedChallengeEnvelope | undefined;
|
|
25
|
+
request: Record<string, unknown>;
|
|
26
|
+
};
|
|
27
|
+
/** Lazily resolves request-scoped PaymentIntent options before the terminal payment operation. */
|
|
28
|
+
export type ResolveOptions = (context: ResolveOptionsContext) => MaybePromise<Options | undefined>;
|
|
29
|
+
export type OptionsInput = Options | ResolveOptions;
|
|
30
|
+
/** PaymentIntent options accepted only by server-side method input. */
|
|
31
|
+
export declare const InputSchema: z.ZodMiniUnion<readonly [z.ZodMiniObject<{
|
|
32
|
+
customer: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
33
|
+
hooks: z.ZodMiniOptional<z.ZodMiniObject<{
|
|
34
|
+
inputs: z.ZodMiniObject<{
|
|
35
|
+
tax: z.ZodMiniObject<{
|
|
36
|
+
calculation: z.ZodMiniString<string>;
|
|
37
|
+
}, z.core.$strip>;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
}, z.core.$strip>>;
|
|
40
|
+
metadata: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
|
|
41
|
+
receipt_email: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
42
|
+
}, z.core.$strip>, z.ZodMiniCustom<ResolveOptions, ResolveOptions>]>;
|
|
43
|
+
/** Resolves and validates request-scoped PaymentIntent options. */
|
|
44
|
+
export declare function resolve(input: OptionsInput | undefined, context: ResolveOptionsContext): Promise<Options | undefined>;
|
|
7
45
|
//# sourceMappingURL=payment-intent.d.ts.map
|
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
import * as z from '../../zod.js';
|
|
2
2
|
/** Stripe PaymentIntent options accepted only by server-side method input. */
|
|
3
3
|
export const Schema = z.object({
|
|
4
|
-
|
|
4
|
+
customer: z.optional(z.string().check(z.minLength(1))),
|
|
5
|
+
hooks: z.optional(z.object({
|
|
6
|
+
inputs: z.object({
|
|
7
|
+
tax: z.object({ calculation: z.string().check(z.minLength(1)) }),
|
|
8
|
+
}),
|
|
9
|
+
})),
|
|
10
|
+
metadata: z.optional(z.record(z.string(), z.string())),
|
|
11
|
+
receipt_email: z.optional(z.string().check(z.minLength(1))),
|
|
5
12
|
});
|
|
13
|
+
const ResolveOptionsSchema = z.custom((value) => typeof value === 'function');
|
|
14
|
+
/** PaymentIntent options accepted only by server-side method input. */
|
|
15
|
+
export const InputSchema = z.union([Schema, ResolveOptionsSchema]);
|
|
16
|
+
/** Resolves and validates request-scoped PaymentIntent options. */
|
|
17
|
+
export async function resolve(input, context) {
|
|
18
|
+
const options = typeof input === 'function' ? await input(context) : input;
|
|
19
|
+
return z.optional(Schema).parse(options);
|
|
20
|
+
}
|
|
6
21
|
//# sourceMappingURL=payment-intent.js.map
|
|
@@ -6,6 +6,10 @@ import * as StripeJsTypes from '../../stripe/server/internal/html/types.js';
|
|
|
6
6
|
* Uses loose signatures so any Stripe SDK version is assignable.
|
|
7
7
|
*/
|
|
8
8
|
export type StripeClient = {
|
|
9
|
+
/** Stripe-node request transport used for hosted fee-payer requests. */
|
|
10
|
+
_requestSender?: {
|
|
11
|
+
_request(...args: any[]): void;
|
|
12
|
+
} | undefined;
|
|
9
13
|
paymentIntents: {
|
|
10
14
|
create(...args: any[]): Promise<{
|
|
11
15
|
id: string;
|
|
@@ -4,6 +4,7 @@ import type { ConfiguredDefaults, LooseOmit, MaybePromise, OneOf } from '../../i
|
|
|
4
4
|
import * as Method from '../../Method.js';
|
|
5
5
|
import type * as Html from '../../server/internal/html/config.ts';
|
|
6
6
|
import type * as z from '../../zod.js';
|
|
7
|
+
import * as PaymentIntent from '../internal/payment-intent.js';
|
|
7
8
|
import type { StripeClient, CreatePaymentMethodFromElements, StripeElementsOptionsMode, StripePaymentElementOptions } from '../internal/types.js';
|
|
8
9
|
import * as Methods from '../Methods.js';
|
|
9
10
|
/**
|
|
@@ -49,9 +50,18 @@ export declare function charge<const parameters extends charge.Parameters>(param
|
|
|
49
50
|
externalId: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
50
51
|
metadata: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
|
|
51
52
|
networkId: z.ZodMiniString<string>;
|
|
52
|
-
paymentIntentOptions: z.ZodMiniOptional<z.ZodMiniObject<{
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
paymentIntentOptions: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniObject<{
|
|
54
|
+
customer: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
55
|
+
hooks: z.ZodMiniOptional<z.ZodMiniObject<{
|
|
56
|
+
inputs: z.ZodMiniObject<{
|
|
57
|
+
tax: z.ZodMiniObject<{
|
|
58
|
+
calculation: z.ZodMiniString<string>;
|
|
59
|
+
}, z.core.$strip>;
|
|
60
|
+
}, z.core.$strip>;
|
|
61
|
+
}, z.core.$strip>>;
|
|
62
|
+
metadata: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
|
|
63
|
+
receipt_email: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
64
|
+
}, z.core.$strip>, z.ZodMiniCustom<PaymentIntent.ResolveOptions, PaymentIntent.ResolveOptions>]>>;
|
|
55
65
|
paymentMethodTypes: z.ZodMiniArray<z.ZodMiniString<string>>;
|
|
56
66
|
recipient: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
57
67
|
}, z.core.$strip>, z.ZodMiniTransform<{
|
|
@@ -73,8 +83,17 @@ export declare function charge<const parameters extends charge.Parameters>(param
|
|
|
73
83
|
externalId?: string | undefined;
|
|
74
84
|
metadata?: Record<string, string> | undefined;
|
|
75
85
|
networkId: string;
|
|
76
|
-
paymentIntentOptions?: {
|
|
77
|
-
|
|
86
|
+
paymentIntentOptions?: PaymentIntent.ResolveOptions | {
|
|
87
|
+
customer?: string | undefined;
|
|
88
|
+
hooks?: {
|
|
89
|
+
inputs: {
|
|
90
|
+
tax: {
|
|
91
|
+
calculation: string;
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
} | undefined;
|
|
95
|
+
metadata?: Record<string, string> | undefined;
|
|
96
|
+
receipt_email?: string | undefined;
|
|
78
97
|
} | undefined;
|
|
79
98
|
paymentMethodTypes: string[];
|
|
80
99
|
recipient?: string | undefined;
|
|
@@ -112,6 +131,7 @@ export declare namespace charge {
|
|
|
112
131
|
* `decimals` remains required when it was not configured on `stripe.charge()`.
|
|
113
132
|
*/
|
|
114
133
|
type DeriveDefaults<parameters extends Parameters> = ConfiguredDefaults<parameters, Defaults>;
|
|
134
|
+
type ResolvePaymentIntentOptionsContext = PaymentIntent.ResolveOptionsContext;
|
|
115
135
|
/**
|
|
116
136
|
* Server-side Stripe Connect settlement parameters.
|
|
117
137
|
*
|
|
@@ -2,7 +2,9 @@ import { InvalidChallengeError, PaymentActionRequiredError, VerificationFailedEr
|
|
|
2
2
|
import * as Expires from '../../Expires.js';
|
|
3
3
|
import * as Method from '../../Method.js';
|
|
4
4
|
import { stripePreviewVersion } from '../internal/constants.js';
|
|
5
|
+
import * as PaymentIntent from '../internal/payment-intent.js';
|
|
5
6
|
import * as Methods from '../Methods.js';
|
|
7
|
+
import { buildAnalytics } from './internal/analytics.js';
|
|
6
8
|
import { html as htmlContent } from './internal/html.gen.js';
|
|
7
9
|
/**
|
|
8
10
|
* Stripe's general minimum charge amounts in each currency's smallest unit.
|
|
@@ -117,7 +119,7 @@ export function charge(parameters) {
|
|
|
117
119
|
onPaymentSuccess,
|
|
118
120
|
async verify({ credential, envelope, request }) {
|
|
119
121
|
const { challenge } = credential;
|
|
120
|
-
const { paymentIntentOptions, ...methodRequest } = request;
|
|
122
|
+
const { paymentIntentOptions: paymentIntentOptionsInput, ...methodRequest } = request;
|
|
121
123
|
const resolvedRequest = (() => {
|
|
122
124
|
const parsed = Methods.charge.schema.request.safeParse(methodRequest);
|
|
123
125
|
if (parsed.success)
|
|
@@ -139,32 +141,44 @@ export function charge(parameters) {
|
|
|
139
141
|
});
|
|
140
142
|
}
|
|
141
143
|
const userMetadata = resolvedRequest.methodDetails?.metadata;
|
|
142
|
-
const resolvedMetadata = {
|
|
143
|
-
...buildAnalytics({ credential }),
|
|
144
|
-
...userMetadata,
|
|
145
|
-
...paymentIntentOptions?.metadata,
|
|
146
|
-
};
|
|
147
144
|
const settlement = validateConnectSettlement({
|
|
148
145
|
amount: resolvedRequest.amount,
|
|
149
146
|
settlement: typeof connect === 'function'
|
|
150
147
|
? await connect({ challenge, credential, envelope, request: resolvedRequest })
|
|
151
148
|
: connect,
|
|
152
149
|
});
|
|
150
|
+
const paymentIntentOptions = await PaymentIntent.resolve(paymentIntentOptionsInput, {
|
|
151
|
+
challenge,
|
|
152
|
+
credential,
|
|
153
|
+
envelope,
|
|
154
|
+
request: resolvedRequest,
|
|
155
|
+
});
|
|
156
|
+
const { customer, hooks, metadata: optionMetadata, receipt_email, } = paymentIntentOptions ?? {};
|
|
157
|
+
const resolvedPaymentIntentOptions = {
|
|
158
|
+
...(customer !== undefined && { customer }),
|
|
159
|
+
...(hooks !== undefined && { hooks }),
|
|
160
|
+
metadata: {
|
|
161
|
+
...buildAnalytics({ challenge }),
|
|
162
|
+
...userMetadata,
|
|
163
|
+
...optionMetadata,
|
|
164
|
+
},
|
|
165
|
+
...(receipt_email !== undefined && { receipt_email }),
|
|
166
|
+
};
|
|
153
167
|
const pi = client
|
|
154
168
|
? await createWithClient({
|
|
155
169
|
client,
|
|
156
170
|
challenge,
|
|
171
|
+
paymentIntentOptions: resolvedPaymentIntentOptions,
|
|
157
172
|
request: resolvedRequest,
|
|
158
173
|
spt,
|
|
159
|
-
metadata: resolvedMetadata,
|
|
160
174
|
settlement,
|
|
161
175
|
})
|
|
162
176
|
: await createWithSecretKey({
|
|
163
177
|
secretKey: secretKey,
|
|
164
178
|
challenge,
|
|
179
|
+
paymentIntentOptions: resolvedPaymentIntentOptions,
|
|
165
180
|
request: resolvedRequest,
|
|
166
181
|
spt,
|
|
167
|
-
metadata: resolvedMetadata,
|
|
168
182
|
settlement,
|
|
169
183
|
});
|
|
170
184
|
if (pi.replayed)
|
|
@@ -186,14 +200,18 @@ export function charge(parameters) {
|
|
|
186
200
|
}
|
|
187
201
|
/** Creates a PaymentIntent using the Stripe SDK client. */
|
|
188
202
|
async function createWithClient(parameters) {
|
|
189
|
-
const { client, challenge,
|
|
203
|
+
const { client, challenge, paymentIntentOptions, request, settlement, spt } = parameters;
|
|
204
|
+
const { customer, hooks, metadata, receipt_email } = paymentIntentOptions;
|
|
190
205
|
try {
|
|
191
206
|
const paymentIntentParams = {
|
|
192
207
|
amount: Number(request.amount),
|
|
193
208
|
automatic_payment_methods: { allow_redirects: 'never', enabled: true },
|
|
194
209
|
confirm: true,
|
|
195
210
|
currency: request.currency,
|
|
211
|
+
...(customer !== undefined && { customer }),
|
|
212
|
+
...(hooks !== undefined && { hooks }),
|
|
196
213
|
metadata,
|
|
214
|
+
...(receipt_email !== undefined && { receipt_email }),
|
|
197
215
|
...(settlement?.applicationFeeAmount !== undefined && {
|
|
198
216
|
application_fee_amount: settlement.applicationFeeAmount,
|
|
199
217
|
}),
|
|
@@ -210,12 +228,12 @@ async function createWithClient(parameters) {
|
|
|
210
228
|
// `shared_payment_granted_token` is not yet in the Stripe SDK types (SPTs are in private preview).
|
|
211
229
|
shared_payment_granted_token: spt,
|
|
212
230
|
};
|
|
213
|
-
const
|
|
231
|
+
const requestOptions = {
|
|
214
232
|
apiVersion: stripePreviewVersion,
|
|
215
233
|
idempotencyKey: `mpp_${challenge.id}_${spt}`,
|
|
216
234
|
...(settlement?.stripeAccount !== undefined && { stripeAccount: settlement.stripeAccount }),
|
|
217
235
|
};
|
|
218
|
-
const result = await client.paymentIntents.create(paymentIntentParams,
|
|
236
|
+
const result = await client.paymentIntents.create(paymentIntentParams, requestOptions);
|
|
219
237
|
// https://docs.stripe.com/error-low-level#idempotency
|
|
220
238
|
const replayed = result.lastResponse?.headers?.['idempotent-replayed'] === 'true';
|
|
221
239
|
return { id: result.id, status: result.status, replayed };
|
|
@@ -229,18 +247,23 @@ async function createWithClient(parameters) {
|
|
|
229
247
|
}
|
|
230
248
|
/** Creates a PaymentIntent using a raw secret key and fetch. */
|
|
231
249
|
async function createWithSecretKey(parameters) {
|
|
232
|
-
const { secretKey, challenge,
|
|
250
|
+
const { secretKey, challenge, paymentIntentOptions, request, settlement, spt } = parameters;
|
|
251
|
+
const { customer, hooks, metadata, receipt_email } = paymentIntentOptions;
|
|
233
252
|
const body = new URLSearchParams({
|
|
234
253
|
amount: request.amount,
|
|
235
254
|
'automatic_payment_methods[allow_redirects]': 'never',
|
|
236
255
|
'automatic_payment_methods[enabled]': 'true',
|
|
237
256
|
confirm: 'true',
|
|
238
257
|
currency: request.currency,
|
|
258
|
+
...(customer !== undefined && { customer }),
|
|
259
|
+
...(receipt_email !== undefined && { receipt_email }),
|
|
239
260
|
shared_payment_granted_token: spt,
|
|
240
261
|
});
|
|
241
262
|
for (const [key, value] of Object.entries(metadata)) {
|
|
242
263
|
body.set(`metadata[${key}]`, value);
|
|
243
264
|
}
|
|
265
|
+
if (hooks !== undefined)
|
|
266
|
+
body.set('hooks[inputs][tax][calculation]', hooks.inputs.tax.calculation);
|
|
244
267
|
if (settlement?.applicationFeeAmount !== undefined)
|
|
245
268
|
body.set('application_fee_amount', String(settlement.applicationFeeAmount));
|
|
246
269
|
if (settlement?.onBehalfOf !== undefined)
|
|
@@ -284,17 +307,6 @@ async function createWithSecretKey(parameters) {
|
|
|
284
307
|
const result = (await response.json());
|
|
285
308
|
return { ...result, replayed };
|
|
286
309
|
}
|
|
287
|
-
/** @internal */
|
|
288
|
-
function buildAnalytics(parameters) {
|
|
289
|
-
const { credential } = parameters;
|
|
290
|
-
const { challenge } = credential;
|
|
291
|
-
return {
|
|
292
|
-
mpp_intent: challenge.intent,
|
|
293
|
-
mpp_challenge_id: challenge.id,
|
|
294
|
-
mpp_server_id: challenge.realm,
|
|
295
|
-
...(credential.source ? { mpp_client_id: credential.source } : {}),
|
|
296
|
-
};
|
|
297
|
-
}
|
|
298
310
|
function validateConnectSettlement(parameters) {
|
|
299
311
|
const { amount, settlement } = parameters;
|
|
300
312
|
if (settlement === undefined)
|
|
@@ -2,12 +2,14 @@ import { charge as evmCharge } from '../../evm/server/Charge.js';
|
|
|
2
2
|
import type * as Method from '../../Method.js';
|
|
3
3
|
import { charge as tempoCharge } from '../../tempo/server/Charge.js';
|
|
4
4
|
import { session as tempoSession } from '../../tempo/session/server/Session.js';
|
|
5
|
+
import * as PaymentIntent from '../internal/payment-intent.js';
|
|
5
6
|
import type { StripeClient } from '../internal/types.js';
|
|
6
7
|
import { charge as charge_ } from './Charge.js';
|
|
7
8
|
import { findOrCreateDepositAddress as _findOrCreateDepositAddress } from './internal/deposit-address.js';
|
|
8
9
|
import { type ConnectConfig } from './internal/request.js';
|
|
9
10
|
export declare namespace stripe {
|
|
10
11
|
type Network = 'tempo' | 'base' | 'solana';
|
|
12
|
+
type ResolvePaymentIntentOptionsContext = PaymentIntent.ResolveOptionsContext;
|
|
11
13
|
type DepositAddress<N extends Network = Network> = string & {
|
|
12
14
|
readonly __brand: 'StripeDepositAddress';
|
|
13
15
|
readonly __network: N;
|
|
@@ -16,6 +18,7 @@ export declare namespace stripe {
|
|
|
16
18
|
client: StripeClient;
|
|
17
19
|
networkId: string;
|
|
18
20
|
livemode: boolean;
|
|
21
|
+
hostedFeePayer?: boolean | undefined;
|
|
19
22
|
connect?: ConnectConfig;
|
|
20
23
|
depositAddresses?: Partial<Record<Network, string>> | ((network: Network) => Promise<string>);
|
|
21
24
|
metadata?: Record<string, string> | undefined;
|
|
@@ -139,6 +142,11 @@ declare class DefaultMethodsBuilder implements PromiseLike<DefaultMethods> {
|
|
|
139
142
|
* secretKey: mppSecretKey,
|
|
140
143
|
* })
|
|
141
144
|
* ```
|
|
145
|
+
*
|
|
146
|
+
* PaymentIntent option resolvers run after non-mutating method validation, when
|
|
147
|
+
* available, and before the terminal payment operation. If Stripe later rejects
|
|
148
|
+
* resolved optional fields while recording a completed crypto payment, mppx
|
|
149
|
+
* retries the recording once without them. SPT payments do not use this fallback.
|
|
142
150
|
*/
|
|
143
151
|
export declare function stripe<const P extends stripe.Parameters>(parameters: P): StripeMachinePayments<P>;
|
|
144
152
|
export declare namespace stripe {
|
|
@@ -6,7 +6,9 @@ import { session as tempoSession } from '../../tempo/session/server/Session.js';
|
|
|
6
6
|
import * as z from '../../zod.js';
|
|
7
7
|
import * as PaymentIntent from '../internal/payment-intent.js';
|
|
8
8
|
import { charge as charge_ } from './Charge.js';
|
|
9
|
+
import { buildAnalytics } from './internal/analytics.js';
|
|
9
10
|
import { findOrCreateDepositAddress as _findOrCreateDepositAddress } from './internal/deposit-address.js';
|
|
11
|
+
import * as HostedFeePayer from './internal/hosted-fee-payer.js';
|
|
10
12
|
import { recordCryptoPayment } from './internal/record-payment.js';
|
|
11
13
|
const defaultMethodNames = ['tempo', 'spt'];
|
|
12
14
|
const additionalBuiltinKeys = ['base', 'tempo'];
|
|
@@ -71,12 +73,22 @@ class DefaultMethodsBuilder {
|
|
|
71
73
|
* secretKey: mppSecretKey,
|
|
72
74
|
* })
|
|
73
75
|
* ```
|
|
76
|
+
*
|
|
77
|
+
* PaymentIntent option resolvers run after non-mutating method validation, when
|
|
78
|
+
* available, and before the terminal payment operation. If Stripe later rejects
|
|
79
|
+
* resolved optional fields while recording a completed crypto payment, mppx
|
|
80
|
+
* retries the recording once without them. SPT payments do not use this fallback.
|
|
74
81
|
*/
|
|
75
82
|
export function stripe(parameters) {
|
|
76
|
-
const { client, networkId, livemode, connect, depositAddresses, metadata } = parameters;
|
|
83
|
+
const { client, networkId, livemode, hostedFeePayer, connect, depositAddresses, metadata } = parameters;
|
|
77
84
|
if (!client.rawRequest)
|
|
78
85
|
throw new Error('stripe.create() requires a Stripe SDK client with rawRequest() (v15+)');
|
|
86
|
+
if (hostedFeePayer && !livemode)
|
|
87
|
+
throw new Error('Stripe hosted fee payer requires a live-mode integration.');
|
|
88
|
+
if (hostedFeePayer && connect)
|
|
89
|
+
throw new Error('Stripe hosted fee payer does not support Connect account routing.');
|
|
79
90
|
const tempoCurrency = (livemode ? tempoDefaults.tokens.usdc : tempoDefaults.tokens.pathUsd);
|
|
91
|
+
const hostedTempoFeePayer = hostedFeePayer ? HostedFeePayer.create(client) : undefined;
|
|
80
92
|
const tempoPaymentHandler = createPaymentSuccessHandler(client, 'tempo', connect, metadata);
|
|
81
93
|
const basePaymentHandler = createPaymentSuccessHandler(client, 'base', connect, metadata);
|
|
82
94
|
// All stripe-managed crypto rails use 6-decimal stablecoins. Reject amounts
|
|
@@ -102,6 +114,7 @@ export function stripe(parameters) {
|
|
|
102
114
|
currency: tempoCurrency,
|
|
103
115
|
recipient,
|
|
104
116
|
...(!livemode && { testnet: true }),
|
|
117
|
+
...(hostedTempoFeePayer && { feePayer: hostedTempoFeePayer }),
|
|
105
118
|
canOffer: cryptoCanOffer,
|
|
106
119
|
onPaymentSuccess: handler,
|
|
107
120
|
...rest,
|
|
@@ -113,6 +126,7 @@ export function stripe(parameters) {
|
|
|
113
126
|
currency: tempoCurrency,
|
|
114
127
|
recipient,
|
|
115
128
|
...(!livemode && { testnet: true }),
|
|
129
|
+
...(hostedTempoFeePayer && { feePayer: hostedTempoFeePayer }),
|
|
116
130
|
...rest,
|
|
117
131
|
});
|
|
118
132
|
}
|
|
@@ -269,18 +283,27 @@ function customRails(additional) {
|
|
|
269
283
|
}
|
|
270
284
|
function createPaymentSuccessHandler(client, network, connect, metadata) {
|
|
271
285
|
return (params) => {
|
|
272
|
-
const { receipt, request, requestInput } = params;
|
|
286
|
+
const { challenge, receipt, request, requestInput } = params;
|
|
273
287
|
if (receipt?.reference && request?.amount) {
|
|
288
|
+
const paymentIntentOptionsInput = requestInput?.paymentIntentOptions;
|
|
289
|
+
const paymentIntentOptions = typeof paymentIntentOptionsInput === 'function' ? undefined : paymentIntentOptionsInput;
|
|
274
290
|
const resolvedMetadata = {
|
|
275
291
|
...metadata,
|
|
276
|
-
...
|
|
292
|
+
...paymentIntentOptions?.metadata,
|
|
293
|
+
};
|
|
294
|
+
const resolvedPaymentIntentOptions = {
|
|
295
|
+
...paymentIntentOptions,
|
|
296
|
+
...(Object.keys(resolvedMetadata).length > 0 && { metadata: resolvedMetadata }),
|
|
277
297
|
};
|
|
278
298
|
return recordCryptoPayment(client, {
|
|
279
299
|
network,
|
|
280
300
|
reference: receipt.reference,
|
|
281
301
|
amount: String(request.amount),
|
|
282
302
|
...(connect && { connect }),
|
|
283
|
-
|
|
303
|
+
analyticsMetadata: buildAnalytics({ challenge }),
|
|
304
|
+
...(Object.keys(resolvedPaymentIntentOptions).length > 0 && {
|
|
305
|
+
paymentIntentOptions: resolvedPaymentIntentOptions,
|
|
306
|
+
}),
|
|
284
307
|
});
|
|
285
308
|
}
|
|
286
309
|
};
|
|
@@ -289,8 +312,9 @@ function createPaymentSuccessHandler(client, network, connect, metadata) {
|
|
|
289
312
|
* Extends a rail's server-only input with Stripe PaymentIntent options while
|
|
290
313
|
* keeping its canonical request unchanged. The schema strips the options
|
|
291
314
|
* before challenge serialization, and delegated lifecycle hooks receive the
|
|
292
|
-
* underlying rail request without Stripe-only fields.
|
|
293
|
-
* options
|
|
315
|
+
* underlying rail request without Stripe-only fields. After method validation,
|
|
316
|
+
* the wrapper resolves the options immediately before the terminal operation
|
|
317
|
+
* and retains the result in `requestInput` for payment-success recording.
|
|
294
318
|
*/
|
|
295
319
|
function withPaymentIntentInput(method) {
|
|
296
320
|
const baseSchema = method.schema.request;
|
|
@@ -306,7 +330,7 @@ function withPaymentIntentInput(method) {
|
|
|
306
330
|
...method.schema,
|
|
307
331
|
request: z.pipe(z.custom(), z.transform((input) => {
|
|
308
332
|
const { paymentIntentOptions, ...request } = input;
|
|
309
|
-
z.optional(PaymentIntent.
|
|
333
|
+
z.optional(PaymentIntent.InputSchema).parse(paymentIntentOptions);
|
|
310
334
|
// Only the base schema's output is included in the challenge.
|
|
311
335
|
return baseSchema.parse(request);
|
|
312
336
|
})),
|
|
@@ -314,22 +338,43 @@ function withPaymentIntentInput(method) {
|
|
|
314
338
|
async request(context) {
|
|
315
339
|
const { paymentIntentOptions, ...request } = context.request;
|
|
316
340
|
const resolved = baseRequest ? await baseRequest({ ...context, request }) : request;
|
|
341
|
+
// Keep the server-only value in requestInput for the success hook. The
|
|
342
|
+
// schema transform above still excludes it from the signed challenge.
|
|
317
343
|
return { ...resolved, paymentIntentOptions };
|
|
318
344
|
},
|
|
319
345
|
...(baseRespond && {
|
|
320
346
|
respond: (context) => baseRespond(withoutPaymentIntentOptions(context)),
|
|
321
347
|
}),
|
|
322
348
|
...(baseBroadcast && {
|
|
323
|
-
broadcast
|
|
349
|
+
async broadcast(context) {
|
|
350
|
+
await resolvePaymentIntentOptions(context);
|
|
351
|
+
return baseBroadcast(withoutPaymentIntentOptions(context));
|
|
352
|
+
},
|
|
324
353
|
}),
|
|
325
354
|
...(baseValidate && {
|
|
326
355
|
validate: (context) => baseValidate(withoutPaymentIntentOptions(context)),
|
|
327
356
|
}),
|
|
328
357
|
...(baseVerify && {
|
|
329
|
-
verify
|
|
358
|
+
async verify(context) {
|
|
359
|
+
await resolvePaymentIntentOptions(context);
|
|
360
|
+
return baseVerify(withoutPaymentIntentOptions(context));
|
|
361
|
+
},
|
|
330
362
|
}),
|
|
331
363
|
};
|
|
332
364
|
}
|
|
365
|
+
/** Resolves Stripe-only options immediately before the terminal payment operation. */
|
|
366
|
+
async function resolvePaymentIntentOptions(context) {
|
|
367
|
+
const { paymentIntentOptions } = context.request;
|
|
368
|
+
const resolved = await PaymentIntent.resolve(paymentIntentOptions, {
|
|
369
|
+
challenge: context.credential.challenge,
|
|
370
|
+
credential: context.credential,
|
|
371
|
+
envelope: context.envelope,
|
|
372
|
+
request: context.envelope?.request ?? context.credential.challenge.request,
|
|
373
|
+
});
|
|
374
|
+
// MPPX later snapshots this request-local input for onPaymentSuccess. Replacing
|
|
375
|
+
// only the schema-stripped field keeps the canonical challenge unchanged.
|
|
376
|
+
context.request.paymentIntentOptions = resolved;
|
|
377
|
+
}
|
|
333
378
|
function withoutPaymentIntentOptions(context) {
|
|
334
379
|
const { paymentIntentOptions: _, ...request } = context.request;
|
|
335
380
|
return { ...context, request };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type * as Challenge from '../../../Challenge.js';
|
|
2
|
+
/** Builds Stripe metadata used to identify and analyze MPP payments. */
|
|
3
|
+
export declare function buildAnalytics(parameters: {
|
|
4
|
+
challenge?: Pick<Challenge.Challenge, 'id' | 'intent'> | undefined;
|
|
5
|
+
}): Record<string, string>;
|
|
6
|
+
//# sourceMappingURL=analytics.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { sdkIdentifier } from '../../../internal/version.js';
|
|
2
|
+
import { machinePaymentMetadata } from '../../internal/constants.js';
|
|
3
|
+
/** Builds Stripe metadata used to identify and analyze MPP payments. */
|
|
4
|
+
export function buildAnalytics(parameters) {
|
|
5
|
+
const { challenge } = parameters;
|
|
6
|
+
const metadata = {
|
|
7
|
+
...machinePaymentMetadata,
|
|
8
|
+
mpp_sdk: sdkIdentifier,
|
|
9
|
+
...(challenge && {
|
|
10
|
+
mpp_challenge_id: challenge.id,
|
|
11
|
+
mpp_intent: challenge.intent,
|
|
12
|
+
}),
|
|
13
|
+
};
|
|
14
|
+
return Object.fromEntries(Object.entries(metadata).map(([key, value]) => [key, [...value].slice(0, 500).join('')]));
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=analytics.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type * as RemoteFeePayer from '../../../tempo/internal/remote-fee-payer.js';
|
|
2
|
+
import type { StripeClient } from '../../internal/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Creates an instance of a Stripe feepayer using an authenticated Stripe client.
|
|
5
|
+
*
|
|
6
|
+
* This compatibility path uses the Stripe client so that requests to the feepayer
|
|
7
|
+
* retain their authentication, timeouts, telemetry, and request events.
|
|
8
|
+
*/
|
|
9
|
+
export declare function create(client: StripeClient): RemoteFeePayer.Config;
|
|
10
|
+
//# sourceMappingURL=hosted-fee-payer.d.ts.map
|