at.marque.partner.createCheckout

marque.at

Schema Diff

+50 -7

From

CID
bafyreidxfygkw3b...
Indexed At
2026-06-16 14:49 UTC
View this version

To

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

Compatibility Analysis

Breaking Changes Detected

1 breaking change, 7 non-breaking changes.

Breaking Changes (1)
  • RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "at.marque.partner.createCheckout:output", src: "at.marque.partner.createCheckout:output", tgt: "at.marque.partner.createCheckout:output.paymentMethod", kind: "prop", name: Some("paymentMethod") }
Non-Breaking Changes (7)
  • AddedVertex AddedVertex { vertex_id: "at.marque.partner.createCheckout:input.paymentMethod" }
  • AddedVertex AddedVertex { vertex_id: "at.marque.partner.createCheckout:output.paymentMethod" }
  • 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:input", tgt: "at.marque.partner.createCheckout:input.paymentMethod", kind: "prop", name: Some("paymentMethod") }
  • 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:input.paymentMethod" }
  • AddedVertex { vertex_id: "at.marque.partner.createCheckout:output.paymentMethod" }
  • AddedVertex { vertex_id: "at.marque.partner.createCheckout:output.taxCents" }
  • AddedVertex { vertex_id: "at.marque.partner.createCheckout:output.totalCents" }

Additional Notes

  • Breaking: RequiredEdgeAdded { vertex_id: "at.marque.partner.createCheckout:output", src: "at.marque.partner.createCheckout:output", tgt: "at.marque.partner.createCheckout:output.paymentMethod", kind: "prop", name: Some("paymentMethod") }
  • Non-breaking: AddedEdge { src: "at.marque.partner.createCheckout:input", tgt: "at.marque.partner.createCheckout:input.paymentMethod", kind: "prop", name: Some("paymentMethod") }
  • 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 -
              "description": "Where Stripe redirects if the user cancels."
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 -
              "description": "Where Stripe redirects after successful payment. An order parameter carrying the order id is appended."
65 +
              "description": "Where the payment provider redirects after successful payment. An order parameter carrying the order id is appended."
66 +
            },
67 +
            "paymentMethod": {
68 +
              "type": "string",
69 +
              "description": "Hosted payment provider. Defaults to stripe when omitted. Use paypal for PayPal checkout or nowpayments for cryptocurrency checkout.",
70 +
              "knownValues": [
71 +
                "stripe",
72 +
                "paypal",
73 +
                "nowpayments"
74 +
              ]
66 75
            }
67 76
          }
68 77
        },
69 78
        "encoding": "application/json"
70 79
      },
71 80
      "errors": [
72 81
        {
73 82
          "name": "InvalidRequest",
74 83
          "description": "The request is malformed: no items, too many items (max 50), or an item with an invalid domain."
75 84
        },
76 85
        {
77 86
          "name": "Unavailable",
78 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."
79 88
        },
80 89
        {
81 90
          "name": "InvalidRegistrant",
82 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."
83 92
        },
84 93
        {
85 94
          "name": "InvalidCallback",
86 95
          "description": "successUrl or cancelUrl is not a valid absolute https URL."
96 +
        },
97 +
        {
98 +
          "name": "InvalidPaymentMethod",
99 +
          "description": "paymentMethod is not stripe, paypal, or nowpayments."
100 +
        },
101 +
        {
102 +
          "name": "PaymentMethodUnavailable",
103 +
          "description": "The selected payment provider is not configured."
104 +
        },
105 +
        {
106 +
          "name": "PaymentAmountTooLow",
107 +
          "description": "NOWPayments was selected but the order total is below the configured crypto minimum."
108 +
        },
109 +
        {
110 +
          "name": "PaymentProviderError",
111 +
          "description": "The selected payment provider could not create a hosted checkout."
87 112
        }
88 113
      ],
89 114
      "output": {
90 115
        "schema": {
91 116
          "type": "object",
92 117
          "required": [
93 118
            "orderId",
94 119
            "checkoutUrl",
95 120
            "subtotalCents",
96 -
            "currency"
121 +
            "currency",
122 +
            "paymentMethod"
97 123
          ],
98 124
          "properties": {
99 125
            "orderId": {
100 126
              "type": "string",
101 127
              "description": "Opaque order id; pass to getOrder to poll status."
102 128
            },
103 129
            "currency": {
104 130
              "type": "string",
105 131
              "description": "ISO 4217 currency code of subtotalCents. Currently always usd."
106 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 +
            },
107 141
            "checkoutUrl": {
108 142
              "type": "string",
109 143
              "format": "uri",
110 -
              "description": "Hosted Stripe Checkout URL to send the user to."
144 +
              "description": "Hosted checkout URL from the selected payment provider."
145 +
            },
146 +
            "paymentMethod": {
147 +
              "type": "string",
148 +
              "description": "Payment provider selected for this order.",
149 +
              "knownValues": [
150 +
                "stripe",
151 +
                "paypal",
152 +
                "nowpayments"
153 +
              ]
111 154
            },
112 155
            "subtotalCents": {
113 156
              "type": "integer",
114 -
              "description": "Order subtotal in cents, before tax. Tax (if any) is computed by Stripe on the hosted page and added on top, so the amount the user pays may be higher."
157 +
              "description": "Order subtotal in cents, before provider-specific tax or conversion adjustments. The amount shown on the hosted page may be higher."
115 158
            }
116 159
          }
117 160
        },
118 161
        "encoding": "application/json"
119 162
      },
