From 9b005b40f6c00b9d3bc08e7be56a6d2c43879d5f Mon Sep 17 00:00:00 2001 From: Mohd Salman Date: Sat, 11 Oct 2025 21:48:10 +0530 Subject: [PATCH 1/2] feat(business): add support for fetching order details --- business.go | 124 ++++++++++++++++++++++++++++++++++++++++++++++ types/business.go | 33 ++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 business.go create mode 100644 types/business.go diff --git a/business.go b/business.go new file mode 100644 index 000000000..ca0b25e54 --- /dev/null +++ b/business.go @@ -0,0 +1,124 @@ +// Copyright (c) 2025 Tulir Asokan +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package whatsmeow + +import ( + "context" + "fmt" + "strconv" + + waBinary "go.mau.fi/whatsmeow/binary" + "go.mau.fi/whatsmeow/types" +) + +// GetOrderDetails fetches the details of a specific order using its ID and token. +// Both token and orderID is found in the OrderMessage. +func (cli *Client) GetOrderDetails(ctx context.Context, orderID, tokenBase64 string) (*types.OrderDetails, error) { + resp, err := cli.sendIQ(infoQuery{ + Namespace: "fb:thrift_iq", + Type: iqGet, + SMaxID: "5", + To: types.ServerJID, + Content: []waBinary.Node{{ + Tag: "order", + Attrs: waBinary.Attrs{ + "op": "get", + "id": orderID, + }, + Content: []waBinary.Node{ + { + Tag: "image_dimensions", + Content: []waBinary.Node{ + {Tag: "width", Content: []byte("100")}, + {Tag: "height", Content: []byte("100")}, + }, + }, + {Tag: "token", Content: []byte(tokenBase64)}, + }, + }}, + Context: ctx, + }) + if err != nil { + return nil, fmt.Errorf("failed to send order IQ: %w", err) + } + + orderNode, ok := resp.GetOptionalChildByTag("order") + if !ok { + return nil, &ElementMissingError{Tag: "order", In: "response to order query"} + } + + return parseOrderDetailsNode(orderNode) +} + +// Helper to get the string content of a child node. +func getStringChild(node waBinary.Node, tag string) string { + child, ok := node.GetOptionalChildByTag(tag) + if !ok { + return "" + } + content, _ := child.Content.([]byte) + return string(content) +} + +func parseOrderDetailsNode(orderNode waBinary.Node) (*types.OrderDetails, error) { + ag := orderNode.AttrGetter() + details := &types.OrderDetails{ + ID: ag.String("id"), + CreatedAt: ag.UnixTime("creation_ts"), + } + if err := ag.Error(); err != nil { + return nil, err + } + + // Parse Price + priceNode, ok := orderNode.GetOptionalChildByTag("price") + if ok { + subtotal, _ := strconv.ParseInt(getStringChild(priceNode, "subtotal"), 10, 64) + total, _ := strconv.ParseInt(getStringChild(priceNode, "total"), 10, 64) + details.Price = types.OrderPrice{ + Subtotal: subtotal, + Total: total, + Currency: getStringChild(priceNode, "currency"), + PriceStatus: getStringChild(priceNode, "price_status"), + } + } + + // Parse Catalog ID + catalogNode, ok := orderNode.GetOptionalChildByTag("catalog") + if ok { + details.CatalogID = getStringChild(catalogNode, "id") + } + + // Parse Products + for _, productNode := range orderNode.GetChildrenByTag("product") { + price, _ := strconv.ParseInt(getStringChild(productNode, "price"), 10, 64) + quantity, _ := strconv.Atoi(getStringChild(productNode, "quantity")) + + product := types.OrderProduct{ + ID: getStringChild(productNode, "id"), + Price: price, + Currency: getStringChild(productNode, "currency"), + Name: getStringChild(productNode, "name"), + Quantity: quantity, + } + + // Parse Product Image + if imageNode, ok := productNode.GetOptionalChildByTag("image"); ok { + product.ImageID = getStringChild(imageNode, "id") + product.ImageURL = getStringChild(imageNode, "url") + } + + // Parse Variant Info + if variantNode, ok := productNode.GetOptionalChildByTag("variant_info"); ok { + product.VariantInfo.Properties = getStringChild(variantNode, "properties") + } + + details.Products = append(details.Products, product) + } + + return details, nil +} diff --git a/types/business.go b/types/business.go new file mode 100644 index 000000000..f23bca83c --- /dev/null +++ b/types/business.go @@ -0,0 +1,33 @@ +package types + +import "time" + +type OrderDetails struct { + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + CatalogID string `json:"catalog_id,omitempty"` + Price OrderPrice `json:"price"` + Products []OrderProduct `json:"products"` +} + +type OrderProduct struct { + ID string `json:"id"` + ImageID string `json:"image_id,omitempty"` + ImageURL string `json:"image_url,omitempty"` + Price int64 `json:"price"` + Currency string `json:"currency"` + Name string `json:"name"` + Quantity int `json:"quantity"` + VariantInfo VariantInfo `json:"variant_info,omitempty"` +} + +type VariantInfo struct { + Properties string `json:"properties,omitempty"` +} + +type OrderPrice struct { + Subtotal int64 `json:"subtotal"` + Total int64 `json:"total"` + Currency string `json:"currency"` + PriceStatus string `json:"price_status,omitempty"` +} From 0bfb7caac8616e32a340180540255614cf6ef464 Mon Sep 17 00:00:00 2001 From: Mohd Salman Date: Sat, 11 Oct 2025 21:59:22 +0530 Subject: [PATCH 2/2] add missing license header --- types/business.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/types/business.go b/types/business.go index f23bca83c..0cefc9c75 100644 --- a/types/business.go +++ b/types/business.go @@ -1,3 +1,9 @@ +// Copyright (c) 2025 Tulir Asokan +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + package types import "time"