client

package
v0.4.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 8, 2026 License: Apache-2.0 Imports: 25 Imported by: 0

Documentation

Overview

Package client provides the HTTP client for the GSPAY2 API.

This package is the foundation of the SDK, providing configuration, HTTP request handling, and utility functions for all API operations.

Creating a Client

Use New with functional options pattern:

c := client.New("auth-key", "secret-key",
    client.WithTimeout(60*time.Second),
    client.WithRetries(5),
    client.WithLanguage(i18n.Indonesian),
)

Configuration Options

Available options:

Retry Logic

The client includes automatic retry with exponential backoff and jitter for transient failures (5xx errors, timeouts, connection issues).

Helper Functions

Utility functions for common operations:

Logging

By default, logging is disabled. Enable it with:

// Quick debug mode
client.WithDebug(true)

// Custom logger
client.WithLogger(logger.NewStd(os.Stdout, logger.LevelInfo))

See the logger subpackage for more logging options.

Index

Constants

View Source
const (
	// DefaultQRSize is the default QR code image width and height in pixels.
	DefaultQRSize = 256
)

Default values for QR code generation.

Variables

This section is empty.

Functions

func BuildReturnURL

func BuildReturnURL(paymentURL, returnURL string) string

BuildReturnURL appends an encoded return URL to a payment URL for 1-way redirect.

Example:

paymentURL := "https://pay.example.com/payment/123"
returnURL := "https://mysite.com/payment/complete"
fullURL := client.BuildReturnURL(paymentURL, returnURL)
// Result: "https://pay.example.com/payment/123?return=https%3A%2F%2Fmysite.com%2Fpayment%2Fcomplete"

func FormatAmountIDR

func FormatAmountIDR(amount int64) string

FormatAmountIDR formats an integer amount as IDR currency string.

Example:

formatted := client.FormatAmountIDR(50000)
// Result: "Rp 50.000"

func FormatAmountUSDT

func FormatAmountUSDT(amount float64) string

FormatAmountUSDT formats a float amount as USDT currency string.

Example:

formatted := client.FormatAmountUSDT(10.50)
// Result: "10.50 USDT"

func GenerateTransactionID

func GenerateTransactionID(prefix string) string

GenerateTransactionID generates a unique transaction ID suitable for GSPAY2 API.

Format: PREFIX + YmdHis + random (total max 20 chars)

Example:

txnID := client.GenerateTransactionID("TXN")
// Result: "TXN20260126143022123"

func GenerateUUIDTransactionID added in v0.2.4

func GenerateUUIDTransactionID(prefix string) string

GenerateUUIDTransactionID generates a cryptographically secure UUID v4 transaction ID.

This provides stronger uniqueness guarantees than the timestamp-based approach. The UUID is truncated to 20 characters to fit GSPAY2 API limits.

Format: PREFIX + UUID (first 17 chars of UUID v4, total max 20 chars)

Example:

txnID := client.GenerateUUIDTransactionID("TXN")
// Result: "TXN3d66c16c9db64210a"

func ParseData

func ParseData[T any](data json.RawMessage, lang i18n.Language) (*T, error)

ParseData parses the data field from an API response. GSPAY2 API returns data as a JSON string that needs to be decoded.

Types

type Client

type Client struct {
	// AuthKey is the operator authentication key (used in URL path).
	AuthKey string
	// SecretKey is the operator secret key (used for signature generation).
	SecretKey string
	// BaseURL is the API base URL.
	BaseURL string
	// HTTPClient is the underlying HTTP client.
	// See [WithHTTPClient] for configuration.
	HTTPClient *http.Client
	// Timeout is the request timeout duration.
	Timeout time.Duration
	// Retries is the number of retry attempts for transient failures.
	Retries int
	// RetryWaitMin is the minimum wait time between retries.
	RetryWaitMin time.Duration
	// RetryWaitMax is the maximum wait time between retries.
	RetryWaitMax time.Duration
	// CallbackIPWhitelist contains allowed IP addresses/CIDR ranges for callbacks.
	// If empty, IP validation is skipped.
	CallbackIPWhitelist []string

	// Debug controls whether sensitive data is sanitized in log output.
	//
	// If Debug is true, raw values (auth keys, account numbers, account names) are shown in logs,
	// and a default logger is used when no custom logger is set.
	// If Debug is false (default), sensitive data is automatically redacted for safe logging.
	Debug bool

	// Language is the language for SDK error and log messages.
	// Default is [i18n.English]. See [WithLanguage] for configuration.
	Language i18n.Language
	// contains filtered or unexported fields
}

