# Purchases

Fulfill a consumable purchase from your backend over HTTP.

Source: https://docs.wavedash.com/api/purchases

## Fulfill a purchase

```text
POST /api/purchases/{purchaseId}/fulfill
```

This is the backend version of the SDK's `fulfillPurchase`. Call it once your backend has saved the grant for a [consumable](/sdk/paid-content/consumables), so the SDK stops delivering the purchase at launch. It's idempotent, and it's safe to call alongside the SDK's `fulfillPurchase` for the same purchase.

<Note>
This endpoint doesn't take an API key. The purchase's `receiptJwt` authenticates the request, so your backend can call it straight from a webhook handler. Wavedash verifies the receipt the same way you [verify it yourself](/sdk/paid-content/consumables#verifying-the-receiptjwt).
</Note>

### Body

| Field | Description |
| --- | --- |
| `receiptJwt` | String. A `purchase.completed` receipt for this purchase, from the webhook or the `PURCHASE_COMPLETED` event. |

### Example

```bash
curl "https://api.wavedash.com/api/purchases/$PURCHASE_ID/fulfill" \
  -X POST \
  -H "Content-Type: application/json" \
  -d "{\"receiptJwt\": \"$RECEIPT_JWT\"}"
```

### Response

`200` with the outcome:

```json
{ "status": "FULFILLED" }
```

| Status | Meaning |
| --- | --- |
| `FULFILLED` | Marked fulfilled by this call. |
| `ALREADY_FULFILLED` | Your game or backend fulfilled it earlier, or it's a durable. Treat it as success. |

### Errors

In addition to the [standard codes](/api#responses):

| Status | When |
| --- | --- |
| `400` | `invalid_input`: the body is missing `receiptJwt`, or the receipt is for a different purchase than `purchaseId`. |
| `401` | `unauthorized`: the receipt doesn't verify, or it isn't a `purchase.completed` receipt. |
| `404` | `not_found`: the purchase doesn't exist or was refunded. The body also carries `"status": "NOT_FOUND"`. Don't grant it. |

## Fulfilling from a webhook

Most backends call this endpoint from their webhook handler, right after granting the purchase. See [Handling a webhook](/api/webhooks#handling-a-webhook) for a complete example that verifies the receipt, grants the consumable, and fulfills it.
