Skip to content

Go Examples

Complete Go examples for integrating with the Pixlpay API.

API Client

go
package pixlpay

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"time"
)

type Client struct {
	BaseURL    string
	Token      string
	HTTPClient *http.Client
}

type PixlpayError struct {
	Message string            `json:"message"`
	Code    string            `json:"error"`
	Status  int               `json:"-"`
	Errors  map[string]string `json:"errors,omitempty"`
}

func (e *PixlpayError) Error() string {
	return fmt.Sprintf("%s: %s", e.Code, e.Message)
}

func NewClient(storeURL, token string) *Client {
	return &Client{
		BaseURL: storeURL + "/api/external/v1",
		Token:   token,
		HTTPClient: &http.Client{
			Timeout: 30 * time.Second,
		},
	}
}

func (c *Client) request(method, endpoint string, params url.Values, body interface{}) ([]byte, error) {
	reqURL := c.BaseURL + endpoint
	if params != nil && len(params) > 0 {
		reqURL += "?" + params.Encode()
	}

	var reqBody io.Reader
	if body != nil {
		jsonBody, err := json.Marshal(body)
		if err != nil {
			return nil, err
		}
		reqBody = bytes.NewReader(jsonBody)
	}

	req, err := http.NewRequest(method, reqURL, reqBody)
	if err != nil {
		return nil, err
	}

	req.Header.Set("Authorization", "Bearer "+c.Token)
	req.Header.Set("Accept", "application/json")
	req.Header.Set("Content-Type", "application/json")

	resp, err := c.HTTPClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode >= 400 {
		var apiErr PixlpayError
		json.Unmarshal(respBody, &apiErr)
		apiErr.Status = resp.StatusCode
		return nil, &apiErr
	}

	return respBody, nil
}

// Products
func (c *Client) GetProducts(params url.Values) (*ProductsResponse, error) {
	body, err := c.request("GET", "/products", params, nil)
	if err != nil {
		return nil, err
	}

	var resp ProductsResponse
	err = json.Unmarshal(body, &resp)
	return &resp, err
}

func (c *Client) GetProduct(id int) (*ProductResponse, error) {
	body, err := c.request("GET", fmt.Sprintf("/products/%d", id), nil, nil)
	if err != nil {
		return nil, err
	}

	var resp ProductResponse
	err = json.Unmarshal(body, &resp)
	return &resp, err
}

// Orders
func (c *Client) GetOrders(params url.Values) (*OrdersResponse, error) {
	body, err := c.request("GET", "/orders", params, nil)
	if err != nil {
		return nil, err
	}

	var resp OrdersResponse
	err = json.Unmarshal(body, &resp)
	return &resp, err
}

func (c *Client) FulfillOrder(id int) (*OrderResponse, error) {
	body, err := c.request("POST", fmt.Sprintf("/orders/%d/fulfill", id), nil, nil)
	if err != nil {
		return nil, err
	}

	var resp OrderResponse
	err = json.Unmarshal(body, &resp)
	return &resp, err
}

// Webhooks
func (c *Client) CreateWebhook(webhookURL string, events []string) (*WebhookResponse, error) {
	body, err := c.request("POST", "/webhooks", nil, map[string]interface{}{
		"url":    webhookURL,
		"events": events,
	})
	if err != nil {
		return nil, err
	}

	var resp WebhookResponse
	err = json.Unmarshal(body, &resp)
	return &resp, err
}

Types

go
package pixlpay

type Product struct {
	ID          int       `json:"id"`
	Name        string    `json:"name"`
	Description string    `json:"description"`
	Price       string    `json:"price"`
	Type        string    `json:"type"`
	IsActive    bool      `json:"is_active"`
	CreatedAt   string    `json:"created_at"`
	UpdatedAt   string    `json:"updated_at"`
}

type Order struct {
	ID            int         `json:"id"`
	OrderNumber   string      `json:"order_number"`
	Status        string      `json:"status"`
	PaymentStatus string      `json:"payment_status"`
	Total         string      `json:"total"`
	Currency      string      `json:"currency"`
	CustomerEmail string      `json:"customer_email"`
	CustomerName  string      `json:"customer_name"`
	Items         []OrderItem `json:"items"`
	CreatedAt     string      `json:"created_at"`
}

type OrderItem struct {
	ID          int    `json:"id"`
	ProductID   int    `json:"product_id"`
	ProductName string `json:"product_name"`
	Quantity    int    `json:"quantity"`
	Price       string `json:"price"`
	Total       string `json:"total"`
}

