2024-04-16 08:42:44 +08:00

143 lines
4.0 KiB
Go

package lemonsqueezy
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"github.com/pkg/errors"
)
const (
// The base API URL for the Lemon Squeezy API.
baseAPIURL = "https://api.lemonsqueezy.com"
// The store ID for the yourselfhosted store.
// Link: https://yourselfhosted.lemonsqueezy.com
storeID = 15634
// The product ID for the subscription pro product.
// Link: https://yourselfhosted.lemonsqueezy.com/checkout/buy/d03a2696-8a8b-49c9-9e19-d425e3884fd7
subscriptionProProductID = 98995
)
type LicenseKey struct {
ID int32 `json:"id"`
Status string `json:"status"`
Key string `json:"key"`
CreatedAt string `json:"created_at"`
ExpiresAt *string `json:"updated_at"`
}
type LicenseKeyMeta struct {
StoreID int32 `json:"store_id"`
OrderID int32 `json:"order_id"`
OrderItemID int32 `json:"order_item_id"`
ProductID int32 `json:"product_id"`
ProductName string `json:"product_name"`
VariantID int32 `json:"variant_id"`
VariantName string `json:"variant_name"`
CustomerID int32 `json:"customer_id"`
CustomerName string `json:"customer_name"`
CustomerEmail string `json:"customer_email"`
}
type ValidateLicenseKeyResponse struct {
Valid bool `json:"valid"`
Error *string `json:"error"`
LicenseKey *LicenseKey `json:"license_key"`
Meta *LicenseKeyMeta `json:"meta"`
}
type ActiveLicenseKeyResponse struct {
Activated bool `json:"activated"`
Error *string `json:"error"`
LicenseKey *LicenseKey `json:"license_key"`
Meta *LicenseKeyMeta `json:"meta"`
}
func ValidateLicenseKey(licenseKey string, instanceName string) (*ValidateLicenseKeyResponse, error) {
data := map[string]string{"license_key": licenseKey}
if instanceName != "" {
data["instance_name"] = instanceName
}
payload, err := json.Marshal(data)
if err != nil {
return nil, errors.Wrap(err, "failed to marshal data")
}
req, err := http.NewRequest("POST", fmt.Sprintf("%s/v1/licenses/validate", baseAPIURL), bytes.NewBuffer(payload))
if err != nil {
return nil, errors.Wrap(err, "failed to create request")
}
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, errors.Wrap(err, "failed to do request")
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var response ValidateLicenseKeyResponse
if err := json.Unmarshal(body, &response); err != nil {
return nil, err
}
if response.Error == nil {
if response.Meta == nil {
return nil, errors.New("meta is nil")
}
if response.Meta.StoreID != storeID || response.Meta.ProductID != subscriptionProProductID {
return nil, errors.New("invalid store or product id")
}
}
return &response, nil
}
func ActiveLicenseKey(licenseKey string, instanceName string) (*ActiveLicenseKeyResponse, error) {
data := map[string]string{"license_key": licenseKey, "instance_name": instanceName}
payload, err := json.Marshal(data)
if err != nil {
return nil, errors.Wrap(err, "failed to marshal data")
}
req, err := http.NewRequest("POST", fmt.Sprintf("%s/v1/licenses/activate", baseAPIURL), bytes.NewBuffer(payload))
if err != nil {
return nil, errors.Wrap(err, "failed to create request")
}
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, errors.Wrap(err, "failed to do request")
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var response ActiveLicenseKeyResponse
if err := json.Unmarshal(body, &response); err != nil {
return nil, err
}
if response.Error == nil {
if response.Meta == nil {
return nil, errors.New("meta is nil")
}
if response.Meta.StoreID != storeID || response.Meta.ProductID != subscriptionProProductID {
return nil, errors.New("invalid store or product id")
}
}
return &response, nil
}