npm install @paykit-sdk/gopay
Setup
Environment variables
Direct config
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
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',
}),
);
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 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.
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
},
});