Skip to content

Go (Server)

orca-server-sdk-go is a backend-only SDK — there’s no UI or purchase flow here. It’s what your Go server uses to check whether a customer has paid access, look them up, cancel their subscription, and verify that a webhook actually came from Orca. Purchases themselves happen on the client, through one of the Swift, Kotlin, Dart, or TypeScript SDKs.

Terminal window
go get github.com/maxint-app/orca-server-sdk-go
import (
"context"
orca "github.com/maxint-app/orca-server-sdk-go"
)
client, err := orca.NewOrcaServerClient("your_api_key_here")
if err != nil {
log.Fatal(err)
}

This uses your private API key — never expose this in a mobile app or frontend bundle.

The most common thing you’ll do: gate a request

Section titled “The most common thing you’ll do: gate a request”

Whenever a request comes in for something paid, check whether the customer has an active entitlement before serving it:

func premiumHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
email := getLoggedInEmail(r)
active, err := client.GetActiveEntitlements(ctx, email, orca.EnvironmentProduction)
if err != nil {
http.Error(w, "could not verify subscription", http.StatusInternalServerError)
return
}
hasAccess := false
for _, e := range active {
if e.Id == "pro_tier" {
hasAccess = true
break
}
}
if !hasAccess {
http.Error(w, "subscribe to access this", http.StatusPaymentRequired)
return
}
// serve the paid content
}

If you’d rather work with product data (price, name) than raw entitlement IDs:

activeProducts, err := client.GetActiveProducts(ctx, email, orca.EnvironmentProduction)

Building an admin dashboard or support tool

Section titled “Building an admin dashboard or support tool”

Look up a specific customer:

customerInfo, err := client.GetCustomerInfo(ctx, "user@example.com", orca.EnvironmentProduction)

Or page through everyone:

limit := int64(20)
var cursor *string
for {
page, err := client.ListCustomers(ctx, &limit, cursor)
if err != nil {
break
}
// do something with page.Data
if page.Cursor == nil {
break
}
cursor = page.Cursor
}

Useful for support flows — a customer emails asking to cancel, and you do it from your own admin panel rather than sending them to app store settings:

err = client.CancelStripeSubscription(ctx, orca.EnvironmentProduction, "entitlement_id", "user@example.com")
// or, for direct debit customers:
err = client.CancelGocardlessSubscription(ctx, orca.EnvironmentProduction, "entitlement_id", "user@example.com")

This only applies to Stripe and GoCardless subscriptions — App Store and Play Store subscriptions are cancelled by the customer through their platform’s own settings, since Apple/Google don’t let third parties cancel on a user’s behalf.

Orca calls your webhook endpoint whenever a customer’s entitlement changes — a new purchase, a renewal, a cancellation, a refund. Always verify the signature before trusting the payload; this is what stops someone from forging a “purchase successful” request to your server:

event, err := client.ConstructWebhookEvent(
webhookPublicKey, // from your Orca dashboard
rawPayload, // the raw request body, unparsed
signatureHeader, // the X-Orca-Signature header
timestampHeader, // the X-Orca-Timestamp header
)
if err != nil {
// bad signature, expired timestamp, or malformed payload — reject the request
http.Error(w, "invalid webhook", http.StatusBadRequest)
return
}
// event is the customer's updated entitlement — update your own database here

ConstructWebhookEvent rejects anything older than 5 minutes, so replayed requests get bounced automatically.

A typical setup: your Flutter/Swift/Kotlin/web app handles the actual purchase using its client SDK, and your Go backend is the source of truth for access control. The backend either:

  • checks GetActiveEntitlements live on every request that needs paid access, or
  • listens for webhooks and keeps its own copy of “who has access to what” up to date, then checks that local copy instead of calling Orca on every request.

Most teams do the second once they’re past prototype stage — it’s faster and doesn’t depend on Orca’s API being up for every single request your app serves.

The generated types you’ll see in method signatures:

  • TenantProduct — a sellable product (price, name, linked entitlement)
  • TenantEntitlement — an entitlement definition from your dashboard
  • StorableEntitlement — an entitlement a specific customer actually has
  • CustomerEntitlements — what a webhook payload deserializes into
  • ListCustomerResponseBody — paginated customer list, with a Cursor for the next page

See example/example.go in the repo for a complete runnable version of everything above.