type Meta struct {
	CurrentPage int `json:"current_page"`
	LastPage    int `json:"last_page"`
	PerPage     int `json:"per_page"`
	Total       int `json:"total"`
}

type ProductsResponse struct {
	Success bool      `json:"success"`
	Data    []Product `json:"data"`
	Meta    Meta      `json:"meta"`
}

type ProductResponse struct {
	Success bool    `json:"success"`
	Data    Product `json:"data"`
}

type OrdersResponse struct {
	Success bool    `json:"success"`
	Data    []Order `json:"data"`
	Meta    Meta    `json:"meta"`
}

type OrderResponse struct {
	Success bool   `json:"success"`
	Data    Order  `json:"data"`
	Message string `json:"message,omitempty"`
}

type WebhookResponse struct {
	Success bool `json:"success"`
	Data    struct {
		ID     int      `json:"id"`
		URL    string   `json:"url"`
		Events []string `json:"events"`
		Secret string   `json:"secret"`
	} `json:"data"`
}

type WebhookEvent struct {
	ID        string                 `json:"id"`
	EventType string                 `json:"event_type"`
	CreatedAt string                 `json:"created_at"`
	Data      map[string]interface{} `json:"data"`
}

Usage Examples

go
package main

import (
	"fmt"
	"net/url"
	"os"

	"yourapp/pixlpay"
)

func main() {
	client := pixlpay.NewClient(
		os.Getenv("PIXLPAY_STORE_URL"),
		os.Getenv("PIXLPAY_API_TOKEN"),
	)

	// List products
	params := url.Values{}
	params.Set("is_active", "true")
	params.Set("per_page", "50")

	products, err := client.GetProducts(params)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	for _, product := range products.Data {
		fmt.Printf("%s - $%s\n", product.Name, product.Price)
	}

	// Fulfill an order
	result, err := client.FulfillOrder(123)
	if err != nil {
		if apiErr, ok := err.(*pixlpay.PixlpayError); ok {
			if apiErr.Code == "ORDER_ALREADY_COMPLETED" {
				fmt.Println("Order was already completed")
				return
			}
		}
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Printf("Order %s fulfilled!\n", result.Data.OrderNumber)
}

HTTP Webhook Handler

go
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"

	"yourapp/pixlpay"
)

func verifySignature(payload []byte, signature, secret string) bool {
	mac := hmac.New(sha256.New, []byte(secret))
	mac.Write(payload)
	expected := hex.EncodeToString(mac.Sum(nil))
	return hmac.Equal([]byte(expected), []byte(signature))
}

func webhookHandler(w http.ResponseWriter, r *http.Request) {
	// Read body
	payload, err := io.ReadAll(r.Body)
	if err != nil {
		http.Error(w, "Failed to read body", http.StatusBadRequest)
		return
	}

	// Verify signature
	signature := r.Header.Get("X-Webhook-Signature")
	secret := os.Getenv("PIXLPAY_WEBHOOK_SECRET")

	if !verifySignature(payload, signature, secret) {
		http.Error(w, "Invalid signature", http.StatusUnauthorized)
		return
	}

	// Parse event
	var event pixlpay.WebhookEvent
	if err := json.Unmarshal(payload, &event); err != nil {
		http.Error(w, "Invalid JSON", http.StatusBadRequest)
		return
	}

	fmt.Printf("Received: %s (%s)\n", event.EventType, event.ID)

	// Respond immediately
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(map[string]string{"status": "received"})

	// Process asynchronously
	go processEvent(event)
}

func processEvent(event pixlpay.WebhookEvent) {
	switch event.EventType {
	case "order.paid":
		handleOrderPaid(event.Data)
	case "order.refunded":
		handleOrderRefunded(event.Data)
	default:
		fmt.Printf("Unhandled event: %s\n", event.EventType)
	}
}

func handleOrderPaid(data map[string]interface{}) {
	orderID := data["order_id"]
	customerEmail := data["customer_email"]
	fmt.Printf("Order %v paid by %v\n", orderID, customerEmail)
}

func handleOrderRefunded(data map[string]interface{}) {
	orderID := data["order_id"]
	fmt.Printf("Order %v refunded\n", orderID)
}

func main() {
	http.HandleFunc("/webhooks/pixlpay", webhookHandler)
	fmt.Println("Webhook server running on :3000")
	http.ListenAndServe(":3000", nil)
}

Built for game developers, by game developers.