# Referrals with Paddle Billing

A notification destination and its secret: transactions, renewals, refunds and chargebacks, with discount ids learned from Paddle's own events.

Connect Paddle Billing and every paid transaction, renewal, refund and
chargeback reaches the program, credited to the partner whose link or code
brought the customer. Paddle signs each delivery with a secret of its own, with a
timestamp, so a delivery cannot be replayed later.

## Add a notification destination

1. Open the program, **Setup**, **Billing**, **Paddle**, and copy the endpoint URL.
2. In Paddle: **Developer Tools**, **Notifications**, **New destination**. Paste
   the URL and select these events:

   `transaction.completed`, `adjustment.created`, `adjustment.updated`,
   `discount.created`, `discount.updated`

3. Open the destination again with **Edit destination**: Paddle shows its secret
   key (it starts `pdl_ntfset_`). Paste it on the card.

## Pass the referral to checkout

Give Paddle.js the code as custom data. Paddle stores it on the transaction,
copies it to the subscription, and from there to every renewal, so renewals are
credited too.

```js
Paddle.Checkout.open({
  items: [{ priceId: "pri_monthly", quantity: 1 }],
  customData: { boltclaw_ref: BoltClawReferral.code(), boltclaw_customer_id: "acme-user-10442" },
});
```

Without `boltclaw_customer_id`, Paddle's own customer id (`ctm_`) stands in.
When a transaction's line items add up to what was paid, each one is read, so a
reward rule for one product or price applies to it.

## Refunds and chargebacks

Paddle reports both as adjustments. A refund counts once Paddle approves it
(most start as pending approval), for its own amount, so a partial refund takes
back that share of the commission. A chargeback reverses the sale in full.

## Discount codes

Paddle sends a discount as an id. With `discount.created` and `.updated`
selected, Bolt Claw learns each id's code, so a sale made with a partner's code
alone is credited to them.

## Test mode

Paddle's sandbox is its own account, and its events do not say they are tests.
Add a second Paddle integration for the sandbox and switch **Sandbox** on: every
event it receives is test data.

## Check it works

On the program's **Setup** tab, the **Billing** row of the setup status turns
`Connected` with the first verified event, and says when a delivery was refused
(nearly always the wrong secret). Then press **Send a test sale** to see a
click, a signup, a sale and a refund go through your rules with test data, or
make a real test purchase in your Paddle sandbox. See [Connect your billing system](https://boltclaw.ai/docs/referral-setup)
for the whole setup status and what test data never does.

<!-- https://boltclaw.ai/docs/referral-billing-paddle as markdown. Generated from openapi.yaml; API version 1.22.0. -->
<!-- Every /docs page answers as markdown: add .md to its path, or send Accept: text/markdown. -->
