> ## Documentation Index
> Fetch the complete documentation index at: https://commet.co/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrar con Encore

> Agrega cobros y pagos a tu aplicación de Encore.

Instala la Commet Skill para que tu agente integre el SDK actual y valide su trabajo contra el contrato vivo de la API.

```bash theme={null}
npx skills add commet-labs/skills --skill commet
```

<Steps>
  <Step title="Instalar">
    ```bash theme={null}
    encore app create --example=hello-world myapp
    cd myapp
    go get github.com/commet-labs/commet-go/v9
    ```
  </Step>

  <Step title="Configurar">
    Guarda los secretos usando el gestor de secretos de Encore en lugar de variables de entorno:

    ```bash theme={null}
    encore secret set --type dev,local,pr,prod CommetAPIKey
    encore secret set --type dev,local,pr,prod CommetWebhookSecret
    ```

    ```go title="billing/billing.go" theme={null}
    package billing

    import (
    	commet "github.com/commet-labs/commet-go/v9"
    )

    var secrets struct {
    	CommetAPIKey       string
    	CommetWebhookSecret string
    }

    var client *commet.Client

    func initClient() error {
    	var err error
    	client, err = commet.New(secrets.CommetAPIKey)
    	return err
    }
    ```

    El cliente no tiene opción de environment: sandbox o live lo decide la organización a la que pertenece la API key.
  </Step>

  <Step title="Suscribir">
    ```go title="billing/billing.go" theme={null}
    import "context"

    type SubscribeParams struct {
    	Email      string `json:"email"`
    	CustomerID string `json:"customer_id"`
    }

    type SubscribeResponse struct {
    	CheckoutURL string `json:"checkout_url"`
    }

    //encore:api public method=POST path=/billing/subscribe
    func Subscribe(ctx context.Context, req *SubscribeParams) (*SubscribeResponse, error) {
    	if err := initClient(); err != nil {
    		return nil, err
    	}

    	_, err := client.Customers.Create(ctx, &commet.CreateCustomerParams{
    		Email: req.Email,
    		ID:    &req.CustomerID,
    	})
    	if err != nil {
    		return nil, err
    	}

    	planCode := "pro"
    	subscription, err := client.Subscriptions.Create(ctx, &commet.CreateSubscriptionParams{
    		CustomerID: req.CustomerID,
    		PlanCode:   &planCode,
    	})
    	if err != nil {
    		return nil, err
    	}

    	checkoutURL := ""
    	if subscription.CheckoutURL != nil {
    		checkoutURL = *subscription.CheckoutURL
    	}

    	return &SubscribeResponse{
    		CheckoutURL: checkoutURL,
    	}, nil
    }
    ```
  </Step>

  <Step title="Verificar acceso">
    ```go title="billing/billing.go" theme={null}
    type SubscriptionResponse struct {
    	Status string `json:"status"`
    }

    //encore:api public method=GET path=/billing/subscription/:customerID
    func GetSubscription(ctx context.Context, customerID string) (*SubscriptionResponse, error) {
    	if err := initClient(); err != nil {
    		return nil, err
    	}

    	sub, err := client.Subscriptions.GetActive(ctx, &commet.GetActiveSubscriptionParams{
    		CustomerID: customerID,
    	})
    	if err != nil {
    		return nil, err
    	}

    	if sub == nil {
    		return &SubscriptionResponse{Status: "none"}, nil
    	}

    	return &SubscriptionResponse{
    		Status: string(sub.Status),
    	}, nil
    }

    type FeatureResponse struct {
    	Allowed bool `json:"allowed"`
    }

    //encore:api public method=GET path=/billing/features/:feature/:customerID
    func CheckFeature(ctx context.Context, feature string, customerID string) (*FeatureResponse, error) {
    	if err := initClient(); err != nil {
    		return nil, err
    	}

    	result, err := client.FeatureAccess.Get(ctx, feature, &commet.GetFeatureAccessParams{
    		CustomerID: customerID,
    	})
    	if err != nil {
    		return nil, err
    	}

    	return &FeatureResponse{
    		Allowed: result.Allowed,
    	}, nil
    }
    ```
  </Step>

  <Step title="Trackear uso">
    ```go title="billing/billing.go" theme={null}
    func float64Ptr(value float64) *float64 { return &value }

    type UsageParams struct {
    	CustomerID string `json:"customer_id"`
    }

    type UsageResponse struct {
    	Tracked bool `json:"tracked"`
    }

    //encore:api public method=POST path=/billing/usage
    func TrackUsage(ctx context.Context, req *UsageParams) (*UsageResponse, error) {
    	if err := initClient(); err != nil {
    		return nil, err
    	}

    	_, err := client.Usage.Track(ctx, &commet.TrackUsageParams{
    		CustomerID: req.CustomerID,
    		FeatureCode: "api_calls",
    		Value:       float64Ptr(1),
    	})
    	if err != nil {
    		return nil, err
    	}

    	return &UsageResponse{Tracked: true}, nil
    }
    ```

    El uso se agrega y se cobra al final del período.
  </Step>

  <Step title="Webhooks">
    ```go title="billing/webhooks.go" theme={null}
    package billing

    import (

    	"io"
    	"net/http"

    	commet "github.com/commet-labs/commet-go/v9"
    )

    //encore:api public raw method=POST path=/webhooks/commet
    func HandleWebhook(w http.ResponseWriter, r *http.Request) {
    	rawBody, err := io.ReadAll(r.Body)
    	if err != nil {
    		http.Error(w, "Failed to read body", http.StatusBadRequest)
    		return
    	}

    	webhooks := &commet.WebhooksResource{}
    	payload, err := webhooks.VerifyAndParse(
    		string(rawBody),
    		r.Header.Get("x-commet-signature"),
    		secrets.CommetWebhookSecret,
    	)
    	if err != nil {
    		http.Error(w, "Invalid signature", http.StatusUnauthorized)
    		return
    	}

    	switch payload["event"] {
    	case "subscription.activated":
    		// manejar activación
    	}

    	w.Header().Set("Content-Type", "application/json")
    	w.Write([]byte(`{"ok":true}`))
    }
    ```
  </Step>

  <Step title="Ejecutar">
    ```bash theme={null}
    encore run
    ```
  </Step>
</Steps>

## Relacionado

* [Suscripciones](/docs/es/manage-subscriptions)
* [Trackear Uso](/docs/es/track-usage)
* [Portal del Cliente](/docs/es/customer-portal)
* [Referencia del SDK](/docs/es/sdk-reference)


## Related topics

- [Integrar con Flask](/docs/es/integrate-with-flask.md)
- [Integrar con Java](/docs/es/integrate-with-java.md)
- [Integrar con Django](/docs/es/integrate-with-django.md)
- [Integrar con Laravel](/docs/es/integrate-with-laravel.md)
- [Integrar con PHP](/docs/es/integrate-with-php.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.