Compare commits

..

17 Commits

Author SHA1 Message Date
Bastian de Byl
ae0e5fc379 feat: add price, url, image, description, archived fields to Product struct
All checks were successful
Release / release (push) Successful in 24s
Extends the Product struct to include additional fields from the Snipcart
Products API response, enabling filtering of archived products and access
to product metadata like images and URLs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 19:51:24 -05:00
Bastian de Byl
914e49e9be chore: add InProgress status and document all order statuses
Added missing InProgress status constant and added comments to
document the meaning of each order status.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 16:58:43 -05:00
gitea-actions[bot]
43eed98f7c chore(release): 0.5.2 [skip ci]
## [0.5.2](https://git.debyl.io/debyltech/go-snipcart/compare/v0.5.1...v0.5.2) (2026-01-04)

### Bug Fixes

* use fedora runner label for Gitea Actions ([de552fc](de552fc8d4))
2026-01-03 22:44:41 -05:00
Bastian de Byl
de552fc8d4 fix: use fedora runner label for Gitea Actions
All checks were successful
Release / release (push) Successful in 21s
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 22:43:39 -05:00
gitea-actions[bot]
70d6955a63 chore(release): 0.5.1 [skip ci]
## [0.5.1](https://git.debyl.io/debyltech/go-snipcart/compare/v0.5.0...v0.5.1) (2026-01-03)

### Bug Fixes

* migrate semantic-release from GitHub to Gitea ([3b19919](3b1991970b))
* remove persist-credentials to allow semantic-release push ([a8646a6](a8646a6d52))
2026-01-03 17:24:30 -05:00
Bastian de Byl
a8646a6d52 fix: remove persist-credentials to allow semantic-release push
All checks were successful
Release / release (push) Successful in 23s
2026-01-03 17:24:06 -05:00
Bastian de Byl
3b1991970b fix: migrate semantic-release from GitHub to Gitea
Some checks failed
Release / release (push) Failing after 19s
- Replace @semantic-release/github with @saithodev/semantic-release-gitea
- Configure giteaUrl for git.debyl.io
- Use Gitea's automatic GITHUB_TOKEN as GITEA_TOKEN
- Set git author/committer for bot commits
2026-01-02 17:27:31 -05:00
semantic-release-bot
dd69d72adb chore(release): 0.5.0 [skip ci]
# [0.5.0](https://git.debyl.io/debyltech/go-snipcart/compare/v0.4.1...v0.5.0) (2026-01-02)

### Features

* add discount and savings fields to Order struct ([043da74](043da741fa))
2026-01-01 23:24:29 -05:00
Bastian de Byl
8bcd564447 chore: add semantic-release workflow and configuration
Some checks failed
Release / release (push) Failing after 41s
Added GitHub Actions workflow for automatic versioning and releases using semantic-release with Angular commit convention.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-03 11:11:16 -04:00
Bastian de Byl
043da741fa feat: add discount and savings fields to Order struct
Added Discount struct with comprehensive discount information and added discount-related fields (Discounts, SavedAmount, TotalRebateRate) to Order struct to expose discount data from Snipcart API.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-03 10:49:36 -04:00
Bastian de Byl
a2fdeafc3c noticket - add missing shippingAddressSameAsBilling order field 2024-11-05 18:42:03 -05:00
Bastian de Byl
5e2a2afd42 added OrderNotification, OrderNotifications, client.GetOrderNotifications 2023-09-25 13:05:05 -04:00
Bastian de Byl
d7c5fd3b74 updated helpers for Get request fix 2023-09-13 13:48:50 -04:00
Bastian de Byl
b586a3184c added TotalTaxes to Order 2023-08-11 11:29:15 -04:00
Bastian de Byl
805491571c added missing Completed field for completion date of order 2023-07-29 17:34:01 -04:00
Bastian de Byl
10a9427598 corrected CustomField.Options field to string from []string 2023-07-27 13:48:13 -04:00
Bastian de Byl
3816c67b95 added more data types to CustomField struct 2023-07-27 13:44:06 -04:00
10 changed files with 292 additions and 45 deletions

