Skip to main content
npm install @paykit-sdk/gopay

Setup

import { PayKit } from '@paykit-sdk/core';
import { gopay } from '@paykit-sdk/gopay';

export const paykit = new PayKit(gopay());
Required env vars:
GOPAY_CLIENT_ID=140...
GOPAY_CLIENT_SECRET=n6W...
GOPAY_GO_ID=864...
GOPAY_SANDBOX=true
GOPAY_WEBHOOK_URL=https://example.com/api/webhook

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.
GoPay sends webhook notifications via GET requests. Your handler must accept GET, not POST.
GoPay does not support customer management. createCustomer, retrieveCustomer, updateCustomer, and deleteCustomer all throw ProviderNotSupportedError.

Webhooks

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 statePayKit events emitted
CREATEDpayment.created
PAYMENT_METHOD_CHOSENpayment.updated
PAIDpayment.succeeded + invoice.generated (+ subscription.created if recurring)
AUTHORIZEDpayment.updated
CANCELEDpayment.failed (+ subscription.canceled if recurrence STOPPED)
TIMEOUTEDpayment.failed
REFUNDEDrefund.created
PARTIALLY_REFUNDEDrefund.created

Subscriptions

GoPay maps PayKit billing intervals to its recurrence_cycle field:
PayKit billing_intervalGoPay recurrence_cycle
dayDAY
weekWEEK
monthMONTH
yearON_DEMAND
customON_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:
// 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
  },
});