Instructions for installing Archetype's Golang SDK

What is Archetype

Archetype is a powerful, reliable purchase server with cross-platform support. Our open-source framework provides a backend and a wrapper around Stripe to make implementing API keys and creating quotas and subscriptions easy.

Requirements

Golang >= 1.17

Installation Guide

Step 1: Install and Import Archetype

2. go get -u github.com/ArchetypeAPI/archetype-go

Step 2: Add this snippet to the file where you initialize your go server

package main

import (
	"fmt"
	"log"
	"net/http"
  
	"github.com/ArchetypeAPI/archetype-go/helper"
	"github.com/ArchetypeAPI/archetype-go/archetype"
	"github.com/ArchetypeAPI/archetype-go/middleware"
)

func main() {
	m := http.NewServeMux()
	arch := archetype.NewArchetype("YOUR_APP_ID", "YOUR_SECRET_KEY", true)

	m.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		fmt.Fprintf(w, "Welcome to the home page!")
	})

	a := middleware.New(
		archetype.NewLogger(),
		archetype.NewMiddleware(arch),
	)
	a.UseHandler(m)

	log.Fatal(http.ListenAndServe(":3000", a))
}

What this does is it adds the Archetype middleware to automatically authorize your users and log events.

You can further customize and configure parameters in your SDK like setting whether you want to use our auth system.

The following steps can be done either on your API codebase or if you have a separate server for your user authentication stuff.

Register your users

Archetype provides a way to register new users and new API Keys via our SDK.

m.HandleFunc("/create-user", func(w http.ResponseWriter, req *http.Request) {
		user, err := arch.RegisterUser("CUSTOM_UID", "Archetype Team", "[email protected]")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		json.NewEncoder(w).Encode(user)
})

You can pass a custom uid which is a unique identifier for each user and optionally add details like their emails to register a new user. You'll soon be able to add custom attributes and flags for each user. This will automatically create an API key.

Below is a sample response after generating a new user

{
	"apikey": "USERS_APIKEY",
	"attrs": {},
	"custom_uid": "CUSTOM_UID",
	"description": null,
	"email": "[email protected]",
	"first_seen": 1647895155.932904,
	"is_new": true,
	"is_trial": false,
	"last_seen": 1647895155.932909,
	"name": "Archetype Team",
	"quota": 0,
	"status": "not_subscribed",
	"subscription_date": null,
	"subscription_id": null,
	"tier_id": null,
	"trial_end": null
}

The API Key will not be tied to a specific plan unless the user subscribes.

Retrieve User

When the user is logged in and authorized whether via a session based token or however you think about auth, you can actually pass their custom_uid unique identifier to get their details like API keys, quota, usage and more. More details can be found in the Users page.

Below is an example of adding an endpoint that returns user details

m.HandleFunc("/user", func(w http.ResponseWriter, req *http.Request) {
		user, err := arch.GetUser("CUSTOM_UID")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		json.NewEncoder(w).Encode(user)
})

This returns a user JSON object

{
	"apikey": "USERS_API_KEY",
	"app_id": "YOUR_APP_ID",
	"attrs": {},
	"custom_uid": "CUSTOM_UID",
	"email": "[email protected]",
	"first_seen": 1647895155.932904,
	"is_new": true,
	"is_trial": false,
	"last_seen": 1647895155.932909,
	"last_updated": 1647895155.932909,
	"quota": 0,
	"renewal_number": 0,
	"start_time": 1647839226,
	"status": "not_subscribed",
	"tier_id": null,
}

Retrieve Available Products

This function returns all the products that you currently and publicly offer to your users. Pulling this list is how you can dynamically render prices.

m.HandleFunc("/products", func(w http.ResponseWriter, req *http.Request) {
		products, err := arch.GetProducts()
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		json.NewEncoder(w).Encode(products)
})

This returns a JSON object that is a list of products.

[
  {
    app_id: 'YOUR_APP_ID',
    currency: 'usd',
    description: 'Basic tier',
    endpoints: [],
    has_full_access: true,
    has_quota: true,
    has_trial: true,
    is_active: true,
    is_free: false,
    is_new: true,
    name: 'Basic',
    period: 'month',
    price: 124,
    quota: 1000,
    tier_id: 'YOUR_TIER_ID',
    trial_length: 7,
    trial_time_frame: 'days'
  }
]

We have a ton of SDKs for frontend libraries that make this process very straightforward but this is helpful if you want to keep as much control in your services as possible. The only caveat is that pulling this data and piping it from your backend services to frontend might create a less optimal pricing page experience.

Generate Checkout Sessions.

Once you get a product, you can pass the tier_id provided in the getproducts function and the user's custom_uid to generate a checkout session url.

What this does is create an ephemeral link to stripe that allows the user to enter their credit card details to purchase a subscription. This handles both creating and updating a checkout session.

The function returns a URL which you can then use to redirect a user to. In your API Settings Page on the Archetype side, you can set a return and redirect url after they've completed (or cancelled) the checkout process.

m.HandleFunc("/create-checkout-session", func(w http.ResponseWriter, req *http.Request) {
		session, err := arch.CreateCheckoutSession("CUSTOM_UID", "tier_id")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		json.NewEncoder(w).Encode(session)
})

Cancel Products

We lastly provide an easy functionality for you to allow a user to cancel their subscription without any headache on your end.

m.HandleFunc("/cancel-subscription", func(w http.ResponseWriter, req *http.Request) {
		err := arch.CancelSubscription("CUSTOM_UID")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		fmt.Fprintf(w, "Subscription Canceled Successfully")
})

Tracking without Middleware

If you want to track individual endpoints, you can simply add a track function to the call that'll asynchronously log the call without any further input.

You can optionally supply the user's API Key or their Custom uid that you provided to track events based on users.

m.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		arch.Track("USER_ID", helper.Timestamp(), w, req)
		fmt.Fprintf(w, "Hello World!")
})