Skip to content

Commit

Permalink
Add license activate, validate and deactivate
Browse files Browse the repository at this point in the history
Added `licenses` endpoint to the API. This endpoint allows to activate,
validate and deactivate licenses.

See https://docs.lemonsqueezy.com/help/licensing/license-api
  • Loading branch information
igolaizola committed Jan 12, 2024
1 parent d66aeba commit 9df148f
Show file tree
Hide file tree
Showing 5 changed files with 407 additions and 0 deletions.
2 changes: 2 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type Client struct {
Checkouts *CheckoutsService
LicenseKeys *LicenseKeysService
LicenseKeyInstances *LicenseKeyInstancesService
Licenses *LicensesService
}

// New creates and returns a new Client from a slice of Option.
Expand Down Expand Up @@ -73,6 +74,7 @@ func New(options ...Option) *Client {
client.Checkouts = (*CheckoutsService)(&client.common)
client.LicenseKeys = (*LicenseKeysService)(&client.common)
client.LicenseKeyInstances = (*LicenseKeyInstancesService)(&client.common)
client.Licenses = (*LicensesService)(&client.common)

return client
}
Expand Down
104 changes: 104 additions & 0 deletions internal/stubs/licenses.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package stubs

// LicenseActivateResponse is a dummy response to the POST /v1/licenses/activate endpoint
func LicenseActivateResponse() []byte {
return []byte(`
{
"activated": true,
"error": null,
"license_key": {
"id": 1,
"status": "active",
"key": "38b1460a-5104-4067-a91d-77b872934d51",
"activation_limit": 1,
"activation_usage": 5,
"created_at": "2021-01-24T14:15:07.000000Z",
"expires_at": null
},
"instance": {
"id": "47596ad9-a811-4ebf-ac8a-03fc7b6d2a17",
"name": "Test",
"created_at": "2021-04-06T14:15:07.000000Z"
},
"meta": {
"store_id": 1,
"order_id": 2,
"order_item_id": 3,
"product_id": 4,
"product_name": "Example Product",
"variant_id": 5,
"variant_name": "Default",
"customer_id": 6,
"customer_name": "Luke Skywalker",
"customer_email": "[email protected]"
}
}
`)
}

// LicenseValidateResponse is a dummy response to the POST /v1/licenses/validate endpoint
func LicenseValidateResponse() []byte {
return []byte(`
{
"valid": true,
"error": null,
"license_key": {
"id": 1,
"status": "active",
"key": "38b1460a-5104-4067-a91d-77b872934d51",
"activation_limit": 1,
"activation_usage": 5,
"created_at": "2021-01-24T14:15:07.000000Z",
"expires_at": "2022-01-24T14:15:07.000000Z"
},
"instance": {
"id": "f90ec370-fd83-46a5-8bbd-44a241e78665",
"name": "Test",
"created_at": "2021-02-24T14:15:07.000000Z"
},
"meta": {
"store_id": 1,
"order_id": 2,
"order_item_id": 3,
"product_id": 4,
"product_name": "Example Product",
"variant_id": 5,
"variant_name": "Default",
"customer_id": 6,
"customer_name": "Luke Skywalker",
"customer_email": "[email protected]"
}
}
`)
}

// LicenseDeactivateResponse is a dummy response to the POST /v1/licenses/deactivate endpoint
func LicenseDeactivateResponse() []byte {
return []byte(`
{
"deactivated": true,
"error": null,
"license_key": {
"id": 1,
"status": "inactive",
"key": "38b1460a-5104-4067-a91d-77b872934d51",
"activation_limit": 5,
"activation_usage": 0,
"created_at": "2021-01-24T14:15:07.000000Z",
"expires_at": null
},
"meta": {
"store_id": 1,
"order_id": 2,
"order_item_id": 3,
"product_id": 4,
"product_name": "Example Product",
"variant_id": 5,
"variant_name": "Default",
"customer_id": 6,
"customer_name": "Luke Skywalker",
"customer_email": "[email protected]"
}
}
`)
}
70 changes: 70 additions & 0 deletions licenses.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package lemonsqueezy

import "time"

