at.marque.partner.createCheckout

marque.at

Schema Diff

+16 -2

From

CID
bafyreighmrbtujl...
Indexed At
2026-07-30 09:24 UTC
View this version

To

CID
bafyreifnngr4inv...
Indexed At
2026-08-11 19:08 UTC
View this version

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
}

Compare Other Versions

Lexicon Garden

@