Repository: stripe/stripe-cli
Pull request #747 (2021-09-17 00:30:12)

Updating all instances of context.TODO() with context from caller
 ### Reviewers
r? @bernerd-stripe 
cc @stripe/developer-products

 ### Summary
Updating all instances of context.TODO() to grab the context passed in by the caller. 
For runtime, this means that we pass in the context that's instantiated from the main() function. Most end up just being context.Background() which is no different from context.TODO(), but some get the context that has cancel set if the calling cmd set it. 

For tests, I just passed in an empty context. 

Motivation: This will allow us to use this object to pass along telemetry context for the upcoming migration. 

### Testing
Compiling and unit testing.
I also manually ran through some of my workspace commands. 


Patch:
diff --git a/cmd/stripe/main.go b/cmd/stripe/main.go
index 7f9620b..f8942cc 100644
--- a/cmd/stripe/main.go
+++ b/cmd/stripe/main.go
@@ -1,7 +1,11 @@
 package main
 
-import "github.com/stripe/stripe-cli/pkg/cmd"
+import (
+	"context"
+
+	"github.com/stripe/stripe-cli/pkg/cmd"
+)
 
 func main() {
-	cmd.Execute()
+	cmd.Execute(context.Background())
 }
diff --git a/pkg/cmd/daemon.go b/pkg/cmd/daemon.go
index fee6f76..4ca4718 100644
--- a/pkg/cmd/daemon.go
+++ b/pkg/cmd/daemon.go
@@ -4,8 +4,6 @@ import (
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 
-	"context"
-
 	"github.com/stripe/stripe-cli/pkg/config"
 	"github.com/stripe/stripe-cli/pkg/rpcservice"
 	"github.com/stripe/stripe-cli/pkg/validators"
@@ -45,7 +43,7 @@ func (dc *daemonCmd) runDaemonCmd(cmd *cobra.Command, args []string) {
 		UserCfg: dc.cfg,
 	})
 
