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: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\"]" }
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
"$type": "com.atproto.lexicon.schema",
3
3
"defs": {
4
4
"item": {
5
5
"properties": {
6
6
"autoRenew": {
7
7
"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.",
8
8
"type": "boolean"
9
9
},
10
10
"domain": {
11
11
"description": "Fully qualified domain name to register.",
12
12
"maxLength": 253,
13
13
"type": "string"
14
14
},
15
15
"whoisPrivacy": {
16
16
"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).",
17
17
"type": "boolean"
18
18
},
19
19
"years": {
20
20
"description": "Registration period in years. Defaults to the TLD minimum.",
21
21
"maximum": 10,
22
22
"minimum": 1,
23
23
"type": "integer"
24
24
}
25
25
},
26
26
"required": [
27
27
"domain"
28
28
],
29
29
"type": "object"
30
30
},
31
31
"main": {
32
32
"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).",
33
33
"errors": [
34
34
{
35
35
"description": "The request is malformed: no items, too many items (max 50), or an item with an invalid domain.",
36
36
"name": "InvalidRequest"
37
37
},
38
38
{
39
39
"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.",
40
40
"name": "Unavailable"
41
41
},
42
42
{
43
43
"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.",
44
44
"name": "InvalidRegistrant"
45
45
},
46
46
{
47
47
"description": "successUrl or cancelUrl is not a valid absolute https URL.",
48
48
"name": "InvalidCallback"
49
49
},
50
50
{
51
-
"description": "paymentMethod is not stripe or nowpayments.",
51
+
"description": "paymentMethod is not stripe, paypal, or nowpayments.",
52
52
"name": "InvalidPaymentMethod"
53
53
},
54
54
{
55
55
"description": "The selected payment provider is not configured.",
56
56
"name": "PaymentMethodUnavailable"
57
57
},
58
58
{
59
+
"description": "NOWPayments was selected but the order total is below the configured crypto minimum.",
60
+
"name": "PaymentAmountTooLow"
61
+
},
62
+
{
59
63
"description": "The selected payment provider could not create a hosted checkout.",
60
64
"name": "PaymentProviderError"
61
65
}
62
66
],
63
67
"input": {
64
68
"encoding": "application/json",
65
69
"schema": {
66
70
"properties": {
67
71
"cancelUrl": {
68
72
"description": "Where the payment provider redirects if the user cancels.",
69
73
"format": "uri",
70
74
"type": "string"
71
75
},
72
76
"items": {
73
77
"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.",
74
78
"items": {
75
79
"ref": "#item",
76
80
"type": "ref"
77
81
},
78
82
"maxLength": 50,
79
83
"minLength": 1,
80
84
"type": "array"
81
85
},
82
86
"paymentMethod": {
83
-
"description": "Hosted payment provider. Defaults to stripe when omitted. Use nowpayments for cryptocurrency checkout.",
87
+
"description": "Hosted payment provider. Defaults to stripe when omitted. Use paypal for PayPal checkout or nowpayments for cryptocurrency checkout.",
84
88
"knownValues": [
85
89
"stripe",
90
+
"paypal",
86
91
"nowpayments"
87
92
],
88
93
"type": "string"
89
94
},
90
95
"registrant": {
91
96
"ref": "#registrant",
92
97
"type": "ref"
93
98
},
94
99
"successUrl": {
95
100
"description": "Where the payment provider redirects after successful payment. An order parameter carrying the order id is appended.",
96
101
"format": "uri",
97
102
"type": "string"
98
103
}
99
104
},
100
105
"required": [
101
106
"items",
102
107
"registrant",
103
108
"successUrl",
104
109
"cancelUrl"
105
110
],
106
111
"type": "object"
107
112
}
108
113
},
109
114
"output": {
110
115
"encoding": "application/json",
111
116
"schema": {
112
117
"properties": {
113
118
"checkoutUrl": {
114
119
"description": "Hosted checkout URL from the selected payment provider.",
115
120
"format": "uri",
116
121
"type": "string"
117
122
},
118
123
"currency": {
119
124
"description": "ISO 4217 currency code of subtotalCents. Currently always usd.",
120
125
"type": "string"
121
126
},
122
127
"orderId": {
123
128
"description": "Opaque order id; pass to getOrder to poll status.",
124
129
"type": "string"
125
130
},
126
131
"paymentMethod": {
127
132
"description": "Payment provider selected for this order.",
128
133
"knownValues": [
129
134
"stripe",
135
+
"paypal",
130
136
"nowpayments"
131
137
],
132
138
"type": "string"
133
139
},
134
140
"subtotalCents": {
135
141
"description": "Order subtotal in cents, before provider-specific tax or conversion adjustments. The amount shown on the hosted page may be higher.",
136
142
"type": "integer"
143
+
},
144
+
"taxCents": {
145
+
"description": "Tax charged in cents. Zero when tax is calculated by the hosted provider.",
146
+
"type": "integer"
147
+
},
148
+
"totalCents": {
149
+
"description": "Checkout total in cents, including tax known when the checkout is created.",
150
+
"type": "integer"
137
151
}
138
152
},
139
153
"required": [
140
154
"orderId",
141
155
"checkoutUrl",
142
156
"subtotalCents",
143
157
"currency",
144
158
"paymentMethod"
145
159
],
146
160
"type": "object"
147
161
}
148
162
},
149
163
"type": "procedure"
150
164
},
151
165
"registrant": {
152
166
"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.",
153
167
"properties": {
154
168
"city": {
155
169
"description": "City or locality.",
156
170
"maxLength": 255,
157
171
"type": "string"
158
172
},
159
173
"companyRegistrationNumber": {
160
174
"description": "Optional. Company/commercial register number. Required by some TLDs when registering to an organization (organization set).",
161
175
"maxLength": 64,
162
176
"type": "string"
163
177
},
164
178
"country": {
165
179
"description": "ISO 3166-1 alpha-2 country code, uppercase, e.g. US, GB, DE. Determines which address/state rules apply.",
166
180
"maxLength": 2,
167
181
"minLength": 2,
168
182
"type": "string"
169
183
},
170
184
"email": {
171
185
"description": "Registrant email. Must be a real, monitored address: registries may send a verification message here, and registry/transfer notifications go to it.",
172
186
"maxLength": 320,
173
187
"type": "string"
174
188
},
175
189
"firstName": {
176
190
"description": "Registrant's legal given name.",
177
191
"maxLength": 255,
178
192
"type": "string"
179
193
},
180
194
"lastName": {
181
195
"description": "Registrant's legal family name.",
182
196
"maxLength": 255,
183
197
"type": "string"
184
198
},
185
199
"organization": {
186
200
"description": "Optional. If set, the domain is registered to this organization rather than an individual. Leave empty for a personal registration.",
187
201
"maxLength": 255,
188
202
"type": "string"
189
203
},
190
204
"passportNumber": {
191
205
"description": "Optional. Passport or national identity document number. Required by a few ccTLDs for individual registrants.",
192
206
"maxLength": 64,
193
207
"type": "string"
194
208
},
195
209
"phoneAreaCode": {
196
210
"description": "Optional area/city code, for regions that use one separately from the subscriber number.",
197
211
"maxLength": 16,
198
212
"type": "string"
199
213
},
200
214
"phoneCountryCode": {
201
215
"description": "International calling code with a leading plus, e.g. +1 for US/CA or +44 for UK. Required.",
202
216
"maxLength": 8,
203
217
"type": "string"
204
218
},
205
219
"phoneSubscriber": {
206
220
"description": "Local subscriber number, digits only. Combined with phoneCountryCode (and phoneAreaCode) to form the full phone number. Required.",
207
221
"maxLength": 32,
208
222
"type": "string"
209
223
},
210
224
"socialSecurityNumber": {
211
225
"description": "Optional. National identification / social security number, where a TLD mandates it (e.g. certain Nordic or Latin American ccTLDs). Handle as sensitive data.",
212
226
"maxLength": 64,
213
227
"type": "string"
214
228
},
215
229
"state": {
216
230
"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.",
217
231
"maxLength": 255,
218
232
"type": "string"
219
233
},
220
234
"street": {
221
235
"description": "Street address including house/building number, e.g. '123 Main St'.",
222
236
"maxLength": 255,
223
237
"type": "string"
224
238
},
225
239
"taxIdType": {
226
240
"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.",
227
241
"maxLength": 32,
228
242
"type": "string"
229
243
},
230
244
"taxIdValue": {
231
245
"description": "Optional. The tax identifier itself, e.g. an EU VAT number like DE123456789. Paired with taxIdType.",
232
246
"maxLength": 64,
233
247
"type": "string"
234
248
},
235
249
"zipcode": {
236
250
"description": "Postal/ZIP code. Required even where the country's format is loose.",
237
251
"maxLength": 32,
238
252
"type": "string"
239
253
}
240
254
},
241
255
"required": [
242
256
"firstName",
243
257
"lastName",
244
258
"email",
245
259
"street",
246
260
"city",
247
261
"zipcode",
248
262
"country",
249
263
"phoneCountryCode",
250
264
"phoneSubscriber"
251
265
],
252
266
"type": "object"
253
267
}
254
268
},
255
269
"description": "Create a hosted payment checkout to register one or more domains for the calling user.",
256
270
"id": "at.marque.partner.createCheckout",
257
271
"lexicon": 1
258
272
}