# RevenueCat Web Billing for GoCommerce — Open-Source Module

> Sell digital goods through a RevenueCat Web Purchase Link from a GoCommerce store: link token, webhook, price matching, and why refunds are not supported.

- Canonical: https://kitcommerce.store/integrations/payments-revenuecat/
- Last updated: 2026-09-25

---

Payments

## RevenueCat Web Billing for GoCommerce

A Go package that builds a RevenueCat Web Purchase Link for each order and marks the GoCommerce order paid when RevenueCat’s webhook reports a purchase matching the order total to the minor unit. For digital goods only, and with no refunds through GoCommerce.

- **Payments** module
- **4** settings
- **10** tests
- **ext/payments-revenuecat**

### What it does

The module registers “revenuecat” as a payment method. At checkout it makes no API call at all: it builds the purchase link — your link token, then the order number as RevenueCat’s app user id, with the shopper’s email and the currency as query parameters — and answers with a redirect intent carrying it. A storefront can preselect a package by sending package_id in the checkout’s payment data.

RevenueCat then calls POST /api/checkout/revenuecat/webhook. The module checks the Authorization header, and the HMAC signature too when one is configured. On INITIAL_PURCHASE or NON_RENEWING_PURCHASE it finds the order by its number and marks it paid — but only if what RevenueCat charged equals the order’s total and currency.

The package is candid about the fit. RevenueCat sells a product from its own catalogue at its own price, so the store does not set the price at checkout; RevenueCat does. And, citing RevenueCat’s documentation, Web Billing does not collect a shipping address, does not support B2B sales and is not available to merchants in India. This provider is for downloads, licences and memberships.

### Configuration

Two settings are required: the Web Purchase Link token and the exact Authorization header RevenueCat is configured to send. Set them in Config from your own main(), or under Settings › Payment methods.

*RevenueCat module settings — 4 settings, 2 required*

| Setting | Environment variable | Required | What it does |
| --- | --- | --- | --- |
| `LinkToken` Web Purchase Link token | `REVENUECAT_LINK_TOKEN` | Yes | The path segment in https://pay.rev.cat/\<token>. |
| `WebhookAuthorization` Webhook Authorization header | `REVENUECAT_WEBHOOK_AUTHORIZATION` | Yes | Exactly what RevenueCat sends in the Authorization header, compared in constant time. Required because, as the code puts it, without it any caller could mark orders paid. |
| `SigningSecret` Webhook signing secret | — | No | Adds HMAC verification when the webhook has signing switched on in RevenueCat. The package calls it worth it: the header alone is a bearer secret every delivery repeats. |
| `BaseURL` Purchase link host | — | No | Overrides https://pay.rev.cat, for tests. Empty for production. |

The module reads its Config struct, not the environment. The variable names are the ones the package’s own example or the reference binary uses; in your own `main()` you choose where each value comes from. Where a setting has a panel label, the admin’s settings drawer can hold it too, and a value typed there wins over Config.

### Setting it up

1. **Match the price** — In RevenueCat, the product’s price must equal the order total — so leave GoCommerce’s tax rates empty, as for a merchant of record.
2. **Configure the webhook** — Point RevenueCat’s webhook at https://your-api-host/api/checkout/revenuecat/webhook, set its Authorization header, and switch signing on.
3. **Install and configure** — Pass revenuecat.New to gocommerce.New as below, or run the reference binary with -gateways and fill in Settings › Payment methods.
4. **Take a payment** — POST /api/checkout/revenuecat answers with a redirect intent whose url is the purchase link. A matching purchase event marks the order paid.

main.go

```
import (
	"os"

	"github.com/itswadesh/gocommerce/core"
	revenuecat "github.com/itswadesh/gocommerce/ext/payments-revenuecat"
)

app, err := gocommerce.New(cfg,
	revenuecat.New(revenuecat.Config{
		LinkToken:            os.Getenv("REVENUECAT_LINK_TOKEN"),
		WebhookAuthorization: os.Getenv("REVENUECAT_WEBHOOK_AUTHORIZATION"),
	}),
)
```

The package doc’s own example, with its imports; cfg is your gocommerce.Config. Add SigningSecret when the webhook has signing on. Import path `github.com/itswadesh/gocommerce/ext/payments-revenuecat`.

