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.
Install it
Section titled “Install it”go get github.com/maxint-app/orca-server-sdk-goCreate the client
Section titled “Create the client”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}Cancelling a subscription for a customer
Section titled “Cancelling a subscription for a customer”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.
Verifying webhooks
Section titled “Verifying webhooks”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 hereConstructWebhookEvent rejects anything older than 5 minutes, so replayed requests get bounced automatically.
How this fits together with a client SDK
Section titled “How this fits together with a client SDK”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
GetActiveEntitlementslive 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.
Types you’ll run into
Section titled “Types you’ll run into”The generated types you’ll see in method signatures:
TenantProduct— a sellable product (price, name, linked entitlement)TenantEntitlement— an entitlement definition from your dashboardStorableEntitlement— an entitlement a specific customer actually hasCustomerEntitlements— what a webhook payload deserializes intoListCustomerResponseBody— paginated customer list, with aCursorfor the next page
See example/example.go in the repo for a complete runnable version of everything above.