Documentation
¶
Overview ¶
Package opensettle is the official Go SDK for the OpenSettle API.
OpenSettle is a non-custodial stablecoin billing platform: USDC and USDT subscriptions, one-shot checkouts, and invoices on Base, Ethereum, Polygon, Arbitrum, Solana, and Tron.
Quick start ¶
import "github.com/OpenSettle/opensettle-sdk-go"
client, err := opensettle.NewClient(
os.Getenv("OPENSETTLE_KEY"),
os.Getenv("OPENSETTLE_WORKSPACE"),
opensettle.WithTestMode(os.Getenv("ENV") != "production"),
)
if err != nil { log.Fatal(err) }
checkout, err := client.Checkouts.Create(ctx, opensettle.CreateCheckoutRequest{ /* ... */ })
Typed errors ¶
Every API error is mapped to a typed value reachable via errors.As:
if _, err := client.Payments.Refund(ctx, paymentID, req); err != nil {
var rl *opensettle.RateLimitError
if errors.As(err, &rl) {
time.Sleep(time.Duration(rl.RetryAfter) * time.Second)
return retry()
}
var settle *opensettle.SettlementError
if errors.As(err, &settle) && settle.Code == opensettle.CodeSigningRequired {
return promptCustomerToReapprove()
}
return err
}
Pagination ¶
Every List endpoint has a sibling ListIter that returns an Iter walking every page transparently:
it := client.Customers.ListIter(ctx, &opensettle.ListCustomersQuery{Status: opensettle.CustomerActive})
for it.Next() {
fmt.Println(it.Item().ID)
}
if err := it.Err(); err != nil { … }
Polling ¶
WaitFor is a polling helper for scripts and CI; production code should prefer webhooks. It calls retrieve every opts.Interval until the until predicate succeeds, then returns the resource:
pmt, err := opensettle.WaitFor(ctx,
client.Payments.Retrieve, "pay_…",
func(p *opensettle.Payment) bool { return p.Status == opensettle.PaymentConfirmed },
opensettle.WaitOptions{Timeout: 2 * time.Minute, Interval: 2 * time.Second},
)
On timeout you get a *WaitTimeoutError that carries the last-observed resource so you can inspect the partial state.
Idempotency keys ¶
Every money-adjacent write (Create, Refund, RotateSecret, …) auto-attaches an Idempotency-Key that is preserved across retry attempts. Pass WithIdempotencyKey to use a caller-chosen key when you have a natural deterministic id (e.g. your DB row id):
checkout, err := client.Checkouts.Create(ctx, req,
opensettle.WithIdempotencyKey("order:" + order.ID),
)
Webhooks ¶
Webhook signature verification lives in the sub-package github.com/OpenSettle/opensettle-sdk-go/webhooks so consumers can use it without dragging the full SDK into their webhook handler.
Index ¶
- Constants
- func FromEnvelope(body []byte, status int, retryAfter float64) error
- func IsOpenSettleError(err error) bool
- func WaitFor[T any](ctx context.Context, retrieve func(ctx context.Context, id string) (T, error), ...) (T, error)
- type APIError
- type AuthenticationError
- type AutopayMode
- type CancelMode
- type CancelSubscriptionRequest
- type ChainID
- type ChainIddeprecated
- type ChangePlanRequest
- type Checkout
- type CheckoutMode
- type CheckoutStatus
- type CheckoutsResource
- type Client
- type ConfigError
- type ConflictError
- type CreateCheckoutRequest
- type CreateCustomerRequest
- type CreateInvoiceRequest
- type CreatePriceRequest
- type CreateProductRequest
- type CreateSubscriptionRequest
- type CreateWebhookEndpointRequest
- type CreateWebhookEndpointResponse
- type CursorPage
- type Customer
- type CustomerStatus
- type CustomersResource
- func (r *CustomersResource) Create(ctx context.Context, input CreateCustomerRequest, opts ...RequestOption) (*Customer, error)
- func (r *CustomersResource) Delete(ctx context.Context, customerID string) error
- func (r *CustomersResource) List(ctx context.Context, query *ListCustomersQuery) (*CursorPage[Customer], error)
- func (r *CustomersResource) ListIter(ctx context.Context, query *ListCustomersQuery) *Iter[Customer]
- func (r *CustomersResource) Retrieve(ctx context.Context, customerID string) (*Customer, error)
- func (r *CustomersResource) Update(ctx context.Context, customerID string, input UpdateCustomerRequest) (*Customer, error)
- type ErrorCode
- type ForbiddenError
- type InitiateRefundRequest
- type InitiateRefundResponse
- type InvalidRequestError
- type InvalidStateTransitionError
- type Invoice
- type InvoiceStatus
- type InvoicesResource
- func (r *InvoicesResource) Create(ctx context.Context, input CreateInvoiceRequest, opts ...RequestOption) (*Invoice, error)
- func (r *InvoicesResource) List(ctx context.Context, query *ListInvoicesQuery) (*CursorPage[Invoice], error)
- func (r *InvoicesResource) ListIter(ctx context.Context, query *ListInvoicesQuery) *Iter[Invoice]
- func (r *InvoicesResource) Remind(ctx context.Context, invoiceID string, opts ...RequestOption) (*Invoice, error)
- func (r *InvoicesResource) Retrieve(ctx context.Context, invoiceID string) (*Invoice, error)
- func (r *InvoicesResource) Send(ctx context.Context, invoiceID string, opts ...RequestOption) (*Invoice, error)
- func (r *InvoicesResource) Void(ctx context.Context, invoiceID string) (*Invoice, error)
- type Iter
- type LineItem
- type ListCustomersQuery
- type ListInvoicesQuery
- type ListPaymentsQuery
- type ListProductsQuery
- type ListSubscriptionsQuery
- type Metadata
- type NetworkError
- type NotFoundError
- type OpenSettleError
- type Option
- type Payment
- type PaymentStatus
- type PaymentsResource
- func (r *PaymentsResource) List(ctx context.Context, query *ListPaymentsQuery) (*CursorPage[Payment], error)
- func (r *PaymentsResource) ListIter(ctx context.Context, query *ListPaymentsQuery) *Iter[Payment]
- func (r *PaymentsResource) Refund(ctx context.Context, paymentID string, input InitiateRefundRequest, ...) (*InitiateRefundResponse, error)
- func (r *PaymentsResource) RefundBroadcast(ctx context.Context, paymentID string, input RecordRefundBroadcastRequest, ...) (*Payment, error)
- func (r *PaymentsResource) Retrieve(ctx context.Context, paymentID string) (*Payment, error)
- type Price
- type PriceInterval
- type Product
- type ProductsResource
- func (r *ProductsResource) Create(ctx context.Context, input CreateProductRequest, opts ...RequestOption) (*Product, error)
- func (r *ProductsResource) CreatePrice(ctx context.Context, productID string, input CreatePriceRequest, ...) (*Price, error)
- func (r *ProductsResource) Delete(ctx context.Context, productID string) error
- func (r *ProductsResource) DeletePrice(ctx context.Context, priceID string) error
- func (r *ProductsResource) List(ctx context.Context, query *ListProductsQuery) (*CursorPage[Product], error)
- func (r *ProductsResource) ListIter(ctx context.Context, query *ListProductsQuery) *Iter[Product]
- func (r *ProductsResource) ListPrices(ctx context.Context, productID string) ([]Price, error)
- func (r *ProductsResource) Retrieve(ctx context.Context, productID string) (*Product, error)
- func (r *ProductsResource) Update(ctx context.Context, productID string, input UpdateProductRequest) (*Product, error)
- type ProrationMode
- type RateLimitError
- type RecordRefundBroadcastRequest
- type RequestOption
- type RotateWebhookSecretRequest
- type RotateWebhookSecretResponsedeprecated
- type SettlementError
- type StepUpRequiredError
- type Subscription
- type SubscriptionStatus
- type SubscriptionsResource
- func (r *SubscriptionsResource) Cancel(ctx context.Context, subID string, input CancelSubscriptionRequest) (*Subscription, error)
- func (r *SubscriptionsResource) ChangePlan(ctx context.Context, subID string, input ChangePlanRequest, ...) (*Subscription, error)
- func (r *SubscriptionsResource) Create(ctx context.Context, input CreateSubscriptionRequest, opts ...RequestOption) (*Subscription, error)
- func (r *SubscriptionsResource) List(ctx context.Context, query *ListSubscriptionsQuery) (*CursorPage[Subscription], error)
- func (r *SubscriptionsResource) ListIter(ctx context.Context, query *ListSubscriptionsQuery) *Iter[Subscription]
- func (r *SubscriptionsResource) Pause(ctx context.Context, subID string) (*Subscription, error)
- func (r *SubscriptionsResource) Resume(ctx context.Context, subID string) (*Subscription, error)
- func (r *SubscriptionsResource) Retrieve(ctx context.Context, subID string) (*Subscription, error)
- type TestWebhookEndpointRequest
- type TestWebhookEndpointResponse
- type TokenSymbol
- type UnsignedEVMTx
- type UnsignedEvmTxdeprecated
- type UnsignedTxEnvelope
- type UpdateCustomerRequest
- type UpdateProductRequest
- type UpdateWebhookEndpointRequest
- type WaitOptions
- type WaitTimeoutError
- type WebhookEndpoint
- type WebhookEndpointStatus
- type WebhookEndpointsResource
- func (r *WebhookEndpointsResource) Create(ctx context.Context, input CreateWebhookEndpointRequest, opts ...RequestOption) (*CreateWebhookEndpointResponse, error)
- func (r *WebhookEndpointsResource) Delete(ctx context.Context, endpointID string) error
- func (r *WebhookEndpointsResource) List(ctx context.Context) ([]WebhookEndpoint, error)
- func (r *WebhookEndpointsResource) Retrieve(ctx context.Context, endpointID string) (*WebhookEndpoint, error)
- func (r *WebhookEndpointsResource) RotateSecret(ctx context.Context, endpointID string, input RotateWebhookSecretRequest, ...) (*CreateWebhookEndpointResponse, error)
- func (r *WebhookEndpointsResource) Test(ctx context.Context, endpointID string, input TestWebhookEndpointRequest) (*TestWebhookEndpointResponse, error)
- func (r *WebhookEndpointsResource) Update(ctx context.Context, endpointID string, input UpdateWebhookEndpointRequest) (*WebhookEndpoint, error)
Examples ¶
Constants ¶
const Version = "0.5.0"
Version is the SDK release tag this build was cut from. It is sent as part of the User-Agent header on every request so the API can break out adoption by SDK version.
Variables ¶
This section is empty.
Functions ¶
func FromEnvelope ¶
FromEnvelope maps a parsed envelope + HTTP status to the right typed error. Unknown codes fall back to *APIError so a new server-side code can't crash older SDKs.
retryAfter is the parsed Retry-After header value (seconds); 0 means the server didn't send one.
func IsOpenSettleError ¶
IsOpenSettleError reports whether err is or wraps an *OpenSettleError. Convenience around errors.As for the broad case.
func WaitFor ¶ added in v0.3.0
func WaitFor[T any]( ctx context.Context, retrieve func(ctx context.Context, id string) (T, error), resourceID string, until func(T) bool, opts WaitOptions, ) (T, error)
WaitFor polls retrieve(ctx, id) every opts.Interval until until(r) returns true, then returns the resource. Returns *WaitTimeoutError when opts.Timeout elapses first, or the wrapped ctx error on cancellation. Any error returned by retrieve aborts the loop immediately.
Type parameter T is the concrete resource pointed at by Retrieve (e.g. *Payment, *Invoice).
Example ¶
package main
import (
"context"
"errors"
"fmt"
"log"
"time"
opensettle "github.com/OpenSettle/opensettle-sdk-go"
)
func main() {
client, _ := opensettle.NewClient("sk_test_x", "ws_test", opensettle.WithTestMode(true))
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
payment, err := opensettle.WaitFor(
ctx,
client.Payments.Retrieve,
"pay_123",
func(p *opensettle.Payment) bool { return p.Status == opensettle.PaymentConfirmed },
opensettle.WaitOptions{Timeout: 2 * time.Minute, Interval: 2 * time.Second},
)
if err != nil {
var timeoutErr *opensettle.WaitTimeoutError
if errors.As(err, &timeoutErr) {
last, _ := timeoutErr.Last.(*opensettle.Payment)
log.Fatalf("timed out; last status: %s", last.Status)
}
log.Fatal(err)
}
fmt.Println(payment.TxHash)
}
Output:
Types ¶
type APIError ¶
type APIError struct{ *OpenSettleError }
APIError is the catch-all for server-side problems: internal errors and codes the SDK doesn't recognize. Forward-compatible — a new server code won't crash older SDKs, just classify here.
type AuthenticationError ¶
type AuthenticationError struct{ *OpenSettleError }
AuthenticationError signals a 401 — missing, malformed, expired, or revoked credentials. Rotate the API key or re-authenticate the session.
func (*AuthenticationError) Unwrap ¶
func (e *AuthenticationError) Unwrap() error
Unwrap returns the embedded *OpenSettleError so errors.Is/As can match the base type.
type AutopayMode ¶
type AutopayMode string
AutopayMode controls how a subscription's renewal charge is collected. allowance uses an ERC-20 spend approval against the merchant's collector; smart-wallet uses a session-key-style preauthorization; manual prompts the customer to sign each renewal in their wallet.
const ( AutopayAllowance AutopayMode = "allowance" AutopaySmartWallet AutopayMode = "smart-wallet" AutopayManual AutopayMode = "manual" )
type CancelMode ¶
type CancelMode string
CancelMode controls whether cancellation is immediate or deferred to the next billing boundary.
const ( CancelImmediately CancelMode = "immediately" CancelAtPeriodEnd CancelMode = "at_period_end" )
type CancelSubscriptionRequest ¶
type CancelSubscriptionRequest struct {
Reason string `json:"reason,omitempty"`
Mode CancelMode `json:"mode,omitempty"`
}
CancelSubscriptionRequest is the body for POST /subscriptions/<id>/cancel. Reason is recorded on the audit log. Mode defaults to at_period_end when empty.
type ChainID ¶ added in v0.5.0
type ChainID string
ChainID is a supported settlement chain. Mirrors `ChainId` in `@opensettle/shared/schemas/wallet`.
type ChangePlanRequest ¶
type ChangePlanRequest struct {
PriceID string `json:"priceId"`
ProrationMode ProrationMode `json:"prorationMode,omitempty"`
}
ChangePlanRequest is the body for POST /subscriptions/<id>/change_plan. ProrationMode controls when the swap takes effect; default is immediately when empty.
type Checkout ¶
type Checkout struct {
ID string `json:"id"`
WorkspaceID string `json:"workspaceId"`
Mode CheckoutMode `json:"mode"`
Status CheckoutStatus `json:"status"`
CustomerID string `json:"customerId"`
InvoiceID *string `json:"invoiceId"`
PriceID *string `json:"priceId"`
AmountMinor int `json:"amountMinor"`
Currency string `json:"currency"`
Chain ChainId `json:"chain"`
Token TokenSymbol `json:"token"`
Description *string `json:"description"`
SuccessURL string `json:"successUrl"`
CancelURL *string `json:"cancelUrl"`
ExpiresAt string `json:"expiresAt"`
CompletedAt *string `json:"completedAt"`
Metadata Metadata `json:"metadata"`
CreatedAt string `json:"createdAt"`
// HostedURL is a relative URL path (e.g. "/checkout/<hostedToken>");
// concatenate with the web origin (e.g. "https://opensettle.io"+HostedURL)
// to get the buyer-facing redirect URL.
HostedURL string `json:"hostedUrl"`
}
Checkout is a hosted payment session. HostedURL is the relative path (e.g. "/checkout/<token>") to redirect the buyer to; concatenate with the OpenSettle web origin. AmountMinor + Currency are populated once the underlying invoice/price is resolved.
type CheckoutMode ¶
type CheckoutMode string
CheckoutMode selects what a hosted checkout session does. "payment" is a one-shot charge (typically attached to an invoice); "subscription" creates a recurring Subscription on successful completion.
const ( CheckoutPayment CheckoutMode = "payment" CheckoutSubscription CheckoutMode = "subscription" )
type CheckoutStatus ¶
type CheckoutStatus string
CheckoutStatus is the lifecycle bucket of a hosted checkout session. open is awaiting buyer; pending is buyer signed and broadcast, awaiting chain confirmation; succeeded, failed, and expired are terminal.
const ( CheckoutOpen CheckoutStatus = "open" CheckoutPending CheckoutStatus = "pending" CheckoutSucceeded CheckoutStatus = "succeeded" CheckoutFailed CheckoutStatus = "failed" CheckoutExpired CheckoutStatus = "expired" )
type CheckoutsResource ¶
type CheckoutsResource struct {
// contains filtered or unexported fields
}
CheckoutsResource exposes /v1/workspaces/<ws>/checkouts.
func (*CheckoutsResource) Create ¶
func (r *CheckoutsResource) Create(ctx context.Context, input CreateCheckoutRequest, opts ...RequestOption) (*Checkout, error)
Create starts a hosted checkout session. Body is required; the request is sent with an auto-generated Idempotency-Key to make retries safe. Supply WithIdempotencyKey to use a caller-chosen key instead.
Example ¶
package main
import (
"context"
"fmt"
"log"
opensettle "github.com/OpenSettle/opensettle-sdk-go"
)
func main() {
client, _ := opensettle.NewClient("sk_test_x", "ws_test", opensettle.WithTestMode(true))
ctx := context.Background()
checkout, err := client.Checkouts.Create(ctx, opensettle.CreateCheckoutRequest{
Mode: opensettle.CheckoutPayment,
CustomerID: "cu_123",
InvoiceID: "in_123",
SuccessURL: "https://example.com/thanks",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(checkout.HostedURL)
}
Output:
type Client ¶
type Client struct {
Checkouts *CheckoutsResource
Customers *CustomersResource
Invoices *InvoicesResource
Payments *PaymentsResource
Products *ProductsResource
Subscriptions *SubscriptionsResource
WebhookEndpoints *WebhookEndpointsResource
// contains filtered or unexported fields
}
Client is the top-level handle. One per workspace. Safe for concurrent use by multiple goroutines.
Example (TypedErrors) ¶
package main
import (
"context"
"errors"
"log"
"time"
opensettle "github.com/OpenSettle/opensettle-sdk-go"
)
func main() {
client, _ := opensettle.NewClient("sk_test_x", "ws_test", opensettle.WithTestMode(true))
ctx := context.Background()
_, err := client.Payments.Refund(ctx, "pay_123", opensettle.InitiateRefundRequest{})
if err == nil {
return
}
var rl *opensettle.RateLimitError
if errors.As(err, &rl) {
time.Sleep(time.Duration(rl.RetryAfter) * time.Second)
return
}
var stepUp *opensettle.StepUpRequiredError
if errors.As(err, &stepUp) {
// Caller needs to re-auth with AAL=2 before the refund will succeed.
log.Fatal("step-up required")
}
var settle *opensettle.SettlementError
if errors.As(err, &settle) && settle.Code == opensettle.CodeSigningRequired {
// Customer's wallet needs to re-approve the spend allowance.
log.Fatal("re-approval required")
}
log.Fatal(err)
}
Output:
func NewClient ¶
NewClient builds a Client. apiKey must start with sk_live_ or sk_test_; workspaceID is the merchant's workspace (required on every route).
Example ¶
package main
import (
"log"
"os"
"time"
opensettle "github.com/OpenSettle/opensettle-sdk-go"
)
func main() {
client, err := opensettle.NewClient(
os.Getenv("OPENSETTLE_KEY"),
os.Getenv("OPENSETTLE_WORKSPACE"),
opensettle.WithTestMode(true),
opensettle.WithTimeout(15*time.Second),
opensettle.WithMaxRetries(3),
)
if err != nil {
log.Fatal(err)
}
_ = client
}
Output:
type ConfigError ¶
type ConfigError struct{ Message string }
ConfigError is returned by NewClient when the caller's config is internally inconsistent (e.g. test-mode with a live key). Kept distinct from API-side errors so callers don't have to know they need a transport before hitting an obvious config bug.
func (*ConfigError) Error ¶
func (e *ConfigError) Error() string
type ConflictError ¶
type ConflictError struct{ *OpenSettleError }
ConflictError signals a 409 — typically an idempotency-key collision with a different request body, or an attempt to delete a resource that is still referenced by another.
func (*ConflictError) Unwrap ¶
func (e *ConflictError) Unwrap() error
Unwrap returns the embedded *OpenSettleError so errors.Is/As can match the base type.
type CreateCheckoutRequest ¶
type CreateCheckoutRequest struct {
Mode CheckoutMode `json:"mode"`
CustomerID string `json:"customerId,omitempty"`
CustomerEmail string `json:"customerEmail,omitempty"`
CustomerName string `json:"customerName,omitempty"`
InvoiceID string `json:"invoiceId,omitempty"`
PriceID string `json:"priceId,omitempty"`
SuccessURL string `json:"successUrl"`
CancelURL string `json:"cancelUrl,omitempty"`
Chain ChainId `json:"chain,omitempty"`
Token TokenSymbol `json:"token,omitempty"`
ExpiresInMinutes int `json:"expiresInMinutes,omitempty"`
Metadata Metadata `json:"metadata,omitempty"`
}
CreateCheckoutRequest is the body for POST /checkouts. Exactly one of (CustomerID) or (CustomerEmail [+ CustomerName]) should be supplied — the latter form auto-creates a Customer on the fly. For Mode=payment pass InvoiceID; for Mode=subscription pass PriceID. Chain/Token are optional pre-selections; if omitted, the buyer picks on the hosted page.
type CreateCustomerRequest ¶
type CreateCustomerRequest struct {
Email string `json:"email"`
Name string `json:"name,omitempty"`
Wallet string `json:"wallet,omitempty"`
Country string `json:"country,omitempty"`
Metadata Metadata `json:"metadata,omitempty"`
}
CreateCustomerRequest is the body for POST /customers. Email is the only required field; Wallet (when present) is validated against the workspace's enabled chains on the server.
type CreateInvoiceRequest ¶
type CreateInvoiceRequest struct {
CustomerID string `json:"customerId"`
Chain ChainId `json:"chain"`
Token TokenSymbol `json:"token"`
Currency string `json:"currency,omitempty"`
LineItems []LineItem `json:"lineItems"`
Memo string `json:"memo,omitempty"`
DueInDays int `json:"dueInDays,omitempty"`
SubscriptionID string `json:"subscriptionId,omitempty"`
Metadata Metadata `json:"metadata,omitempty"`
}
CreateInvoiceRequest is the body for POST /invoices. DueInDays is an integer offset from the server clock; the API converts it to DueAt. SubscriptionID is set automatically for subscription-generated invoices and should normally be left empty by callers.
type CreatePriceRequest ¶
type CreatePriceRequest struct {
Amount int `json:"amount"`
Currency string `json:"currency,omitempty"`
Interval PriceInterval `json:"interval"`
Metadata Metadata `json:"metadata,omitempty"`
}
CreatePriceRequest is the body for POST /products/<id>/prices. Amount is required and in minor units (e.g. cents). Currency defaults to the workspace's default fiat when empty.
type CreateProductRequest ¶
type CreateProductRequest struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
Metadata Metadata `json:"metadata,omitempty"`
}
CreateProductRequest is the body for POST /products.
type CreateSubscriptionRequest ¶
type CreateSubscriptionRequest struct {
CustomerID string `json:"customerId"`
PriceID string `json:"priceId"`
Chain ChainId `json:"chain"`
Token TokenSymbol `json:"token"`
Autopay AutopayMode `json:"autopay,omitempty"`
TrialDays int `json:"trialDays,omitempty"`
Metadata Metadata `json:"metadata,omitempty"`
}
CreateSubscriptionRequest is the body for POST /subscriptions. Autopay defaults to manual when empty. TrialDays > 0 starts the subscription in trialing status; the first charge fires at trial end.
type CreateWebhookEndpointRequest ¶
type CreateWebhookEndpointRequest struct {
URL string `json:"url"`
Description string `json:"description,omitempty"`
Events []string `json:"events,omitempty"`
}
CreateWebhookEndpointRequest is the body for POST /webhook_endpoints. Events is an allow-list of event-type names (e.g. "payment.confirmed"); omit or pass an empty slice to subscribe to all events.
type CreateWebhookEndpointResponse ¶
type CreateWebhookEndpointResponse struct {
Endpoint WebhookEndpoint `json:"endpoint"`
SigningSecret string `json:"signingSecret"`
}
CreateWebhookEndpointResponse is the multi-key envelope returned by POST /webhook_endpoints (and by /rotate). SigningSecret is the plaintext HMAC secret returned exactly once — store it immediately; subsequent reads only return the endpoint metadata.
type CursorPage ¶
type CursorPage[T any] struct { Data []T `json:"data"` NextCursor string `json:"nextCursor"` HasMore bool `json:"hasMore,omitempty"` }
CursorPage wraps a paginated list response. The API returns a cursor envelope around every listed collection.
type Customer ¶
type Customer struct {
ID string `json:"id"`
WorkspaceID string `json:"workspaceId"`
Email string `json:"email"`
Name string `json:"name"`
Wallet *string `json:"wallet"`
Country *string `json:"country"`
Status CustomerStatus `json:"status"`
ActiveSubscriptions int `json:"activeSubscriptions"`
LifetimeValue int `json:"lifetimeValue"`
Metadata Metadata `json:"metadata"`
CreatedAt string `json:"createdAt"`
DeletedAt *string `json:"deletedAt"`
}
Customer is a merchant's customer record. Email and Name are stored encrypted at rest; the API returns the decrypted view on Retrieve. ActiveSubscriptions and LifetimeValue are server-computed rollups. DeletedAt is set when the row is soft-deleted; reads still return it for audit purposes.
type CustomerStatus ¶
type CustomerStatus string
CustomerStatus is the derived health bucket OpenSettle assigns based on recent payment + subscription activity. It is not directly settable; the platform updates it as a side effect of billing events.
const ( CustomerActive CustomerStatus = "active" CustomerAtRisk CustomerStatus = "at_risk" CustomerChurned CustomerStatus = "churned" )
type CustomersResource ¶
type CustomersResource struct {
// contains filtered or unexported fields
}
CustomersResource exposes /v1/workspaces/<ws>/customers.
func (*CustomersResource) Create ¶
func (r *CustomersResource) Create(ctx context.Context, input CreateCustomerRequest, opts ...RequestOption) (*Customer, error)
Create makes a new customer. Auto-attaches an Idempotency-Key; supply WithIdempotencyKey to use a caller-chosen key instead.
func (*CustomersResource) Delete ¶
func (r *CustomersResource) Delete(ctx context.Context, customerID string) error
Delete is a soft-delete: PII is scrubbed but historical references continue to resolve.
func (*CustomersResource) List ¶
func (r *CustomersResource) List(ctx context.Context, query *ListCustomersQuery) (*CursorPage[Customer], error)
List returns a cursor-paginated page of customers.
func (*CustomersResource) ListIter ¶ added in v0.3.0
func (r *CustomersResource) ListIter(ctx context.Context, query *ListCustomersQuery) *Iter[Customer]
ListIter returns a cursor-driven iterator over all customers matching the query. Auto-fetches subsequent pages.
it := c.Customers.ListIter(ctx, &opensettle.ListCustomersQuery{Status: opensettle.CustomerActive})
for it.Next() { fmt.Println(it.Item().ID) }
if err := it.Err(); err != nil { … }
Example ¶
package main
import (
"context"
"fmt"
"log"
opensettle "github.com/OpenSettle/opensettle-sdk-go"
)
func main() {
client, _ := opensettle.NewClient("sk_test_x", "ws_test", opensettle.WithTestMode(true))
ctx := context.Background()
it := client.Customers.ListIter(ctx, &opensettle.ListCustomersQuery{
Status: opensettle.CustomerActive,
Limit: 100,
})
for it.Next() {
fmt.Println(it.Item().ID)
}
if err := it.Err(); err != nil {
log.Fatal(err)
}
}
Output:
func (*CustomersResource) Update ¶
func (r *CustomersResource) Update(ctx context.Context, customerID string, input UpdateCustomerRequest) (*Customer, error)
Update applies a partial update.
type ErrorCode ¶
type ErrorCode string
ErrorCode is the API's stable error taxonomy. Values mirror `packages/sdk/src/errors.ts` exactly.
const ( CodeInvalidRequest ErrorCode = "invalid_request" CodeInvalidStateTransition ErrorCode = "invalid_state_transition" CodeForbidden ErrorCode = "forbidden" CodeNotFound ErrorCode = "not_found" CodeConflict ErrorCode = "conflict" CodeRateLimited ErrorCode = "rate_limited" CodeInternalError ErrorCode = "internal_error" CodeChainReverted ErrorCode = "chain_reverted" CodeInsufficientConfirmations ErrorCode = "insufficient_confirmations" CodeSigningRequired ErrorCode = "signing_required" CodeAALRequired ErrorCode = "aal_required" CodeNetworkError ErrorCode = "network_error" )
type ForbiddenError ¶
type ForbiddenError struct{ *OpenSettleError }
ForbiddenError signals a 403 — credentials are valid but lack permission for the requested action or workspace.
func (*ForbiddenError) Unwrap ¶
func (e *ForbiddenError) Unwrap() error
Unwrap returns the embedded *OpenSettleError so errors.Is/As can match the base type.
type InitiateRefundRequest ¶
type InitiateRefundRequest struct {
AmountMinor int `json:"amountMinor,omitempty"`
Reason string `json:"reason,omitempty"`
RecipientAddress string `json:"recipientAddress,omitempty"`
}
InitiateRefundRequest is the body for POST /payments/<id>/refund. AmountMinor omitted (zero) means refund the full remaining amount. RecipientAddress overrides the default refund destination (the original payer); the server validates it against the payment's chain.
type InitiateRefundResponse ¶
type InitiateRefundResponse struct {
Payment Payment `json:"payment"`
UnsignedTx UnsignedTxEnvelope `json:"unsignedTx"`
}
InitiateRefundResponse is the multi-key envelope returned by POST /payments/<id>/refund. The Payment is in status refund_pending; the UnsignedTx must be signed by the merchant wallet and broadcast, then reported back via RefundBroadcast.
type InvalidRequestError ¶
type InvalidRequestError struct{ *OpenSettleError }
InvalidRequestError signals a 4xx validation failure: malformed JSON, missing required fields, or values that fail server-side schema checks. Param often names the offending field.
func (*InvalidRequestError) Unwrap ¶
func (e *InvalidRequestError) Unwrap() error
Unwrap returns the embedded *OpenSettleError so errors.Is/As can match the base type.
type InvalidStateTransitionError ¶
type InvalidStateTransitionError struct{ *OpenSettleError }
InvalidStateTransitionError signals an attempt to move a resource to a state its current state forbids (e.g. voiding a paid invoice, canceling an already-canceled subscription).
func (*InvalidStateTransitionError) Unwrap ¶
func (e *InvalidStateTransitionError) Unwrap() error
Unwrap returns the embedded *OpenSettleError so errors.Is/As can match the base type.
type Invoice ¶
type Invoice struct {
ID string `json:"id"`
WorkspaceID string `json:"workspaceId"`
Number string `json:"number"`
CustomerID string `json:"customerId"`
SubscriptionID *string `json:"subscriptionId"`
AmountMinor int `json:"amountMinor"`
Currency string `json:"currency"`
Chain ChainId `json:"chain"`
Token TokenSymbol `json:"token"`
Status InvoiceStatus `json:"status"`
LineItems []LineItem `json:"lineItems"`
Memo *string `json:"memo"`
PaymentID *string `json:"paymentId"`
HostedURL string `json:"hostedUrl"`
IssuedAt *string `json:"issuedAt"`
DueAt string `json:"dueAt"`
PaidAt *string `json:"paidAt"`
VoidedAt *string `json:"voidedAt"`
Metadata Metadata `json:"metadata"`
CreatedAt string `json:"createdAt"`
}
Invoice is a billable document. AmountMinor is in minor units of Currency (fiat). Chain + Token specify how the customer will settle on chain. HostedURL is the buyer-facing page the customer pays from. PaymentID is set once a payment confirms.
type InvoiceStatus ¶
type InvoiceStatus string
InvoiceStatus is the lifecycle state of an invoice. draft is the only editable state; open is sent-but-unpaid; paid and void are terminal; past_due is open + past DueAt.
const ( InvoiceDraft InvoiceStatus = "draft" InvoiceOpen InvoiceStatus = "open" InvoicePaid InvoiceStatus = "paid" InvoicePastDue InvoiceStatus = "past_due" InvoiceVoid InvoiceStatus = "void" )
type InvoicesResource ¶
type InvoicesResource struct {
// contains filtered or unexported fields
}
InvoicesResource exposes /v1/workspaces/<ws>/invoices.
func (*InvoicesResource) Create ¶
func (r *InvoicesResource) Create(ctx context.Context, input CreateInvoiceRequest, opts ...RequestOption) (*Invoice, error)
Create makes a new invoice. Auto-attaches an Idempotency-Key; supply WithIdempotencyKey to use a caller-chosen key instead.
func (*InvoicesResource) List ¶
func (r *InvoicesResource) List(ctx context.Context, query *ListInvoicesQuery) (*CursorPage[Invoice], error)
List returns one page of invoices for the workspace. Pass nil for an unfiltered first page; use ListIter for cursor-driven full iteration.
func (*InvoicesResource) ListIter ¶ added in v0.3.0
func (r *InvoicesResource) ListIter(ctx context.Context, query *ListInvoicesQuery) *Iter[Invoice]
ListIter returns a cursor-driven iterator over all invoices matching the query.
func (*InvoicesResource) Remind ¶
func (r *InvoicesResource) Remind(ctx context.Context, invoiceID string, opts ...RequestOption) (*Invoice, error)
Remind re-sends a reminder for an unpaid invoice. Auto-attaches an Idempotency-Key; supply WithIdempotencyKey to override.
func (*InvoicesResource) Send ¶
func (r *InvoicesResource) Send(ctx context.Context, invoiceID string, opts ...RequestOption) (*Invoice, error)
Send emails the hosted invoice link to the customer. Auto-attaches an Idempotency-Key; supply WithIdempotencyKey to override.
type Iter ¶ added in v0.3.0
type Iter[T any] struct { // contains filtered or unexported fields }
Iter is a cursor-driven iterator over a paginated API resource. It auto-fetches the next page when the current page is drained and stops when the server signals hasMore=false.
Resource List methods continue to return a single page for backward compatibility; iterators are returned by separate ListIter (or Iter-suffixed) methods on each resource — see the resource files.
Usage:
it := c.Customers.ListIter(ctx, &opensettle.ListCustomersQuery{Status: opensettle.CustomerActive})
for it.Next() {
fmt.Println(it.Item().ID)
}
if err := it.Err(); err != nil { … }
func (*Iter[T]) Err ¶ added in v0.3.0
Err returns any error that stopped the iteration. Nil on a clean end.
type LineItem ¶
type LineItem struct {
Description string `json:"description"`
Quantity int `json:"quantity"`
UnitAmountMinor int `json:"unitAmountMinor"`
}
LineItem is a single row on an invoice. UnitAmountMinor is in minor units (e.g. cents); the line total is Quantity * UnitAmountMinor.
type ListCustomersQuery ¶
type ListCustomersQuery struct {
Status CustomerStatus
Q string
Cursor string
Limit int
}
ListCustomersQuery filters GET /customers. Q is a free-text search over email + name. Status filters by derived health bucket; leave empty for all. Cursor + Limit drive pagination (Limit max 100).
type ListInvoicesQuery ¶
type ListInvoicesQuery struct {
Cursor string
Limit int
CustomerID string
Status InvoiceStatus
}
ListInvoicesQuery filters GET /invoices. CustomerID narrows to one customer; Status filters by lifecycle bucket. Cursor + Limit drive pagination.
type ListPaymentsQuery ¶
type ListPaymentsQuery struct {
Cursor string
Limit int
CustomerID string
Status PaymentStatus
}
ListPaymentsQuery filters GET /payments. CustomerID narrows to one customer; Status filters by on-chain lifecycle bucket. Cursor + Limit drive pagination.
type ListProductsQuery ¶
ListProductsQuery filters GET /products. Active is a tri-state pointer: nil = both active and inactive, &true = active only, &false = inactive only.
type ListSubscriptionsQuery ¶
type ListSubscriptionsQuery struct {
Cursor string
Limit int
CustomerID string
Status SubscriptionStatus
}
ListSubscriptionsQuery filters GET /subscriptions. CustomerID narrows to one customer; Status filters by lifecycle bucket. Cursor + Limit drive pagination.
type Metadata ¶
Metadata is the free-form key/value blob attached to most resources. Values are arbitrary JSON; Go callers can marshal whatever the API accepts on their side. Nil = no metadata.
type NetworkError ¶
type NetworkError struct{ *OpenSettleError }
NetworkError is the transport-layer failure: DNS, ECONNREFUSED, TLS handshake errors, context-deadline. Status is always 0.
func (*NetworkError) Unwrap ¶
func (e *NetworkError) Unwrap() error
Unwrap returns the embedded *OpenSettleError so errors.Is/As can match the base type.
type NotFoundError ¶
type NotFoundError struct{ *OpenSettleError }
NotFoundError signals a 404 — the resource ID doesn't exist or isn't visible to the calling credentials.
func (*NotFoundError) Unwrap ¶
func (e *NotFoundError) Unwrap() error
Unwrap returns the embedded *OpenSettleError so errors.Is/As can match the base type.
type OpenSettleError ¶
type OpenSettleError struct {
Code ErrorCode
Message string
Status int
RequestID string
Param string
}
OpenSettleError is the base type. Every concrete error in this package embeds it, so callers can either match the broad type via errors.As(err, &*OpenSettleError{}) or branch on the specific subtype. Param, when non-empty, names the request field the server rejected (e.g. "amountMinor") — useful for surfacing per-field validation messages.
func (*OpenSettleError) Error ¶
func (e *OpenSettleError) Error() string
Error formats the error for log output. Includes the stable code, HTTP status, and (when available) request ID for support correlation.
type Option ¶
type Option func(*clientConfig)
Option configures a Client. Use NewClient(...).
func WithBaseURL ¶
WithBaseURL overrides the API host. Defaults to https://api.opensettle.io.
func WithHTTPClient ¶
WithHTTPClient replaces the underlying *http.Client. Useful for injecting custom transports, proxies, or mocks. The SDK still applies its own retry and timeout logic on top.
func WithMaxRetries ¶
WithMaxRetries sets the retry budget for transient failures (5xx, 429, transport errors). Default 3. Set 0 to disable retries entirely.
func WithTestMode ¶
WithTestMode asserts the apiKey environment matches. With true, the SDK refuses sk_live_… keys; with false it refuses sk_test_…. Useful as a circuit breaker in CI. Default is unasserted (either accepted).
func WithTimeout ¶
WithTimeout sets the per-request timeout. Default 30s.
func WithUserAgent ¶
WithUserAgent appends a caller-supplied product token to the SDK's User-Agent. The default is `opensettle-go/<Version>`; with this option the header becomes `opensettle-go/<Version> <userAgent>`.
type Payment ¶
type Payment struct {
ID string `json:"id"`
WorkspaceID string `json:"workspaceId"`
CustomerID *string `json:"customerId"`
SubscriptionID *string `json:"subscriptionId"`
InvoiceID *string `json:"invoiceId"`
WalletID *string `json:"walletId"`
AmountMinor int `json:"amountMinor"`
FeeMinor int `json:"feeMinor"`
NetMinor int `json:"netMinor"`
Currency string `json:"currency"`
Token TokenSymbol `json:"token"`
Chain ChainId `json:"chain"`
Status PaymentStatus `json:"status"`
FailureReason *string `json:"failureReason"`
Description *string `json:"description"`
TxHash *string `json:"txHash"`
BlockNumber *int `json:"blockNumber"`
Confirmations int `json:"confirmations"`
RefundTxHash *string `json:"refundTxHash"`
RefundAmountMinor *int `json:"refundAmountMinor"`
RefundBroadcastAt *string `json:"refundBroadcastAt"`
RefundedAt *string `json:"refundedAt"`
RefundReason *string `json:"refundReason"`
CreatedAt string `json:"createdAt"`
ConfirmedAt *string `json:"confirmedAt"`
}
Payment is a single on-chain settlement attempt. AmountMinor, FeeMinor, and NetMinor are denominated in minor units of Currency (fiat); the on-chain settlement value is in Token base units, derived at quote time. TxHash is set once the customer broadcasts. Refund fields are populated only after Refund + RefundBroadcast are called.
type PaymentStatus ¶
type PaymentStatus string
PaymentStatus is the on-chain lifecycle of a payment. pending means broadcast-but-unconfirmed; confirmed has met the workspace's required confirmation depth; refunded means a refund tx has confirmed; reorged means a previously-confirmed payment was rolled back by a chain reorganization.
const ( PaymentPending PaymentStatus = "pending" PaymentConfirmed PaymentStatus = "confirmed" PaymentFailed PaymentStatus = "failed" PaymentRefunded PaymentStatus = "refunded" PaymentReorged PaymentStatus = "reorged" )
type PaymentsResource ¶
type PaymentsResource struct {
// contains filtered or unexported fields
}
PaymentsResource exposes /v1/workspaces/<ws>/payments.
func (*PaymentsResource) List ¶
func (r *PaymentsResource) List(ctx context.Context, query *ListPaymentsQuery) (*CursorPage[Payment], error)
List returns one page of payments for the workspace. Pass nil for an unfiltered first page; use ListIter for cursor-driven full iteration.
func (*PaymentsResource) ListIter ¶ added in v0.3.0
func (r *PaymentsResource) ListIter(ctx context.Context, query *ListPaymentsQuery) *Iter[Payment]
ListIter returns a cursor-driven iterator over all payments matching the query.
func (*PaymentsResource) Refund ¶
func (r *PaymentsResource) Refund(ctx context.Context, paymentID string, input InitiateRefundRequest, opts ...RequestOption) (*InitiateRefundResponse, error)
Refund initiates a refund. Returns a multi-key envelope {payment, unsignedTx} — the merchant's wallet signs unsignedTx and broadcasts it; OpenSettle never holds funds.
Step-up auth (AAL=2) is required on this route, surfaced as *StepUpRequiredError for API-key callers. Sessions get through if they re-authed within freshWithinSeconds.
Auto-attaches an Idempotency-Key; supply WithIdempotencyKey to use a caller-chosen key (recommended for refund flows where the caller has a natural deterministic id, e.g. the refund's row id in your DB).
func (*PaymentsResource) RefundBroadcast ¶
func (r *PaymentsResource) RefundBroadcast(ctx context.Context, paymentID string, input RecordRefundBroadcastRequest, opts ...RequestOption) (*Payment, error)
RefundBroadcast tells OpenSettle the merchant has signed and broadcast the refund tx. The chain reader picks it up and flips status to refunded once it confirms. Auto-attaches an Idempotency-Key; supply WithIdempotencyKey to override.
type Price ¶
type Price struct {
ID string `json:"id"`
WorkspaceID string `json:"workspaceId"`
ProductID string `json:"productId"`
Amount int `json:"amount"`
Currency string `json:"currency"`
Interval PriceInterval `json:"interval"`
Active bool `json:"active"`
Metadata Metadata `json:"metadata"`
CreatedAt string `json:"createdAt"`
}
Price is a (product, amount, interval) tuple. Amount is in minor units (e.g. cents). Currency is the fiat denomination (USD, EUR, …); the chain + token used to settle are chosen per-charge, not on the price.
type PriceInterval ¶
type PriceInterval string
PriceInterval is the billing cadence of a Price. "one_time" is a non-recurring price suitable for invoices and single-payment checkouts; the others are recurring intervals consumed by subscriptions.
const ( PriceOneTime PriceInterval = "one_time" PriceWeek PriceInterval = "week" PriceMonth PriceInterval = "month" PriceYear PriceInterval = "year" )
type Product ¶
type Product struct {
ID string `json:"id"`
WorkspaceID string `json:"workspaceId"`
Name string `json:"name"`
Description *string `json:"description"`
Active bool `json:"active"`
Metadata Metadata `json:"metadata"`
CreatedAt string `json:"createdAt"`
}
Product is a sellable item in the workspace catalog. Active=false hides it from new checkouts but does not affect subscriptions already using its prices.
type ProductsResource ¶
type ProductsResource struct {
// contains filtered or unexported fields
}
ProductsResource exposes /v1/workspaces/<ws>/products and the nested /prices collection.
func (*ProductsResource) Create ¶
func (r *ProductsResource) Create(ctx context.Context, input CreateProductRequest, opts ...RequestOption) (*Product, error)
Create makes a new product. Auto-attaches an Idempotency-Key; supply WithIdempotencyKey to use a caller-chosen key instead.
func (*ProductsResource) CreatePrice ¶
func (r *ProductsResource) CreatePrice(ctx context.Context, productID string, input CreatePriceRequest, opts ...RequestOption) (*Price, error)
CreatePrice attaches a new price to a product. Auto-attaches an Idempotency-Key; supply WithIdempotencyKey to override.
func (*ProductsResource) Delete ¶
func (r *ProductsResource) Delete(ctx context.Context, productID string) error
Delete is a hard-delete. Returns *ConflictError (409) if any subscription still references the product.
func (*ProductsResource) DeletePrice ¶
func (r *ProductsResource) DeletePrice(ctx context.Context, priceID string) error
DeletePrice hard-deletes a price. Returns *ConflictError (409) if any subscription still references it.
func (*ProductsResource) List ¶
func (r *ProductsResource) List(ctx context.Context, query *ListProductsQuery) (*CursorPage[Product], error)
List returns one page of products. Pass nil for an unfiltered first page; use ListIter for cursor-driven full iteration.
func (*ProductsResource) ListIter ¶ added in v0.3.0
func (r *ProductsResource) ListIter(ctx context.Context, query *ListProductsQuery) *Iter[Product]
ListIter returns a cursor-driven iterator over all products matching the query.
func (*ProductsResource) ListPrices ¶
ListPrices returns the prices attached to a product.
func (*ProductsResource) Update ¶
func (r *ProductsResource) Update(ctx context.Context, productID string, input UpdateProductRequest) (*Product, error)
Update patches a product. Fields left nil on input are unchanged.
type ProrationMode ¶
type ProrationMode string
ProrationMode controls when a plan change takes effect.
const ( ProrationImmediately ProrationMode = "immediately" ProrationAtPeriodEnd ProrationMode = "at_period_end" )
type RateLimitError ¶
type RateLimitError struct {
*OpenSettleError
RetryAfter float64
}
RateLimitError carries the optional Retry-After hint advertised by the API. Value is in seconds. A zero RetryAfter means the server didn't advertise one — caller should fall back to its own backoff.
func (*RateLimitError) Unwrap ¶
func (e *RateLimitError) Unwrap() error
Unwrap returns the embedded *OpenSettleError so errors.Is/As can match the base type.
type RecordRefundBroadcastRequest ¶
type RecordRefundBroadcastRequest struct {
RefundTxHash string `json:"refundTxHash"`
}
RecordRefundBroadcastRequest is the body for POST /payments/<id>/refund/broadcast. The caller supplies the tx hash returned by their wallet after broadcasting the unsigned refund tx.
type RequestOption ¶ added in v0.5.0
type RequestOption func(*requestConfig)
RequestOption is a per-call knob that can be supplied to any money-adjacent write method (Create, Refund, RotateSecret, etc.). The SDK applies all options after its own defaults, so options always win.
Today the only option is WithIdempotencyKey; the type is exported so the SDK can grow per-call options without breaking method signatures.
func WithIdempotencyKey ¶ added in v0.5.0
func WithIdempotencyKey(key string) RequestOption
WithIdempotencyKey supplies a caller-chosen Idempotency-Key for this request. Use this when you want to assign a deterministic key (e.g. your own order id) so that retries from different machines or processes collapse to the same server-side operation.
If WithIdempotencyKey is not supplied, the SDK auto-generates a UUIDv4 key for every money-adjacent write. Either way, the same key is reused across all retry attempts of a single call.
Example ¶
package main
import (
"context"
"fmt"
"log"
opensettle "github.com/OpenSettle/opensettle-sdk-go"
)
func main() {
client, _ := opensettle.NewClient("sk_test_x", "ws_test", opensettle.WithTestMode(true))
ctx := context.Background()
// Use the merchant's order id as the idempotency key — any number of
// retries (from this machine or another) will collapse to the same
// server-side checkout.
checkout, err := client.Checkouts.Create(ctx,
opensettle.CreateCheckoutRequest{
Mode: opensettle.CheckoutPayment,
CustomerID: "cu_123",
InvoiceID: "in_123",
SuccessURL: "https://example.com/thanks",
},
opensettle.WithIdempotencyKey("order:42"),
)
if err != nil {
log.Fatal(err)
}
fmt.Println(checkout.ID)
}
Output:
type RotateWebhookSecretRequest ¶
type RotateWebhookSecretRequest struct {
GraceSeconds int `json:"graceSeconds,omitempty"`
}
RotateWebhookSecretRequest is the body for POST /webhook_endpoints/<id>/rotate. GraceSeconds is the dual-signing window during which both old and new secrets produce valid signatures; default is server-side when zero.
type RotateWebhookSecretResponse
deprecated
type RotateWebhookSecretResponse = CreateWebhookEndpointResponse
RotateWebhookSecretResponse is now an alias for CreateWebhookEndpointResponse — the rotate endpoint returns the same {endpoint, signingSecret} envelope as create.
Deprecated: use *CreateWebhookEndpointResponse directly. This alias will be removed in a future release.
type SettlementError ¶
type SettlementError struct{ *OpenSettleError }
SettlementError covers chain-level failures: reverted txs, insufficient confirmations, signing/re-approval required.
func (*SettlementError) Unwrap ¶
func (e *SettlementError) Unwrap() error
Unwrap returns the embedded *OpenSettleError so errors.Is/As can match the base type.
type StepUpRequiredError ¶
type StepUpRequiredError struct{ *OpenSettleError }
StepUpRequiredError is returned when a route requires AAL=2 (step-up auth) that the current session hasn't met. API-key callers see this on money-adjacent writes that need explicit re-authorization.
func (*StepUpRequiredError) Unwrap ¶
func (e *StepUpRequiredError) Unwrap() error
Unwrap returns the embedded *OpenSettleError so errors.Is/As can match the base type.
type Subscription ¶
type Subscription struct {
ID string `json:"id"`
WorkspaceID string `json:"workspaceId"`
CustomerID string `json:"customerId"`
ProductID string `json:"productId"`
PriceID string `json:"priceId"`
AmountMinor int `json:"amountMinor"`
Currency string `json:"currency"`
Chain ChainId `json:"chain"`
Token TokenSymbol `json:"token"`
Status SubscriptionStatus `json:"status"`
Autopay AutopayMode `json:"autopay"`
AllowanceTx *string `json:"allowanceTx"`
AllowanceRemaining *int `json:"allowanceRemaining"`
TrialEndsAt *string `json:"trialEndsAt"`
StartedAt string `json:"startedAt"`
CurrentPeriodEnd string `json:"currentPeriodEnd"`
NextBillingDate string `json:"nextBillingDate"`
CanceledAt *string `json:"canceledAt"`
CancelReason *string `json:"cancelReason"`
PausedAt *string `json:"pausedAt"`
MRRMinor int `json:"mrrMinor"`
Metadata Metadata `json:"metadata"`
CreatedAt string `json:"createdAt"`
}
Subscription is a recurring billing arrangement. AmountMinor is in minor units of Currency (fiat); MRRMinor is the normalized monthly recurring revenue contribution. AllowanceTx/AllowanceRemaining are populated only when Autopay=allowance. CurrentPeriodEnd and NextBillingDate are server-managed.
type SubscriptionStatus ¶
type SubscriptionStatus string
SubscriptionStatus is the lifecycle bucket of a subscription. trialing is pre-billing; active is current; past_due is one or more failed renewals; paused stops billing without canceling; canceled is terminal.
const ( SubTrialing SubscriptionStatus = "trialing" SubActive SubscriptionStatus = "active" SubPastDue SubscriptionStatus = "past_due" SubPaused SubscriptionStatus = "paused" SubCanceled SubscriptionStatus = "canceled" )
type SubscriptionsResource ¶
type SubscriptionsResource struct {
// contains filtered or unexported fields
}
SubscriptionsResource exposes /v1/workspaces/<ws>/subscriptions.
func (*SubscriptionsResource) Cancel ¶
func (r *SubscriptionsResource) Cancel(ctx context.Context, subID string, input CancelSubscriptionRequest) (*Subscription, error)
Cancel ends a subscription. Mode controls timing (immediately vs at_period_end). Default is at_period_end when input.Mode is empty. Reason is recorded on the audit log.
func (*SubscriptionsResource) ChangePlan ¶
func (r *SubscriptionsResource) ChangePlan(ctx context.Context, subID string, input ChangePlanRequest, opts ...RequestOption) (*Subscription, error)
ChangePlan swaps the subscription to a new price. ProrationMode controls whether the customer is billed immediately for the delta or at the next period boundary. Auto-attaches an Idempotency-Key; supply WithIdempotencyKey to override.
func (*SubscriptionsResource) Create ¶
func (r *SubscriptionsResource) Create(ctx context.Context, input CreateSubscriptionRequest, opts ...RequestOption) (*Subscription, error)
Create starts a new subscription. Auto-attaches an Idempotency-Key; supply WithIdempotencyKey to use a caller-chosen key instead.
func (*SubscriptionsResource) List ¶
func (r *SubscriptionsResource) List(ctx context.Context, query *ListSubscriptionsQuery) (*CursorPage[Subscription], error)
List returns one page of subscriptions. Pass nil for an unfiltered first page; use ListIter for cursor-driven full iteration.
func (*SubscriptionsResource) ListIter ¶ added in v0.3.0
func (r *SubscriptionsResource) ListIter(ctx context.Context, query *ListSubscriptionsQuery) *Iter[Subscription]
ListIter returns a cursor-driven iterator over all subscriptions matching the query.
func (*SubscriptionsResource) Pause ¶
func (r *SubscriptionsResource) Pause(ctx context.Context, subID string) (*Subscription, error)
Pause stops billing on a subscription without canceling it. Resume to continue. No proration; the next billing date shifts forward by the paused interval.
func (*SubscriptionsResource) Resume ¶
func (r *SubscriptionsResource) Resume(ctx context.Context, subID string) (*Subscription, error)
Resume reactivates a paused subscription. Billing restarts from the shifted next-billing date set when the subscription was paused.
func (*SubscriptionsResource) Retrieve ¶
func (r *SubscriptionsResource) Retrieve(ctx context.Context, subID string) (*Subscription, error)
Retrieve fetches a single subscription by ID.
type TestWebhookEndpointRequest ¶
type TestWebhookEndpointRequest struct {
EventType string `json:"eventType"`
}
TestWebhookEndpointRequest is the body for POST /webhook_endpoints/<id>/test. EventType is the event-type name to fire as a sample (e.g. "payment.confirmed"); the payload is server-generated.
type TestWebhookEndpointResponse ¶
type TestWebhookEndpointResponse struct {
OK bool `json:"ok"`
Status int `json:"status"`
LatencyMs int `json:"latencyMs"`
}
TestWebhookEndpointResponse reports the result of a synchronous test delivery. Status is the HTTP status the endpoint returned to OpenSettle; LatencyMs is the round-trip latency observed by the dispatcher. OK is true when Status was 2xx.
type TokenSymbol ¶
type TokenSymbol string
TokenSymbol is a supported stablecoin. The platform settles only in USDC and USDT.
const ( TokenUSDC TokenSymbol = "USDC" TokenUSDT TokenSymbol = "USDT" )
type UnsignedEVMTx ¶ added in v0.5.0
type UnsignedEVMTx struct {
To string `json:"to"`
Data string `json:"data"`
Value string `json:"value"`
ChainID int `json:"chainId"`
TokenAddress string `json:"tokenAddress"`
Recipient string `json:"recipient"`
AmountBaseUnits string `json:"amountBaseUnits"`
}
UnsignedEVMTx is the EVM-shaped portion of an unsigned refund payload. Value is the native-currency wei value (typically "0" for ERC-20 transfers); AmountBaseUnits is the token amount in its smallest unit (e.g. 6-decimal USDC). The merchant signs this with their wallet and broadcasts; OpenSettle never holds keys.
type UnsignedEvmTx
deprecated
type UnsignedEvmTx = UnsignedEVMTx
UnsignedEvmTx is the pre-Go-idiomatic name for UnsignedEVMTx. Kept as a type alias for backward compatibility; new code should prefer UnsignedEVMTx.
Deprecated: use UnsignedEVMTx instead.
type UnsignedTxEnvelope ¶
type UnsignedTxEnvelope struct {
Chain ChainId `json:"chain"`
Token TokenSymbol `json:"token"`
To string `json:"to"`
AmountMinor int `json:"amountMinor"`
Memo string `json:"memo,omitempty"`
Instructions string `json:"instructions"`
EVM *UnsignedEvmTx `json:"evm,omitempty"`
}
UnsignedTxEnvelope wraps a chain-agnostic refund description plus an optional chain-specific payload (today: EVM). Instructions is a human-readable hint for wallet UIs. AmountMinor is in fiat minor units; the chain-specific block carries the token-base-unit amount.
type UpdateCustomerRequest ¶
type UpdateCustomerRequest struct {
Name *string `json:"name,omitempty"`
Wallet *string `json:"wallet,omitempty"`
Country *string `json:"country,omitempty"`
Metadata Metadata `json:"metadata,omitempty"`
}
UpdateCustomerRequest is the body for PATCH /customers/<id>. Fields are PATCH-style: omit a field (leave the pointer nil) to leave the existing value unchanged. To clear a string field, pass a pointer to the empty string.
type UpdateProductRequest ¶
type UpdateProductRequest struct {
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
Active *bool `json:"active,omitempty"`
Metadata Metadata `json:"metadata,omitempty"`
}
UpdateProductRequest is the body for PATCH /products/<id>. Fields are PATCH-style: omit a field (leave the pointer nil) to leave the existing value unchanged. Setting Active=false hides the product from new checkouts.
type UpdateWebhookEndpointRequest ¶
type UpdateWebhookEndpointRequest struct {
URL *string `json:"url,omitempty"`
Description *string `json:"description,omitempty"`
Events []string `json:"events,omitempty"`
Status *WebhookEndpointStatus `json:"status,omitempty"`
}
UpdateWebhookEndpointRequest is the body for PATCH /webhook_endpoints/<id>. Fields are PATCH-style: omit a field (leave the pointer nil) to leave the existing value unchanged. Passing a non-nil Events replaces the allow-list entirely.
type WaitOptions ¶ added in v0.3.0
type WaitOptions struct {
// Hard timeout. Defaults to 2 minutes when zero.
Timeout time.Duration
// Poll interval. Defaults to 2 seconds when zero.
Interval time.Duration
// contains filtered or unexported fields
}
WaitOptions tunes polling behaviour.
type WaitTimeoutError ¶ added in v0.3.0
type WaitTimeoutError struct {
ResourceID string
Timeout time.Duration
// Last is the most-recently-observed resource (typed as the
// concrete *T that the Retrieve closure returns).
Last any
}
WaitTimeoutError is returned when the target state is not reached before the timeout elapses. It carries the last-observed resource as an opaque any value — type-assert to the expected pointer type to inspect it.
func (*WaitTimeoutError) Error ¶ added in v0.3.0
func (e *WaitTimeoutError) Error() string
type WebhookEndpoint ¶
type WebhookEndpoint struct {
ID string `json:"id"`
WorkspaceID string `json:"workspaceId"`
URL string `json:"url"`
Description *string `json:"description"`
Events []string `json:"events"`
Status WebhookEndpointStatus `json:"status"`
SuccessRate float64 `json:"successRate"`
RotationGraceUntil *string `json:"rotationGraceUntil"`
CreatedAt string `json:"createdAt"`
}
WebhookEndpoint is a merchant-configured HTTPS destination for event deliveries. SuccessRate is the server-computed rolling success ratio over the recent delivery window. RotationGraceUntil is set during a signing-secret rotation: until then, both the old and new secrets produce valid signatures.
type WebhookEndpointStatus ¶
type WebhookEndpointStatus string
WebhookEndpointStatus is the delivery state of a webhook endpoint. disabled stops new deliveries (existing in-flight retries still run); enabled is the normal state.
const ( WebhookEnabled WebhookEndpointStatus = "enabled" WebhookDisabled WebhookEndpointStatus = "disabled" )
type WebhookEndpointsResource ¶
type WebhookEndpointsResource struct {
// contains filtered or unexported fields
}
WebhookEndpointsResource exposes /v1/workspaces/<ws>/webhook_endpoints.
func (*WebhookEndpointsResource) Create ¶
func (r *WebhookEndpointsResource) Create(ctx context.Context, input CreateWebhookEndpointRequest, opts ...RequestOption) (*CreateWebhookEndpointResponse, error)
Create makes a new endpoint. The response includes the plaintext signing secret exactly once — store it immediately. Multi-key envelope {endpoint, signingSecret} preserved.
Auto-attaches an Idempotency-Key; supply WithIdempotencyKey to override.
func (*WebhookEndpointsResource) Delete ¶
func (r *WebhookEndpointsResource) Delete(ctx context.Context, endpointID string) error
Delete permanently removes a webhook endpoint. In-flight retries are dropped; consider Update with Status=disabled instead if you want to pause without losing the configuration.
func (*WebhookEndpointsResource) List ¶
func (r *WebhookEndpointsResource) List(ctx context.Context) ([]WebhookEndpoint, error)
List returns every webhook endpoint configured for the workspace. The endpoint is small enough that the API doesn't paginate.
func (*WebhookEndpointsResource) Retrieve ¶
func (r *WebhookEndpointsResource) Retrieve(ctx context.Context, endpointID string) (*WebhookEndpoint, error)
Retrieve fetches a single webhook endpoint by ID. The signing secret is never returned here — only Create and RotateSecret produce it.
func (*WebhookEndpointsResource) RotateSecret ¶
func (r *WebhookEndpointsResource) RotateSecret(ctx context.Context, endpointID string, input RotateWebhookSecretRequest, opts ...RequestOption) (*CreateWebhookEndpointResponse, error)
RotateSecret rotates the signing secret. Returns the same {endpoint, signingSecret} envelope as Create — store SigningSecret immediately. Step-up auth (AAL=2) required; API-key callers receive *StepUpRequiredError. Auto-attaches an Idempotency-Key; supply WithIdempotencyKey to override.
func (*WebhookEndpointsResource) Test ¶
func (r *WebhookEndpointsResource) Test(ctx context.Context, endpointID string, input TestWebhookEndpointRequest) (*TestWebhookEndpointResponse, error)
Test fires a sample event at the endpoint synchronously to verify wiring. The returned status is the response status the endpoint returned to OpenSettle.
func (*WebhookEndpointsResource) Update ¶
func (r *WebhookEndpointsResource) Update(ctx context.Context, endpointID string, input UpdateWebhookEndpointRequest) (*WebhookEndpoint, error)
Update patches a webhook endpoint. Fields left nil on input are unchanged. A non-nil Events replaces the allow-list entirely.