Przelewy24

Accept Przelewy24 — Poland's largest payment gateway — with VINR.

View as MarkdownInstall skills

Przelewy24 (P24) is one of Poland's most popular online payment methods, aggregating over 150 Polish banks and payment channels into a single redirect flow. Customers select their bank or payment channel at the P24 hosted page and authenticate with their existing online banking credentials. Przelewy24 is the only Polish local method on VINR that supports both PLN and EUR.

AvailabilityAsk

DetailValue
CountriesPoland
CurrenciesPLN, EUR
FlowBank redirect (aggregator)
FinalityFinal on confirmation (see note on pending)
RefundsSupported via standard refund API

Payment flowAsk

Create the payment

Create a payment with methods: ['przelewy24'] and a PLN or EUR amount. You receive a checkoutUrl pointing to the Przelewy24 hosted bank picker.

Customer selects their bank and authenticates

The customer chooses from over 150 banks and payment channels on the P24 page. They are redirected to their bank's login and approve the payment.

P24 confirms and redirects back

On approval, Przelewy24 confirms to VINR and redirects the customer to your returnUrl. The payment moves to completed for most channels.

Fulfill on the webhook

For some bank-transfer-backed channels, the payment may briefly stay pending while the underlying transfer clears (typically seconds to minutes). Always drive fulfillment from payment.completed, not the return redirect or pending status.

Creating a Przelewy24 paymentAsk

import { Vinr } from '@vinr/sdk';

const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });

const payment = await vinr.payments.create({
  amount: 24900,             // 249.00 PLN in minor units (groszy)
  currency: 'PLN',
  description: 'Order #5502',
  methods: ['przelewy24'],
  returnUrl: 'https://yoursite.com/payment/complete',
  metadata: { orderId: '5502' },
});

// Redirect the customer to payment.checkoutUrl

For EUR amounts, pass currency: 'EUR'. Fulfill from the webhook:

// POST /webhooks/vinr
const event = vinr.webhooks.verify(rawBody, req.headers['x-vinr-signature']);

if (event.type === 'payment.completed') {
  const payment = event.data;
  // payment.method → "przelewy24"
  await fulfillOrder(payment.metadata.orderId);
}

Pending paymentsAsk

Some Przelewy24 bank channels rely on an underlying bank transfer that can take up to a few minutes to clear. While clearing, the payment stays pending. Your returnUrl will be called with the payment in pending state — hold fulfillment until payment.completed arrives via webhook.

Surface a "payment is processing" message on your returnUrl page and send a fulfillment confirmation once the webhook fires.

Set a payment.expired handler as well. If the customer abandons the redirect without completing their bank login, the payment expires after your configured timeout and you should prompt them to try again.

Settlement & timingAsk

Most Przelewy24 channels clear within seconds; a small subset may take up to a few minutes. Once completed, the amount lands in your balance and follows your normal settlement schedule.

RefundsAsk

Refunds are returned to the customer's originating bank account, typically within one to three business days.

const refund = await vinr.refunds.create({
  payment: 'pay_...',
  amount: 24900,  // full refund; omit amount for full
  reason: 'requested_by_customer',
});

Because Przelewy24 payments are final once completed, there are no chargebacks. A refund is the only way to return funds after completion.

TestingAsk

In the VINR sandbox, Przelewy24 redirects open a VINR test page where you choose Approve or Fail. No real Polish bank account is required.

LimitationsAsk

  • PLN and EUR only. Przelewy24 does not support other currencies.
  • Poland only. The method only appears for customers with a Przelewy24-supported Polish bank account; presenting it outside Poland returns method_not_available.
  • No manual capture. Przelewy24 captures in full at confirmation.
  • Some channels may stay pending. Always fulfill on payment.completed, not payment.pending.

See alsoAsk

Was this page helpful?
Edit on GitHub

Last updated on

On this page