@openrails/billing-ui 0.236.0 → 0.238.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/CHANGELOG.md +87 -9
- package/README.md +78 -83
- package/dist/account/account-billing.d.ts +1 -1
- package/dist/account/payment-methods-panel.d.ts +2 -2
- package/dist/authenticate.d.ts +5 -4
- package/dist/buy-button.d.ts +17 -10
- package/dist/client/client.d.ts +52 -23
- package/dist/client/generated/error-codes.d.ts +1 -1
- package/dist/client/generated/routes.d.ts +24 -218
- package/dist/client/generated/wire.d.ts +39 -200
- package/dist/client/index.d.ts +2 -1
- package/dist/client/token-source.d.ts +60 -0
- package/dist/client/types.d.ts +108 -199
- package/dist/client-Bi_lP_M0.js +932 -0
- package/dist/client-Bi_lP_M0.js.map +1 -0
- package/dist/client.js +2 -2
- package/dist/components/eyebrow.d.ts +5 -0
- package/dist/embedded-checkout.d.ts +22 -0
- package/dist/{hooks-2d-XjpuI.js → hooks-Bk80rNv8.js} +99 -90
- package/dist/hooks-Bk80rNv8.js.map +1 -0
- package/dist/index.d.ts +5 -8
- package/dist/index.js +1149 -2163
- package/dist/index.js.map +1 -1
- package/dist/modal.d.ts +3 -9
- package/dist/offers.d.ts +10 -9
- package/dist/psp.d.ts +0 -8
- package/dist/react/config.d.ts +17 -12
- package/dist/react/context.d.ts +3 -1
- package/dist/react/hooks.d.ts +5 -5
- package/dist/react/index.d.ts +1 -1
- package/dist/react.js +2 -2
- package/dist/styles.css +1 -1
- package/dist/tokenized-card-form.d.ts +5 -1
- package/dist/types.d.ts +12 -250
- package/docs/payment-form-contract.md +31 -74
- package/package.json +1 -2
- package/dist/checkout-frame.d.ts +0 -17
- package/dist/checkout-page.d.ts +0 -21
- package/dist/checkout.d.ts +0 -22
- package/dist/client/checkout.d.ts +0 -28
- package/dist/client-BuvolBPT.js +0 -1092
- package/dist/client-BuvolBPT.js.map +0 -1
- package/dist/components/ccbill-fields.d.ts +0 -8
- package/dist/components/methods.d.ts +0 -13
- package/dist/components/summary.d.ts +0 -12
- package/dist/fixtures.d.ts +0 -9
- package/dist/frame.d.ts +0 -47
- package/dist/hooks-2d-XjpuI.js.map +0 -1
- package/dist/lib/rail-meta.d.ts +0 -15
- package/dist/lib/redirect.d.ts +0 -2
- package/dist/source.d.ts +0 -5
|
@@ -13,7 +13,11 @@ export interface TokenizedCardData {
|
|
|
13
13
|
export interface TokenizedCardFormProps {
|
|
14
14
|
tokenizationKey: string;
|
|
15
15
|
tokenizationURL: string;
|
|
16
|
-
|
|
16
|
+
/**
|
|
17
|
+
* The host's use of the card. Resolving `false` says it was definitely
|
|
18
|
+
* refused (a decline): the form takes another card.
|
|
19
|
+
*/
|
|
20
|
+
onTokenized: (card: TokenizedCardData) => Promise<void | boolean>;
|
|
17
21
|
submitLabel?: string;
|
|
18
22
|
disabled?: boolean;
|
|
19
23
|
/** Billing country to preselect; default: the browser locale's region. */
|
package/dist/types.d.ts
CHANGED
|
@@ -1,250 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}>;
|
|
14
|
-
export type CheckoutSessionStatus = z.infer<typeof checkoutSessionStatusSchema>;
|
|
15
|
-
export declare const paymentFailureSchema: z.ZodObject<{
|
|
16
|
-
reason: z.ZodString;
|
|
17
|
-
message: z.ZodString;
|
|
18
|
-
field: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
19
|
-
}, z.core.$strip>;
|
|
20
|
-
export type PaymentFailure = z.infer<typeof paymentFailureSchema>;
|
|
21
|
-
export declare const checkoutOperationSchema: z.ZodObject<{
|
|
22
|
-
id: z.ZodString;
|
|
23
|
-
status: z.ZodString;
|
|
24
|
-
}, z.core.$strip>;
|
|
25
|
-
export declare const paymentOptionSchema: z.ZodObject<{
|
|
26
|
-
id: z.ZodString;
|
|
27
|
-
psp_id: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | undefined, string | null | undefined>>>;
|
|
28
|
-
rail: z.ZodString;
|
|
29
|
-
mode: z.ZodEnum<{
|
|
30
|
-
one_off: "one_off";
|
|
31
|
-
subscription: "subscription";
|
|
32
|
-
}>;
|
|
33
|
-
driver: z.ZodEnum<{
|
|
34
|
-
collect_js: "collect_js";
|
|
35
|
-
card: "card";
|
|
36
|
-
stripe_elements: "stripe_elements";
|
|
37
|
-
redirect: "redirect";
|
|
38
|
-
solana_pay: "solana_pay";
|
|
39
|
-
}>;
|
|
40
|
-
psp_key: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | undefined, string | null | undefined>>>;
|
|
41
|
-
public_config: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodString>>>, z.ZodTransform<Record<string, string> | undefined, Record<string, string> | null | undefined>>>;
|
|
42
|
-
}, z.core.$strip>;
|
|
43
|
-
export type PaymentOption = z.infer<typeof paymentOptionSchema>;
|
|
44
|
-
export declare const nextActionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
45
|
-
type: z.ZodLiteral<"redirect_to_url">;
|
|
46
|
-
url: z.ZodString;
|
|
47
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
48
|
-
type: z.ZodLiteral<"solana_pay">;
|
|
49
|
-
url: z.ZodString;
|
|
50
|
-
}, z.core.$strip>], "type">;
|
|
51
|
-
export type NextAction = z.infer<typeof nextActionSchema>;
|
|
52
|
-
export declare const savedPaymentMethodSchema: z.ZodObject<{
|
|
53
|
-
id: z.ZodString;
|
|
54
|
-
option_id: z.ZodString;
|
|
55
|
-
rail: z.ZodString;
|
|
56
|
-
card: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
57
|
-
brand: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
58
|
-
last4: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
59
|
-
exp_month: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
60
|
-
exp_year: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
61
|
-
}, z.core.$strip>>>;
|
|
62
|
-
}, z.core.$strip>;
|
|
63
|
-
export type SavedPaymentMethod = z.infer<typeof savedPaymentMethodSchema>;
|
|
64
|
-
export declare const checkoutLineItemSchema: z.ZodObject<{
|
|
65
|
-
label: z.ZodString;
|
|
66
|
-
sublabel: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | undefined, string | null | undefined>>>;
|
|
67
|
-
amount: z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>;
|
|
68
|
-
}, z.core.$strip>;
|
|
69
|
-
export type CheckoutLineItem = z.infer<typeof checkoutLineItemSchema>;
|
|
70
|
-
export declare const checkoutPlanSchema: z.ZodObject<{
|
|
71
|
-
auto_renew: z.ZodBoolean;
|
|
72
|
-
display_name: z.ZodString;
|
|
73
|
-
unit_amount: z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>;
|
|
74
|
-
currency: z.ZodString;
|
|
75
|
-
unit_decimals: z.ZodNumber & z.ZodType<number, number, z.core.$ZodTypeInternals<number, number>>;
|
|
76
|
-
billing_interval_hours: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodNumber>>, z.ZodTransform<number | undefined, number | null | undefined>>>;
|
|
77
|
-
access_duration_hours: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodNumber>>, z.ZodTransform<number | undefined, number | null | undefined>>>;
|
|
78
|
-
}, z.core.$strip>;
|
|
79
|
-
export type CheckoutPlan = z.infer<typeof checkoutPlanSchema>;
|
|
80
|
-
export declare const checkoutSessionSchema: z.ZodObject<{
|
|
81
|
-
id: z.ZodString;
|
|
82
|
-
status: z.ZodEnum<{
|
|
83
|
-
created: "created";
|
|
84
|
-
requires_action: "requires_action";
|
|
85
|
-
processing: "processing";
|
|
86
|
-
succeeded: "succeeded";
|
|
87
|
-
failed: "failed";
|
|
88
|
-
blocked: "blocked";
|
|
89
|
-
expired: "expired";
|
|
90
|
-
canceled: "canceled";
|
|
91
|
-
}>;
|
|
92
|
-
merchant: z.ZodObject<{
|
|
93
|
-
display_name: z.ZodString;
|
|
94
|
-
}, z.core.$strip>;
|
|
95
|
-
plan: z.ZodObject<{
|
|
96
|
-
auto_renew: z.ZodBoolean;
|
|
97
|
-
display_name: z.ZodString;
|
|
98
|
-
unit_amount: z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>;
|
|
99
|
-
currency: z.ZodString;
|
|
100
|
-
unit_decimals: z.ZodNumber & z.ZodType<number, number, z.core.$ZodTypeInternals<number, number>>;
|
|
101
|
-
billing_interval_hours: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodNumber>>, z.ZodTransform<number | undefined, number | null | undefined>>>;
|
|
102
|
-
access_duration_hours: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodNumber>>, z.ZodTransform<number | undefined, number | null | undefined>>>;
|
|
103
|
-
}, z.core.$strip>;
|
|
104
|
-
line_items: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
105
|
-
label: z.ZodString;
|
|
106
|
-
sublabel: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | undefined, string | null | undefined>>>;
|
|
107
|
-
amount: z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>;
|
|
108
|
-
}, z.core.$strip>>>>, z.ZodTransform<{
|
|
109
|
-
label: string;
|
|
110
|
-
amount: string;
|
|
111
|
-
sublabel?: string | undefined;
|
|
112
|
-
}[] | undefined, {
|
|
113
|
-
label: string;
|
|
114
|
-
amount: string;
|
|
115
|
-
sublabel?: string | undefined;
|
|
116
|
-
}[] | null | undefined>>>;
|
|
117
|
-
tax: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>>>, z.ZodTransform<string | undefined, string | null | undefined>>>;
|
|
118
|
-
due_today: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>>>, z.ZodTransform<string | undefined, string | null | undefined>>>;
|
|
119
|
-
options: z.ZodArray<z.ZodObject<{
|
|
120
|
-
id: z.ZodString;
|
|
121
|
-
psp_id: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | undefined, string | null | undefined>>>;
|
|
122
|
-
rail: z.ZodString;
|
|
123
|
-
mode: z.ZodEnum<{
|
|
124
|
-
one_off: "one_off";
|
|
125
|
-
subscription: "subscription";
|
|
126
|
-
}>;
|
|
127
|
-
driver: z.ZodEnum<{
|
|
128
|
-
collect_js: "collect_js";
|
|
129
|
-
card: "card";
|
|
130
|
-
stripe_elements: "stripe_elements";
|
|
131
|
-
redirect: "redirect";
|
|
132
|
-
solana_pay: "solana_pay";
|
|
133
|
-
}>;
|
|
134
|
-
psp_key: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | undefined, string | null | undefined>>>;
|
|
135
|
-
public_config: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodString>>>, z.ZodTransform<Record<string, string> | undefined, Record<string, string> | null | undefined>>>;
|
|
136
|
-
}, z.core.$strip>>;
|
|
137
|
-
saved_methods: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
138
|
-
id: z.ZodString;
|
|
139
|
-
option_id: z.ZodString;
|
|
140
|
-
rail: z.ZodString;
|
|
141
|
-
card: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
142
|
-
brand: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
143
|
-
last4: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
144
|
-
exp_month: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
145
|
-
exp_year: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
146
|
-
}, z.core.$strip>>>;
|
|
147
|
-
}, z.core.$strip>>>>, z.ZodTransform<{
|
|
148
|
-
id: string;
|
|
149
|
-
option_id: string;
|
|
150
|
-
rail: string;
|
|
151
|
-
card?: {
|
|
152
|
-
brand?: string | null | undefined;
|
|
153
|
-
last4?: string | null | undefined;
|
|
154
|
-
exp_month?: number | null | undefined;
|
|
155
|
-
exp_year?: number | null | undefined;
|
|
156
|
-
} | null | undefined;
|
|
157
|
-
}[] | undefined, {
|
|
158
|
-
id: string;
|
|
159
|
-
option_id: string;
|
|
160
|
-
rail: string;
|
|
161
|
-
card?: {
|
|
162
|
-
brand?: string | null | undefined;
|
|
163
|
-
last4?: string | null | undefined;
|
|
164
|
-
exp_month?: number | null | undefined;
|
|
165
|
-
exp_year?: number | null | undefined;
|
|
166
|
-
} | null | undefined;
|
|
167
|
-
}[] | null | undefined>>>;
|
|
168
|
-
next_action: z.ZodOptional<z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
169
|
-
type: z.ZodLiteral<"redirect_to_url">;
|
|
170
|
-
url: z.ZodString;
|
|
171
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
172
|
-
type: z.ZodLiteral<"solana_pay">;
|
|
173
|
-
url: z.ZodString;
|
|
174
|
-
}, z.core.$strip>], "type">>>;
|
|
175
|
-
payment_id: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | undefined, string | null | undefined>>>;
|
|
176
|
-
subscription_id: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | undefined, string | null | undefined>>>;
|
|
177
|
-
failure_message: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | undefined, string | null | undefined>>>;
|
|
178
|
-
failure: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
179
|
-
reason: z.ZodString;
|
|
180
|
-
message: z.ZodString;
|
|
181
|
-
field: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
182
|
-
}, z.core.$strip>>>;
|
|
183
|
-
operation: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
184
|
-
id: z.ZodString;
|
|
185
|
-
status: z.ZodString;
|
|
186
|
-
}, z.core.$strip>>>;
|
|
187
|
-
success_url: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | undefined, string | null | undefined>>>;
|
|
188
|
-
embed_origin: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | undefined, string | null | undefined>>>;
|
|
189
|
-
expires_at: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | undefined, string | null | undefined>>>;
|
|
190
|
-
}, z.core.$strip>;
|
|
191
|
-
export type CheckoutSession = z.infer<typeof checkoutSessionSchema>;
|
|
192
|
-
export declare const payRequestSchema: z.ZodObject<{
|
|
193
|
-
option_id: z.ZodString;
|
|
194
|
-
payment_token: z.ZodOptional<z.ZodString>;
|
|
195
|
-
payment_method_id: z.ZodOptional<z.ZodString>;
|
|
196
|
-
card: z.ZodOptional<z.ZodObject<{
|
|
197
|
-
number: z.ZodString;
|
|
198
|
-
exp_month: z.ZodNumber;
|
|
199
|
-
exp_year: z.ZodNumber;
|
|
200
|
-
cvc: z.ZodString;
|
|
201
|
-
}, z.core.$strip>>;
|
|
202
|
-
billing_details: z.ZodOptional<z.ZodObject<{
|
|
203
|
-
name: z.ZodOptional<z.ZodString>;
|
|
204
|
-
email: z.ZodOptional<z.ZodString>;
|
|
205
|
-
phone: z.ZodOptional<z.ZodString>;
|
|
206
|
-
address: z.ZodOptional<z.ZodObject<{
|
|
207
|
-
line1: z.ZodOptional<z.ZodString>;
|
|
208
|
-
line2: z.ZodOptional<z.ZodString>;
|
|
209
|
-
city: z.ZodOptional<z.ZodString>;
|
|
210
|
-
state: z.ZodOptional<z.ZodString>;
|
|
211
|
-
postal_code: z.ZodOptional<z.ZodString>;
|
|
212
|
-
country: z.ZodOptional<z.ZodString>;
|
|
213
|
-
}, z.core.$strip>>;
|
|
214
|
-
}, z.core.$strip>>;
|
|
215
|
-
token_symbol: z.ZodOptional<z.ZodString>;
|
|
216
|
-
}, z.core.$strip>;
|
|
217
|
-
export type PayRequest = z.infer<typeof payRequestSchema>;
|
|
218
|
-
export declare const payResultSchema: z.ZodObject<{
|
|
219
|
-
status: z.ZodEnum<{
|
|
220
|
-
created: "created";
|
|
221
|
-
requires_action: "requires_action";
|
|
222
|
-
processing: "processing";
|
|
223
|
-
succeeded: "succeeded";
|
|
224
|
-
failed: "failed";
|
|
225
|
-
blocked: "blocked";
|
|
226
|
-
expired: "expired";
|
|
227
|
-
canceled: "canceled";
|
|
228
|
-
}>;
|
|
229
|
-
next_action: z.ZodOptional<z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
230
|
-
type: z.ZodLiteral<"redirect_to_url">;
|
|
231
|
-
url: z.ZodString;
|
|
232
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
233
|
-
type: z.ZodLiteral<"solana_pay">;
|
|
234
|
-
url: z.ZodString;
|
|
235
|
-
}, z.core.$strip>], "type">>>;
|
|
236
|
-
operation: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
237
|
-
id: z.ZodString;
|
|
238
|
-
status: z.ZodString;
|
|
239
|
-
}, z.core.$strip>>>;
|
|
240
|
-
payment_id: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | undefined, string | null | undefined>>>;
|
|
241
|
-
subscription_id: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | undefined, string | null | undefined>>>;
|
|
242
|
-
failure_message: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | undefined, string | null | undefined>>>;
|
|
243
|
-
failure: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
244
|
-
reason: z.ZodString;
|
|
245
|
-
message: z.ZodString;
|
|
246
|
-
field: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
247
|
-
}, z.core.$strip>>>;
|
|
248
|
-
}, z.core.$strip>;
|
|
249
|
-
export type PayResult = z.infer<typeof payResultSchema>;
|
|
250
|
-
export type CheckoutPhase = "loading" | "ready" | "processing" | "succeeded" | "failed" | "blocked" | "expired" | "unavailable" | "error";
|
|
1
|
+
export interface SavedPaymentMethod {
|
|
2
|
+
id: string;
|
|
3
|
+
/** The PSP that holds the card. */
|
|
4
|
+
psp_id: string;
|
|
5
|
+
rail: string;
|
|
6
|
+
card?: {
|
|
7
|
+
brand?: string | null;
|
|
8
|
+
last4?: string | null;
|
|
9
|
+
exp_month?: number | null;
|
|
10
|
+
exp_year?: number | null;
|
|
11
|
+
} | null;
|
|
12
|
+
}
|
|
@@ -1,46 +1,23 @@
|
|
|
1
1
|
# Payment form contract
|
|
2
2
|
|
|
3
|
-
`
|
|
4
|
-
native submit event. Every host-owned billing field has a stable `id`,
|
|
5
|
-
label, and standards-based autocomplete token.
|
|
3
|
+
`OrderCheckout` renders one real `<form autocomplete="on">` and submits through
|
|
4
|
+
its native submit event. Every host-owned billing field has a stable `id`,
|
|
5
|
+
`name`, label, and standards-based autocomplete token.
|
|
6
6
|
|
|
7
7
|
## Money
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
`
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"display_name": "Premium Membership",
|
|
17
|
-
"unit_amount": "99000000",
|
|
18
|
-
"currency": "USD",
|
|
19
|
-
"unit_decimals": 6,
|
|
20
|
-
"auto_renew": true,
|
|
21
|
-
"billing_interval_hours": 720,
|
|
22
|
-
"access_duration_hours": 720
|
|
23
|
-
},
|
|
24
|
-
"line_items": [{ "label": "Premium Membership", "amount": "99000000" }],
|
|
25
|
-
"tax": "0",
|
|
26
|
-
"due_today": "99000000"
|
|
27
|
-
}
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
`unit_amount`, `line_items[].amount`, `tax` and `due_today` share the plan's
|
|
31
|
-
currency and scale. A JSON number, a decimal point, a value outside int64, or
|
|
32
|
-
a missing `unit_decimals` fails schema validation and the session is
|
|
33
|
-
unavailable; the package never assumes a scale. Hosts take the scale from
|
|
34
|
-
OpenRails' currency registry (`billing.LookupCurrency`, the same table as
|
|
35
|
-
the `currencies` of `GET /v1/config`); OpenRails serves the session at
|
|
36
|
-
`GET /v1/checkout-sessions/{id}`; its canonical fixture
|
|
37
|
-
(`testdata/wire/checkout_session.json`) is decoded by this package's tests.
|
|
9
|
+
An order (`GET /billing/v1/me/orders/{id}`) carries every amount as an exact
|
|
10
|
+
int64 decimal string of its `currency`'s native unit: `total`, each line's
|
|
11
|
+
`unit_amount` and `amount`, and a usage order's `amount_paid` and
|
|
12
|
+
`amount_due`. A JSON number, a decimal point or a value outside int64 fails
|
|
13
|
+
schema validation; the package never assumes a scale. It takes the scale from
|
|
14
|
+
OpenRails' currency registry (`billing.LookupCurrency`, the `currencies` of
|
|
15
|
+
`GET /v1/config`).
|
|
38
16
|
|
|
39
17
|
Rendering scales with `BigInt` and hands Intl the exact major-unit decimal;
|
|
40
18
|
`formatAmount`, `amountToDecimal` and `addAmounts` are exported for hosts that
|
|
41
19
|
show the same figures outside the component. An amount the engine cannot show
|
|
42
|
-
exactly is refused with a visible notice, never rounded.
|
|
43
|
-
absent, is the exact sum of the line items and `tax`.
|
|
20
|
+
exactly is refused with a visible notice, never rounded.
|
|
44
21
|
|
|
45
22
|
## NMI new cards
|
|
46
23
|
|
|
@@ -64,60 +41,40 @@ and the outer host page provides stable labelled containers. Verify saved-card
|
|
|
64
41
|
autofill against the real gateway in each supported browser because a DOM unit
|
|
65
42
|
test cannot inspect or control the cross-origin fields.
|
|
66
43
|
|
|
67
|
-
A PSP that takes cards on OpenRails itself (`card_entry: server
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
request carries `card: {number, exp_month, exp_year, cvc}` in place of
|
|
71
|
-
`payment_token`; the inputs are cleared once the card is sent.
|
|
44
|
+
A PSP that takes cards on OpenRails itself (`card_entry: server`) takes no
|
|
45
|
+
card on an order: `OrderCheckout` offers it for saved cards only, and the card
|
|
46
|
+
is saved first (`SavePaymentMethod`).
|
|
72
47
|
|
|
73
|
-
A new-card payment
|
|
48
|
+
A new-card payment sends the one-time `token` and its `psp_id` plus
|
|
74
49
|
`billing_details`: `name`, and `address` with the uppercase ISO `country` and
|
|
75
|
-
`postal_code`. Paying with an
|
|
76
|
-
|
|
77
|
-
|
|
50
|
+
`postal_code`. Paying with an existing saved card sends only
|
|
51
|
+
`payment_method_id`; it does not overwrite the stored billing identity with
|
|
52
|
+
empty form values.
|
|
78
53
|
|
|
79
54
|
The package never shows separate first- and last-name inputs; OpenRails
|
|
80
55
|
projects the one name onto provider-specific fields at the rail boundary.
|
|
81
56
|
|
|
82
57
|
## Card subscriptions
|
|
83
58
|
|
|
84
|
-
|
|
85
|
-
`payment_method_id`) saves a new card
|
|
86
|
-
|
|
59
|
+
Subscribing is one action: paying the order with a `token` (or a
|
|
60
|
+
`payment_method_id`) charges and saves a new card and starts the subscription.
|
|
61
|
+
A decline answers `402` with the order open again and keeps no card.
|
|
87
62
|
|
|
88
63
|
## Solana Pay
|
|
89
64
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
(`USDC`, `USD1`, …). It is sent back verbatim (uppercased) as the pay
|
|
95
|
-
request's `token_symbol`. An option without it is not offered at all.
|
|
96
|
-
- `token_name` — optional buyer-facing name (`USD Coin`), shown next to the
|
|
97
|
-
symbol in the method list.
|
|
98
|
-
- `network` — optional Solana cluster (`mainnet-beta`, `devnet`, `testnet`).
|
|
99
|
-
Any network other than `mainnet-beta` is named in the method hint
|
|
100
|
-
(“USD Coin (USDC) on Solana devnet”) so a test-network payment is never
|
|
101
|
-
mistaken for a real one.
|
|
65
|
+
A Solana payment option takes a token from `GET /v1/me/config`'s
|
|
66
|
+
`payment.solana.tokens`; the pay sends its `token_symbol`. The order answers a
|
|
67
|
+
`solana_pay` next action whose `url` the package shows as a QR code and a
|
|
68
|
+
wallet link, and it confirms the order until the transfer lands.
|
|
102
69
|
|
|
103
70
|
## Pending payment outcomes
|
|
104
71
|
|
|
105
|
-
`processing` means an accepted outcome is unresolved
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
a fresh card token and payment. Tokenization/field validation errors before
|
|
112
|
-
submission remain editable. Explicit `failed` results are definitive host
|
|
113
|
-
responses; they must not represent an unknown provider result.
|
|
114
|
-
|
|
115
|
-
A checkout source reads and pays the OpenRails session; `getSession` is a
|
|
116
|
-
read, never another payment. With the session id alone (the shared payment
|
|
117
|
-
page) it sends no bearer, so it pays with a new card only. `<BuyButton>` pays
|
|
118
|
-
as the signed-in customer through the customer surface, at
|
|
119
|
-
`/billing/v1/me/checkout-sessions/{id}` with the client's credential, so saved
|
|
120
|
-
cards pay too.
|
|
72
|
+
`processing` means an accepted outcome is unresolved; `onSettled` reports it,
|
|
73
|
+
and the host waits for the verified terminal state (the order read again, or
|
|
74
|
+
its host event) rather than inferring payment from navigation or a timeout.
|
|
75
|
+
Each pay sends one Idempotency-Key, minted when the button renders: a retry of
|
|
76
|
+
the same request answers what the first did. A refusal or an error shows its
|
|
77
|
+
message, and the next pay is a new attempt under a new key.
|
|
121
78
|
|
|
122
79
|
## Separate NMI card setup
|
|
123
80
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openrails/billing-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.238.0",
|
|
4
4
|
"description": "Embeddable OpenRails checkout and account-billing UI: client, React hooks and styled components.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -105,7 +105,6 @@
|
|
|
105
105
|
"typecheck": "tsc --noEmit",
|
|
106
106
|
"lint": "eslint .",
|
|
107
107
|
"test": "vitest run",
|
|
108
|
-
"test:browser": "playwright test",
|
|
109
108
|
"test:e2e": "playwright test -c playwright.e2e.config.ts",
|
|
110
109
|
"contract": "cd ../.. && go run ./scripts/contracts -write",
|
|
111
110
|
"contract:check": "cd ../.. && go run ./scripts/contracts",
|
package/dist/checkout-frame.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { CheckoutFrameTheme } from './frame';
|
|
2
|
-
import { CheckoutSessionStatus } from './types';
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
export interface CheckoutFrameProps {
|
|
5
|
-
/** The minted session's `url` (createCheckoutSession). */
|
|
6
|
-
url: string;
|
|
7
|
-
onComplete?: (status: CheckoutSessionStatus) => void;
|
|
8
|
-
/** Default "auto": the buyer's system preference. */
|
|
9
|
-
theme?: CheckoutFrameTheme;
|
|
10
|
-
/** Accessible name of the frame. */
|
|
11
|
-
title?: string;
|
|
12
|
-
/** Height before the page reports its own, in pixels. Default 480. */
|
|
13
|
-
minHeight?: number;
|
|
14
|
-
className?: string;
|
|
15
|
-
style?: React.CSSProperties;
|
|
16
|
-
}
|
|
17
|
-
export declare function CheckoutFrame({ url, onComplete, theme, title, minHeight, className, style, }: CheckoutFrameProps): React.JSX.Element | null;
|
package/dist/checkout-page.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { CheckoutAppearance } from './appearance';
|
|
2
|
-
import { CheckoutLayout } from './checkout';
|
|
3
|
-
import { BillingClient } from './client/client';
|
|
4
|
-
import * as React from "react";
|
|
5
|
-
export interface CheckoutPageProps {
|
|
6
|
-
/** OpenRails mount on this host. Default "/billing/v1". */
|
|
7
|
-
baseUrl?: string;
|
|
8
|
-
/** Replaces the client built from `baseUrl`. */
|
|
9
|
-
client?: BillingClient;
|
|
10
|
-
/**
|
|
11
|
-
* Pay as the signed-in customer on this customer surface (its `/me`
|
|
12
|
-
* prefix) instead of with the session id alone; see `checkoutSource`.
|
|
13
|
-
*/
|
|
14
|
-
customerBase?: string;
|
|
15
|
-
/** This host's branding; the framing app chooses the theme. */
|
|
16
|
-
appearance?: CheckoutAppearance;
|
|
17
|
-
layout?: CheckoutLayout;
|
|
18
|
-
defaultCountry?: string;
|
|
19
|
-
className?: string;
|
|
20
|
-
}
|
|
21
|
-
export declare function CheckoutPage({ baseUrl, client, customerBase, appearance, layout, defaultCountry, className, }: CheckoutPageProps): React.JSX.Element;
|
package/dist/checkout.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { CheckoutAppearance } from './appearance';
|
|
2
|
-
import { CheckoutSource } from './source';
|
|
3
|
-
import { CheckoutPhase, PayResult } from './types';
|
|
4
|
-
import * as React from "react";
|
|
5
|
-
export type CheckoutLayout = "auto" | "wide" | "compact";
|
|
6
|
-
export interface CheckoutProps {
|
|
7
|
-
source: CheckoutSource;
|
|
8
|
-
appearance?: CheckoutAppearance;
|
|
9
|
-
layout?: CheckoutLayout;
|
|
10
|
-
/** Billing country to preselect; default: the browser locale's region. */
|
|
11
|
-
defaultCountry?: string;
|
|
12
|
-
onComplete?: (result: PayResult) => void;
|
|
13
|
-
/**
|
|
14
|
-
* Leaves for a redirect rail's page. Default: navigate the top window,
|
|
15
|
-
* which a nested frame may not do; <CheckoutPage> asks its app instead.
|
|
16
|
-
*/
|
|
17
|
-
onRedirect?: (url: string) => void;
|
|
18
|
-
onPhaseChange?: (phase: CheckoutPhase) => void;
|
|
19
|
-
completionMode?: "embedded" | "redirect";
|
|
20
|
-
className?: string;
|
|
21
|
-
}
|
|
22
|
-
export declare function Checkout({ source, appearance, layout, defaultCountry, onComplete, onRedirect, onPhaseChange, completionMode, className, }: CheckoutProps): React.JSX.Element;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { CheckoutSource } from '../source';
|
|
2
|
-
import { CheckoutSessionLink } from './types';
|
|
3
|
-
export interface CheckoutSourceOptions {
|
|
4
|
-
/**
|
|
5
|
-
* A customer surface's base: its `/me` prefix, such as `/billing/v1/me` or
|
|
6
|
-
* a host's own `/api/v1/merchants/acme/billing/me`. The session is read and
|
|
7
|
-
* paid there with this client's credential, which proves the session's
|
|
8
|
-
* customer, so its saved cards pay. Default: the session id alone, at
|
|
9
|
-
* `{baseUrl}/checkout-sessions`.
|
|
10
|
-
*/
|
|
11
|
-
customerBase?: string;
|
|
12
|
-
}
|
|
13
|
-
export interface CheckoutCalls {
|
|
14
|
-
createCheckoutSession(input: {
|
|
15
|
-
priceKey?: string;
|
|
16
|
-
productKey?: string;
|
|
17
|
-
priceId?: string;
|
|
18
|
-
/** Customer-selected deposit in the price currency's native units. */
|
|
19
|
-
amount?: string;
|
|
20
|
-
/** Defaults to true for recurring prices; false buys the initial term only. */
|
|
21
|
-
autoRenew?: boolean;
|
|
22
|
-
successUrl?: string;
|
|
23
|
-
}): Promise<CheckoutSessionLink>;
|
|
24
|
-
checkoutSource(sessionId: string, opts?: CheckoutSourceOptions): CheckoutSource;
|
|
25
|
-
}
|
|
26
|
-
export declare function registerCheckout(client: object, checkout: CheckoutCalls): void;
|
|
27
|
-
/** The checkout calls of a client from createBillingClient. */
|
|
28
|
-
export declare function checkoutOf(client: object): CheckoutCalls;
|