Client is the GSPAY2 API client.

func New

func New(authKey, secretKey string, opts ...Option) *Client

New creates a new GSPAY2 API client.

Parameters:

  • authKey: Operator authentication key (used in URL path)
  • secretKey: Operator secret key (used for signature generation)
  • opts: Optional configuration options (see Option)

func (*Client) DoRequest

func (c *Client) DoRequest(ctx context.Context, method, endpoint string, body any) (*Response, error)

DoRequest performs an HTTP request with retry logic.

func (*Client) Error added in v0.4.0

func (c *Client) Error(sentinel error, args ...any) error

Error creates a localized error wrapping the provided sentinel error. This is a convenience method that uses the client's language setting.

func (*Client) GenerateSignature

func (c *Client) GenerateSignature(data string) string

GenerateSignature generates a signature for API requests. Uses the configured digest function (see WithDigest), or crypto/md5 if not set.

func (*Client) Get

func (c *Client) Get(ctx context.Context, endpoint string, params map[string]string) (*Response, error)

Get performs a GET request with query parameters.

func (*Client) I18n added in v0.4.0

func (c *Client) I18n(key i18n.MessageKey) string

I18n returns the localized message for the given key using the client's language setting. This is a convenience method for i18n support in logging and error messages.

func (*Client) IsIPWhitelisted added in v0.2.0

func (c *Client) IsIPWhitelisted(ipStr string) bool

IsIPWhitelisted checks if the given IP address is in the whitelist.

Returns true if:

  • The whitelist is empty (IP validation disabled)
  • The IP matches an individual whitelisted IP
  • The IP falls within a whitelisted CIDR range

The ipStr parameter can include a port (e.g., "192.168.1.1:8080"), which will be automatically stripped before validation.

func (*Client) LogAccountName added in v0.3.9

func (c *Client) LogAccountName(accountName string) string

LogAccountName returns the account name for logging, sanitized unless debug mode is enabled.

In debug mode, the full account name is returned for troubleshooting. In production mode, only initials are shown (e.g., "J*** D***").

func (*Client) LogAccountNumber added in v0.3.9

func (c *Client) LogAccountNumber(accountNumber string) string

LogAccountNumber returns the account number for logging, sanitized unless debug mode is enabled.

In debug mode, the full account number is returned for troubleshooting. In production mode, only the last 4 digits are shown (e.g., "****7890").

func (*Client) LogEndpoint added in v0.3.9

func (c *Client) LogEndpoint(endpoint string) string

LogEndpoint returns the endpoint for logging, sanitized unless debug mode is enabled.

In debug mode, the full endpoint (including auth keys) is returned for troubleshooting. In production mode, auth keys are redacted (e.g., "/operators/[REDACTED]/idr/payment").

func (*Client) Logger added in v0.3.9

func (c *Client) Logger() Logger

Logger returns the configured logger instance.

This allows services and other packages to use the same logger configuration as the client for consistent logging across the SDK.

func (*Client) Post

func (c *Client) Post(ctx context.Context, endpoint string, body any) (*Response, error)

Post performs a POST request.

func (*Client) QR added in v0.4.2

func (c *Client) QR() *QR

QR returns a handle to the QR code.

func (*Client) VerifyCallbackIP added in v0.2.0

func (c *Client) VerifyCallbackIP(ipStr string) error

VerifyCallbackIP verifies that the callback request originates from a whitelisted IP.

Returns nil if the IP is whitelisted or if the whitelist is empty. Returns ErrIPNotWhitelisted if the IP is not in the whitelist. Returns ErrInvalidIPAddress if the IP address format is invalid.

func (*Client) VerifySignature

func (c *Client) VerifySignature(expected, actual string) bool

VerifySignature verifies a callback signature.

type Logger added in v0.3.8

type Logger = logger.Handler

Logger is an alias for logger.Handler.

This allows users to implement custom loggers without importing the logger subpackage.

Example:

type MyLogger struct{}
func (l *MyLogger) Debug(msg string, keysAndValues ...any) { /* ... */ }
func (l *MyLogger) Info(msg string, keysAndValues ...any)  { /* ... */ }
func (l *MyLogger) Warn(msg string, keysAndValues ...any)  { /* ... */ }
func (l *MyLogger) Error(msg string, keysAndValues ...any) { /* ... */ }

c := client.New("auth", "secret", client.WithLogger(&MyLogger{}))

type Option

type Option func(*Client)

Option is a functional option for configuring the Client.

func WithBaseURL

func WithBaseURL(baseURL string) Option

WithBaseURL sets a custom base URL for the API.

