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

# Collect with Go

> Collect a payment via invoice (orders use the same flow) using the Dollr API with Go net/http.

<Note>
  **Invoices vs orders:** These guides walk through **invoices** (formal billing, line items, publish). The collect flow is the same for **orders** — use `/v1/orders/*` instead of `/v1/invoices/*` and set `source_type: "ORDER"` on the checkout session. See [Orders](/api/orders) and [Parties & counterparties](/concepts/parties-and-counterparties).

  **Hosted checkout:** To skip party, invoice, session, and execute steps entirely, see [Hosted checkout](/guides/hosted-checkout).
</Note>

End-to-end **invoice collection** with the standard library `net/http` and `encoding/json`.

<Note>
  **API Reference:** [Obtain token](/api-reference/jwt/client-obtain-token) · [Collect](/api-reference/executions/collect)
</Note>

## Prerequisites

* Go 1.21+
* `os.Getenv` for `DOLLR_CLIENT_ID` and `DOLLR_CLIENT_SECRET`

## Steps

<Steps>
  <Step title="Client and token">
    ```go theme={null}
    package main

    import (
        "bytes"
        "encoding/json"
        "net/http"
        "os"
    )

    const baseURL = "https://api.heydollr.app"

    func obtainToken() (string, error) {
        body, _ := json.Marshal(map[string]string{
            "client_id":     os.Getenv("DOLLR_CLIENT_ID"),
            "client_secret": os.Getenv("DOLLR_CLIENT_SECRET"),
        })
        req, _ := http.NewRequest(http.MethodPost, baseURL+"/v1/jwt/client/obtain/token", bytes.NewReader(body))
        req.Header.Set("Content-Type", "application/json")
        res, err := http.DefaultClient.Do(req)
        // decode access_token from res.Body
        return "", err
    }
    ```
  </Step>

  <Step title="POST helper">
    ```go theme={null}
    func dollrPost(path, token string, payload any) (map[string]any, error) {
        b, _ := json.Marshal(payload)
        req, _ := http.NewRequest(http.MethodPost, baseURL+path, bytes.NewReader(b))
        req.Header.Set("Authorization", "Bearer "+token)
        req.Header.Set("Content-Type", "application/json")
        res, err := http.DefaultClient.Do(req)
        // json.NewDecoder(res.Body).Decode(&out)
        return nil, err
    }
    ```

    Chain: parties → counterparties → invoices → items → publish.
  </Step>

  <Step title="Execute with idempotency key">
    ```go theme={null}
    import "github.com/google/uuid"

    referenceID := uuid.New().String()
    _, err = dollrPost("/v1/executions/collection", token, map[string]string{
        "session_id":         sessionID,
        "payment_account_id": paymentAccountID,
        "currency":           "USD",
        "reference_id":       referenceID,
    })
    ```
  </Step>

  <Step title="Poll status">
    ```go theme={null}
    req, _ := http.NewRequest(http.MethodGet, baseURL+"/v1/status/collection/"+referenceID, nil)
    req.Header.Set("Authorization", "Bearer "+token)
    ```
  </Step>
</Steps>

## Try it yourself

<CardGroup cols={3}>
  <Card title="Hosted checkout" icon="window-maximize" href="/guides/hosted-checkout">
    Mobile money and card on a Dollr-hosted page — fastest path.
  </Card>

  <Card title="Orders" icon="box" href="/api/orders">
    Same collect flow with `source_type: ORDER` and `/v1/orders/*`.
  </Card>

  <Card title="Direct checkout" icon="cart-shopping" href="/guides/collect-via-checkout">
    One API call to create source — API-embedded flow.
  </Card>
</CardGroup>

## Related

* [Hosted checkout](/guides/hosted-checkout) · [Orders](/api/orders)
* [Collect via checkout](/guides/collect-via-checkout)
* [Choose your integration](/guides/choose-integration)
* [Error handling](/guides/error-handling)
* [Sessions & executions](/concepts/sessions-and-executions)
