at.marque.partner.createCheckout
Schema Diff
+16 -2
Compatibility Analysis
Breaking Changes Detected
2 breaking changes, 4 non-breaking changes.
Breaking Changes (2)
- ConstraintTightened ConstraintTightened { vertex_id: "at.marque.partner.createCheckout:input.paymentMethod", sort: "knownValues", old_value: "[\"stripe\",\"nowpayments\"]", new_value: "[\"stripe\",\"paypal\",\"nowpayments\"]" }
- ConstraintTightened ConstraintTightened { vertex_id: "at.marque.partner.createCheckout:output.paymentMethod", sort: "knownValues", old_value: "[\"stripe\",\"nowpayments\"]", new_value: "[\"stripe\",\"paypal\",\"nowpayments\"]" }
Non-Breaking Changes (4)
- AddedVertex AddedVertex { vertex_id: "at.marque.partner.createCheckout:output.taxCents" }
- AddedVertex AddedVertex { vertex_id: "at.marque.partner.createCheckout:output.totalCents" }
- AddedEdge AddedEdge { src: "at.marque.partner.createCheckout:output", tgt: "at.marque.partner.createCheckout:output.taxCents", kind: "prop", name: Some("taxCents") }
- AddedEdge AddedEdge { src: "at.marque.partner.createCheckout:output", tgt: "at.marque.partner.createCheckout:output.totalCents", kind: "prop", name: Some("totalCents") }
Migration Guidance
Added Elements
AddedVertex { vertex_id: "at.marque.partner.createCheckout:output.taxCents" }AddedVertex { vertex_id: "at.marque.partner.createCheckout:output.totalCents" }
Constraint Changes
- ConstraintTightened ConstraintTightened { vertex_id: "at.marque.partner.createCheckout:output.paymentMethod", sort: "knownValues", old_value: "[\"stripe\",\"nowpayments\"]", new_value: "[\"stripe\",\"paypal\",\"nowpayments\"]" }
- ConstraintTightened ConstraintTightened { vertex_id: "at.marque.partner.createCheckout:input.paymentMethod", sort: "knownValues", old_value: "[\"stripe\",\"nowpayments\"]", new_value: "[\"stripe\",\"paypal\",\"nowpayments\"]" }
Additional Notes
- Non-breaking: AddedEdge { src: "at.marque.partner.createCheckout:output", tgt: "at.marque.partner.createCheckout:output.taxCents", kind: "prop", name: Some("taxCents") }
- Non-breaking: AddedEdge { src: "at.marque.partner.createCheckout:output", tgt: "at.marque.partner.createCheckout:output.totalCents", kind: "prop", name: Some("totalCents") }
1
1
{
2
2
"id": "at.marque.partner.createCheckout",
3
3
"defs": {
4
4
"item": {
5
5
"type": "object",
6
6
"required": [
7
7
"domain"
8
8
],
9
9
"properties": {
10
10
"years": {
11
11
"type": "integer",
12
12
"maximum": 10,
13
13
"minimum": 1,
14
14
"description": "Registration period in years. Defaults to the TLD minimum."
15
15
},
16
16
"domain": {
17
17
"type": "string",
18
18
"maxLength": 253,
19
19
"description": "Fully qualified domain name to register."
20
20
},
21
21
"autoRenew": {
22
22
"type": "boolean",
23
23
"description": "Mark the domain to auto-renew before expiry using the user's saved payment method. Defaults to false. Auto-renewal is charged separately from this order."
24
24
},
25
25
"whoisPrivacy": {
26
26
"type": "boolean",
27
27
"description": "Whether to redact the registrant's details from public WHOIS. Defaults to true (privacy on) when omitted; set false to publish the registrant's contact data. Silently ignored for TLDs that do not allow it, and for TLDs whose registry redacts WHOIS regardless (see whoisPrivacyAllowed from listPricing / checkAvailability)."
28
28
}
29
29
}
30
30
},
31
31
"main": {
32
32
"type": "procedure",
33
33
"input": {
34
34
"schema": {
35
35
"type": "object",
36
36
"required": [
37
37
"items",
38
38
"registrant",
39
39
"successUrl",
40
40
"cancelUrl"
41
41
],
42
42
"properties": {
43
43
"items": {
44
44
"type": "array",
45
45
"items": {
46
46
"ref": "#item",
47
47
"type": "ref"
48
48
},
49
49
"maxLength": 50,
50
50
"minLength": 1,
51
51
"description": "Domains to register in this order, 1 to 50. Every domain must currently be available (verify with checkAvailability first); if any is unavailable or on an unsupported TLD the whole call fails."
52
52
},
53
53
"cancelUrl": {
54
54
"type": "string",
55
55
"format": "uri",
56
56
"description": "Where the payment provider redirects if the user cancels."
57
57
},
58
58
"registrant": {
59
59
"ref": "#registrant",
60
60
"type": "ref"
61
61
},
62
62
"successUrl": {
63
63
"type": "string",
64
64
"format": "uri",
65
65
"description": "Where the payment provider redirects after successful payment. An order parameter carrying the order id is appended."
66
66
},
67
67
"paymentMethod": {
68
68
"type": "string",
69
-
"description": "Hosted payment provider. Defaults to stripe when omitted. Use nowpayments for cryptocurrency checkout.",
69
+
"description": "Hosted payment provider. Defaults to stripe when omitted. Use paypal for PayPal checkout or nowpayments for cryptocurrency checkout.",
70
70
"knownValues": [
71
71
"stripe",
72
+
"paypal",
72
73
"nowpayments"
73
74
]
74
75
}
75
76
}
76
77
},
77
78
"encoding": "application/json"
78
79
},
79
80
"errors": [
80
81
{
81
82
"name": "InvalidRequest",
82
83
"description": "The request is malformed: no items, too many items (max 50), or an item with an invalid domain."
83
84
},
84
85
{
85
86
"name": "Unavailable",
86
87
"description": "A requested domain cannot be registered: it is taken, on an unsupported TLD, or could not be verified with the registry. The message identifies the domain."
87
88
},
88
89
{
89
90
"name": "InvalidRegistrant",
90
91
"description": "The registrant is missing a required field (including state/province where the country requires it) or is missing an extra field a specific TLD mandates. The message names what is missing."
91
92
},
92
93
{
93
94
"name": "InvalidCallback",
94
95
"description": "successUrl or cancelUrl is not a valid absolute https URL."
95
96
},
96
97
{
97
98
"name": "InvalidPaymentMethod",
98
-
"description": "paymentMethod is not stripe or nowpayments."
99
+
"description": "paymentMethod is not stripe, paypal, or nowpayments."
99
100
},
100
101
{
101
102
"name": "PaymentMethodUnavailable",
102
103
"description": "The selected payment provider is not configured."
103
104
},
104
105
{
106
+
"name": "PaymentAmountTooLow",
107
+
"description": "NOWPayments was selected but the order total is below the configured crypto minimum."
108
+
},
109
+
{
105
110
"name": "PaymentProviderError",
106
111
"description": "The selected payment provider could not create a hosted checkout."
107
112
}
108
113
],
109
114
"output": {
110
115
"schema": {
111
116
"type": "object",
112
117
"required": [
113
118
"orderId",
114
119
"checkoutUrl",
115
120
"subtotalCents",
116
121
"currency",
117
122
"paymentMethod"
118
123
],
119
124
"properties": {
120
125
"orderId": {
121
126
"type": "string",
122
127
"description": "Opaque order id; pass to getOrder to poll status."
123
128
},
124
129
"currency": {
125
130
"type": "string",
126
131
"description": "ISO 4217 currency code of subtotalCents. Currently always usd."
127
132
},
133
+
"taxCents": {
134
+
"type": "integer",
135
+
"description": "Tax charged in cents. Zero when tax is calculated by the hosted provider."
136
+
},
137
+
"totalCents": {
138
+
"type": "integer",
139
+
"description": "Checkout total in cents, including tax known when the checkout is created."
140
+
},
128
141
"checkoutUrl": {
129
142
"type": "string",
130
143
"format": "uri",
131
144
"description": "Hosted checkout URL from the selected payment provider."
132
145
},
133
146
"paymentMethod": {
134
147
"type": "string",
135
148
"description": "Payment provider selected for this order.",
136
149
"knownValues": [
137
150
"stripe",
151
+
"paypal",
138
152
"nowpayments"
139
153
]
140
154
},
141
155
"subtotalCents": {
142
156
"type": "integer",
143
157
"description": "Order subtotal in cents, before provider-specific tax or conversion adjustments. The amount shown on the hosted page may be higher."
144
158
}
145
159
}
146
160
},
147
161
"encoding": "application/json"
148
162
},
149
163
"description": "Prices and validates the requested domains, ensures a registrant contact for the authenticated user, and returns a hosted checkout URL. Call this proxied through the user's PDS (atproto-proxy: did:web:marque.at#marque_registrar) with a token holding the at.marque.partnerApi permission set: the authenticated user (the JWT iss) becomes the owner of the domains and is billed by the selected payment provider. The owning DID is taken from that authenticated session, never from input. The end user completes payment on the provider's hosted page and is redirected to successUrl with an order query parameter (successUrl?order=<orderId>) on success, or to cancelUrl if they abandon. Domains are not registered until payment is confirmed; poll at.marque.partner.getOrder with the returned orderId for provisioning status, then write the at.marque.domain and at.marque.dns records into the user's repository yourself. Only new registrations are supported here (no transfers or renewals)."
150
164
},
151
165
"registrant": {
152
166
"type": "object",
153
167
"required": [
154
168
"firstName",
155
169
"lastName",
156
170
"email",
157
171
"street",
158
172
"city",
159
173
"zipcode",
160
174
"country",
161
175
"phoneCountryCode",
162
176
"phoneSubscriber"
163
177
],
164
178
"properties": {
165
179
"city": {
166
180
"type": "string",
167
181
"maxLength": 255,
168
182
"description": "City or locality."
169
183
},
170
184
"email": {
171
185
"type": "string",
172
186
"maxLength": 320,
173
187
"description": "Registrant email. Must be a real, monitored address: registries may send a verification message here, and registry/transfer notifications go to it."
174
188
},
175
189
"state": {
176
190
"type": "string",
177
191
"maxLength": 255,
178
192
"description": "State, province, or region. Required for countries that mandate one (e.g. US, CA, AU, BR); send the full name or its ISO 3166-2 code (e.g. 'California' or 'CA'). Omit for countries that do not use one."
179
193
},
180
194
"street": {
181
195
"type": "string",
182
196
"maxLength": 255,
183
197
"description": "Street address including house/building number, e.g. '123 Main St'."
184
198
},
185
199
"country": {
186
200
"type": "string",
187
201
"maxLength": 2,
188
202
"minLength": 2,
189
203
"description": "ISO 3166-1 alpha-2 country code, uppercase, e.g. US, GB, DE. Determines which address/state rules apply."
190
204
},
191
205
"zipcode": {
192
206
"type": "string",
193
207
"maxLength": 32,
194
208
"description": "Postal/ZIP code. Required even where the country's format is loose."
195
209
},
196
210
"lastName": {
197
211
"type": "string",
198
212
"maxLength": 255,
199
213
"description": "Registrant's legal family name."
200
214
},
201
215
"firstName": {
202
216
"type": "string",
203
217
"maxLength": 255,
204
218
"description": "Registrant's legal given name."
205
219
},
206
220
"taxIdType": {
207
221
"type": "string",
208
222
"maxLength": 32,
209
223
"description": "Optional. Type of the tax identifier in taxIdValue, e.g. 'vat' for an EU VAT number or a registry-specific code. Send together with taxIdValue. Some TLDs (notably several EU ccTLDs registered to an organization) require a VAT number."
210
224
},
211
225
"taxIdValue": {
212
226
"type": "string",
213
227
"maxLength": 64,
214
228
"description": "Optional. The tax identifier itself, e.g. an EU VAT number like DE123456789. Paired with taxIdType."
215
229
},
216
230
"organization": {
217
231
"type": "string",
218
232
"maxLength": 255,
219
233
"description": "Optional. If set, the domain is registered to this organization rather than an individual. Leave empty for a personal registration."
220
234
},
221
235
"phoneAreaCode": {
222
236
"type": "string",
223
237
"maxLength": 16,
224
238
"description": "Optional area/city code, for regions that use one separately from the subscriber number."
225
239
},
226
240
"passportNumber": {
227
241
"type": "string",
228
242
"maxLength": 64,
229
243
"description": "Optional. Passport or national identity document number. Required by a few ccTLDs for individual registrants."
230
244
},
231
245
"phoneSubscriber": {
232
246
"type": "string",
233
247
"maxLength": 32,
234
248
"description": "Local subscriber number, digits only. Combined with phoneCountryCode (and phoneAreaCode) to form the full phone number. Required."
235
249
},
236
250
"phoneCountryCode": {
237
251
"type": "string",
238
252
"maxLength": 8,
239
253
"description": "International calling code with a leading plus, e.g. +1 for US/CA or +44 for UK. Required."
240
254
},
241
255
"socialSecurityNumber": {
242
256
"type": "string",
243
257
"maxLength": 64,
244
258
"description": "Optional. National identification / social security number, where a TLD mandates it (e.g. certain Nordic or Latin American ccTLDs). Handle as sensitive data."
245
259
},
246
260
"companyRegistrationNumber": {
247
261
"type": "string",
248
262
"maxLength": 64,
249
263
"description": "Optional. Company/commercial register number. Required by some TLDs when registering to an organization (organization set)."
250
264
}
251
265
},
252
266
"description": "The person or organization that will own the domains (the WHOIS registrant). Marque creates one registrant contact from these fields and uses it as the registrant, admin, tech, and billing contact for every domain in this order. Collect these in the partner's UI; the end user never visits Marque. All names and addresses must be real and accurate. Most gTLDs require the registrant email to be verifiable, so a registry verification email may be sent to it after registration; an unverified address can cause some TLDs to suspend the domain until confirmed. Certain TLDs require extra fields beyond these (for example a tax/VAT or national ID); those orders fail with InvalidRegistrant naming the missing field, and are not yet supported through this endpoint."
253
267
}
254
268
},
255
269
"$type": "com.atproto.lexicon.schema",
256
270
"lexicon": 1,
257
271
"description": "Create a hosted payment checkout to register one or more domains for the calling user."
258
272
}