42
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,42 @@
name: Release
on:
push:
branches: [main]
permissions:
contents: write
issues: write
pull-requests: write
jobs:
release:
runs-on: fedora
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 'lts/*'
- name: Install semantic-release
run: |
npm install -g semantic-release \
@semantic-release/commit-analyzer \
@semantic-release/release-notes-generator \
@semantic-release/changelog \
@saithodev/semantic-release-gitea \
@semantic-release/git
- name: Release
env:
# Use Gitea's automatic token (requires contents: write permission above)
GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GIT_AUTHOR_NAME: gitea-actions[bot]
GIT_AUTHOR_EMAIL: gitea-actions[bot]@users.noreply.git.debyl.io
GIT_COMMITTER_NAME: gitea-actions[bot]
GIT_COMMITTER_EMAIL: gitea-actions[bot]@users.noreply.git.debyl.io
run: npx semantic-release

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
*.json
!.releaserc.json
*.sum
config/*

44
.releaserc.json Normal file
View File

@@ -0,0 +1,44 @@
{
"branches": ["main"],
"plugins": [
[
"@semantic-release/commit-analyzer",
{
"preset": "angular",
"releaseRules": [
{"message": "*#patch*", "release": "patch"},
{"message": "*#minor*", "release": "minor"},
{"message": "*#major*", "release": "major"},
{"type": "fix", "release": "patch"},
{"type": "feat", "release": "minor"},
{"type": "perf", "release": "patch"}
]
}
],
[
"@semantic-release/release-notes-generator",
{
"preset": "angular"
}
],
[
"@semantic-release/changelog",
{
"changelogFile": "CHANGELOG.md"
}
],
[
"@saithodev/semantic-release-gitea",
{
"giteaUrl": "https://git.debyl.io"
}
],
[
"@semantic-release/git",
{
"assets": ["CHANGELOG.md"],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
]
]
}

21
CHANGELOG.md Normal file
View File

@@ -0,0 +1,21 @@
## [0.5.2](https://git.debyl.io/debyltech/go-snipcart/compare/v0.5.1...v0.5.2) (2026-01-04)
### Bug Fixes
* use fedora runner label for Gitea Actions ([de552fc](https://git.debyl.io/debyltech/go-snipcart/commit/de552fc8d4c37fb5af5e93ce4f4b8ae6e8e4bfcc))
## [0.5.1](https://git.debyl.io/debyltech/go-snipcart/compare/v0.5.0...v0.5.1) (2026-01-03)
### Bug Fixes
* migrate semantic-release from GitHub to Gitea ([3b19919](https://git.debyl.io/debyltech/go-snipcart/commit/3b1991970b64ac8c983006d4cf18bc6e080d6511))
* remove persist-credentials to allow semantic-release push ([a8646a6](https://git.debyl.io/debyltech/go-snipcart/commit/a8646a6d5258435b26a052ad57136032bb949ec7))
# [0.5.0](https://git.debyl.io/debyltech/go-snipcart/compare/v0.4.1...v0.5.0) (2026-01-02)
### Features
* add discount and savings fields to Order struct ([043da74](https://git.debyl.io/debyltech/go-snipcart/commit/043da741fafd24e3fb0bddbe06880c81c1b64b1f))

31
example_get_orders_by.go Normal file
View File

@@ -0,0 +1,31 @@
package main
import (
"flag"
"log"
"github.com/debyltech/go-snipcart/snipcart"
)
func main() {
snipcartApiKey := flag.String("key", "", "Snipcart API Key")
flag.Parse()
if *snipcartApiKey == "" {
log.Fatal("missing -key flag")
}
Client := snipcart.NewClient(*snipcartApiKey)
response, err := Client.GetOrders(map[string]string{
"placedBy": "bastian@bdebyl.net",
})
if err != nil {
log.Fatal(err)
}
log.Println("no errors continuing")
for k, v := range response.Items {
log.Printf("%v: %v\n", k, v)
}
}

32
example_update_order.go Normal file
View File

@@ -0,0 +1,32 @@
package main
import (
"flag"
"log"
"github.com/debyltech/go-snipcart/snipcart"
)
func main() {
snipcartApiKey := flag.String("key", "", "Snipcart API Key")
flag.Parse()
if *snipcartApiKey == "" {
log.Fatal("missing -key flag")
}
Client := snipcart.NewClient(*snipcartApiKey)
updateOrder := snipcart.SnipcartOrderUpdate{
ShippingRateId: "b1f5a5bca34d4e9ea7a55c011b22644f;5677a809435d46cbbb5dda2485295326",
}
response, err := Client.UpdateOrder("e6e72c95-31df-4594-b9a3-8603ce3914c8", &updateOrder)
if err != nil {
log.Fatal(err)
}
for k, v := range response.Items {
log.Printf("%v: %v\n", k, v)
}
}

3
go.mod
View File

@@ -3,7 +3,6 @@ module github.com/debyltech/go-snipcart
go 1.19
require (
github.com/debyltech/go-helpers v1.1.0
github.com/debyltech/go-shippr v0.1.0
github.com/debyltech/go-helpers v1.1.1
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
)

View File

@@ -12,6 +12,8 @@ var (
orderUri = apiUri + ordersPath
productsUri = apiUri + productsPath
validationUri = apiUri + validationPath
orderNotificationPath = "notifications"
)
type Address struct {
@@ -37,6 +39,9 @@ type Client struct {
}
type CustomField struct {
Name string `json:"name"`
Value string `json:"value"`
Name string `json:"name"`
Value string `json:"value"`
Type string `json:"type,omitempty"`
Options string `json:"options,omitempty"`
Required bool `json:"required"`
}

View File

@@ -4,17 +4,18 @@ type OrderStatus string
type NotificationType string
const (
Processed OrderStatus = "Processed"
Disputed = "Disputed"
Shipped = "Shipped"
Delivered = "Delivered"
Pending = "Pending"
Cancelled = "Cancelled"
Dispatched = "Dispatched"
InProgress OrderStatus = "InProgress" // Open cart, not finalized
Pending OrderStatus = "Pending" // Waiting for payment/processing
Processed OrderStatus = "Processed" // Order completed
Disputed OrderStatus = "Disputed" // Order has dispute
Shipped OrderStatus = "Shipped" // Order shipped
Delivered OrderStatus = "Delivered" // Order delivered
Dispatched OrderStatus = "Dispatched" // Order dispatched
Cancelled OrderStatus = "Cancelled" // Order cancelled
Comment NotificationType = "Comment"
OrderStatusChanged = "OrderStatusChanged"
OrderShipped = "OrderShipped"
TrackingNumber = "TrackingNumber"
Invoice = "Invice"
OrderStatusChanged NotificationType = "OrderStatusChanged"
OrderShipped NotificationType = "OrderShipped"
TrackingNumber NotificationType = "TrackingNumber"
Invoice NotificationType = "Invice"
)

View File

@@ -26,6 +26,29 @@ type Item struct {
Shippable bool `json:"shippable,omitempty"`
}
type Discount struct {
ID string `json:"id"`
DiscountID string `json:"discountId"`
Name string `json:"name"`
Code string `json:"code,omitempty"`
Trigger string `json:"trigger,omitempty"`
Type string `json:"type,omitempty"`
Rate float64 `json:"rate,omitempty"`
Amount float64 `json:"amount,omitempty"`
AmountSaved float64 `json:"amountSaved,omitempty"`
NormalizedRate float64 `json:"normalizedRate,omitempty"`
Combinable bool `json:"combinable"`
HasSavedAmount bool `json:"hasSavedAmount"`
MaxDiscountsPerItem *int `json:"maxDiscountsPerItem,omitempty"`
TotalToReach *float64 `json:"totalToReach,omitempty"`
ProductIds string `json:"productIds,omitempty"`
Categories string `json:"categories,omitempty"`
NumberOfUsages int `json:"numberOfUsages,omitempty"`
AppliesOnAllRecurring bool `json:"appliesOnAllRecurringOrders"`
CreationDate string `json:"creationDate,omitempty"`
ModificationDate string `json:"modificationDate,omitempty"`
}
type OrderTax struct {
Name string `json:"taxName"`
Rate float64 `json:"taxRate"`
@@ -33,37 +56,60 @@ type OrderTax struct {
NumberForInvoice string `json:"numberForInvoice"`
}
type OrderNotification struct {
Id string `json:"id"`
Created time.Time `json:"creationDate"`
Type NotificationType `json:"type"`
DeliveryMethod string `json:"deliveryMethod"`
Message string `json:"message,omitempty"`
SendDate time.Time `json:"sentOn,omitempty"`
Subject string `json:"subject,omitempty"`
}
type OrderNotifications struct {
TotalNotifications int `json:"totalItems"`
Offset int `json:"offset"`
Limit int `json:"limit"`
Notifications []OrderNotification `json:"items"`
}
type Order struct {
Token string `json:"token"`
Created time.Time `json:"creationDate"`
Modified time.Time `json:"modificationDate"`
Invoice string `json:"invoiceNumber"`
Subtotal float64 `json:"subtotal,omitempty"`
Currency string `json:"currency,omitempty"`
Total float64 `json:"grandTotal,omitempty"`
TotalTaxable float64 `json:"taxableTotal,omitempty"`
Status string `json:"status"`
TotalWeight float64 `json:"totalWeight"`
ShippingAddress Address `json:"shippingAddress,omitempty"`
Name string `json:"shippingAddressName,omitempty"`
Company string `json:"shippingAddressCompanyName,omitempty"`
Address1 string `json:"shippingAddressAddress1,omitempty"`
Address2 string `json:"shippingAddressAddress2,omitempty"`
City string `json:"shippingAddressCity,omitempty"`
Province string `json:"shippingAddressProvince,omitempty"`
Country string `json:"shippingAddressCountry,omitempty"`
PostalCode string `json:"shippingAddressPostalCode,omitempty"`
Phone string `json:"shippingAddressPhone,omitempty"`
Email string `json:"email,omitempty"`
TrackingNumber string `json:"trackingNumber"`
TrackingUrl string `json:"trackingUrl"`
ShippingCost float64 `json:"shippingFees"`
ShippingProvider string `json:"shippingProvider,omitempty"`
ShippingMethod string `json:"shippingMethod,omitempty"`
ShippingRateId string `json:"shippingRateUserDefinedId,omitempty"`
Items []Item `json:"items"`
Taxes []OrderTax `json:"taxes,omitempty"`
Metadata any `json:"metadata"`
Token string `json:"token"`
Created time.Time `json:"creationDate"`
Modified time.Time `json:"modificationDate"`
Completed time.Time `json:"completionDate"`
Invoice string `json:"invoiceNumber"`
Subtotal float64 `json:"subtotal,omitempty"`
Currency string `json:"currency,omitempty"`
Total float64 `json:"grandTotal,omitempty"`
TotalTaxable float64 `json:"taxableTotal,omitempty"`
TotalTaxes float64 `json:"taxesTotal,omitempty"`
Status string `json:"status"`
TotalWeight float64 `json:"totalWeight"`
ShippingAddressSameAsBilling bool `json:"shippingAddressSameAsBilling,omitempty"`
ShippingAddress Address `json:"shippingAddress,omitempty"`
Name string `json:"shippingAddressName,omitempty"`
Company string `json:"shippingAddressCompanyName,omitempty"`
Address1 string `json:"shippingAddressAddress1,omitempty"`
Address2 string `json:"shippingAddressAddress2,omitempty"`
City string `json:"shippingAddressCity,omitempty"`
Province string `json:"shippingAddressProvince,omitempty"`
Country string `json:"shippingAddressCountry,omitempty"`
PostalCode string `json:"shippingAddressPostalCode,omitempty"`
Phone string `json:"shippingAddressPhone,omitempty"`
Email string `json:"email,omitempty"`
TrackingNumber string `json:"trackingNumber"`
TrackingUrl string `json:"trackingUrl"`
ShippingCost float64 `json:"shippingFees"`
ShippingProvider string `json:"shippingProvider,omitempty"`
ShippingMethod string `json:"shippingMethod,omitempty"`
ShippingRateId string `json:"shippingRateUserDefinedId,omitempty"`
Discounts []Discount `json:"discounts,omitempty"`
SavedAmount float64 `json:"savedAmount,omitempty"`
TotalRebateRate float64 `json:"totalRebateRate,omitempty"`
Items []Item `json:"items"`
Taxes []OrderTax `json:"taxes,omitempty"`
Metadata any `json:"metadata"`
}
type OrderUpdate struct {
@@ -121,6 +167,11 @@ type Product struct {
Token string `json:"id"`
Id string `json:"userDefinedId"`
Name string `json:"name"`
Price float64 `json:"price"`
Url string `json:"url"`
Image string `json:"image"`
Description string `json:"description"`
Archived bool `json:"archived"`
Stock int `json:"stock"`
TotalStock int `json:"totalStock"`
AllowBackorder bool `json:"allowOutOfStockPurchases"`
@@ -170,6 +221,26 @@ func (s *Client) GetOrder(token string) (*Order, error) {
return &order, nil
}
func (s *Client) GetOrderNotifications(token string) (*OrderNotifications, error) {
response, err := helper.Get(orderUri+"/"+token+"/"+orderNotificationPath, "Basic", s.AuthBase64, nil)
if err != nil {
return nil, err
}
if response.StatusCode < 200 && response.StatusCode >= 300 {
return nil, fmt.Errorf("unexpected response received: %s", response.Status)
}
defer response.Body.Close()
var notifications OrderNotifications
err = json.NewDecoder(response.Body).Decode(&notifications)
if err != nil {
return nil, err
}
return &notifications, nil
}
func (s *Client) GetOrders(queries map[string]string) (*Orders, error) {
response, err := helper.Get(orderUri, "Basic", s.AuthBase64, queries)
if err != nil {