Skip to content

Commit a4fd5be

Browse files
authored
Merge pull request #18 from PaulSonOfLars/paul/add-checkout-create-options
Add support for all checkout creation options
2 parents 50bf287 + 1327a52 commit a4fd5be

16 files changed

Lines changed: 137 additions & 90 deletions

checkout.go

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,58 @@ type CheckoutApiResponse = ApiResponse[CheckoutAttributes, ApiResponseRelationsh
8787
// CheckoutsApiResponse is the api response for a list of checkout.
8888
type CheckoutsApiResponse = ApiResponseList[CheckoutAttributes, ApiResponseRelationshipsDiscount]
8989

90-
// CheckoutCreateParams are parameters for creating a checkout
91-
type CheckoutCreateParams struct {
92-
CustomPrice int `json:"custom_price"`
93-
EnabledVariants []int `json:"enabled_variants"`
94-
ButtonColor string `json:"button_color"`
95-
DiscountCode *string `json:"discount_code"`
96-
CustomData map[string]string `json:"custom_data"`
97-
ExpiresAt time.Time `json:"expires_at"`
98-
StoreID string `json:"store_id"`
99-
VariantID string `json:"variant_id"`
90+
// CheckoutCreateDataQuantity represents variant quantities when creating checkout
91+
type CheckoutCreateDataQuantity struct {
92+
VariantId int `json:"variant_id"`
93+
Quantity int `json:"quantity"`
94+
}
95+
96+
// CheckoutCreateData represents the data options for creating a checkout.
97+
type CheckoutCreateData struct {
98+
Email string `json:"email,omitempty"`
99+
Name string `json:"name,omitempty"`
100+
BillingAddressCountry string `json:"billing_address.country,omitempty"`
101+
BillingAddressZip string `json:"billing_address.zip,omitempty"`
102+
TaxNumber string `json:"tax_number,omitempty"`
103+
DiscountCode string `json:"discount_code,omitempty"`
104+
Custom map[string]any `json:"custom,omitempty"`
105+
VariantQuantities []CheckoutCreateDataQuantity `json:"variant_quantities,omitempty"`
106+
}
107+
108+
// CheckoutCreateOptions represents the checkout options for creating a checkout.
109+
//
110+
// Note: We use pointers for the boolean fields as otherwise, setting them to "false" would omit them, which would
111+
// break some of the boolean checks in the API. See: https://docs.lemonsqueezy.com/api/checkouts#create-a-checkout
112+
type CheckoutCreateOptions struct {
113+
Embed *bool `json:"embed,omitempty"`
114+
Media *bool `json:"media,omitempty"`
115+
Logo *bool `json:"logo,omitempty"`
116+
Desc *bool `json:"desc,omitempty"`
117+
Discount *bool `json:"discount,omitempty"`
118+
Dark *bool `json:"dark,omitempty"`
119+
SubscriptionPreview *bool `json:"subscription_preview,omitempty"`
120+
ButtonColor string `json:"button_color,omitempty"`
121+
}
122+
123+
// CheckoutCreateProductOptions represents product options for creating a checkout.
124+
type CheckoutCreateProductOptions struct {
125+
Name string `json:"name,omitempty"`
126+
Description string `json:"description,omitempty"`
127+
Media []string `json:"media,omitempty"`
128+
RedirectUrl string `json:"redirect_url,omitempty"`
129+
ReceiptButtonText string `json:"receipt_button_text,omitempty"`
130+
ReceiptLinkUrl string `json:"receipt_link_url,omitempty"`
131+
ReceiptThankYouNote string `json:"receipt_thank_you_note,omitempty"`
132+
EnabledVariants []int `json:"enabled_variants,omitempty"`
133+
}
134+
135+
// CheckoutCreateAttributes represents individual parameters for creating a checkout.
136+
type CheckoutCreateAttributes struct {
137+
CustomPrice *int `json:"custom_price,omitempty"`
138+
ProductOptions CheckoutCreateProductOptions `json:"product_options,omitempty"`
139+
CheckoutOptions CheckoutCreateOptions `json:"checkout_options,omitempty"`
140+
CheckoutData CheckoutCreateData `json:"checkout_data,omitempty"`
141+
Preview *bool `json:"preview,omitempty"`
142+
TestMode *bool `json:"test_mode,omitempty"`
143+
ExpiresAt *time.Time `json:"expires_at,omitempty"`
100144
}

checkouts_service.go

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"context"
55
"encoding/json"
66
"net/http"
7-
"time"
7+
"strconv"
88
)
99

1010
// CheckoutsService is the API client for the `/v1/checkouts` endpoint
@@ -13,39 +13,21 @@ type CheckoutsService service
1313
// Create a custom checkout.
1414
//
1515
// https://docs.lemonsqueezy.com/api/checkouts#create-a-checkout
16-
func (service *CheckoutsService) Create(ctx context.Context, params *CheckoutCreateParams) (*CheckoutApiResponse, *Response, error) {
17-
checkoutData := map[string]any{
18-
"custom": params.CustomData,
19-
}
20-
if params.DiscountCode != nil {
21-
checkoutData["discount_code"] = params.DiscountCode
22-
}
23-
16+
func (service *CheckoutsService) Create(ctx context.Context, storeId int, variantId int, attributes *CheckoutCreateAttributes) (*CheckoutApiResponse, *Response, error) {
2417
payload := map[string]any{
2518
"data": map[string]any{
26-
"type": "checkouts",
27-
"attributes": map[string]any{
28-
"custom_price": params.CustomPrice,
29-
"product_options": map[string]any{
30-
"enabled_variants": params.EnabledVariants,
31-
},
32-
"checkout_options": map[string]any{
33-
"button_color": params.ButtonColor,
34-
},
35-
"checkout_data": checkoutData,
36-
"expires_at": params.ExpiresAt.Format(time.RFC3339),
37-
"preview": true,
38-
},
19+
"type": "checkouts",
20+
"attributes": attributes,
3921
"relationships": map[string]any{
4022
"store": map[string]any{
4123
"data": map[string]any{
42-
"id": params.StoreID,
24+
"id": strconv.Itoa(storeId),
4325
"type": "stores",
4426
},
4527
},
4628
"variant": map[string]any{
4729
"data": map[string]any{
48-
"id": params.VariantID,
30+
"id": strconv.Itoa(variantId),
4931
"type": "variants",
5032
},
5133
},

checkouts_service_test.go

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ import (
66
"testing"
77
"time"
88

9+
"github.com/stretchr/testify/assert"
10+
911
"github.com/NdoleStudio/lemonsqueezy-go/internal/helpers"
1012
"github.com/NdoleStudio/lemonsqueezy-go/internal/stubs"
11-
"github.com/stretchr/testify/assert"
1213
)
1314

1415
func TestCheckoutService_Create(t *testing.T) {
@@ -20,14 +21,20 @@ func TestCheckoutService_Create(t *testing.T) {
2021
client := New(WithBaseURL(server.URL))
2122

2223
// Act
23-
checkout, response, err := client.Checkouts.Create(context.Background(), &CheckoutCreateParams{
24-
CustomPrice: 5000,
25-
EnabledVariants: []int{1},
26-
ButtonColor: "#2DD272",
27-
CustomData: map[string]string{"user_id": "123"},
28-
ExpiresAt: time.Now().UTC(),
29-
StoreID: "1",
30-
VariantID: "1",
24+
expireAt := time.Now().UTC()
25+
customPrice := 5000
26+
checkout, response, err := client.Checkouts.Create(context.Background(), 1, 1, &CheckoutCreateAttributes{
27+
CustomPrice: &customPrice,
28+
ProductOptions: CheckoutCreateProductOptions{
29+
EnabledVariants: []int{1},
30+
},
31+
CheckoutOptions: CheckoutCreateOptions{
32+
ButtonColor: "2DD272",
33+
},
34+
CheckoutData: CheckoutCreateData{
35+
Custom: map[string]any{"user_id": "123"},
36+
},
37+
ExpiresAt: &expireAt,
3138
})
3239

3340
// Assert
@@ -50,7 +57,7 @@ func TestCheckoutService_CreateWithError(t *testing.T) {
5057
client := New(WithBaseURL(server.URL))
5158

5259
// Act
53-
_, response, err := client.Checkouts.Create(context.Background(), &CheckoutCreateParams{})
60+
_, response, err := client.Checkouts.Create(context.Background(), 1, 1, &CheckoutCreateAttributes{})
5461

5562
// Assert
5663
assert.NotNil(t, err)

discount.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,5 @@ type DiscountCreateParams struct {
4141
Code string `json:"code"`
4242
Amount int `json:"amount"`
4343
AmountType string `json:"amountType"`
44-
StoreID string `json:"storeID"`
44+
StoreID int `json:"storeID"`
4545
}

discounts_service.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/json"
66
"net/http"
7+
"strconv"
78
)
89

910
// DiscountsService is the API client for the `/v1/discounts` endpoint
@@ -26,7 +27,7 @@ func (service *DiscountsService) Create(ctx context.Context, params *DiscountCre
2627
"store": map[string]any{
2728
"data": map[string]any{
2829
"type": "stores",
29-
"id": params.StoreID,
30+
"id": strconv.Itoa(params.StoreID),
3031
},
3132
},
3233
},

discounts_service_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ import (
55
"net/http"
66
"testing"
77

8+
"github.com/stretchr/testify/assert"
9+
810
"github.com/NdoleStudio/lemonsqueezy-go/internal/helpers"
911
"github.com/NdoleStudio/lemonsqueezy-go/internal/stubs"
10-
"github.com/stretchr/testify/assert"
1112
)
1213

1314
func TestDiscountsService_Create(t *testing.T) {
@@ -24,7 +25,7 @@ func TestDiscountsService_Create(t *testing.T) {
2425
Code: "10PERCENT",
2526
Amount: 10,
2627
AmountType: "percent",
27-
StoreID: "1",
28+
StoreID: 1,
2829
})
2930

3031
// Assert
@@ -52,7 +53,7 @@ func TestDiscountsService_CreateWithError(t *testing.T) {
5253
Code: "10PERCENT",
5354
Amount: 10,
5455
AmountType: "percent",
55-
StoreID: "1",
56+
StoreID: 1,
5657
})
5758

5859
// Assert

e2e/checkouts_service_test.go

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,42 @@ package e2e
22

33
import (
44
"context"
5-
"fmt"
65
"net/http"
6+
"strconv"
77
"testing"
88
"time"
99

10-
lemonsqueezy "github.com/NdoleStudio/lemonsqueezy-go"
1110
"github.com/stretchr/testify/assert"
11+
12+
"github.com/NdoleStudio/lemonsqueezy-go"
1213
)
1314

1415
func TestCheckoutsService_Create(t *testing.T) {
16+
storeID := 11559
17+
variantId := 36096
18+
expiresAt := time.Now().UTC().Add(time.Hour * 24)
19+
customPrice := 5000
20+
1521
// Act
16-
storeID := "11559"
17-
checkout, response, err := client.Checkouts.Create(context.Background(), &lemonsqueezy.CheckoutCreateParams{
18-
CustomPrice: 5000,
19-
EnabledVariants: []int{36096},
20-
ButtonColor: "#2DD272",
21-
CustomData: map[string]string{"user_id": "123"},
22-
ExpiresAt: time.Now().UTC().Add(time.Hour * 24),
23-
StoreID: storeID,
24-
VariantID: "36096",
22+
checkout, response, err := client.Checkouts.Create(context.Background(), storeID, variantId, &lemonsqueezy.CheckoutCreateAttributes{
23+
CustomPrice: &customPrice,
24+
ProductOptions: lemonsqueezy.CheckoutCreateProductOptions{
25+
EnabledVariants: []int{variantId},
26+
},
27+
CheckoutOptions: lemonsqueezy.CheckoutCreateOptions{
28+
ButtonColor: "#2DD272",
29+
},
30+
CheckoutData: lemonsqueezy.CheckoutCreateData{
31+
Custom: map[string]any{"user_id": "123"},
32+
},
33+
ExpiresAt: &expiresAt,
2534
})
2635

2736
// Assert
2837
assert.Nil(t, err)
2938

3039
assert.Equal(t, http.StatusCreated, response.HTTPResponse.StatusCode)
31-
assert.Equal(t, storeID, fmt.Sprintf("%d", checkout.Data.Attributes.StoreID))
40+
assert.Equal(t, storeID, strconv.Itoa(checkout.Data.Attributes.StoreID))
3241
}
3342

3443
func TestCheckoutsService_Get(t *testing.T) {

e2e/stores_service_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ func TestStoreService_Get(t *testing.T) {
1212
// Setup
1313
t.Parallel()
1414

15-
store, response, err := client.Stores.Get(context.Background(), "11559")
15+
store, response, err := client.Stores.Get(context.Background(), 11559)
1616

1717
// Assert
1818
assert.Nil(t, err)

e2e/variants_service_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212

1313
func TestVariantsService_Get(t *testing.T) {
1414
// Act
15-
variant, response, err := client.Variants.Get(context.Background(), "36095")
15+
variant, response, err := client.Variants.Get(context.Background(), 36095)
1616

1717
// Assert
1818
assert.Nil(t, err)

stores_service.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/json"
66
"net/http"
7+
"strconv"
78
)
89

910
// StoresService is the API client for the `/v1/stores` endpoint
@@ -12,8 +13,8 @@ type StoresService service
1213
// Get returns the store with the given ID.
1314
//
1415
// https://docs.lemonsqueezy.com/api/stores#retrieve-a-store
15-
func (service *StoresService) Get(ctx context.Context, storeID string) (*StoreApiResponse, *Response, error) {
16-
response, err := service.client.do(ctx, http.MethodGet, "/v1/stores/"+storeID)
16+
func (service *StoresService) Get(ctx context.Context, storeID int) (*StoreApiResponse, *Response, error) {
17+
response, err := service.client.do(ctx, http.MethodGet, "/v1/stores/"+strconv.Itoa(storeID))
1718
if err != nil {
1819
return nil, response, err
1920
}

0 commit comments

Comments
 (0)