Paddle Billing is a complete digital product sales and subscription management platform, designed for modern software businesses. It helps you increase your revenue, retain customers, and scale your operations.
This is a Go SDK that you can use to integrate Paddle Billing with applications written in server-side Go.
For working with Paddle in your frontend, use Paddle.js. You can open checkouts, securely collect payment information, build pricing pages, and integrate with Paddle Retain.
Important: This package works with Paddle Billing. It does not support Paddle Classic. To work with Paddle Classic, see: Paddle Classic API reference
Go 1.21 or later
If you've used this SDK, we'd love to hear how you found it! Email us at team-dx@paddle.com with any thoughts.
Make sure your project is using Go Modules (it will have a go.mod file in its root if it already is):
go mod init
To install the Paddle Go SDK, use the following command:
go get github.com/PaddleHQ/paddle-go-sdk
Then, reference paddle-go-sdk in a Go program with import:
import (
paddle "github.com/PaddleHQ/paddle-go-sdk/v3"
)
To authenticate, you'll need an API key. You can create and manage API keys in Paddle > Developer tools > Authentication.
Pass your API key while initializing a new Paddle client.
import (
paddle "github.com/PaddleHQ/paddle-go-sdk/v3"
)
client, err := paddle.New(
os.Getenv("PADDLE_API_KEY"),
paddle.WithBaseURL(paddle.ProductionBaseURL),
)
You can now use the client to make requests to the Paddle API.
Below are some concise examples to get you going. You can also compile and run the testable examples.
You can list supported entities with the List*
function. It returns an iterator to help when working with multiple pages.
products, err := client.ListProducts(ctx, &paddle.ListProductsRequest{IncludePrices: true})
if err != nil {
panic(err)
}
err = products.Iter(ctx, func(p *paddle.Product) (bool, error) {
// Do something with the product
fmt.Printf("%+v\n", p)
return true, nil
})
if err != nil {
panic(err)
}
You can create a supported entity with the Create*
function. It accepts the resource's corresponding Create*Request
operation e.g. CreateProductRequest
. The created entity is returned.
product, err := client.CreateProduct(ctx, &paddle.CreateProductRequest{
Name: "Test Product - GO SDK",
TaxCategory: paddle.TaxCategoryStandard,
})
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", product)
You can update a supported entity with the Update*
function. It accepts the ID
of the entity to update and the corresponding Update*Request
operation e.g. UpdateProductRequest
. The updated entity is returned.
product, err := client.UpdateProduct(ctx, &paddle.UpdateProductRequest{
ProductID: product.ID,
Name: paddle.NewPatchField("Test Product - GO SDK Updated"),
})
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", product)
You can get an entity with the Get*
function. It accepts the ID
of the entity to get and the corresponding Get*Request
operation e.g. GetProductRequest
. The entity is returned.
product, err := client.GetProduct(ctx, &paddle.GetProductRequest{
ProductID: productID,
IncludePrices: true
})
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", product)
The SDK includes a couple of helper functions to verify webhook signatures sent by Notifications from Paddle.
You could use a middleware to verify the signature of the incoming request before processing it.
verifier := paddle.NewWebhookVerifier(os.Getenv("WEBHOOK_SECRET_KEY"))
// Wrap your handler with the verifier.Middleware method
handler := verifier.Middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// The request making it this far means the webhook was verified
// Best practice here is to check if you have processed this webhook already using the event id
// At this point you should store for async processing
// For example a local queue or db entry
// Respond as soon as possible with a 200 OK
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"success": true}`))
}))
Alternatively you can verify the signature of the incoming request manually.
webhookVerifier := paddle.NewWebhookVerifier(os.Getenv("WEBHOOK_SECRET_KEY"))
// Note: the request (req *http.Request) should be pass exactly as it comes without altering it.
ok, err := webhookVerifier.Verify(req)
The SDK uses testable examples in Go, which are compiled and executed as part of testing the package.
These testable examples use a mock server that returns predefined responses. This approach means you can make sure the examples compile and execute as expected.
These are not intended to be comprehensive for each and every operation. Instead, they cover the general flow of operations for entities as well as some useful examples.