# Payment Providers

URL: https://zerodev.ca/docs/store/providers

> Connect Stripe, PayPal, Razorpay, Polar or NOWPayments, and set up their webhooks.



Set up only the providers you want to use. Each one needs its API keys in `configuration/store.json5` and a webhook, so AthenaBot hears about payments.

## Webhook Address

Webhooks go to AthenaBot's `web_api` plugin, which listens on port `3111` by default. Providers need a public HTTPS address, so put a reverse proxy in front of it. Pick yours:

<ReverseProxy sites="[{ domain: &#x22;shop.example.com&#x22;, port: 3111 }]" />

Then set `base_ip` in `configuration/web_api.json5` to `shop.example.com`. Each provider's webhook URL is:

```text
https://shop.example.com/api/store/webhook/<provider>
```

Every webhook is checked against its provider's secret before anything is given out. A provider with no secret set rejects all webhooks with a `500`, so fill in the secret for every provider you use.

If a provider sends the same payment twice, Store notices the transaction ID it already saved and skips it, so rewards are never given twice.

## Stripe

1. In the [Stripe Dashboard](https://dashboard.stripe.com), go to **Developers > API keys** and copy the **Secret key**.
2. Go to **Developers > Webhooks**, add an endpoint at `https://<your-domain>/api/store/webhook/stripe` and select the `checkout.session.completed` event.
3. Copy the endpoint's **Signing secret**.

```json5
stripe: {
  secret_key: "sk_live_...",
  webhook_secret: "whsec_...",
},
```

Use `sk_test_...` keys and a test webhook to try it without real payments.

The checkout page offers whatever payment methods you turn on under **Settings > Payment methods** in the Stripe Dashboard, such as cards, Apple Pay or Link.

## PayPal

1. In the [PayPal Developer Dashboard](https://developer.paypal.com), create an app under **Apps & Credentials** and copy its **Client ID** and **Secret**.
2. In the app, add a webhook at `https://<your-domain>/api/store/webhook/paypal` with the `PAYMENT.CAPTURE.COMPLETED` event.
3. Copy the **Webhook ID**.

```json5
paypal: {
  client_id: "",
  client_secret: "",
  webhook_id: "",
  mode: "live",
},
```

Set `mode` to `sandbox` with sandbox credentials to test.

## Razorpay

1. In the [Razorpay Dashboard](https://dashboard.razorpay.com), go to **Account & Settings > API Keys** and generate a key.
2. Go to **Webhooks**, add `https://<your-domain>/api/store/webhook/razorpay` with the `payment_link.paid` event.
3. Set a **Secret** on the webhook and copy it.

```json5
razorpay: {
  key_id: "rzp_live_...",
  key_secret: "",
  webhook_secret: "",
},
```

## Polar

1. In [Polar](https://polar.sh), create a product for each item you sell and copy each one's **Price ID**.
2. Under **Settings > Developers**, create an **Access Token**.
3. Under **Settings > Webhooks**, add `https://<your-domain>/api/store/webhook/polar` with the `order.created` event and copy its secret.

```json5
polar: {
  access_token: "",
  webhook_secret: "",
  server: "production",
},
```

Add `polar_price_id` to every product sold through Polar. Set `server` to `sandbox` to test.

## Crypto (NOWPayments)

1. Create an account at [NOWPayments](https://nowpayments.io) and generate an **API key**.
2. Under **Settings > Payments > Instant payment notifications**, set the IPN callback to `https://<your-domain>/api/store/webhook/crypto` and copy the **IPN secret**.

```json5
crypto: {
  api_key: "",
  ipn_secret: "",
},
```

A crypto purchase completes when NOWPayments marks it `finished`, which can take a while depending on the coin.

## Testing

1. Use each provider's test or sandbox mode.
2. Post a panel and buy something.
3. Check the console for the webhook request and the `store-logs` channel for the purchase.

If the purchase never completes, see [Troubleshooting](/docs/store/purchase-flow#troubleshooting).