type LicenseAttributes struct {
Error string `json:"error"`
LicenseKey LicenseKey `json:"license_key"`
Instance LicenseInstance `json:"instance"`
Meta LicenseMeta `json:"meta"`
}

type LicenseKey struct {
ID int `json:"id"`
Status string `json:"status"`
Key string `json:"key"`
ActivationLimit int `json:"activation_limit"`
ActivationUsage int `json:"activation_usage"`
CreatedAt time.Time `json:"created_at"`
ExpiresAt *time.Time `json:"expires_at"`
TestMode bool `json:"test_mode"`
}

type LicenseInstance struct {
ID string `json:"id"`
Name string `json:"name"`
CreatedAt time.Time `json:"created_at"`
}

type LicenseMeta struct {
StoreID int `json:"store_id"`
OrderID int `json:"order_id"`
OrderItemID int `json:"order_item_id"`
VariantID int `json:"variant_id"`
VariantName string `json:"variant_name"`
ProductID int `json:"product_id"`
ProductName string `json:"product_name"`
CustomerID int `json:"customer_id"`
CustomerName string `json:"customer_name"`
CustomerEmail string `json:"customer_email"`
}

type LicenseActivateParams struct {
LicenseKey string `json:"license_key"`
InstanceName string `json:"instance_name"`
}

type LicenseActivateApiResponse struct {
Activated bool `json:"activated"`
LicenseAttributes
}

type LicenseValidateParams struct {
LicenseKey string `json:"license_key"`
InstanceID string `json:"instance_id"`
}

type LicenseValidateApiResponse struct {
Valid bool `json:"valid"`
LicenseAttributes
}

type LicenseDeactivateParams struct {
LicenseKey string `json:"license_key"`
InstanceID string `json:"instance_id"`
}

type LicenseDeactivateApiResponse struct {
Deactivated bool `json:"deactivated"`
LicenseAttributes
}
76 changes: 76 additions & 0 deletions licenses_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package lemonsqueezy

import (
"context"
"encoding/json"
"net/http"
)

// LicensesService is the API client for the `/v1/licenses` endpoint
type LicensesService service

// Activate a license key.
//
// https://docs.lemonsqueezy.com/help/licensing/license-api
func (service *LicensesService) Activate(ctx context.Context, params *LicenseActivateParams) (*LicenseActivateApiResponse, *Response, error) {
payload := map[string]any{
"license_key": params.LicenseKey,
"instance_name": params.InstanceName,
}

response, err := service.client.do(ctx, http.MethodPost, "/v1/licenses/activate", payload)
if err != nil {
return nil, response, err
}

activation := new(LicenseActivateApiResponse)
if err = json.Unmarshal(*response.Body, activation); err != nil {
return nil, response, err
}

return activation, response, nil
}

// Validate a license key.
//
// https://docs.lemonsqueezy.com/help/licensing/license-api
func (service *LicensesService) Validate(ctx context.Context, params *LicenseValidateParams) (*LicenseValidateApiResponse, *Response, error) {
payload := map[string]any{
"license_key": params.LicenseKey,
"instance_id": params.InstanceID,
}

response, err := service.client.do(ctx, http.MethodPost, "/v1/licenses/validate", payload)
if err != nil {
return nil, response, err
}

validation := new(LicenseValidateApiResponse)
if err = json.Unmarshal(*response.Body, validation); err != nil {
return nil, response, err
}

return validation, response, nil
}

// Deactivate a license key.
//
// https://docs.lemonsqueezy.com/help/licensing/license-api
func (service *LicensesService) Deactivate(ctx context.Context, params *LicenseDeactivateParams) (*LicenseDeactivateApiResponse, *Response, error) {
payload := map[string]any{
"license_key": params.LicenseKey,
"instance_id": params.InstanceID,
}

response, err := service.client.do(ctx, http.MethodPost, "/v1/licenses/deactivate", payload)
if err != nil {
return nil, response, err
}

deactivation := new(LicenseDeactivateApiResponse)
if err = json.Unmarshal(*response.Body, deactivation); err != nil {
return nil, response, err
}

return deactivation, response, nil
}
Loading

0 comments on commit 9df148f

Please sign in to comment.