Trailing slashes are automatically trimmed from the URL. Default is "https://api.thegspay.com".

Example:

c := client.New("auth", "secret", client.WithBaseURL("https://sandbox.api.com"))

func WithCallbackIPWhitelist added in v0.2.0

func WithCallbackIPWhitelist(ips ...string) Option

WithCallbackIPWhitelist sets the allowed IP addresses or CIDR ranges for callback verification.

Accepts individual IP addresses (e.g., "192.168.1.1") or CIDR notation (e.g., "192.168.1.0/24"). If the whitelist is empty, IP validation is skipped during callback verification.

Example:

client.New("auth", "secret", client.WithCallbackIPWhitelist(
    "192.168.1.1",
    "10.0.0.0/8",
    "2001:db8::/32",
))

func WithDebug added in v0.2.6

func WithDebug(debug bool) Option

WithDebug enables debug mode for the client.

When enabled, sensitive data (auth keys, account numbers, account names) is shown unsanitized in log output, and a logger.Default logger is automatically used if no custom logger is set via WithLogger.

Example:

// Enable debug logging (uses default stderr logger)
c := client.New("auth", "secret", client.WithDebug(true))

func WithDigest added in v0.4.1

func WithDigest(digest signature.Digest) Option

WithDigest sets a custom hash function for signature generation.

Note: The GSPAY2 API requires crypto/md5 for signature verification. This option is provided for flexibility in case the API adds support for stronger algorithms, or for use with other compatible APIs. If digest is nil, crypto/md5 is used (default behavior for GSPAY2 compatibility).

Standard library hash functions can be used directly:

Example:

// Use SHA-256 for signature generation (if API supports it)
c := client.New("auth", "secret", client.WithDigest(sha256.New))

// Use SHA-512
c := client.New("auth", "secret", client.WithDigest(sha512.New))

func WithHTTPClient

func WithHTTPClient(httpClient *http.Client) Option

WithHTTPClient sets a custom HTTP client.

Use this to configure custom transport settings, proxies, or TLS configurations. If not set, a default net/http.Client is used.

Example:

customClient := &http.Client{
    Transport: &http.Transport{
        MaxIdleConns: 100,
    },
}
c := client.New("auth", "secret", client.WithHTTPClient(customClient))

For advanced use cases such as routing requests through a proxy:

proxyURL, _ := url.Parse("http://proxy.example.com:8080")
customClient := &http.Client{
    Transport: &http.Transport{
        Proxy: http.ProxyURL(proxyURL),
    },
}
c := client.New("auth", "secret", client.WithHTTPClient(customClient))

func WithLanguage added in v0.3.2

func WithLanguage(lang i18n.Language) Option

WithLanguage sets the language for localized SDK messages. This affects error messages, log messages, and the output of Client.I18n and Client.Error methods.

Default is i18n.English. Supported languages:

Example:

client.New("auth", "secret", client.WithLanguage(i18n.Indonesian))

func WithLogger added in v0.3.8

func WithLogger(l logger.Handler) Option

WithLogger sets a custom logger.Handler for the client.

If l is nil, a logger.Nop is used (no logging). For debug logging, use logger.Default or logger.NewStd.

Example:

// Enable debug logging to stderr
c := client.New("auth", "secret", client.WithLogger(logger.Default()))

// Custom log level
l := logger.NewStd(os.Stdout, logger.LevelInfo)
c := client.New("auth", "secret", client.WithLogger(l))

// Disable logging explicitly
c := client.New("auth", "secret", client.WithLogger(nil))

func WithQRCodeOptions added in v0.4.2

func WithQRCodeOptions(opts ...QROption) Option

WithQRCodeOptions sets options for QR code generation.

These options configure the QR code methods on Client: [Client.QREncode], [Client.QRWrite], and [Client.QRWriteFile].

Example:

c := client.New("auth", "secret",
    client.WithQRCodeOptions(
        client.WithQRSize(512),
        client.WithQRRecoveryLevel(client.QRRecoveryHigh),
    ),
)
png, err := c.QREncode(resp.QR)

func WithRetries

func WithRetries(retries int) Option

WithRetries sets the number of retry attempts for transient failures.

Retries are attempted for 5xx server errors, timeouts, and connection issues. Negative values are ignored. Set to 0 to disable retries. Default is 3 retries.

Example:

c := client.New("auth", "secret", client.WithRetries(5))

func WithRetryWait

func WithRetryWait(min, max time.Duration) Option

WithRetryWait sets the minimum and maximum wait times between retries.

The actual wait time is calculated using exponential backoff with jitter, bounded between min and max values. Default is 500ms minimum, 2s maximum.

