Documentation
¶
Overview ¶
Package vtex is a client for the public VTEX storefront APIs: catalog search, checkout orderForm, delivery simulation, VTEX ID auth, and order history.
Nothing here is store-specific. Every store-dependent value comes from the store.Store descriptor the client is constructed with.
Index ¶
- Constants
- Variables
- func GenerateClearSaleSession(doer store.HTTPDoer, endpoint string) (string, error)
- type Client
- func (c *Client) AddToCart(orderFormID, skuID, seller string, quantity int) (*OrderForm, error)
- func (c *Client) AddToWishlist(shopperID, listName string, item WishlistItem) error
- func (c *Client) AuthStart() (*store.Capabilities, error)
- func (c *Client) AuthToken() string
- func (c *Client) AuthenticatedUser() (string, error)
- func (c *Client) ClassicLogin(email, password string) (string, error)
- func (c *Client) GatewayCallback(orderGroup string) error
- func (c *Client) Get(path string) ([]byte, error)
- func (c *Client) GetDeliveryWindows(orderFormID string) ([]DeliveryWindow, error)
- func (c *Client) GetOrder(orderID string) (*OrderDetail, error)
- func (c *Client) GetOrderForm(orderFormID string) (*OrderForm, error)
- func (c *Client) GetSavedCards(orderFormID string) ([]SavedCard, error)
- func (c *Client) GetSession() (*Session, error)
- func (c *Client) HTTPClient() *http.Client
- func (c *Client) ListOrders() ([]Order, error)
- func (c *Client) Login(ctx context.Context, email, password string) (string, error)
- func (c *Client) NewOrderForm() (*OrderForm, error)
- func (c *Client) PatchJSON(path string, payload any) ([]byte, error)
- func (c *Client) PayWithSavedCard(tx *TransactionResult, card SavedCard, cvv string, orderValue money.Centavos) error
- func (c *Client) PlaceOrder(orderFormID string, orderValue money.Centavos) (*TransactionResult, error)
- func (c *Client) PostForm(path string, values url.Values) ([]byte, error)
- func (c *Client) PostJSON(path string, payload any) ([]byte, error)
- func (c *Client) PostJSONAbsolute(absoluteURL string, payload any) ([]byte, error)
- func (c *Client) RefreshToken() (string, error)
- func (c *Client) RemoveAllItems(orderFormID string) error
- func (c *Client) RemoveFromWishlist(shopperID, listName string, id int) (bool, error)
- func (c *Client) ResolvePaymentSystem(of *OrderForm, name string) (int, error)
- func (c *Client) Search(query string, limit int) ([]SearchResult, error)
- func (c *Client) SendAccessCode(email string) error
- func (c *Client) SetAddress(orderFormID string, numItems int) error
- func (c *Client) SetAuthToken(token string)
- func (c *Client) SetPayment(orderFormID string, paymentSystemID int, value money.Centavos) error
- func (c *Client) SetPaymentWithSavedCard(orderFormID string, card SavedCard, value money.Centavos) error
- func (c *Client) SetShippingWindow(orderFormID string, window DeliveryWindow, numItems int) error
- func (c *Client) Simulate(items []SimulationItemRequest, cep string) (*Simulation, error)
- func (c *Client) Store() store.Store
- func (c *Client) UpdateItemQuantity(orderFormID string, index, quantity int) (*OrderForm, error)
- func (c *Client) UsableCart(persistedID string) (*OrderForm, bool, error)
- func (c *Client) ValidateAccessCode(code, emailOverride string) (string, string, error)
- func (c *Client) Wishlists(shopperID string) ([]Wishlist, error)
- type DeliveryWindow
- type Order
- type OrderDetail
- type OrderForm
- type OrderFormItem
- type OrderItem
- type PaymentSystem
- type PendingAuth
- type SavedCard
- type SearchResult
- type Session
- type Simulation
- type SimulationItem
- type SimulationItemRequest
- type SimulationLogisticsInfo
- type SimulationSLA
- type Totalizer
- type TransactionResult
- type Wishlist
- type WishlistItem
Constants ¶
const DefaultWishlistName = "Wishlist"
DefaultWishlistName is the list vtex.wish-list writes to when the storefront's heart icon is used.
Variables ¶
var ErrAccessKeyRequired = errors.New("store requires an emailed access code")
ErrAccessKeyRequired reports that the only login method the store offers is an emailed access code, which cannot complete in a single call. The caller must run SendAccessCode, collect the code, then ValidateAccessCode.
Functions ¶
func GenerateClearSaleSession ¶
GenerateClearSaleSession registers an anti-fraud device fingerprint and returns the session ID to send as deviceFingerprint on a card payment.
Nothing here is store-specific — the app key and SDK identifiers are common to the VTEX/ClearSale integration — so it lives in the library and is reached only when a store sets the ClearSaleFingerprint quirk.
doer and endpoint are injected: the original implementation called the package-level http.Get, which bypassed the client's transport and had no timeout, so a hung ClearSale host stalled checkout indefinitely.
Types ¶
type Client ¶
type Client struct {
// GatewayURL overrides the payment gateway host. Tests set it; empty
// means the production vtexpayments host derived from the account.
GatewayURL string
// ClearSaleURL overrides the ClearSale fingerprint host for tests.
ClearSaleURL string
// contains filtered or unexported fields
}
func (*Client) AddToCart ¶
AddToCart adds a SKU. The seller comes from the caller — normally straight off a SearchResult — because it is not a store-wide constant.
func (*Client) AddToWishlist ¶ added in v0.4.0
func (c *Client) AddToWishlist(shopperID, listName string, item WishlistItem) error
AddToWishlist saves a product to the shopper's wishlist. productID and sku differ for products with variants and the API wants both.
func (*Client) AuthStart ¶
func (c *Client) AuthStart() (*store.Capabilities, error)
AuthStart probes what login methods this store supports.
func (*Client) AuthenticatedUser ¶
AuthenticatedUser returns the logged-in email, or an error when the stored token has expired.
func (*Client) ClassicLogin ¶
ClassicLogin authenticates with email and password against stock VTEX ID.
func (*Client) GatewayCallback ¶
GatewayCallback finalizes a card payment. The gateway answers 428 while the transaction is still settling, so this retries with a linear backoff.
func (*Client) GetDeliveryWindows ¶
func (c *Client) GetDeliveryWindows(orderFormID string) ([]DeliveryWindow, error)
GetDeliveryWindows lists the windows available for the cart's address. Requires an orderForm with a shipping address, so it needs authentication; use Simulate for an unauthenticated check.
Windows are deduplicated across items and reindexed from zero, because `--window N` indexes into the returned slice.
func (*Client) GetSavedCards ¶
func (*Client) GetSession ¶
GetSession reads the auth cookie, cart pointer, and logged-in email from the VTEX sessions API.
The auth cookie key is account-scoped (VtexIdclientAutCookie_frescatto), so the response cannot be unmarshalled through a fixed struct tag the way the pre-extraction implementations did. It is decoded into a map and looked up by the descriptor's cookie name.
func (*Client) HTTPClient ¶
func (*Client) ListOrders ¶
func (*Client) Login ¶
Login authenticates with whichever strategy the store supports, preferring a registered OAuth driver, then classic email+password, then access key.
The strategy is discovered rather than declared: a store descriptor does not say how to log in, the storefront does.
func (*Client) NewOrderForm ¶
NewOrderForm mints a genuinely new cart.
It must use its own cookie jar: VTEX pins a client to its current cart via a checkout cookie, so calling GET /orderForm on a client that has already touched a cart hands back that same cart. Without a clean jar this silently returns the cart you were trying to escape.
func (*Client) PayWithSavedCard ¶
func (c *Client) PayWithSavedCard(tx *TransactionResult, card SavedCard, cvv string, orderValue money.Centavos) error
PayWithSavedCard submits a card payment to the VTEX payment gateway.
ClearSale fingerprinting is applied only for stores carrying the ClearSaleFingerprint quirk. Zona Sul's gateway rejects card payments without it (Cielo code 59); Frescatto shows no sign of needing it.
func (*Client) PlaceOrder ¶
func (c *Client) PlaceOrder(orderFormID string, orderValue money.Centavos) (*TransactionResult, error)
PlaceOrder converts the cart into a transaction. This is the point of no return for non-card payments.
func (*Client) PostForm ¶
PostForm submits form-encoded values. VTEX ID's validate endpoints reject JSON bodies, so auth uses this rather than PostJSON.
func (*Client) PostJSONAbsolute ¶
PostJSONAbsolute posts to a full URL rather than a storefront path. The payment gateway lives on a different host, so it cannot use PostJSON.
func (*Client) RefreshToken ¶
RefreshToken asks the sessions API for a fresher JWT. It returns an empty string when the session carries no token, which means the caller must re-authenticate rather than treat it as an error.
func (*Client) RemoveAllItems ¶
func (*Client) RemoveFromWishlist ¶ added in v0.4.0
RemoveFromWishlist deletes an item by its wishlist ID, which is not the SKU. Callers resolve a SKU to an ID by reading the list first.
func (*Client) ResolvePaymentSystem ¶
ResolvePaymentSystem maps a human name such as "pix" to the store's own payment system ID, discovered from the order form. IDs are not portable between stores, so this replaces the hardcoded map the CLIs used to carry.
func (*Client) Search ¶
func (c *Client) Search(query string, limit int) ([]SearchResult, error)
Search queries the store catalog using the descriptor's configured mode.
SearchAuto tries Intelligent Search REST first and falls back to the catalog REST API. Neither needs a persisted GraphQL hash, which is what made the previous implementation brittle: VTEX rotates that hash on every search-graphql release and a stale one returns no results.
func (*Client) SendAccessCode ¶
SendAccessCode emails a one-time login code and records the pending authentication token, which the subsequent validate call must reuse.
func (*Client) SetAddress ¶
SetAddress applies the account's saved delivery address to the cart.
func (*Client) SetAuthToken ¶
func (*Client) SetPayment ¶
func (*Client) SetPaymentWithSavedCard ¶
func (*Client) SetShippingWindow ¶
func (c *Client) SetShippingWindow(orderFormID string, window DeliveryWindow, numItems int) error
SetShippingWindow selects a delivery window for every item in the cart.
func (*Client) Simulate ¶
func (c *Client) Simulate(items []SimulationItemRequest, cep string) (*Simulation, error)
Simulate prices a basket against a postal code without authentication. This is how delivery windows and payment methods can be inspected before anyone logs in.
func (*Client) UpdateItemQuantity ¶
UpdateItemQuantity sets an absolute quantity, not a delta. Setting 0 removes the item.
func (*Client) UsableCart ¶
UsableCart returns a cart that can actually complete a checkout.
VTEX snapshots account data into an order form at creation time and never refreshes it — refreshOutdatedData does not help. A cart minted before the account had a profile or address is therefore permanently unusable, and because the CLI persists a cart id across invocations, a user who tried the CLI before completing their profile would be stuck forever with no way out but deleting the config by hand.
When the persisted cart cannot check out, this mints a fresh one and carries the items across, so nothing the user added is lost.
func (*Client) ValidateAccessCode ¶
ValidateAccessCode exchanges an emailed code for a JWT. It returns the token and the email it authenticated, then clears the pending record.
type DeliveryWindow ¶
type DeliveryWindow struct {
Index int `json:"index"`
Start time.Time `json:"start"`
End time.Time `json:"end"`
Price money.Centavos `json:"price"`
LisPrice money.Centavos `json:"lisPrice"`
Tax money.Centavos `json:"tax"`
// RawStart and RawEnd preserve the exact strings VTEX sent. The
// shipping-window request must echo them back byte for byte; a
// re-formatted timestamp is rejected.
RawStart string `json:"-"`
RawEnd string `json:"-"`
}
type OrderDetail ¶
type OrderForm ¶
type OrderForm struct {
OrderFormID string `json:"orderFormId"`
Items []OrderFormItem `json:"items"`
Totalizers []Totalizer `json:"totalizers"`
PaymentSystems []PaymentSystem `json:"-"`
Value money.Centavos `json:"value"`
LoggedIn bool `json:"loggedIn"`
// AddressCount is how many delivery addresses this cart can see. VTEX
// snapshots account data into an order form when it is created, so a
// cart minted before the account had an address reports zero here
// forever — it can never complete a checkout.
AddressCount int `json:"addressCount"`
}
func (*OrderForm) Checkoutable ¶
Checkoutable reports whether this cart can reach a completed order. A cart with no visible address cannot, regardless of what the account has.
func (*OrderForm) ItemsTotal ¶
ItemsTotal returns the Items totalizer, which excludes shipping. Checkout minimums are assessed against this, not the order total.
type OrderFormItem ¶
type OrderFormItem struct {
ID string `json:"id"`
ProductID string `json:"productId"`
Name string `json:"name"`
Quantity int `json:"quantity"`
Price money.Centavos `json:"price"`
SellingPrice money.Centavos `json:"sellingPrice"`
Seller string `json:"seller"`
Unit string `json:"measurementUnit"`
UnitMult float64 `json:"unitMultiplier"`
}
type PaymentSystem ¶
type PaymentSystem struct {
ID int `json:"id"`
Name string `json:"name"`
GroupName string `json:"groupName"`
}
PaymentSystem is one payment method the store accepts. Discovered from the orderForm rather than hardcoded, because the set differs per store.
type PendingAuth ¶
type PendingAuth struct {
Email string `json:"email"`
AuthenticationToken string `json:"authenticationToken"`
}
PendingAuth records an in-flight access-code login. VTEX rejects a validate call whose authenticationToken came from a different start call, so the token has to survive between the two CLI invocations.
type SearchResult ¶
type SearchResult struct {
ProductID string `json:"productId"`
SKU string `json:"sku"`
Name string `json:"name"`
Price money.Centavos `json:"price"`
ListPrice money.Centavos `json:"listPrice"`
Available int `json:"available"`
Seller string `json:"seller"`
Unit string `json:"unit"`
UnitMult float64 `json:"unitMultiplier"`
}
SearchResult is one purchasable SKU.
Seller is carried per result rather than assumed from a constant: it is the value the cart API needs, and it differs per store (and in principle per item within a store).
type Session ¶
type Session struct {
AuthToken string `json:"authToken"`
OrderFormID string `json:"orderFormId"`
Email string `json:"email"`
}
Session is the storefront's view of the current visitor.
type Simulation ¶
type Simulation struct {
Items []SimulationItem `json:"items"`
LogisticsInfo []SimulationLogisticsInfo `json:"logisticsInfo"`
PaymentSystems []PaymentSystem `json:"paymentSystems"`
}
type SimulationItem ¶
type SimulationItemRequest ¶
type SimulationLogisticsInfo ¶
type SimulationLogisticsInfo struct {
SLAs []SimulationSLA `json:"slas"`
}
type SimulationSLA ¶
type SimulationSLA struct {
Name string `json:"name"`
Price money.Centavos `json:"price"`
ShippingEstimate string `json:"shippingEstimate"`
AvailableDeliveryWindows []DeliveryWindow `json:"availableDeliveryWindows"`
}
type TransactionResult ¶
type Wishlist ¶ added in v0.2.0
type Wishlist struct {
Name string `json:"name"`
Public bool `json:"public"`
Items []WishlistItem `json:"items"`
}
type WishlistItem ¶ added in v0.2.0
type WishlistItem struct {
ID int `json:"id"`
ProductID string `json:"productId"`
SKU string `json:"sku"`
Title string `json:"title"`
}
WishlistItem is one saved product from the store's own wishlist.
ID is the item's position-derived identifier within the list, and it is what RemoveFromList takes — not the SKU. ProductID and SKU genuinely differ for products with variants, and AddToList wants both.