> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usepaykit.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# GoPay

> GoPay provider for PayKit.

```bash theme={null}
npm install @paykit-sdk/gopay
```

## Setup

<Tabs>
  <Tab title="Environment variables">
    ```typescript theme={null}
    import { PayKit } from '@paykit-sdk/core';
    import { gopay } from '@paykit-sdk/gopay';

    export const paykit = new PayKit(gopay());
    ```

    Required env vars:

    ```bash theme={null}
    GOPAY_CLIENT_ID=140...
    GOPAY_CLIENT_SECRET=n6W...
    GOPAY_GO_ID=864...
    GOPAY_SANDBOX=true
    GOPAY_WEBHOOK_URL=https://example.com/api/webhook
    ```
  </Tab>

  <Tab title="Direct config">
    ```typescript theme={null}
    import { PayKit } from '@paykit-sdk/core';
    import { createGopay } from '@paykit-sdk/gopay';

    export const paykit = new PayKit(
      createGopay({
        clientId: '140...',
        clientSecret: 'n6W...',
        goId: '864...',
        isSandbox: true,
        webhookUrl: 'https://example.com/api/webhook',
      }),
    );
    ```
  </Tab>
</Tabs>

## How it works

GoPay authenticates using OAuth 2.0 client credentials (`scope=payment-all`). `createCheckout` calls `POST /payments/payment` and returns a `gw_url` that the customer is redirected to. After the customer pays, GoPay calls your `webhookUrl` via GET with a `?id=<paymentId>` query parameter. The handler fetches the payment state from GoPay to verify it.

Subscriptions (recurring payments) are created as an initial payment with a `recurrence` object. Subsequent charges are triggered automatically by GoPay or on demand via GoPay's `createRecurrence` API.

<Warning>
  GoPay sends webhook notifications via GET requests. Your handler
  must accept GET, not POST.
</Warning>

<Warning>
  GoPay does not support customer management. `createCustomer`,
  `retrieveCustomer`, `updateCustomer`, and `deleteCustomer` all throw
  `ProviderNotSupportedError`.
</Warning>

## Webhooks

```typescript theme={null}
const webhook = paykit.webhooks
  .setup({ webhookSecret: '' }) // GoPay does not use a shared secret
  .on('payment.created', async event => {
    /* CREATED state */
  })
  .on('payment.updated', async event => {
    /* PAYMENT_METHOD_CHOSEN or AUTHORIZED state */
  })
  .on('payment.succeeded', async event => {
    /* PAID state */
  })
  .on('payment.failed', async event => {
    /* CANCELED or TIMEOUTED state */
  })
  .on('invoice.generated', async event => {
    /* emitted alongside payment.succeeded on PAID */
  })
  .on('subscription.created', async event => {
    /* emitted on PAID when the payment has a parent_id (recurring charge) */
  })
  .on('subscription.canceled', async event => {
    /* emitted when recurrence state is STOPPED */
  })
  .on('refund.created', async event => {
    /* REFUNDED or PARTIALLY_REFUNDED state */
  });

await webhook.handle({
  body: '',
  headersAsObject: Object.fromEntries(request.headers),
  fullUrl: request.url, // GoPay passes the payment ID as ?id= query param
});
```

GoPay payment states and their PayKit event mappings:

| GoPay state             | PayKit events emitted                                                             |
| ----------------------- | --------------------------------------------------------------------------------- |
| `CREATED`               | `payment.created`                                                                 |
| `PAYMENT_METHOD_CHOSEN` | `payment.updated`                                                                 |
| `PAID`                  | `payment.succeeded` + `invoice.generated` (+ `subscription.created` if recurring) |
| `AUTHORIZED`            | `payment.updated`                                                                 |
| `CANCELED`              | `payment.failed` (+ `subscription.canceled` if recurrence STOPPED)                |
| `TIMEOUTED`             | `payment.failed`                                                                  |
| `REFUNDED`              | `refund.created`                                                                  |
| `PARTIALLY_REFUNDED`    | `refund.created`                                                                  |

## Subscriptions

GoPay maps PayKit billing intervals to its `recurrence_cycle` field:

| PayKit `billing_interval` | GoPay `recurrence_cycle` |
| ------------------------- | ------------------------ |
| `day`                     | `DAY`                    |
| `week`                    | `WEEK`                   |
| `month`                   | `MONTH`                  |
| `year`                    | `ON_DEMAND`              |
| `custom`                  | `ON_DEMAND`              |

`year` and `custom` intervals fall back to `ON_DEMAND` — GoPay does not natively support them. You must trigger each charge manually via GoPay's `createRecurrence` API.

## provider\_metadata

GoPay requires `amount` and `currency` in `provider_metadata` for checkout, and `success_url` for direct payments and subscriptions:

```typescript theme={null}
// checkout.provider_metadata — amount is required, currency defaults to CZK, language defaults to EN
await paykit.checkouts.create({
  customer: { email: 'user@example.com' },
  item_id: 'my-product',
  session_type: 'one_time',
  quantity: 1,
  success_url: 'https://example.com/success',
  cancel_url: 'https://example.com/cancel',
  provider_metadata: {
    amount: '2900',
    currency: 'CZK',
    language: 'en', // optional, defaults to 'EN'
  },
});

// payment.provider_metadata — success_url is required
await paykit.payments.create({
  customer: { email: 'user@example.com' },
  item_id: 'my-product',
  amount: 2900,
  currency: 'CZK',
  provider_metadata: {
    success_url: 'https://example.com/success', // required
  },
});

// subscription.provider_metadata — success_url is required
await paykit.subscriptions.create({
  customer: { email: 'user@example.com' },
  item_id: 'my-plan',
  amount: 2900,
  currency: 'CZK',
  billing_interval: 'month',
  provider_metadata: {
    success_url: 'https://example.com/success', // required
    description: 'Monthly plan',               // optional
  },
});
```