Example:

c := client.New("auth", "secret", client.WithRetryWait(1*time.Second, 5*time.Second))

func WithTimeout

func WithTimeout(timeout time.Duration) Option

WithTimeout sets the request timeout.

The timeout applies to each individual HTTP request. Minimum allowed timeout is 5 seconds; values below this are ignored. Default is 30 seconds. See time.Duration for duration formatting.

Example:

c := client.New("auth", "secret", client.WithTimeout(60*time.Second))

type QR added in v0.4.2

type QR struct {
	// contains filtered or unexported fields
}

QR provides QR code generation.

func (*QR) Encode added in v0.4.2

func (q *QR) Encode(content string) ([]byte, error)

Encode encodes content into a QR code and returns the PNG image as bytes.

The content is typically a QRIS payment string from the QR field of a payment response (e.g., payment.IDRResponse.QR). QR code settings are configured once via WithQRCodeOptions.

Example:

png, err := c.QR().Encode(resp.QR)
if err != nil {
    log.Fatal(err)
}

func (*QR) Write added in v0.4.2

func (q *QR) Write(w io.Writer, content string) error

Write encodes content into a QR code and writes the PNG image to w.

Example:

w.Header().Set("Content-Type", "image/png")
err := c.QR().Write(w, resp.QR)

func (*QR) WriteFile added in v0.4.2

func (q *QR) WriteFile(filename, content string) error

WriteFile encodes content into a QR code and saves the PNG image to a file.

The file is created with permissions 0644. If the file already exists, it is overwritten.

Example:

err := c.QR().WriteFile("payment_qr.png", resp.QR)

type QROption added in v0.4.2

type QROption func(*qrConfig)

QROption is a functional option for configuring QR code generation.

Pass these to WithQRCodeOptions when creating a Client.

func WithQRBackgroundColor added in v0.4.2

func WithQRBackgroundColor(bg color.Color) QROption

WithQRBackgroundColor sets the background color of the QR code.

Default is color.White.

Example:

client.WithQRBackgroundColor(color.RGBA{R: 240, G: 240, B: 240, A: 255})

func WithQRForegroundColor added in v0.4.2

func WithQRForegroundColor(fg color.Color) QROption

WithQRForegroundColor sets the foreground (module) color of the QR code.

Default is color.Black.

Example:

client.WithQRForegroundColor(color.RGBA{R: 0, G: 0, B: 128, A: 255})

func WithQRRecoveryLevel added in v0.4.2

func WithQRRecoveryLevel(level QRRecoveryLevel) QROption

WithQRRecoveryLevel sets the QR code error correction level.

Higher levels make the QR code more resilient to damage but increase size. Default is QRRecoveryMedium.

Example:

client.New("auth", "secret",
    client.WithQRCodeOptions(client.WithQRRecoveryLevel(client.QRRecoveryHigh)),
)

func WithQRSize added in v0.4.2

func WithQRSize(pixels int) QROption

WithQRSize sets the QR code image size in pixels (width and height).

A positive value sets a fixed image size. Default is 256 pixels.

Example:

client.New("auth", "secret",
    client.WithQRCodeOptions(client.WithQRSize(512)),
)

type QRRecoveryLevel added in v0.4.2

type QRRecoveryLevel = goqrcode.RecoveryLevel

QRRecoveryLevel represents the QR code error correction level.

Higher levels allow more of the QR code to be damaged while remaining readable, but produce physically larger codes.

const (
	// QRRecoveryLow provides approximately 7% error recovery.
	QRRecoveryLow QRRecoveryLevel = goqrcode.Low
	// QRRecoveryMedium provides approximately 15% error recovery (default).
	QRRecoveryMedium QRRecoveryLevel = goqrcode.Medium
	// QRRecoveryHigh provides approximately 25% error recovery.
	QRRecoveryHigh QRRecoveryLevel = goqrcode.High
	// QRRecoveryHighest provides approximately 30% error recovery.
	QRRecoveryHighest QRRecoveryLevel = goqrcode.Highest
)

Error correction levels for QR code generation.

type Response

type Response struct {
	Code    int             `json:"code"`
	Message string          `json:"message"`
	Data    json.RawMessage `json:"data,omitempty"`
}

Response represents a generic API response structure.

func (*Response) IsSuccess

func (r *Response) IsSuccess() bool

IsSuccess checks if the API response indicates success.

Directories

Path Synopsis
Package logger provides structured logging interfaces and implementations for the GSPAY2 SDK client.
Package logger provides structured logging interfaces and implementations for the GSPAY2 SDK client.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL