AtlatestRepositorysigil-lemonsqueezy
1;;; (lemonsqueezy order) - Orders, order items, and subscriptions.
2;;;
3;;; Orders are created when a customer completes a purchase.
4;;; Subscriptions represent recurring billing relationships.
5
6(define-library (lemonsqueezy order)
7 (import (sigil core)
8 (sigil dict)
9 (sigil string)
10 (sigil struct)
11 (sigil json)
12 (lemonsqueezy))
14 (export ;; Order records
15 ls-order
16 ls-order?
17 ls-order-id
18 ls-order-store-id
19 ls-order-customer-id
20 ls-order-identifier
21 ls-order-order-number
22 ls-order-user-name
23 ls-order-user-email
24 ls-order-currency
25 ls-order-subtotal
26 ls-order-discount-total
27 ls-order-tax
28 ls-order-total
29 ls-order-total-formatted
30 ls-order-status
31 ls-order-refunded
32 ls-order-test-mode
33 ls-order-created-at
34 ls-order-updated-at
36 ;; Order item records
37 ls-order-item
38 ls-order-item?
39 ls-order-item-id
40 ls-order-item-order-id
41 ls-order-item-product-id
42 ls-order-item-variant-id
43 ls-order-item-product-name
44 ls-order-item-variant-name
45 ls-order-item-price
46 ls-order-item-quantity
47 ls-order-item-created-at
48 ls-order-item-updated-at
50 ;; Subscription records
51 ls-subscription
52 ls-subscription?
53 ls-subscription-id
54 ls-subscription-store-id
55 ls-subscription-customer-id
56 ls-subscription-order-id
57 ls-subscription-product-id
58 ls-subscription-variant-id
59 ls-subscription-product-name
60 ls-subscription-variant-name
61 ls-subscription-user-name
62 ls-subscription-user-email
63 ls-subscription-status
64 ls-subscription-card-brand
65 ls-subscription-card-last-four
66 ls-subscription-trial-ends-at
67 ls-subscription-renews-at
68 ls-subscription-ends-at
69 ls-subscription-cancelled
70 ls-subscription-test-mode
71 ls-subscription-created-at
72 ls-subscription-updated-at
73 ls-subscription-urls
75 ;; Parsing
76 parse-order
77 parse-order-item
78 parse-subscription
80 ;; Order API functions
81 ls-orders
82 ls-order-get
83 ls-order-items
84 ls-order-item-get
86 ;; Subscription API functions
87 ls-subscriptions
88 ls-subscription-get
89 ls-subscription-update
90 ls-subscription-cancel)
92 (begin
94 ;; ---------------------------------------------------------------
95 ;; Records
96 ;; ---------------------------------------------------------------
98 (define-struct ls-order
99 (id)
100 (store-id default: #f)
101 (customer-id default: #f)
102 (identifier default: "")
103 (order-number default: 0)
104 (user-name default: "")
105 (user-email default: "")
106 (currency default: "USD")
107 (subtotal default: 0)
108 (discount-total default: 0)
109 (tax default: 0)
110 (total default: 0)
111 (total-formatted default: "")
112 (status default: "pending")
113 (refunded default: #f)
114 (test-mode default: #f)
115 (created-at default: #f)
116 (updated-at default: #f))
118 (define-struct ls-order-item
119 (id)
120 (order-id default: #f)
121 (product-id default: #f)
122 (variant-id default: #f)
123 (product-name default: "")
124 (variant-name default: "")
125 (price default: 0)
126 (quantity default: 1)
127 (created-at default: #f)
128 (updated-at default: #f))
130 (define-struct ls-subscription
131 (id)
132 (store-id default: #f)
133 (customer-id default: #f)
134 (order-id default: #f)
135 (product-id default: #f)
136 (variant-id default: #f)
137 (product-name default: "")
138 (variant-name default: "")
139 (user-name default: "")
140 (user-email default: "")
141 (status default: "active")
142 (card-brand default: #f)
143 (card-last-four default: #f)
144 (trial-ends-at default: #f)
145 (renews-at default: #f)
146 (ends-at default: #f)
147 (cancelled default: #f)
148 (test-mode default: #f)
149 (created-at default: #f)
150 (updated-at default: #f)
151 (urls default: #{}))
153 ;; ---------------------------------------------------------------
154 ;; Parsing
155 ;; ---------------------------------------------------------------
157 ;;; Parse a JSON:API order resource into an ls-order record.
158 (define (parse-order resource)
159 (ls-order
160 id: (jsonapi-id resource)
161 store-id: (jsonapi-attr resource store_id: #f)
162 customer-id: (jsonapi-attr resource customer_id: #f)
163 identifier: (jsonapi-attr resource identifier: "")
164 order-number: (jsonapi-attr resource order_number: 0)
165 user-name: (jsonapi-attr resource user_name: "")
166 user-email: (jsonapi-attr resource user_email: "")
167 currency: (jsonapi-attr resource currency: "USD")
168 subtotal: (jsonapi-attr resource subtotal: 0)
169 discount-total: (jsonapi-attr resource discount_total: 0)
170 tax: (jsonapi-attr resource tax: 0)
171 total: (jsonapi-attr resource total: 0)
172 total-formatted: (jsonapi-attr resource total_formatted: "")
173 status: (jsonapi-attr resource status: "pending")
174 refunded: (jsonapi-attr resource refunded: #f)
175 test-mode: (jsonapi-attr resource test_mode: #f)
176 created-at: (jsonapi-attr resource created_at: #f)
177 updated-at: (jsonapi-attr resource updated_at: #f)))
179 ;;; Parse a JSON:API order item resource into an ls-order-item record.
180 (define (parse-order-item resource)
181 (ls-order-item
182 id: (jsonapi-id resource)
183 order-id: (jsonapi-attr resource order_id: #f)
184 product-id: (jsonapi-attr resource product_id: #f)
185 variant-id: (jsonapi-attr resource variant_id: #f)
186 product-name: (jsonapi-attr resource product_name: "")
187 variant-name: (jsonapi-attr resource variant_name: "")
188 price: (jsonapi-attr resource price: 0)
189 quantity: (jsonapi-attr resource quantity: 1)
190 created-at: (jsonapi-attr resource created_at: #f)
191 updated-at: (jsonapi-attr resource updated_at: #f)))
193 ;;; Parse a JSON:API subscription resource into an ls-subscription record.
194 (define (parse-subscription resource)
195 (ls-subscription
196 id: (jsonapi-id resource)
197 store-id: (jsonapi-attr resource store_id: #f)
198 customer-id: (jsonapi-attr resource customer_id: #f)
199 order-id: (jsonapi-attr resource order_id: #f)
200 product-id: (jsonapi-attr resource product_id: #f)
201 variant-id: (jsonapi-attr resource variant_id: #f)
202 product-name: (jsonapi-attr resource product_name: "")
203 variant-name: (jsonapi-attr resource variant_name: "")
204 user-name: (jsonapi-attr resource user_name: "")
205 user-email: (jsonapi-attr resource user_email: "")
206 status: (jsonapi-attr resource status: "active")
207 card-brand: (jsonapi-attr resource card_brand: #f)
208 card-last-four: (jsonapi-attr resource card_last_four: #f)
209 trial-ends-at: (jsonapi-attr resource trial_ends_at: #f)
210 renews-at: (jsonapi-attr resource renews_at: #f)
211 ends-at: (jsonapi-attr resource ends_at: #f)
212 cancelled: (jsonapi-attr resource cancelled: #f)
213 test-mode: (jsonapi-attr resource test_mode: #f)
214 created-at: (jsonapi-attr resource created_at: #f)
215 updated-at: (jsonapi-attr resource updated_at: #f)
216 urls: (let ((attrs (jsonapi-attrs resource)))
217 (dict-ref attrs urls: #{}))))
219 ;; ---------------------------------------------------------------
220 ;; Order API functions
221 ;; ---------------------------------------------------------------
223 ;;; List orders with optional filtering and pagination.
224 (define (ls-orders client . rest)
225 (apply ls-list-endpoint client parse-order '("v1" "orders") rest))
227 ;;; Get a single order by ID.
228 (define (ls-order-get client order-id)
229 (ls-get-endpoint client parse-order '("v1" "orders") order-id))
231 ;;; List order items with optional filtering.
232 (define (ls-order-items client . rest)
233 (apply ls-list-endpoint client parse-order-item '("v1" "order-items") rest))
235 ;;; Get a single order item by ID.
236 (define (ls-order-item-get client order-item-id)
237 (ls-get-endpoint client parse-order-item '("v1" "order-items") order-item-id))
239 ;; ---------------------------------------------------------------
240 ;; Subscription API functions
241 ;; ---------------------------------------------------------------
243 ;;; List subscriptions with optional filtering and pagination.
244 (define (ls-subscriptions client . rest)
245 (apply ls-list-endpoint client parse-subscription '("v1" "subscriptions") rest))
247 ;;; Get a single subscription by ID.
248 (define (ls-subscription-get client subscription-id)
249 (ls-get-endpoint client parse-subscription '("v1" "subscriptions") subscription-id))
251 ;;; Update a subscription.
252 ;;; updates is a dict of attributes to change (e.g., variant_id:, billing_anchor:).
253 ;;; Returns an ls-subscription record.
254 (define (ls-subscription-update client subscription-id updates)
255 (let* ((body #{ data:
256 #{ type: "subscriptions"
257 id: subscription-id
258 attributes: updates } })
259 (url (ls-api-url client "v1" "subscriptions" subscription-id))
260 (response (ls-patch/json client url body)))
261 (parse-subscription (jsonapi-data response))))
263 ;;; Cancel a subscription.
264 ;;; Sets status to "cancelled"; access continues until ends_at.
265 ;;; Returns an ls-subscription record.
266 (define (ls-subscription-cancel client subscription-id)
267 (let* ((url (ls-api-url client "v1" "subscriptions" subscription-id))
268 (response (ls-delete/json client url)))
269 (if (and response (dict? response))
270 (parse-subscription (jsonapi-data response))
271 #t)))
273 ))