### How it works

- **No API call at checkout**

  The purchase link is a URL the module builds from the link token, the order number, the email and the currency. RevenueCat hears about the order only when the shopper pays.

- **Two layers of verification**

  The Authorization header must match exactly, in constant time. With a signing secret set, X-RevenueCat-Webhook-Signature must also verify: t=…,v1=…, an HMAC-SHA256 over the timestamp and the body, within five minutes.

- **The price is checked**

  RevenueCat reports the price as a decimal. The module converts it to minor units — zero- and three-decimal currencies such as JPY and KWD included — and settles only on an exact match with the order’s total and currency.

- **Each event once**

  Claims are keyed on RevenueCat’s event id. A redelivery is answered 200; a TEST event from the dashboard is acknowledged and nothing else.

- **A failed update is retried**

  If marking the order paid fails, the claim is released and the webhook answers 500, so RevenueCat’s retry finds work to do.

- **Warnings where they help**

  An order with a shipping address logs a warning at checkout, because Web Billing will not carry it. A CANCELLATION logs that the order still reads as paid.

### What it does not do

Read these before an order depends on it. No store is known to run GoCommerce in production yet, so these come from the code, not from anyone’s experience.

- **No refunds** — RevenueCat has no API to refund a Web Billing purchase, so the module does not claim the capability. A refund from the admin is answered 409 — the payment method does not support refunds. Refund in RevenueCat or the underlying processor.
- **The price is RevenueCat’s** — The link carries no amount. If the product’s price and the order total differ by one minor unit, the order is not settled and the mismatch is logged for an operator.
- **Digital goods only** — Per the package, Web Billing collects no shipping address and does not support B2B sales. A store that ships parcels should use another provider.
- **Not for merchants in India** — The package cites RevenueCat’s documentation: Web Billing is not available to merchants in India.
- **One customer per order** — The order number is the app user id, so each order is a new RevenueCat customer. A project that also sells subscriptions to the same people would need to alias them in RevenueCat; the module does not.
- **Cancellations are only logged** — A CANCELLATION — how RevenueCat reports a refund — is logged, and the GoCommerce order keeps reading as paid.

FAQ

### Questions about the RevenueCat module

**Can I refund a RevenueCat order from GoCommerce?**

No. RevenueCat has no API for refunding a Web Billing purchase, so the module does not implement refunds — for the same reason cash on delivery does not. The engine answers a refund with 409. Refund in RevenueCat’s dashboard or the underlying processor.

**Why must the product price equal the order total?**

A purchase link carries no amount; RevenueCat charges the price configured on its product. The module compares what was charged with the order total, in minor units and currency, and settles only when they agree. In practice that means GoCommerce’s tax rates stay empty.

**Can I sell physical goods with it?**

The package says not to. Citing RevenueCat’s documentation, Web Billing collects no shipping address, does not support B2B sales and is not available to merchants in India. It is for downloads, licences and memberships.

**Is this a RevenueCat partnership?**

No. The module builds RevenueCat’s public purchase links and reads its webhooks with credentials you supply. RevenueCat does not endorse GoCommerce, and no store is known to run this module in production yet.

### Source

Everything on this page is read from [`ext/payments-revenuecat`](https://github.com/itswadesh/gocommerce/tree/main/ext/payments-revenuecat) in the GoCommerce repository, MIT licensed. When this page and the code disagree, the code is right and this page is out of date.RevenueCat is a trademark of its owner; this module talks to its public API and implies no endorsement. See [trademarks](https://kitcommerce.store/about/#trademarks).

- [ext/payments-revenuecat on GitHub](https://github.com/itswadesh/gocommerce/tree/main/ext/payments-revenuecat)
- [RevenueCat](https://www.revenuecat.com)
- [All GoCommerce modules](https://kitcommerce.store/integrations/)

### Try it against a store of your own

The one-command stack gives you GoCommerce’s API and admin on your own machine in minutes. Add this module to it and try it on test orders before a real one depends on it.

[Deploy in minutes](https://kitcommerce.store/#one-command) · [Read the module](https://github.com/itswadesh/gocommerce/tree/main/ext/payments-revenuecat) · [All integrations](https://kitcommerce.store/integrations/)