120 -
      "description": "Prices and validates the requested domains, ensures a registrant contact for the authenticated user, and returns a hosted Stripe Checkout URL. Call this proxied through the user's PDS (atproto-proxy: did:web:marque.at:api#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 the one billed on Stripe. The owning DID is taken from that authenticated session, never from input. The end user completes payment on Stripe's hosted page (where they see and confirm the exact domains and amount) 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 captured; 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)."
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)."
121 164
    },
122 165
    "registrant": {
123 166
      "type": "object",
124 167
      "required": [
125 168
        "firstName",
126 169
        "lastName",
127 170
        "email",
128 171
        "street",
129 172
        "city",
130 173
        "zipcode",
131 174
        "country",
132 175
        "phoneCountryCode",
133 176
        "phoneSubscriber"
134 177
      ],
135 178
      "properties": {
136 179
        "city": {
137 180
          "type": "string",
138 181
          "maxLength": 255,
139 182
          "description": "City or locality."
140 183
        },
141 184
        "email": {
142 185
          "type": "string",
143 186
          "maxLength": 320,
144 187
          "description": "Registrant email. Must be a real, monitored address: registries may send a verification message here, and registry/transfer notifications go to it."
145 188
        },
146 189
        "state": {
147 190
          "type": "string",
148 191
          "maxLength": 255,
149 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."
150 193
        },
151 194
        "street": {
152 195
          "type": "string",
153 196
          "maxLength": 255,
154 197
          "description": "Street address including house/building number, e.g. '123 Main St'."
155 198
        },
156 199
        "country": {
157 200
          "type": "string",
158 201
          "maxLength": 2,
159 202
          "minLength": 2,
160 203
          "description": "ISO 3166-1 alpha-2 country code, uppercase, e.g. US, GB, DE. Determines which address/state rules apply."
161 204
        },
162 205
        "zipcode": {
163 206
          "type": "string",
164 207
          "maxLength": 32,
165 208
          "description": "Postal/ZIP code. Required even where the country's format is loose."
166 209
        },
167 210
        "lastName": {
168 211
          "type": "string",
169 212
          "maxLength": 255,
170 213
          "description": "Registrant's legal family name."
171 214
        },
172 215
        "firstName": {
173 216
          "type": "string",
174 217
          "maxLength": 255,
175 218
          "description": "Registrant's legal given name."
176 219
        },
177 220
        "taxIdType": {
178 221
          "type": "string",
179 222
          "maxLength": 32,
180 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."
181 224
        },
182 225
        "taxIdValue": {
183 226
          "type": "string",
184 227
          "maxLength": 64,
185 228
          "description": "Optional. The tax identifier itself, e.g. an EU VAT number like DE123456789. Paired with taxIdType."
186 229
        },
187 230
        "organization": {
188 231
          "type": "string",
189 232
          "maxLength": 255,
190 233
          "description": "Optional. If set, the domain is registered to this organization rather than an individual. Leave empty for a personal registration."
191 234
        },
192 235
        "phoneAreaCode": {
193 236
          "type": "string",
194 237
          "maxLength": 16,
195 238
          "description": "Optional area/city code, for regions that use one separately from the subscriber number."
196 239
        },
197 240
        "passportNumber": {
198 241
          "type": "string",
199 242
          "maxLength": 64,
200 243
          "description": "Optional. Passport or national identity document number. Required by a few ccTLDs for individual registrants."
201 244
        },
202 245
        "phoneSubscriber": {
203 246
          "type": "string",
204 247
          "maxLength": 32,
205 248
          "description": "Local subscriber number, digits only. Combined with phoneCountryCode (and phoneAreaCode) to form the full phone number. Required."
206 249
        },
207 250
        "phoneCountryCode": {
208 251
          "type": "string",
209 252
          "maxLength": 8,
210 253
          "description": "International calling code with a leading plus, e.g. +1 for US/CA or +44 for UK. Required."
211 254
        },
212 255
        "socialSecurityNumber": {
213 256
          "type": "string",
214 257
          "maxLength": 64,
215 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."
216 259
        },
217 260
        "companyRegistrationNumber": {
218 261
          "type": "string",
219 262
          "maxLength": 64,
220 263
          "description": "Optional. Company/commercial register number. Required by some TLDs when registering to an organization (organization set)."
221 264
        }
222 265
      },
223 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."
224 267
    }
225 268
  },
226 269
  "$type": "com.atproto.lexicon.schema",
227 270
  "lexicon": 1,
228 -
  "description": "Create a hosted Stripe Checkout session to register one or more domains for the calling user."
271 +
  "description": "Create a hosted payment checkout to register one or more domains for the calling user."
229 272
}

Compare Other Versions

Lexicon Garden

@