-	ctx := withSIGTERMCancel(context.Background(), func() {
+	ctx := withSIGTERMCancel(cmd.Context(), func() {
 		log.WithFields(log.Fields{
 			"prefix": "cmd.daemonCmd.runDaemonCmd",
 		}).Debug("Ctrl+C received, cleaning up...")
diff --git a/pkg/cmd/fixtures.go b/pkg/cmd/fixtures.go
index 701d4bf..7dcf2e1 100644
--- a/pkg/cmd/fixtures.go
+++ b/pkg/cmd/fixtures.go
@@ -73,7 +73,7 @@ func (fc *FixturesCmd) runFixturesCmd(cmd *cobra.Command, args []string) error {
 		return err
 	}
 
-	_, err = fixture.Execute()
+	_, err = fixture.Execute(cmd.Context())
 
 	if err != nil {
 		return err
diff --git a/pkg/cmd/listen.go b/pkg/cmd/listen.go
index 78de034..75e57b4 100644
--- a/pkg/cmd/listen.go
+++ b/pkg/cmd/listen.go
@@ -114,9 +114,15 @@ func (lc *listenCmd) runListenCmd(cmd *cobra.Command, args []string) error {
 		return err
 	}
 
+	ctx := withSIGTERMCancel(cmd.Context(), func() {
+		log.WithFields(log.Fields{
+			"prefix": "proxy.Proxy.Run",
+		}).Debug("Ctrl+C received, cleaning up...")
+	})
+
 	// --print-secret option
 	if lc.onlyPrintSecret {
-		secret, err := proxy.GetSessionSecret(deviceName, key, lc.apiBaseURL)
+		secret, err := proxy.GetSessionSecret(ctx, deviceName, key, lc.apiBaseURL)
 		if err != nil {
 			return err
 		}
@@ -128,7 +134,7 @@ func (lc *listenCmd) runListenCmd(cmd *cobra.Command, args []string) error {
 	proxyVisitor := createVisitor(logger, lc.format, lc.printJSON)
 	proxyOutCh := make(chan websocket.IElement)
 
-	p, err := proxy.Init(&proxy.Config{
+	p, err := proxy.Init(ctx, &proxy.Config{
 		DeviceName:            deviceName,
 		Key:                   key,
 		ForwardURL:            lc.forwardURL,
@@ -150,12 +156,6 @@ func (lc *listenCmd) runListenCmd(cmd *cobra.Command, args []string) error {
 		return err
 	}
 
-	ctx := withSIGTERMCancel(context.Background(), func() {
-		log.WithFields(log.Fields{
-			"prefix": "proxy.Proxy.Run",
-		}).Debug("Ctrl+C received, cleaning up...")
-	})
-
 	go p.Run(ctx)
 
 	for el := range proxyOutCh {
diff --git a/pkg/cmd/login.go b/pkg/cmd/login.go
index 55cb19e..f0f4adc 100644
--- a/pkg/cmd/login.go
+++ b/pkg/cmd/login.go
@@ -37,8 +37,8 @@ func newLoginCmd() *loginCmd {
 
 func (lc *loginCmd) runLoginCmd(cmd *cobra.Command, args []string) error {
 	if lc.interactive {
-		return login.InteractiveLogin(&Config)
+		return login.InteractiveLogin(cmd.Context(), &Config)
 	}
 
-	return login.Login(lc.dashboardBaseURL, &Config, os.Stdin)
+	return login.Login(cmd.Context(), lc.dashboardBaseURL, &Config, os.Stdin)
 }
diff --git a/pkg/cmd/logs/tail.go b/pkg/cmd/logs/tail.go
index 6922a8a..80a7b2a 100644
--- a/pkg/cmd/logs/tail.go
+++ b/pkg/cmd/logs/tail.go
@@ -182,7 +182,7 @@ func (tailCmd *TailCmd) runTailCmd(cmd *cobra.Command, args []string) error {
 		OutCh:      logtailingOutCh,
 	})
 
-	ctx := withSIGTERMCancel(context.Background(), func() {
+	ctx := withSIGTERMCancel(cmd.Context(), func() {
 		log.WithFields(log.Fields{
 			"prefix": "logtailing.Tailer.Run",
 		}).Debug("Ctrl+C received, cleaning up...")
diff --git a/pkg/cmd/resource/operation.go b/pkg/cmd/resource/operation.go
index f51438b..c6cda39 100644
--- a/pkg/cmd/resource/operation.go
+++ b/pkg/cmd/resource/operation.go
@@ -96,12 +96,12 @@ func (oc *OperationCmd) runOperationCmd(cmd *cobra.Command, args []string) error
 		}
 
 		// if confirmation is provided, make the request
-		_, err = oc.MakeRequest(apiKey, path, &oc.Parameters, false)
+		_, err = oc.MakeRequest(cmd.Context(), apiKey, path, &oc.Parameters, false)
 
 		return err
 	}
 	// else
-	_, err = oc.MakeRequest(apiKey, path, &oc.Parameters, false)
+	_, err = oc.MakeRequest(cmd.Context(), apiKey, path, &oc.Parameters, false)
 	return err
 }
 
diff --git a/pkg/cmd/resource/terminal_quickstart.go b/pkg/cmd/resource/terminal_quickstart.go
index 5b10e27..7bb2691 100644
--- a/pkg/cmd/resource/terminal_quickstart.go
+++ b/pkg/cmd/resource/terminal_quickstart.go
@@ -57,7 +57,7 @@ func (cc *QuickstartCmd) runQuickstartCmd(cmd *cobra.Command, args []string) err
 	}
 
 	if reader == terminal.ReaderList["verifone-p400"].Name {
-		err = terminal.QuickstartP400(cc.cfg)
+		err = terminal.QuickstartP400(cmd.Context(), cc.cfg)
 		if err != nil {
 			return fmt.Errorf(err.Error())
 		}
diff --git a/pkg/cmd/root.go b/pkg/cmd/root.go
index d877ebc..20f615e 100644
--- a/pkg/cmd/root.go
+++ b/pkg/cmd/root.go
@@ -4,6 +4,7 @@
 package cmd
 
 import (
+	"context"
 	"fmt"
 	"os"
 	"strings"
@@ -57,11 +58,10 @@ var rootCmd = &cobra.Command{
 
 // Execute adds all child commands to the root command and sets flags appropriately.
 // This is called by main.main(). It only needs to happen once to the rootCmd.
-func Execute() {
+func Execute(ctx context.Context) {
 	rootCmd.SetUsageTemplate(getUsageTemplate())
 	rootCmd.SetVersionTemplate(version.Template)
-
-	if err := rootCmd.Execute(); err != nil {
+	if err := rootCmd.ExecuteContext(ctx); err != nil {
 		errString := err.Error()
 		isLoginRequiredError := errString == validators.ErrAPIKeyNotConfigured.Error() || errString == validators.ErrDeviceNameNotConfigured.Error()
 
diff --git a/pkg/cmd/samples/create.go b/pkg/cmd/samples/create.go
index e9d2f46..033e2d0 100644
--- a/pkg/cmd/samples/create.go
+++ b/pkg/cmd/samples/create.go
@@ -84,6 +84,7 @@ func (cc *CreateCmd) runCreateCmd(cmd *cobra.Command, args []string) error {
 	resultChan := make(chan samples.CreationResult)
 
 	go samples.Create(
+		cmd.Context(),
 		cc.cfg,
 		selectedSample,
 		selectedConfig,
diff --git a/pkg/cmd/trigger.go b/pkg/cmd/trigger.go
index b36cbd7..1b7d873 100644
--- a/pkg/cmd/trigger.go
+++ b/pkg/cmd/trigger.go
@@ -76,7 +76,7 @@ func (tc *triggerCmd) runTriggerCmd(cmd *cobra.Command, args []string) error {
 
 	event := args[0]
 
-	_, err = fixtures.Trigger(event, tc.stripeAccount, tc.apiBaseURL, apiKey, tc.skip, tc.override, tc.add, tc.remove)
+	_, err = fixtures.Trigger(cmd.Context(), event, tc.stripeAccount, tc.apiBaseURL, apiKey, tc.skip, tc.override, tc.add, tc.remove)
 	if err != nil {
 		return err
 	}
diff --git a/pkg/fixtures/fixtures.go b/pkg/fixtures/fixtures.go
index a4c4f0f..d79f4eb 100644
--- a/pkg/fixtures/fixtures.go
+++ b/pkg/fixtures/fixtures.go
@@ -1,6 +1,7 @@
 package fixtures
 
 import (
+	"context"
 	"encoding/json"
 	"fmt"
 	"io/ioutil"
@@ -157,7 +158,7 @@ func (fxt *Fixture) Remove(removals []string) {
 
 // Execute takes the parsed fixture file and runs through all the requests
 // defined to populate the user's account
-func (fxt *Fixture) Execute() ([]string, error) {
+func (fxt *Fixture) Execute(ctx context.Context) ([]string, error) {
 	requestNames := make([]string, len(fxt.fixture.Fixtures))
 	for i, data := range fxt.fixture.Fixtures {
 		if isNameIn(data.Name, fxt.Skip) {
@@ -169,7 +170,7 @@ func (fxt *Fixture) Execute() ([]string, error) {
 		requestNames[i] = data.Name
 
 		fmt.Printf("Running fixture for: %s\n", data.Name)
-		resp, err := fxt.makeRequest(data)
+		resp, err := fxt.makeRequest(ctx, data)
 		if err != nil && !errWasExpected(err, data.ExpectedErrorType) {
 			return nil, err
 		}
@@ -197,7 +198,7 @@ func (fxt *Fixture) UpdateEnv() error {
 	return nil
 }
 
-func (fxt *Fixture) makeRequest(data fixture) ([]byte, error) {
+func (fxt *Fixture) makeRequest(ctx context.Context, data fixture) ([]byte, error) {
 	var rp requests.RequestParameters
 
 	if data.Method == "post" && !fxt.fixture.Meta.ExcludeMetadata {
@@ -225,7 +226,7 @@ func (fxt *Fixture) makeRequest(data fixture) ([]byte, error) {
 		return make([]byte, 0), err
 	}
 
-	return req.MakeRequest(fxt.APIKey, path, params, true)
+	return req.MakeRequest(ctx, fxt.APIKey, path, params, true)
 }
 
 func (fxt *Fixture) createParams(params interface{}) (*requests.RequestParameters, error) {
diff --git a/pkg/fixtures/triggers.go b/pkg/fixtures/triggers.go
index 991df33..d5ae965 100644
--- a/pkg/fixtures/triggers.go
+++ b/pkg/fixtures/triggers.go
@@ -1,6 +1,7 @@
 package fixtures
 
 import (
+	"context"
 	"embed"
 	"fmt"
 	"sort"
@@ -111,7 +112,7 @@ func EventNames() []string {
 }
 
 // Trigger triggers a Stripe event.
-func Trigger(event string, stripeAccount string, baseURL string, apiKey string, skip, override, add, remove []string) ([]string, error) {
+func Trigger(ctx context.Context, event string, stripeAccount string, baseURL string, apiKey string, skip, override, add, remove []string) ([]string, error) {
 	fs := afero.NewOsFs()
 
 	var fixture *Fixture
@@ -134,7 +135,7 @@ func Trigger(event string, stripeAccount string, baseURL string, apiKey string,
 		}
 	}
 
-	requestNames, err := fixture.Execute()
+	requestNames, err := fixture.Execute(ctx)
 	if err != nil {
 		return nil, fmt.Errorf(fmt.Sprintf("Trigger failed: %s\n", err))
 	}
diff --git a/pkg/login/client_login.go b/pkg/login/client_login.go
index 9f1ff64..c02f305 100644
--- a/pkg/login/client_login.go
+++ b/pkg/login/client_login.go
@@ -40,8 +40,8 @@ type Links struct {
 */
 
 // Login function is used to obtain credentials via stripe dashboard.
-func Login(baseURL string, config *config.Config, input io.Reader) error {
-	links, err := GetLinks(baseURL, config.Profile.DeviceName)
+func Login(ctx context.Context, baseURL string, config *config.Config, input io.Reader) error {
+	links, err := GetLinks(ctx, baseURL, config.Profile.DeviceName)
 	if err != nil {
 		return err
 	}
@@ -70,7 +70,7 @@ func Login(baseURL string, config *config.Config, input io.Reader) error {
 		}
 	}
 
-	response, account, err := PollForKey(links.PollURL, 0, 0)
+	response, account, err := PollForKey(ctx, links.PollURL, 0, 0)
 	if err != nil {
 		return err
 	}
@@ -80,7 +80,7 @@ func Login(baseURL string, config *config.Config, input io.Reader) error {
 		return err
 	}
 
-	message, err := SuccessMessage(account, stripe.DefaultAPIBaseURL, response.TestModeAPIKey)
+	message, err := SuccessMessage(ctx, account, stripe.DefaultAPIBaseURL, response.TestModeAPIKey)
 	if err != nil {
 		fmt.Printf("> Error verifying the CLI was set up successfully: %s\n", err)
 		return err
@@ -114,7 +114,7 @@ func ConfigureProfile(config *config.Config, response *PollAPIKeyResponse) error
 }
 
 // GetLinks provides the URLs for the CLI to continue the login flow
-func GetLinks(baseURL string, deviceName string) (*Links, error) {
+func GetLinks(ctx context.Context, baseURL string, deviceName string) (*Links, error) {
 	parsedBaseURL, err := url.Parse(baseURL)
 	if err != nil {
 		return nil, err
@@ -127,7 +127,7 @@ func GetLinks(baseURL string, deviceName string) (*Links, error) {
 	data := url.Values{}
 	data.Set("device_name", deviceName)
 
-	res, err := client.PerformRequest(context.TODO(), http.MethodPost, stripeCLIAuthPath, data.Encode(), nil)
+	res, err := client.PerformRequest(ctx, http.MethodPost, stripeCLIAuthPath, data.Encode(), nil)
 	if err != nil {
 		return nil, err
 	}
diff --git a/pkg/login/interactive_login.go b/pkg/login/interactive_login.go
index 850c533..dc3505f 100644
--- a/pkg/login/interactive_login.go
+++ b/pkg/login/interactive_login.go
@@ -2,6 +2,7 @@ package login
 
 import (
 	"bufio"
+	"context"
 	"errors"
 	"fmt"
 	"io"
@@ -19,7 +20,7 @@ import (
 )
 
 // InteractiveLogin lets the user set configuration on the command line
-func InteractiveLogin(config *config.Config) error {
+func InteractiveLogin(ctx context.Context, config *config.Config) error {
 	apiKey, err := getConfigureAPIKey(os.Stdin)
 	if err != nil {
 		return err
@@ -27,7 +28,7 @@ func InteractiveLogin(config *config.Config) error {
 
 	config.Profile.DeviceName = getConfigureDeviceName(os.Stdin)
 	config.Profile.TestModeAPIKey = apiKey
-	displayName, _ := getDisplayName(nil, stripe.DefaultAPIBaseURL, apiKey)
+	displayName, _ := getDisplayName(ctx, nil, stripe.DefaultAPIBaseURL, apiKey)
 
 	config.Profile.DisplayName = displayName
 
@@ -39,7 +40,7 @@ func InteractiveLogin(config *config.Config) error {
 	// The '>' character is automatically included at the end of client login
 	// due to ansi spinner. Since no spinner is used with interactive login,
 	// we need to include it manually to maintain consistency in outputs.
-	message, err := SuccessMessage(nil, stripe.DefaultAPIBaseURL, apiKey)
+	message, err := SuccessMessage(ctx, nil, stripe.DefaultAPIBaseURL, apiKey)
 	if err != nil {
 		fmt.Printf("> Error verifying the CLI was setup successfully: %s\n", err)
 	} else {
@@ -50,10 +51,10 @@ func InteractiveLogin(config *config.Config) error {
 }
 
 // getDisplayName returns the display name for a successfully authenticated user
-func getDisplayName(account *Account, baseURL string, apiKey string) (string, error) {
+func getDisplayName(ctx context.Context, account *Account, baseURL string, apiKey string) (string, error) {
 	// Account will be nil if user did interactive login
 	if account == nil {
-		acc, err := GetUserAccount(baseURL, apiKey)
+		acc, err := GetUserAccount(ctx, baseURL, apiKey)
 		if err != nil {
 			return "", err
 		}
diff --git a/pkg/login/login_message.go b/pkg/login/login_message.go
index 06f6c68..cd97193 100644
--- a/pkg/login/login_message.go
+++ b/pkg/login/login_message.go
@@ -1,6 +1,7 @@
 package login
 
 import (
+	"context"
 	"fmt"
 	"os"
 
@@ -8,10 +9,10 @@ import (
 )
 
 // SuccessMessage returns the display message for a successfully authenticated user
-func SuccessMessage(account *Account, baseURL string, apiKey string) (string, error) {
+func SuccessMessage(ctx context.Context, account *Account, baseURL string, apiKey string) (string, error) {
 	// Account will be nil if user did interactive login
 	if account == nil {
-		acc, err := GetUserAccount(baseURL, apiKey)
+		acc, err := GetUserAccount(ctx, baseURL, apiKey)
 		if err != nil {
 			return "", err
 		}
diff --git a/pkg/login/poll.go b/pkg/login/poll.go
index 9834ecb..6b85792 100644
--- a/pkg/login/poll.go
+++ b/pkg/login/poll.go
@@ -28,7 +28,7 @@ type PollAPIKeyResponse struct {
 }
 
 // PollForKey polls Stripe at the specified interval until either the API key is available or we've reached the max attempts.
-func PollForKey(pollURL string, interval time.Duration, maxAttempts int) (*PollAPIKeyResponse, *Account, error) {
+func PollForKey(ctx context.Context, pollURL string, interval time.Duration, maxAttempts int) (*PollAPIKeyResponse, *Account, error) {
 	var response PollAPIKeyResponse
 
 	if maxAttempts == 0 {
@@ -52,7 +52,7 @@ func PollForKey(pollURL string, interval time.Duration, maxAttempts int) (*PollA
 
 	var count = 0
 	for count < maxAttempts {
-		res, err := client.PerformRequest(context.TODO(), http.MethodGet, parsedURL.Path, parsedURL.Query().Encode(), nil)
+		res, err := client.PerformRequest(ctx, http.MethodGet, parsedURL.Path, parsedURL.Query().Encode(), nil)
 		if err != nil {
 			return nil, nil, err
 		}
diff --git a/pkg/login/retrieve_account.go b/pkg/login/retrieve_account.go
index 94f0a89..4a4dbde 100644
--- a/pkg/login/retrieve_account.go
+++ b/pkg/login/retrieve_account.go
@@ -25,7 +25,7 @@ type Dashboard struct {
 }
 
 // GetUserAccount retrieves the account information
-func GetUserAccount(baseURL string, apiKey string) (*Account, error) {
+func GetUserAccount(ctx context.Context, baseURL string, apiKey string) (*Account, error) {
 	parsedBaseURL, err := url.Parse(baseURL)
 	if err != nil {
 		return nil, err
@@ -36,7 +36,7 @@ func GetUserAccount(baseURL string, apiKey string) (*Account, error) {
 		APIKey:  apiKey,
 	}
 
-	resp, err := client.PerformRequest(context.TODO(), "GET", "/v1/account", "", nil)
+	resp, err := client.PerformRequest(ctx, "GET", "/v1/account", "", nil)
 
 	if err != nil {
 		return nil, err
diff --git a/pkg/proxy/proxy.go b/pkg/proxy/proxy.go
index 0e72ac1..269ecca 100644
--- a/pkg/proxy/proxy.go
+++ b/pkg/proxy/proxy.go
@@ -204,8 +204,8 @@ func (p *Proxy) Run(ctx context.Context) error {
 }
 
 // GetSessionSecret creates a session and returns the webhook signing secret.
-func GetSessionSecret(deviceName, key, baseURL string) (string, error) {
-	p, err := Init(&Config{
+func GetSessionSecret(ctx context.Context, deviceName, key, baseURL string) (string, error) {
+	p, err := Init(ctx, &Config{
 		DeviceName:       deviceName,
 		Key:              key,
 		APIBaseURL:       baseURL,
@@ -219,7 +219,7 @@ func GetSessionSecret(deviceName, key, baseURL string) (string, error) {
 		return "", err
 	}
 
-	session, err := p.createSession(context.Background())
+	session, err := p.createSession(ctx)
 	if err != nil {
 		log.WithFields(log.Fields{
 			"prefix": "proxy.Proxy.GetSessionSecret",
@@ -430,7 +430,7 @@ func (p *Proxy) processEndpointResponse(evtCtx eventContext, forwardURL string,
 //
 
 // Init initializes a new Proxy
-func Init(cfg *Config) (*Proxy, error) {
+func Init(ctx context.Context, cfg *Config) (*Proxy, error) {
 	if cfg.Log == nil {
 		cfg.Log = &log.Logger{Out: ioutil.Discard}
 	}
@@ -470,7 +470,7 @@ func Init(cfg *Config) (*Proxy, error) {
 	var endpointRoutes []EndpointRoute
 	if cfg.UseConfiguredWebhooks {
 		// build from user's API config
-		endpoints := getEndpointsFromAPI(cfg.Key, cfg.APIBaseURL)
+		endpoints := getEndpointsFromAPI(ctx, cfg.Key, cfg.APIBaseURL)
 		if len(endpoints.Data) == 0 {
 			return nil, errors.New("You have not defined any webhook endpoints on your account. Go to the Stripe Dashboard to add some: https://dashboard.stripe.com/test/webhooks")
 		}
@@ -655,12 +655,12 @@ func parseURL(url string) string {
 	return url
 }
 
-func getEndpointsFromAPI(secretKey, apiBaseURL string) requests.WebhookEndpointList {
+func getEndpointsFromAPI(ctx context.Context, secretKey, apiBaseURL string) requests.WebhookEndpointList {
 	if apiBaseURL == "" {
 		apiBaseURL = stripe.DefaultAPIBaseURL
 	}
 
-	return requests.WebhookEndpointsList(apiBaseURL, "2019-03-14", secretKey, &config.Profile{})
+	return requests.WebhookEndpointsList(ctx, apiBaseURL, "2019-03-14", secretKey, &config.Profile{})
 }
 
 func buildEndpointRoutes(endpoints requests.WebhookEndpointList, forwardURL, forwardConnectURL string, forwardHeaders []string, forwardConnectHeaders []string) ([]EndpointRoute, error) {
diff --git a/pkg/requests/base.go b/pkg/requests/base.go
index 4bc1821..101b740 100644
--- a/pkg/requests/base.go
+++ b/pkg/requests/base.go
@@ -119,7 +119,7 @@ func (rb *Base) RunRequestsCmd(cmd *cobra.Command, args []string) error {
 		return err
 	}
 
-	_, err = rb.MakeRequest(apiKey, path, &rb.Parameters, false)
+	_, err = rb.MakeRequest(cmd.Context(), apiKey, path, &rb.Parameters, false)
 
 	return err
 }
@@ -160,7 +160,7 @@ func (rb *Base) InitFlags() {
 }
 
 // MakeRequest will make a request to the Stripe API with the specific variables given to it
-func (rb *Base) MakeRequest(apiKey, path string, params *RequestParameters, errOnStatus bool) ([]byte, error) {
+func (rb *Base) MakeRequest(ctx context.Context, apiKey, path string, params *RequestParameters, errOnStatus bool) ([]byte, error) {
 	parsedBaseURL, err := url.Parse(rb.APIBaseURL)
 	if err != nil {
 		return []byte{}, err
@@ -183,7 +183,7 @@ func (rb *Base) MakeRequest(apiKey, path string, params *RequestParameters, errO
 		rb.setVersionHeader(req, params)
 	}
 
-	resp, err := client.PerformRequest(context.TODO(), rb.Method, path, data, configureReq)
+	resp, err := client.PerformRequest(ctx, rb.Method, path, data, configureReq)
 	if err != nil {
 		return []byte{}, err
 	}
diff --git a/pkg/requests/webhook_endpoints.go b/pkg/requests/webhook_endpoints.go
index d9bb298..8d04e7f 100644
--- a/pkg/requests/webhook_endpoints.go
+++ b/pkg/requests/webhook_endpoints.go
@@ -1,6 +1,7 @@
 package requests
 
 import (
+	"context"
 	"encoding/json"
 	"net/http"
 
@@ -21,7 +22,7 @@ type WebhookEndpoint struct {
 }
 
 // WebhookEndpointsList returns all the webhook endpoints on a users' account
-func WebhookEndpointsList(baseURL, apiVersion, apiKey string, profile *config.Profile) WebhookEndpointList {
+func WebhookEndpointsList(ctx context.Context, baseURL, apiVersion, apiKey string, profile *config.Profile) WebhookEndpointList {
 	params := &RequestParameters{
 		data:    []string{"limit=30"},
 		version: apiVersion,
@@ -33,7 +34,7 @@ func WebhookEndpointsList(baseURL, apiVersion, apiKey string, profile *config.Pr
 		SuppressOutput: true,
 		APIBaseURL:     baseURL,
 	}
-	resp, _ := base.MakeRequest(apiKey, "/v1/webhook_endpoints", params, true)
+	resp, _ := base.MakeRequest(ctx, apiKey, "/v1/webhook_endpoints", params, true)
 	data := WebhookEndpointList{}
 	json.Unmarshal(resp, &data)
 
diff --git a/pkg/rpcservice/events_resend.go b/pkg/rpcservice/events_resend.go
index 7e9245b..e704b20 100644
--- a/pkg/rpcservice/events_resend.go
+++ b/pkg/rpcservice/events_resend.go
@@ -45,7 +45,7 @@ func (srv *RPCService) EventsResend(ctx context.Context, req *rpc.EventsResendRe
 
 	params := getParamsFromReq(req)
 
-	stripeResp, err := stripeReq.MakeRequest(apiKey, path, params, true)
+	stripeResp, err := stripeReq.MakeRequest(ctx, apiKey, path, params, true)
 	if err != nil {
 		return nil, status.Error(codes.FailedPrecondition, err.Error())
 	}
diff --git a/pkg/rpcservice/listen.go b/pkg/rpcservice/listen.go
index 2e9be20..15ae0a5 100644
--- a/pkg/rpcservice/listen.go
+++ b/pkg/rpcservice/listen.go
@@ -28,8 +28,8 @@ type IProxy interface {
 	Run(context.Context) error
 }
 
-var createProxy = func(cfg *proxy.Config) (IProxy, error) {
-	return proxy.Init(cfg)
+var createProxy = func(ctx context.Context, cfg *proxy.Config) (IProxy, error) {
+	return proxy.Init(ctx, cfg)
 }
 
 // Listen returns a stream of webhook events and forwards them to a local endpoint
@@ -48,7 +48,10 @@ func (srv *RPCService) Listen(req *rpc.ListenRequest, stream rpc.StripeCLI_Liste
 	proxyVisitor := createProxyVisitor(&stream)
 	proxyOutCh := make(chan websocket.IElement)
 
-	p, err := createProxy(&proxy.Config{
+	ctx, cancel := context.WithCancel(stream.Context())
+	defer cancel()
+
+	p, err := createProxy(ctx, &proxy.Config{
 		DeviceName:            deviceName,
 		Key:                   key,
 		ForwardURL:            req.ForwardTo,
@@ -71,10 +74,6 @@ func (srv *RPCService) Listen(req *rpc.ListenRequest, stream rpc.StripeCLI_Liste
 	if err != nil {
 		return err
 	}
-
-	ctx, cancel := context.WithCancel(context.Background())
-	defer cancel()
-
 	go p.Run(ctx)
 
 	for {
diff --git a/pkg/rpcservice/login.go b/pkg/rpcservice/login.go
index 1f6f804..18f675b 100644
--- a/pkg/rpcservice/login.go
+++ b/pkg/rpcservice/login.go
@@ -15,7 +15,7 @@ var getLinks = login.GetLinks
 func (srv *RPCService) Login(ctx context.Context, req *rpc.LoginRequest) (*rpc.LoginResponse, error) {
 	var err error
 
-	links, err = getLinks(stripe.DefaultDashboardBaseURL, srv.cfg.UserCfg.Profile.DeviceName)
+	links, err = getLinks(ctx, stripe.DefaultDashboardBaseURL, srv.cfg.UserCfg.Profile.DeviceName)
 	if err != nil {
 		return nil, err
 	}
diff --git a/pkg/rpcservice/login_status.go b/pkg/rpcservice/login_status.go
index 6c38708..da47580 100644
--- a/pkg/rpcservice/login_status.go
+++ b/pkg/rpcservice/login_status.go
@@ -19,7 +19,7 @@ func (srv *RPCService) LoginStatus(ctx context.Context, req *rpc.LoginStatusRequ
 		return nil, status.Error(codes.FailedPrecondition, "There is no login in progress.")
 	}
 
-	response, account, err := pollForKey(links.PollURL, 0, 0)
+	response, account, err := pollForKey(ctx, links.PollURL, 0, 0)
 	if err != nil {
 		return nil, err
 	}
diff --git a/pkg/rpcservice/logs_tail.go b/pkg/rpcservice/logs_tail.go
index f74c929..b04021d 100644
--- a/pkg/rpcservice/logs_tail.go
+++ b/pkg/rpcservice/logs_tail.go
@@ -54,7 +54,7 @@ func (srv *RPCService) LogsTail(req *rpc.LogsTailRequest, stream rpc.StripeCLI_L
 		NoWSS:      false,
 	})
 
-	ctx, cancel := context.WithCancel(context.Background())
+	ctx, cancel := context.WithCancel(stream.Context())
 	defer cancel()
 
 	go tailer.Run(ctx)
diff --git a/pkg/rpcservice/sample_create.go b/pkg/rpcservice/sample_create.go
index 71db434..88899d2 100644
--- a/pkg/rpcservice/sample_create.go
+++ b/pkg/rpcservice/sample_create.go
@@ -22,6 +22,7 @@ func (srv *RPCService) SampleCreate(ctx context.Context, req *rpc.SampleCreateRe
 
 	resultChan := make(chan samples.CreationResult)
 	go createSample(
+		ctx,
 		srv.cfg.UserCfg,
 		req.SampleName,
 		selectedConfig,
diff --git a/pkg/rpcservice/trigger.go b/pkg/rpcservice/trigger.go
index d491204..6ab2bf5 100644
--- a/pkg/rpcservice/trigger.go
+++ b/pkg/rpcservice/trigger.go
@@ -21,6 +21,7 @@ func (srv *RPCService) Trigger(ctx context.Context, req *rpc.TriggerRequest) (*r
 	}
 
 	requestNames, err := fixtures.Trigger(
+		ctx,
 		req.Event,
 		req.StripeAccount,
 		baseURL,
diff --git a/pkg/samples/create.go b/pkg/samples/create.go
index 2abdbf2..eba4ea4 100644
--- a/pkg/samples/create.go
+++ b/pkg/samples/create.go
@@ -1,6 +1,7 @@
 package samples
 
 import (
+	"context"
 	"fmt"
 	"os"
 	"os/signal"
@@ -50,6 +51,7 @@ type CreationResult struct {
 
 // Create creates a sample at a destination with the selected integration, client language, and server language
 func Create(
+	ctx context.Context,
 	config *config.Config,
 	sampleName string,
 	selectedConfig *SelectedConfig,
@@ -147,7 +149,7 @@ func Create(
 
 	resultChan <- CreationResult{State: WillConfigure}
 
-	err = sample.ConfigureDotEnv(targetPath)
+	err = sample.ConfigureDotEnv(ctx, targetPath)
 	if err != nil {
 		resultChan <- CreationResult{Err: err}
 		return
diff --git a/pkg/samples/samples.go b/pkg/samples/samples.go
index 401e070..93e3748 100644
--- a/pkg/samples/samples.go
+++ b/pkg/samples/samples.go
@@ -271,7 +271,7 @@ func (s *Samples) Copy(target string) error {
 
 // ConfigureDotEnv takes the .env.example from the provided location and
 // modifies it to automatically configure it for the users settings
-func (s *Samples) ConfigureDotEnv(sampleLocation string) error {
+func (s *Samples) ConfigureDotEnv(ctx context.Context, sampleLocation string) error {
 	if s.SelectedConfig.Integration.hasServers() {
 		if !s.SampleConfig.ConfigureDotEnv {
 			return nil
@@ -307,7 +307,7 @@ func (s *Samples) ConfigureDotEnv(sampleLocation string) error {
 
 		authClient := stripeauth.NewClient(apiKey, nil)
 
-		authSession, err := authClient.Authorize(context.TODO(), deviceName, "webhooks", nil, nil)
+		authSession, err := authClient.Authorize(ctx, deviceName, "webhooks", nil, nil)
 		if err != nil {
 			return err
 		}
diff --git a/pkg/terminal/p400/reader_payment.go b/pkg/terminal/p400/reader_payment.go
index 16e3542..17e8e1f 100644
--- a/pkg/terminal/p400/reader_payment.go
+++ b/pkg/terminal/p400/reader_payment.go
@@ -1,6 +1,7 @@
 package p400
 
 import (
+	"context"
 	"fmt"
 	"math/rand"
 	"os"
@@ -9,7 +10,7 @@ import (
 )
 
 // SetUpTestPayment asks the user for their payment amount / currency, then updates the reader display, then creates a new Payment Intent
-func SetUpTestPayment(tsCtx TerminalSessionContext) (TerminalSessionContext, error) {
+func SetUpTestPayment(ctx context.Context, tsCtx TerminalSessionContext) (TerminalSessionContext, error) {
 	var err error
 	tsCtx.Currency, err = ReaderChargeCurrencyPrompt()
 
@@ -37,7 +38,7 @@ func SetUpTestPayment(tsCtx TerminalSessionContext) (TerminalSessionContext, err
 	ansi.StopSpinner(spinner, ansi.Faint("Reader display updated"), os.Stdout)
 	spinner = ansi.StartNewSpinner("Creating a new Payment Intent...", os.Stdout)
 
-	tsCtx.PaymentIntentID, err = CreatePaymentIntent(tsCtx)
+	tsCtx.PaymentIntentID, err = CreatePaymentIntent(ctx, tsCtx)
 
 	if err != nil {
 		return tsCtx, err
@@ -49,7 +50,7 @@ func SetUpTestPayment(tsCtx TerminalSessionContext) (TerminalSessionContext, err
 }
 
 // CompleteTestPayment sets the reader into collect payment mode, waits for the payment, confirms the payment, then finally captures the Payment Intent
-func CompleteTestPayment(tsCtx TerminalSessionContext) (TerminalSessionContext, error) {
+func CompleteTestPayment(ctx context.Context, tsCtx TerminalSessionContext) (TerminalSessionContext, error) {
 	parentTraceID := SetParentTraceID(tsCtx.TransactionID, tsCtx.MethodID, "processPayment")
 	err := CollectPaymentMethod(tsCtx, parentTraceID)
 
@@ -76,7 +77,7 @@ func CompleteTestPayment(tsCtx TerminalSessionContext) (TerminalSessionContext,
 
 	// manually capturing payment intent as required by terminal flow
 	spinner = ansi.StartNewSpinner("Capturing Payment Intent...", os.Stdout)
-	err = CapturePaymentIntent(tsCtx)
+	err = CapturePaymentIntent(ctx, tsCtx)
 
 	if err != nil {
 		return tsCtx, err
diff --git a/pkg/terminal/p400/reader_registration.go b/pkg/terminal/p400/reader_registration.go
index 61cd29b..cc1dbe5 100644
--- a/pkg/terminal/p400/reader_registration.go
+++ b/pkg/terminal/p400/reader_registration.go
@@ -1,6 +1,7 @@
 package p400
 
 import (
+	"context"
 	"fmt"
 	"os"
 
@@ -23,7 +24,7 @@ const (
 // AttemptRegisterReader prompt the user for their p400 registration code, and tries to register the reader via Stripe API
 // it tries three times before returning an error
 // returns the registered reader's IP address if successful
-func AttemptRegisterReader(tsCtx TerminalSessionContext, tries int) (Reader, error) {
+func AttemptRegisterReader(ctx context.Context, tsCtx TerminalSessionContext, tries int) (Reader, error) {
 	regcode, err := ReaderRegistrationCodePrompt()
 	var newReader Reader
 
@@ -33,7 +34,7 @@ func AttemptRegisterReader(tsCtx TerminalSessionContext, tries int) (Reader, err
 
 	spinner := ansi.StartNewSpinner("Registering your reader with Stripe...", os.Stdout)
 
-	newReader, err = RegisterReader(regcode, tsCtx)
+	newReader, err = RegisterReader(ctx, regcode, tsCtx)
 
 	if err != nil {
 		tries++
@@ -41,14 +42,14 @@ func AttemptRegisterReader(tsCtx TerminalSessionContext, tries int) (Reader, err
 		fmt.Println("Could not register the Reader - please try your code again.")
 
 		if tries < 3 {
-			return AttemptRegisterReader(tsCtx, tries)
+			return AttemptRegisterReader(ctx, tsCtx, tries)
 		}
 
 		return newReader, ErrRegisterReaderFailed
 	}
 
 	// we need to get the reader list again in order to source the base_url attr which you don't get back after registering it
-	readerList, err := DiscoverReaders(tsCtx)
+	readerList, err := DiscoverReaders(ctx, tsCtx)
 
 	if err != nil {
 		return newReader, err
@@ -69,14 +70,14 @@ func AttemptRegisterReader(tsCtx TerminalSessionContext, tries int) (Reader, err
 // RegisterAndActivateReader prompts the user to either add a new reader or choose an existing reader on their account
 // it then calls the appropriate method to set them up and activate a reader session for them to take a test payment
 // it returns an updated TerminalSessionContext containing the session's connection token and rpc session token
-func RegisterAndActivateReader(tsCtx TerminalSessionContext) (TerminalSessionContext, error) {
+func RegisterAndActivateReader(ctx context.Context, tsCtx TerminalSessionContext) (TerminalSessionContext, error) {
 	var (
 		reader         Reader
 		activationType string
 	)
 
 	spinner := ansi.StartNewSpinner("Requesting connection token...", os.Stdout)
-	pstToken, err := GetNewConnectionToken(tsCtx)
+	pstToken, err := GetNewConnectionToken(ctx, tsCtx)
 
 	if err != nil {
 		return tsCtx, err
@@ -86,7 +87,7 @@ func RegisterAndActivateReader(tsCtx TerminalSessionContext) (TerminalSessionCon
 	ansi.StopSpinner(spinner, ansi.Faint("Received new connection token"), os.Stdout)
 
 	// check if user has a reader already registered that they might want to use
-	readerList, err := DiscoverReaders(tsCtx)
+	readerList, err := DiscoverReaders(ctx, tsCtx)
 
 	if err != nil {
 		return tsCtx, err
@@ -108,7 +109,7 @@ func RegisterAndActivateReader(tsCtx TerminalSessionContext) (TerminalSessionCon
 			return tsCtx, err
 		}
 	} else {
-		reader, err = AttemptRegisterReader(tsCtx, 0)
+		reader, err = AttemptRegisterReader(ctx, tsCtx, 0)
 
 		if err != nil {
 			return tsCtx, err
diff --git a/pkg/terminal/p400/stripe_requests.go b/pkg/terminal/p400/stripe_requests.go
index f76a3e7..6ddecc0 100644
--- a/pkg/terminal/p400/stripe_requests.go
+++ b/pkg/terminal/p400/stripe_requests.go
@@ -54,7 +54,7 @@ type getConnectionTokenResponse struct {
 
 // DiscoverReaders calls the Stripe API to get a list of currently registered P400 readers on the account
 // it returns a map of Reader types
-func DiscoverReaders(tsCtx TerminalSessionContext) ([]Reader, error) {
+func DiscoverReaders(ctx context.Context, tsCtx TerminalSessionContext) ([]Reader, error) {
 	parsedBaseURL, err := url.Parse(stripe.DefaultAPIBaseURL)
 
 	if err != nil {
@@ -73,7 +73,7 @@ func DiscoverReaders(tsCtx TerminalSessionContext) ([]Reader, error) {
 		Verbose: false,
 	}
 
-	res, err := client.PerformRequest(context.TODO(), http.MethodGet, stripeTerminalReadersPath, "", nil)
+	res, err := client.PerformRequest(ctx, http.MethodGet, stripeTerminalReadersPath, "", nil)
 
 	if err != nil {
 		return readersList, err
@@ -161,7 +161,7 @@ func StartNewRPCSession(tsCtx TerminalSessionContext) (string, error) {
 
 // GetNewConnectionToken calls the Stripe API and requests a new connection token in order to start a new reader session
 // it returns the connection token when successful
-func GetNewConnectionToken(tsCtx TerminalSessionContext) (string, error) {
+func GetNewConnectionToken(ctx context.Context, tsCtx TerminalSessionContext) (string, error) {
 	parsedBaseURL, err := url.Parse(stripe.DefaultAPIBaseURL)
 
 	if err != nil {
@@ -174,7 +174,7 @@ func GetNewConnectionToken(tsCtx TerminalSessionContext) (string, error) {
 		Verbose: false,
 	}
 
-	res, err := client.PerformRequest(context.TODO(), http.MethodPost, stripeTerminalConnectionTokensPath, "", nil)
+	res, err := client.PerformRequest(ctx, http.MethodPost, stripeTerminalConnectionTokensPath, "", nil)
 
 	if err != nil {
 		return "", err
@@ -202,7 +202,7 @@ func GetNewConnectionToken(tsCtx TerminalSessionContext) (string, error) {
 
 // CreatePaymentIntent calls the Stripe API to create a new Payment Intent in order to later attach a collected P400 payment to
 // it returns the Payment Intent Id
-func CreatePaymentIntent(tsCtx TerminalSessionContext) (string, error) {
+func CreatePaymentIntent(ctx context.Context, tsCtx TerminalSessionContext) (string, error) {
 	parsedBaseURL, err := url.Parse(stripe.DefaultAPIBaseURL)
 
 	if err != nil {
@@ -224,7 +224,7 @@ func CreatePaymentIntent(tsCtx TerminalSessionContext) (string, error) {
 	data.Set("capture_method", "manual")
 	data.Set("description", "Stripe CLI Test Payment")
 
-	res, err := client.PerformRequest(context.TODO(), http.MethodPost, stripeCreatePaymentIntentPath, data.Encode(), nil)
+	res, err := client.PerformRequest(ctx, http.MethodPost, stripeCreatePaymentIntentPath, data.Encode(), nil)
 
 	if err != nil {
 		return "", err
@@ -251,7 +251,7 @@ func CreatePaymentIntent(tsCtx TerminalSessionContext) (string, error) {
 }
 
 // CapturePaymentIntent manually captures the Payment Intent after a Payment Method is attached which is the required flow for collecting payments on the Terminal platform
-func CapturePaymentIntent(tsCtx TerminalSessionContext) error {
+func CapturePaymentIntent(ctx context.Context, tsCtx TerminalSessionContext) error {
 	parsedBaseURL, err := url.Parse(stripe.DefaultAPIBaseURL)
 
 	if err != nil {
@@ -266,7 +266,7 @@ func CapturePaymentIntent(tsCtx TerminalSessionContext) error {
 		Verbose: false,
 	}
 
-	res, err := client.PerformRequest(context.TODO(), http.MethodPost, stripeCapturePaymentIntentURL, "", nil)
+	res, err := client.PerformRequest(ctx, http.MethodPost, stripeCapturePaymentIntentURL, "", nil)
 
 	if err != nil {
 		return ErrCapturePaymentIntentFailed
@@ -289,7 +289,7 @@ func CapturePaymentIntent(tsCtx TerminalSessionContext) error {
 
 // RegisterReader calls the Stripe API to register a new P400 reader to an account
 // it returns the IP address of the reader if successful
-func RegisterReader(regcode string, tsCtx TerminalSessionContext) (Reader, error) {
+func RegisterReader(ctx context.Context, regcode string, tsCtx TerminalSessionContext) (Reader, error) {
 	parsedBaseURL, err := url.Parse(stripe.DefaultAPIBaseURL)
 	var result Reader
 
@@ -306,7 +306,7 @@ func RegisterReader(regcode string, tsCtx TerminalSessionContext) (Reader, error
 	data := url.Values{}
 	data.Set("registration_code", regcode)
 
-	res, err := client.PerformRequest(context.TODO(), http.MethodPost, stripeTerminalRegisterPath, data.Encode(), nil)
+	res, err := client.PerformRequest(ctx, http.MethodPost, stripeTerminalRegisterPath, data.Encode(), nil)
 
 	if err != nil {
 		return result, err
diff --git a/pkg/terminal/quickstart_p400.go b/pkg/terminal/quickstart_p400.go
index bd6b2a6..1d95a1e 100644
--- a/pkg/terminal/quickstart_p400.go
+++ b/pkg/terminal/quickstart_p400.go
@@ -1,6 +1,7 @@
 package terminal
 
 import (
+	"context"
 	"fmt"
 	"os"
 	"time"
@@ -12,10 +13,10 @@ import (
 )
 
 // QuickstartP400 runs the quickstart interactive prompt sequence to walk the user through setting up a P400 reader
-func QuickstartP400(cfg *config.Config) error {
+func QuickstartP400(ctx context.Context, cfg *config.Config) error {
 	tsCtx := SetTerminalSessionContext(cfg)
 
-	tsCtx, err := p400.RegisterAndActivateReader(tsCtx)
+	tsCtx, err := p400.RegisterAndActivateReader(ctx, tsCtx)
 
 	if err != nil {
 		if err.Error() == promptui.ErrInterrupt.Error() {
@@ -27,7 +28,7 @@ func QuickstartP400(cfg *config.Config) error {
 
 	fmt.Println("Got it!")
 
-	tsCtx, err = p400.SetUpTestPayment(tsCtx)
+	tsCtx, err = p400.SetUpTestPayment(ctx, tsCtx)
 
 	if err != nil {
 		p400.ClearReaderDisplay(tsCtx)
@@ -38,7 +39,7 @@ func QuickstartP400(cfg *config.Config) error {
 		}
 	}
 
-	tsCtx, err = p400.CompleteTestPayment(tsCtx)
+	tsCtx, err = p400.CompleteTestPayment(ctx, tsCtx)
 
 	if err != nil {
 		p400.ClearReaderDisplay(tsCtx)


Test patch:
diff --git a/pkg/cmd/root_test.go b/pkg/cmd/root_test.go
index b2af77a..40ba95b 100644
--- a/pkg/cmd/root_test.go
+++ b/pkg/cmd/root_test.go
@@ -2,6 +2,7 @@ package cmd
 
 import (
 	"bytes"
+	"context"
 	"path/filepath"
 	"testing"
 
@@ -42,7 +43,7 @@ func TestGetPathXDG(t *testing.T) {
 }
 
 func TestHelpFlag(t *testing.T) {
-	Execute()
+	Execute(context.Background())
 
 	output, err := executeCommand(rootCmd, "--help")
 
diff --git a/pkg/fixtures/fixtures_test.go b/pkg/fixtures/fixtures_test.go
index b72aa75..f87ce52 100644
--- a/pkg/fixtures/fixtures_test.go
+++ b/pkg/fixtures/fixtures_test.go
@@ -1,6 +1,7 @@
 package fixtures
 
 import (
+	"context"
 	"io"
 	"net/http"
 	"net/http/httptest"
@@ -105,7 +106,7 @@ func TestMakeRequest(t *testing.T) {
 	fxt, err := NewFixture(fs, apiKey, "", ts.URL, file, []string{}, []string{}, []string{}, []string{})
 	require.NoError(t, err)
 
-	_, err = fxt.Execute()
+	_, err = fxt.Execute(context.Background())
 	require.NoError(t, err)
 
 	require.NotNil(t, fxt.responses["cust_bender"])
@@ -135,7 +136,7 @@ func TestWithSkipMakeRequest(t *testing.T) {
 	fxt, err := NewFixture(fs, apiKey, "", ts.URL, file, []string{"char_bender", "capt_bender"}, []string{}, []string{}, []string{})
 	require.NoError(t, err)
 
-	_, err = fxt.Execute()
+	_, err = fxt.Execute(context.Background())
 	require.NoError(t, err)
 
 	require.True(t, fxt.responses["cust_bender"].Exists())
@@ -176,7 +177,7 @@ func TestMakeRequestWithOverride(t *testing.T) {
 	fxt, err := NewFixture(fs, apiKey, "", ts.URL, file, []string{}, []string{"cust_bender:name=Fry", "char_bender:amount=3000"}, []string{}, []string{})
 	require.NoError(t, err)
 
-	_, err = fxt.Execute()
+	_, err = fxt.Execute(context.Background())
 	require.NoError(t, err)
 }
 
@@ -221,7 +222,7 @@ func TestMakeRequestWithAdd(t *testing.T) {
 	)
 	require.NoError(t, err)
 
-	_, err = fxt.Execute()
+	_, err = fxt.Execute(context.Background())
 	require.NoError(t, err)
 }
 
@@ -259,7 +260,7 @@ func TestMakeRequestWithRemove(t *testing.T) {
 	)
 	require.NoError(t, err)
 
-	_, err = fxt.Execute()
+	_, err = fxt.Execute(context.Background())
 	require.NoError(t, err)
 }
 
@@ -275,7 +276,7 @@ func TestMakeRequestExpectedFailure(t *testing.T) {
 	fxt, err := NewFixture(fs, apiKey, "", ts.URL, "failured_test_fixture.json", []string{}, []string{}, []string{}, []string{})
 	require.NoError(t, err)
 
-	_, err = fxt.Execute()
+	_, err = fxt.Execute(context.Background())
 	require.NoError(t, err)
 	require.NotNil(t, fxt.responses["charge_expected_failure"])
 }
@@ -292,7 +293,7 @@ func TestMakeRequestUnexpectedFailure(t *testing.T) {
 	fxt, err := NewFixture(fs, apiKey, "", ts.URL, "failured_test_fixture.json", []string{}, []string{}, []string{}, []string{})
 	require.NoError(t, err)
 
-	_, err = fxt.Execute()
+	_, err = fxt.Execute(context.Background())
 	require.NotNil(t, err)
 }
 
@@ -406,7 +407,7 @@ func TestExecuteReturnsRequestNames(t *testing.T) {
 	fxt, err := NewFixture(fs, apiKey, "", ts.URL, file, []string{}, []string{}, []string{}, []string{})
 	require.NoError(t, err)
 
-	requestNames, err := fxt.Execute()
+	requestNames, err := fxt.Execute(context.Background())
 	require.NoError(t, err)
 
 	require.NotNil(t, fxt.responses["cust_bender"])
diff --git a/pkg/login/client_login_test.go b/pkg/login/client_login_test.go
index a328db1..3893e97 100644
--- a/pkg/login/client_login_test.go
+++ b/pkg/login/client_login_test.go
@@ -1,6 +1,7 @@
 package login
 
 import (
+	"context"
 	"encoding/json"
 	"fmt"
 	"net/http"
@@ -75,7 +76,7 @@ func TestLogin(t *testing.T) {
 	pollURL = fmt.Sprintf("%s%s", ts.URL, "/stripecli/auth/cliauth_123?secret=cliauth_secret")
 
 	input := strings.NewReader("\n")
-	err := Login(ts.URL, c, input)
+	err := Login(context.Background(), ts.URL, c, input)
 	require.NoError(t, err)
 
 	viper.Reset()
@@ -101,7 +102,7 @@ func TestGetLinks(t *testing.T) {
 	}))
 	defer ts.Close()
 
-	links, err := GetLinks(ts.URL, "test")
+	links, err := GetLinks(context.Background(), ts.URL, "test")
 	require.NoError(t, err)
 	require.Equal(t, expectedLinks, *links)
 }
@@ -114,7 +115,7 @@ func TestGetLinksHTTPStatusError(t *testing.T) {
 	}))
 	defer ts.Close()
 
-	links, err := GetLinks(ts.URL, "test")
+	links, err := GetLinks(context.Background(), ts.URL, "test")
 	require.EqualError(t, err, "unexpected http status code: 500 ")
 	require.Empty(t, links)
 }
@@ -132,7 +133,7 @@ func TestGetLinksRequestError(t *testing.T) {
 	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
 	ts.Close()
 
-	links, err := GetLinks(ts.URL, "test")
+	links, err := GetLinks(context.Background(), ts.URL, "test")
 	require.Error(t, err)
 	require.Contains(t, err.Error(), errorString)
 	require.Empty(t, links)
@@ -152,7 +153,7 @@ func TestGetLinksParseError(t *testing.T) {
 	}))
 	defer ts.Close()
 
-	links, err := GetLinks(ts.URL, "test")
+	links, err := GetLinks(context.Background(), ts.URL, "test")
 	require.EqualError(t, err, "json: cannot unmarshal number into Go struct field Links.browser_url of type string")
 	require.Empty(t, links)
 }
diff --git a/pkg/login/interactive_login_test.go b/pkg/login/interactive_login_test.go
index 6105f58..65e1a27 100644
--- a/pkg/login/interactive_login_test.go
+++ b/pkg/login/interactive_login_test.go
@@ -1,6 +1,7 @@
 package login
 
 import (
+	"context"
 	"encoding/json"
 	"net/http"
 	"net/http/httptest"
@@ -19,7 +20,7 @@ func TestDisplayName(t *testing.T) {
 	}
 	account.Settings.Dashboard.DisplayName = testAccountName
 
-	displayName, err := getDisplayName(account, "", "sk_test_123")
+	displayName, err := getDisplayName(context.Background(), account, "", "sk_test_123")
 	require.NoError(t, err)
 	require.Equal(
 		t,
@@ -33,7 +34,7 @@ func TestDisplayNameNoName(t *testing.T) {
 		ID: "acct_123",
 	}
 
-	displayName, err := getDisplayName(account, "", "sk_test_123")
+	displayName, err := getDisplayName(context.Background(), account, "", "sk_test_123")
 	require.NoError(t, err)
 	require.Equal(
 		t,
@@ -57,7 +58,7 @@ func TestDisplayNameGetAccount(t *testing.T) {
 	}))
 	defer ts.Close()
 
-	displayName, err := getDisplayName(nil, ts.URL, "sk_test_123")
+	displayName, err := getDisplayName(context.Background(), nil, ts.URL, "sk_test_123")
 	require.NoError(t, err)
 	require.Equal(
 		t,
@@ -80,7 +81,7 @@ func TestDisplayNameGetAccountNoName(t *testing.T) {
 	}))
 	defer ts.Close()
 
-	displayName, err := getDisplayName(nil, ts.URL, "sk_test_123")
+	displayName, err := getDisplayName(context.Background(), nil, ts.URL, "sk_test_123")
 	require.NoError(t, err)
 	require.Equal(
 		t,
diff --git a/pkg/login/login_message_test.go b/pkg/login/login_message_test.go
index afe1446..26513ab 100644
--- a/pkg/login/login_message_test.go
+++ b/pkg/login/login_message_test.go
@@ -1,6 +1,7 @@
 package login
 
 import (
+	"context"
 	"encoding/json"
 	"net/http"
 	"net/http/httptest"
@@ -17,7 +18,7 @@ func TestSuccessMessage(t *testing.T) {
 	}
 	account.Settings.Dashboard.DisplayName = testDisplayName
 
-	msg, err := SuccessMessage(account, "", "sk_test_123")
+	msg, err := SuccessMessage(context.Background(), account, "", "sk_test_123")
 	require.NoError(t, err)
 	require.Equal(
 		t,
@@ -31,7 +32,7 @@ func TestSuccessMessageNoDisplayName(t *testing.T) {
 		ID: "acct_123",
 	}
 
-	msg, err := SuccessMessage(account, "", "sk_test_123")
+	msg, err := SuccessMessage(context.Background(), account, "", "sk_test_123")
 	require.NoError(t, err)
 	require.Equal(
 		t,
@@ -42,7 +43,7 @@ func TestSuccessMessageNoDisplayName(t *testing.T) {
 
 func TestSuccessMessageBasicMessage(t *testing.T) {
 	account := &Account{}
-	msg, err := SuccessMessage(account, "", "sk_test_123")
+	msg, err := SuccessMessage(context.Background(), account, "", "sk_test_123")
 	require.NoError(t, err)
 	require.Equal(
 		t,
@@ -66,7 +67,7 @@ func TestSuccessMessageGetAccount(t *testing.T) {
 	}))
 	defer ts.Close()
 
-	msg, err := SuccessMessage(nil, ts.URL, "sk_test_123")
+	msg, err := SuccessMessage(context.Background(), nil, ts.URL, "sk_test_123")
 	require.NoError(t, err)
 	require.Equal(
 		t,
@@ -89,7 +90,7 @@ func TestSuccessMessageGetAccountNoDisplayName(t *testing.T) {
 	}))
 	defer ts.Close()
 
-	msg, err := SuccessMessage(nil, ts.URL, "sk_test_123")
+	msg, err := SuccessMessage(context.Background(), nil, ts.URL, "sk_test_123")
 	require.NoError(t, err)
 	require.Equal(
 		t,
diff --git a/pkg/login/poll_test.go b/pkg/login/poll_test.go
index ad385ff..bcd209b 100644
--- a/pkg/login/poll_test.go
+++ b/pkg/login/poll_test.go
@@ -1,6 +1,7 @@
 package login
 
 import (
+	"context"
 	"encoding/json"
 	"net/http"
 	"net/http/httptest"
@@ -36,7 +37,7 @@ func TestRedeemed(t *testing.T) {
 	}))
 	defer ts.Close()
 
-	response, account, err := PollForKey(ts.URL, 1*time.Millisecond, 3)
+	response, account, err := PollForKey(context.Background(), ts.URL, 1*time.Millisecond, 3)
 	require.NoError(t, err)
 	require.Equal(t, "sk_test_123", response.TestModeAPIKey)
 	require.Equal(t, "pk_test_123", response.TestModePublishableKey)
@@ -68,7 +69,7 @@ func TestRedeemedNoDisplayName(t *testing.T) {
 	}))
 	defer ts.Close()
 
-	response, account, err := PollForKey(ts.URL, 1*time.Millisecond, 3)
+	response, account, err := PollForKey(context.Background(), ts.URL, 1*time.Millisecond, 3)
 	require.NoError(t, err)
 	require.Equal(t, "sk_test_123", response.TestModeAPIKey)
 	require.Equal(t, "pk_test_123", response.TestModePublishableKey)
@@ -94,7 +95,7 @@ func TestExceedMaxAttempts(t *testing.T) {
 	}))
 	defer ts.Close()
 
-	response, account, err := PollForKey(ts.URL, 1*time.Millisecond, 3)
+	response, account, err := PollForKey(context.Background(), ts.URL, 1*time.Millisecond, 3)
 	require.EqualError(t, err, "exceeded max attempts")
 	require.Nil(t, response)
 	require.Empty(t, account)
@@ -113,7 +114,7 @@ func TestHTTPStatusError(t *testing.T) {
 	}))
 	defer ts.Close()
 
-	response, account, err := PollForKey(ts.URL, 1*time.Millisecond, 3)
+	response, account, err := PollForKey(context.Background(), ts.URL, 1*time.Millisecond, 3)
 	require.EqualError(t, err, "unexpected http status code: 500 ")
 	require.Nil(t, response)
 	require.Nil(t, account)
@@ -133,7 +134,7 @@ func TestHTTPRequestError(t *testing.T) {
 	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
 	ts.Close()
 
-	response, account, err := PollForKey(ts.URL, 1*time.Millisecond, 3)
+	response, account, err := PollForKey(context.Background(), ts.URL, 1*time.Millisecond, 3)
 	require.Error(t, err)
 	require.Contains(t, err.Error(), errorString)
 	require.Nil(t, response)
diff --git a/pkg/login/retrieve_account_test.go b/pkg/login/retrieve_account_test.go
index 36e15b2..494ee6a 100644
--- a/pkg/login/retrieve_account_test.go
+++ b/pkg/login/retrieve_account_test.go
@@ -1,6 +1,7 @@
 package login
 
 import (
+	"context"
 	"encoding/json"
 	"net/http"
 	"net/http/httptest"
@@ -26,7 +27,7 @@ func TestGetAccount(t *testing.T) {
 	}))
 	defer ts.Close()
 
-	acc, err := GetUserAccount(ts.URL, "sk_test_123")
+	acc, err := GetUserAccount(context.Background(), ts.URL, "sk_test_123")
 	require.NoError(t, err)
 	require.Equal(
 		t,
@@ -54,7 +55,7 @@ func TestGetAccountNoDisplayName(t *testing.T) {
 	}))
 	defer ts.Close()
 
-	acc, err := GetUserAccount(ts.URL, "sk_test_123")
+	acc, err := GetUserAccount(context.Background(), ts.URL, "sk_test_123")
 	require.NoError(t, err)
 	require.Equal(
 		t,
diff --git a/pkg/playback/server_test.go b/pkg/playback/server_test.go
index 2ff3095..63d0344 100644
--- a/pkg/playback/server_test.go
+++ b/pkg/playback/server_test.go
@@ -140,7 +140,7 @@ func TestSimpleRecordReplayServerSeparately(t *testing.T) {
 
 	// Shutdown record server
 	resShutdown, err := http.Get("http://localhost:8080/playback/cassette/eject")
-	server.Shutdown(context.TODO())
+	server.Shutdown(context.Background())
 	assert.NoError(t, err)
 	defer resShutdown.Body.Close()
 
@@ -180,7 +180,7 @@ func TestSimpleRecordReplayServerSeparately(t *testing.T) {
 	assert.Equal(t, mockResponse2.Body, bodyBytes2)
 
 	// Shutdown replay server
-	server.Shutdown(context.TODO())
+	server.Shutdown(context.Background())
 }
 
 // Test the full server by switching between modes, loading and ejecting cassettes, and sending real stripe requests
@@ -233,7 +233,7 @@ func TestPlaybackSingleRunCreateCustomerAndStandaloneCharge(t *testing.T) {
 			log.Fatalf("server startup failed - Serve(): %v", err)
 		}
 	}()
-	defer server.Shutdown(context.TODO())
+	defer server.Shutdown(context.Background())
 	<-serverReady
 
 	fullAddressString := "http://" + addressString
diff --git a/pkg/proxy/proxy_test.go b/pkg/proxy/proxy_test.go
index 4c0d334..ae6a2ce 100644
--- a/pkg/proxy/proxy_test.go
+++ b/pkg/proxy/proxy_test.go
@@ -1,6 +1,7 @@
 package proxy
 
 import (
+	"context"
 	"net/url"
 	"testing"
 
@@ -11,8 +12,8 @@ import (
 )
 
 func TestFilterWebhookEvent(t *testing.T) {
-	proxyUseDefault, _ := Init(&Config{UseLatestAPIVersion: false})
-	proxyUseLatest, _ := Init(&Config{UseLatestAPIVersion: true})
+	proxyUseDefault, _ := Init(context.Background(), &Config{UseLatestAPIVersion: false})
+	proxyUseLatest, _ := Init(context.Background(), &Config{UseLatestAPIVersion: true})
 
 	evtDefault := &websocket.WebhookEvent{
 		Endpoint: websocket.WebhookEndpoint{
diff --git a/pkg/requests/base_test.go b/pkg/requests/base_test.go
index 3fe5b68..6390251 100644
--- a/pkg/requests/base_test.go
+++ b/pkg/requests/base_test.go
@@ -2,6 +2,7 @@ package requests
 
 import (
 	"bufio"
+	"context"
 	"io/ioutil"
 	"net/http"
 	"net/http/httptest"
@@ -106,7 +107,7 @@ func TestMakeRequest(t *testing.T) {
 		expand: []string{"futurama.employees", "futurama.ships"},
 	}
 
-	_, err := rb.MakeRequest("sk_test_1234", "/foo/bar", params, true)
+	_, err := rb.MakeRequest(context.Background(), "sk_test_1234", "/foo/bar", params, true)
 	require.NoError(t, err)
 }
 
@@ -122,7 +123,7 @@ func TestMakeRequest_ErrOnStatus(t *testing.T) {
 
 	params := &RequestParameters{}
 
-	_, err := rb.MakeRequest("sk_test_1234", "/foo/bar", params, true)
+	_, err := rb.MakeRequest(context.Background(), "sk_test_1234", "/foo/bar", params, true)
 	require.Error(t, err)
 	require.Equal(t, "Request failed, status=500, body=:(", err.Error())
 }
diff --git a/pkg/rpcservice/listen_test.go b/pkg/rpcservice/listen_test.go
index ecf89f6..d7bcb15 100644
--- a/pkg/rpcservice/listen_test.go
+++ b/pkg/rpcservice/listen_test.go
@@ -40,7 +40,7 @@ func TestListenStreamsState(t *testing.T) {
 	defer conn.Close()
 	client := rpc.NewStripeCLIClient(conn)
 
-	createProxy = func(cfg *proxy.Config) (IProxy, error) {
+	createProxy = func(ctx context.Context, cfg *proxy.Config) (IProxy, error) {
 		runProxy = func(ctx context.Context) error {
 			cfg.OutCh <- websocket.StateElement{
 				State: websocket.Loading,
@@ -94,7 +94,7 @@ func TestListenStreamsEvents(t *testing.T) {
 	defer conn.Close()
 	client := rpc.NewStripeCLIClient(conn)
 
-	createProxy = func(cfg *proxy.Config) (IProxy, error) {
+	createProxy = func(ctx context.Context, cfg *proxy.Config) (IProxy, error) {
 		runProxy = func(ctx context.Context) error {
 			cfg.OutCh <- websocket.DataElement{
 				Data: proxy.StripeEvent{
@@ -177,7 +177,7 @@ func TestListenStreamsEndpointResponses(t *testing.T) {
 	defer conn.Close()
 	client := rpc.NewStripeCLIClient(conn)
 
-	createProxy = func(cfg *proxy.Config) (IProxy, error) {
+	createProxy = func(ctx context.Context, cfg *proxy.Config) (IProxy, error) {
 		runProxy = func(ctx context.Context) error {
 			r := httptest.NewRequest(http.MethodPost, "localhost:4242/webhook", strings.NewReader(""))
 			cfg.OutCh <- websocket.DataElement{
@@ -242,7 +242,7 @@ func TestListenReturnsEndpointResponseError(t *testing.T) {
 	defer conn.Close()
 	client := rpc.NewStripeCLIClient(conn)
 
-	createProxy = func(cfg *proxy.Config) (IProxy, error) {
+	createProxy = func(ctx context.Context, cfg *proxy.Config) (IProxy, error) {
 		runProxy = func(ctx context.Context) error {
 			cfg.OutCh <- websocket.ErrorElement{
 				Error: proxy.FailedToPostError{Err: errors.New("failed to post")},
@@ -283,7 +283,7 @@ func TestListenReturnsGenericError(t *testing.T) {
 	defer conn.Close()
 	client := rpc.NewStripeCLIClient(conn)
 
-	createProxy = func(cfg *proxy.Config) (IProxy, error) {
+	createProxy = func(ctx context.Context, cfg *proxy.Config) (IProxy, error) {
 		runProxy = func(ctx context.Context) error {
 			myErr := errors.New("my error")
 			cfg.OutCh <- websocket.ErrorElement{
@@ -314,7 +314,7 @@ func TestListenSucceedsWithAllParams(t *testing.T) {
 	defer conn.Close()
 	client := rpc.NewStripeCLIClient(conn)
 
-	createProxy = func(cfg *proxy.Config) (IProxy, error) {
+	createProxy = func(ctx context.Context, cfg *proxy.Config) (IProxy, error) {
 		runProxy = func(ctx context.Context) error {
 			return nil
 		}
diff --git a/pkg/rpcservice/login_status_test.go b/pkg/rpcservice/login_status_test.go
index 98a34fe..e54dc8d 100644
--- a/pkg/rpcservice/login_status_test.go
+++ b/pkg/rpcservice/login_status_test.go
@@ -22,7 +22,7 @@ func TestLoginStatusSucceeds(t *testing.T) {
 		VerificationCode: "baz",
 	}
 
-	pollForKey = func(pollURL string, interval time.Duration, maxAttempts int) (*login.PollAPIKeyResponse, *login.Account, error) {
+	pollForKey = func(ctx context.Context, pollURL string, interval time.Duration, maxAttempts int) (*login.PollAPIKeyResponse, *login.Account, error) {
 		return &login.PollAPIKeyResponse{}, &login.Account{
 			ID: "acct_12345",
 			Settings: login.Settings{
@@ -60,7 +60,7 @@ func TestLoginStatusSucceeds(t *testing.T) {
 func TestLoginStatusFailsWhenLinksEmpty(t *testing.T) {
 	links = &login.Links{}
 
-	pollForKey = func(pollURL string, interval time.Duration, maxAttempts int) (*login.PollAPIKeyResponse, *login.Account, error) {
+	pollForKey = func(ctx context.Context, pollURL string, interval time.Duration, maxAttempts int) (*login.PollAPIKeyResponse, *login.Account, error) {
 		return &login.PollAPIKeyResponse{}, &login.Account{
 			ID: "acct_12345",
 			Settings: login.Settings{
@@ -92,7 +92,7 @@ func TestLoginStatusFailsWhenLinksEmpty(t *testing.T) {
 func TestLoginStatusFailsWhenLinksNil(t *testing.T) {
 	links = nil
 
-	pollForKey = func(pollURL string, interval time.Duration, maxAttempts int) (*login.PollAPIKeyResponse, *login.Account, error) {
+	pollForKey = func(ctx context.Context, pollURL string, interval time.Duration, maxAttempts int) (*login.PollAPIKeyResponse, *login.Account, error) {
 		return &login.PollAPIKeyResponse{}, &login.Account{
 			ID: "acct_12345",
 			Settings: login.Settings{
@@ -124,7 +124,7 @@ func TestLoginStatusFailsWhenLinksNil(t *testing.T) {
 func TestLoginStatusFailsWhenPollFails(t *testing.T) {
 	links = nil
 
-	pollForKey = func(pollURL string, interval time.Duration, maxAttempts int) (*login.PollAPIKeyResponse, *login.Account, error) {
+	pollForKey = func(ctx context.Context, pollURL string, interval time.Duration, maxAttempts int) (*login.PollAPIKeyResponse, *login.Account, error) {
 		return nil, nil, errors.New("pollForKey failed")
 	}
 
@@ -149,7 +149,7 @@ func TestLoginStatusFailsWhenPollFails(t *testing.T) {
 func TestLoginStatusFailsWhenConfigureProfileFails(t *testing.T) {
 	links = nil
 
-	pollForKey = func(pollURL string, interval time.Duration, maxAttempts int) (*login.PollAPIKeyResponse, *login.Account, error) {
+	pollForKey = func(ctx context.Context, pollURL string, interval time.Duration, maxAttempts int) (*login.PollAPIKeyResponse, *login.Account, error) {
 		return &login.PollAPIKeyResponse{}, &login.Account{
 			ID: "acct_12345",
 			Settings: login.Settings{
diff --git a/pkg/rpcservice/login_test.go b/pkg/rpcservice/login_test.go
index 8636fe5..e5523d9 100644
--- a/pkg/rpcservice/login_test.go
+++ b/pkg/rpcservice/login_test.go
@@ -14,7 +14,7 @@ import (
 )
 
 func TestLoginReturnsURLAndPairingCode(t *testing.T) {
-	getLinks = func(baseURL string, deviceName string) (*login.Links, error) {
+	getLinks = func(ctx context.Context, baseURL string, deviceName string) (*login.Links, error) {
 		return &login.Links{
 			BrowserURL:       "foo",
 			PollURL:          "bar",
@@ -43,7 +43,7 @@ func TestLoginReturnsURLAndPairingCode(t *testing.T) {
 }
 
 func TestLoginReturnsFailsWhenGetLinksFails(t *testing.T) {
-	getLinks = func(baseURL string, deviceName string) (*login.Links, error) {
+	getLinks = func(ctx context.Context, baseURL string, deviceName string) (*login.Links, error) {
 		return nil, errors.New("Failed to get links")
 	}
 
diff --git a/pkg/rpcservice/sample_create_test.go b/pkg/rpcservice/sample_create_test.go
index 7851fd2..c97f014 100644
--- a/pkg/rpcservice/sample_create_test.go
+++ b/pkg/rpcservice/sample_create_test.go
@@ -27,7 +27,14 @@ func TestSampleCreateSucceeds(t *testing.T) {
 		}, nil
 	}
 
-	createSample = func(config *config.Config, sampleName string, selectedConfig *samples.SelectedConfig, destination string, forceRefresh bool, resultChan chan<- samples.CreationResult) {
+	createSample = func(
+		ctx context.Context,
+		config *config.Config,
+		sampleName string,
+		selectedConfig *samples.SelectedConfig,
+		destination string,
+		forceRefresh bool,
+		resultChan chan<- samples.CreationResult) {
 		defer close(resultChan)
 		resultChan <- samples.CreationResult{
 			State:       samples.Done,
@@ -68,7 +75,13 @@ func TestSampleCreateFailsWhenGetSampleConfigFails(t *testing.T) {
 		return nil, errors.New("getSampleConfig failed")
 	}
 
-	createSample = func(config *config.Config, sampleName string, selectedConfig *samples.SelectedConfig, destination string, forceRefresh bool, resultChan chan<- samples.CreationResult) {
+	createSample = func(
+		ctx context.Context,
+		config *config.Config,
+		sampleName string,
+		selectedConfig *samples.SelectedConfig,
+		destination string, forceRefresh bool,
+		resultChan chan<- samples.CreationResult) {
 		defer close(resultChan)
 		resultChan <- samples.CreationResult{
 			State:       samples.Done,
@@ -111,7 +124,13 @@ func TestSampleCreateFailsWhenIntegrationDoesntExist(t *testing.T) {
 		}, nil
 	}
 
-	createSample = func(config *config.Config, sampleName string, selectedConfig *samples.SelectedConfig, destination string, forceRefresh bool, resultChan chan<- samples.CreationResult) {
+	createSample = func(
+		ctx context.Context,
+		config *config.Config,
+		sampleName string,
+		selectedConfig *samples.SelectedConfig,
+		destination string, forceRefresh bool,
+		resultChan chan<- samples.CreationResult) {
 		defer close(resultChan)
 		resultChan <- samples.CreationResult{
 			State:       samples.Done,
@@ -154,7 +173,14 @@ func TestSampleCreateFailsWhenCreateSampleFails(t *testing.T) {
 		}, nil
 	}
 
-	createSample = func(config *config.Config, sampleName string, selectedConfig *samples.SelectedConfig, destination string, forceRefresh bool, resultChan chan<- samples.CreationResult) {
+	createSample = func(
+		ctx context.Context,
+		config *config.Config,
+		sampleName string,
+		selectedConfig *samples.SelectedConfig,
+		destination string,
+		forceRefresh bool,
+		resultChan chan<- samples.CreationResult) {
 		defer close(resultChan)
 		resultChan <- samples.CreationResult{
 			Err: errors.New("createSample failed"),
diff --git a/pkg/stripe/client_test.go b/pkg/stripe/client_test.go
index da2d45f..1ee4977 100644
--- a/pkg/stripe/client_test.go
+++ b/pkg/stripe/client_test.go
@@ -31,7 +31,7 @@ func TestPerformRequest_ParamsEncoding_Delete(t *testing.T) {
 	params.Add("key_a", "value_a")
 	params.Add("key_b", "value_b")
 
-	resp, err := client.PerformRequest(context.TODO(), http.MethodDelete, "/delete", params.Encode(), nil)
+	resp, err := client.PerformRequest(context.Background(), http.MethodDelete, "/delete", params.Encode(), nil)
 	require.NoError(t, err)
 
 	defer resp.Body.Close()
@@ -57,7 +57,7 @@ func TestPerformRequest_ParamsEncoding_Get(t *testing.T) {
 	params.Add("key_a", "value_a")
 	params.Add("key_b", "value_b")
 
-	resp, err := client.PerformRequest(context.TODO(), http.MethodGet, "/get", params.Encode(), nil)
+	resp, err := client.PerformRequest(context.Background(), http.MethodGet, "/get", params.Encode(), nil)
 	require.NoError(t, err)
 
 	defer resp.Body.Close()
@@ -83,7 +83,7 @@ func TestPerformRequest_ParamsEncoding_Post(t *testing.T) {
 	params.Add("key_a", "value_a")
 	params.Add("key_b", "value_b")
 
-	resp, err := client.PerformRequest(context.TODO(), http.MethodPost, "/post", params.Encode(), nil)
+	resp, err := client.PerformRequest(context.Background(), http.MethodPost, "/post", params.Encode(), nil)
 	require.NoError(t, err)
 
 	defer resp.Body.Close()
@@ -101,7 +101,7 @@ func TestPerformRequest_ApiKey_Provided(t *testing.T) {
 		APIKey:  "sk_test_1234",
 	}
 
-	resp, err := client.PerformRequest(context.TODO(), http.MethodGet, "/get", "", nil)
+	resp, err := client.PerformRequest(context.Background(), http.MethodGet, "/get", "", nil)
 	require.NoError(t, err)
 
 	defer resp.Body.Close()
@@ -118,7 +118,7 @@ func TestPerformRequest_ApiKey_Omitted(t *testing.T) {
 		BaseURL: baseURL,
 	}
 
-	resp, err := client.PerformRequest(context.TODO(), http.MethodGet, "/get", "", nil)
+	resp, err := client.PerformRequest(context.Background(), http.MethodGet, "/get", "", nil)
 	require.NoError(t, err)
 
 	defer resp.Body.Close()
@@ -135,7 +135,7 @@ func TestPerformRequest_ConfigureFunc(t *testing.T) {
 		BaseURL: baseURL,
 	}
 
-	resp, err := client.PerformRequest(context.TODO(), http.MethodGet, "/get", "", func(r *http.Request) {
+	resp, err := client.PerformRequest(context.Background(), http.MethodGet, "/get", "", func(r *http.Request) {
 		r.Header.Add("Stripe-Version", "2019-07-10")
 	})
 	require.NoError(t, err)
diff --git a/pkg/stripeauth/client_test.go b/pkg/stripeauth/client_test.go
index 38596c9..2cc671c 100644
--- a/pkg/stripeauth/client_test.go
+++ b/pkg/stripeauth/client_test.go
@@ -37,7 +37,7 @@ func TestAuthorize(t *testing.T) {
 	client := NewClient("sk_test_123", &Config{
 		APIBaseURL: ts.URL,
 	})
-	session, err := client.Authorize(context.TODO(), "my-device", "webhooks", nil, nil)
+	session, err := client.Authorize(context.Background(), "my-device", "webhooks", nil, nil)
 	require.NoError(t, err)
 	require.Equal(t, "some-id", session.WebSocketID)
 	require.Equal(t, "wss://example.com/subscribe/acct_123", session.WebSocketURL)
@@ -55,7 +55,7 @@ func TestUserAgent(t *testing.T) {
 	client := NewClient("sk_test_123", &Config{
 		APIBaseURL: ts.URL,
 	})
-	client.Authorize(context.TODO(), "my-device", "webhooks", nil, nil)
+	client.Authorize(context.Background(), "my-device", "webhooks", nil, nil)
 }
 
 func TestStripeClientUserAgent(t *testing.T) {
@@ -78,7 +78,7 @@ func TestStripeClientUserAgent(t *testing.T) {
 	client := NewClient("sk_test_123", &Config{
 		APIBaseURL: ts.URL,
 	})
-	client.Authorize(context.TODO(), "my-device", "webhooks", nil, nil)
+	client.Authorize(context.Background(), "my-device", "webhooks", nil, nil)
 }
 
 func TestAuthorizeWithURLDeviceMap(t *testing.T) {
@@ -101,5 +101,5 @@ func TestAuthorizeWithURLDeviceMap(t *testing.T) {
 		ForwardConnectURL: "http://localhost:3000/connect/events",
 	}
 
-	client.Authorize(context.TODO(), "my-device", "webhooks", nil, &devURLMap)
+	client.Authorize(context.Background(), "my-device", "webhooks", nil, &devURLMap)
 }