Skip to main content
Adyen is a global payment technology company founded in 2006 in Amsterdam, Netherlands. The company provides a single platform for accepting payments across online, mobile, and in-store channels for major enterprises worldwide including Uber, Spotify, and Microsoft. BLIK is a mobile payment system widely used in Poland, operated by Polski Standard Płatności (PSP). It allows users to make instant payments, withdraw cash from ATMs, and pay in stores using a 6-digit code generated in their banking app. BLIK is available to customers of most Polish banks and has become one of the fastest-growing payment methods in Poland.

Setup

Please follow the common Adyen instructions to get set up with BLIK. Next, make sure to enable BLIK as a payment method on your configured account.

Supported countries

Supported currencies

Integration

For BLIK, the default integration for Adyen is through a redirect to a hosted payments page.

Redirect integration

Start by creating a new transaction with the following required fields.
var transaction = await client.Transactions.CreateAsync(
  transactionCreate: new TransactionCreate()
  {
    Amount = 1299,
    Currency = "PLN",
    Country = "PL",
    Intent = "capture",
    PaymentMethod =
      TransactionCreatePaymentMethod.CreateRedirectPaymentMethodCreate(
        new RedirectPaymentMethodCreate()
        {
          Method = "blik",
          Country = "PL",
          Currency = "PLN",
          RedirectUrl = "https://example.com/callback",
        }
      ),
  }
);
amount := int64(1299)
currency := "PLN"
country := "PL"
method := components.RedirectPaymentMethodCreateMethodBlik
redirectUrl := "https://example.com/callback"

redirectPaymentMethodCreate := components.RedirectPaymentMethodCreate{
  Method: method,
  Country: country,
  Currency: currency,
  RedirectURL: redirectUrl,
}
paymentMethod := components.CreateTransactionCreatePaymentMethodRedirectPaymentMethodCreate(redirectPaymentMethodCreate)

transactionCreate := components.TransactionCreate{
  Amount:        amount,
  Currency:      currency,
  Country:       &country,
  Intent:       gr4vy.Pointer(components.TransactionIntentCapture),
  PaymentMethod: &paymentMethod,
}

transaction, err := client.Transactions.Create(ctx, transactionCreate, nil, nil, nil)
CreateTransactionResponse transactionResponse = gr4vyClient.transactions().create()
  .transactionCreate(TransactionCreate.builder()
    .amount(1299L)
    .currency("PLN")
    .country("PL")
    .intent(TransactionIntent.CAPTURE)
    .paymentMethod(TransactionCreatePaymentMethod.of(RedirectPaymentMethodCreate.builder()
      .method(RedirectPaymentMethodCreateMethod.BLIK)
      .country("PL")
      .currency("PLN")
      .redirectUrl("https://example.com/callback")
      .build()))
    .build())
  .call();

Transaction transaction = transactionResponse.transaction().orElse(null);
$transactionCreate = new TransactionCreate(
  amount: 1299,
  currency: 'PLN',
  country: 'PL',
  intent: 'capture',
  paymentMethod: new RedirectPaymentMethodCreate(
    method: 'blik',
    country: 'PL',
    currency: 'PLN',
    redirectUrl: 'https://example.com/callback'
  )
);
$response = self::$sdk->transactions->create($transactionCreate);
$transaction = $response->transaction;
transaction: models.Transaction = client.transactions.create(
  amount=1299,
  currency="PLN",
  country="PL",
  intent="capture",
  payment_method={
    "method": "blik",
    "country": "PL",
    "currency": "PLN",
    "redirect_url": "https://example.com/callback",
  }
)
const transaction = await gr4vy.transactions.create({
  amount: 1299,
  currency: "PLN",
  country: "PL",
  intent: "capture",
  paymentMethod: {
    method: "blik",
    country: "PL",
    currency: "PLN",
    redirectUrl: "https://example.com/callback"
  }
})
After the transaction is created, the API response includes payment_method.approval_url and the buyer_approval_pending status.
{
  "type": "transaction",
  "id": "ea1efdd0-20f9-44d9-9b0b-0a3d71e9b625",
  "payment_method": {
    "type": "payment-method",
    "approval_url": "https://cdn.sandbox.spider.gr4vy.app/connectors/adyen/apm.html?token=..."
  },
  "method": "blik"
}
Redirect the buyer to the approval_url so they can complete authentication and approve the payment. After approval the buyer is redirected to the redirect_url you provided when creating the transaction. Do not rely solely on the redirect - either poll the transaction or (recommended) rely on webhooks to detect the final status (for example capture_succeeded or failure states).

Direct integration

Adyen provides web, Android and iOS SDKs for a direct integration. For these flows you should indicate the platform by setting an appropriate integration_client when creating the transaction, and then build a client-side integration that uses the POST /transactions/:transaction_id/session API to initialize the Adyen SDK. To start, create a new transaction with the appropriate integration_client.
var transaction = await client.Transactions.CreateAsync(
  transactionCreate: new TransactionCreate()
  {
    Amount = 1299,
    Currency = "PLN",
    Country = "PL",
    Intent = "capture",
    IntegrationClient = "ios",
    PaymentMethod =
      TransactionCreatePaymentMethod.CreateRedirectPaymentMethodCreate(
        new RedirectPaymentMethodCreate()
        {
          Method = "blik",
          Country = "PL",
          Currency = "PLN",
          RedirectUrl = "https://example.com/callback",
        }
      ),
  }
);
amount := int64(1299)
currency := "PLN"
country := "PL"
integrationClient := "ios"
method := components.RedirectPaymentMethodCreateMethodBlik
redirectUrl := "https://example.com/callback"

redirectPaymentMethodCreate := components.RedirectPaymentMethodCreate{
  Method: method,
  Country: country,
  Currency: currency,
  RedirectURL: redirectUrl,
}
paymentMethod := components.CreateTransactionCreatePaymentMethodRedirectPaymentMethodCreate(redirectPaymentMethodCreate)

transactionCreate := components.TransactionCreate{
  Amount:            amount,
  Currency:          currency,
  Country:           &country,
  Intent:           gr4vy.Pointer(components.TransactionIntentCapture),
  IntegrationClient: &integrationClient,
  PaymentMethod:     &paymentMethod,
}

transaction, err := client.Transactions.Create(ctx, transactionCreate, nil, nil, nil)
CreateTransactionResponse transactionResponse = gr4vyClient.transactions().create()
  .transactionCreate(TransactionCreate.builder()
    .amount(1299L)
    .currency("PLN")
    .country("PL")
    .intent(TransactionIntent.CAPTURE)
    .integrationClient("ios")
    .paymentMethod(TransactionCreatePaymentMethod.of(RedirectPaymentMethodCreate.builder()
      .method(RedirectPaymentMethodCreateMethod.BLIK)
      .country("PL")
      .currency("PLN")
      .redirectUrl("https://example.com/callback")
      .build()))
    .build())
  .call();

Transaction transaction = transactionResponse.transaction().orElse(null);
$transactionCreate = new TransactionCreate(
  amount: 1299,
  currency: 'PLN',
  country: 'PL',
  intent: 'capture',
  integrationClient: 'ios',
  paymentMethod: new RedirectPaymentMethodCreate(
    method: 'blik',
    country: 'PL',
    currency: 'PLN',
    redirectUrl: 'myapp://callback'
  )
);
$response = self::$sdk->transactions->create($transactionCreate);
$transaction = $response->transaction;
transaction: models.Transaction = client.transactions.create(
  amount=1299,
  currency="PLN",
  country="PL",
  intent="capture",
  integration_client="ios",
  payment_method={
    "method": "blik",
    "country": "PL",
    "currency": "PLN",
    "redirect_url": "https://example.com/callback",
  }
)
const transaction = await gr4vy.transactions.create({
  amount: 1299,
  currency: "PLN",
  country: "PL",
  intent: "capture",
  integrationClient: "ios",
  paymentMethod: {
    method: "blik",
    country: "PL",
    currency: "PLN",
    redirectUrl: "https://example.com/callback"
  }
})
For mobile, set integration_client to ios or android and use your app deep link for redirect_url (for example, yourapp://). After the transaction is created, the API response includes a session_token which can be used to get the session data for that transaction.
POST /transactions/:transaction_id/session?token=:session_token
{
  "session_data": {
    "sessionId": "CS04C0B8AC9849A7D8E25B20D",
    "sessionData": "Ab02b4c0!BQABAgBLgbLpvkt1r3",
    "environment": "live",
    "clientKey": "client-key",
    "returnUrl": "https://example.com/callback",
    "paymentMethod": "blik",
    "storePaymentMethod": true
  },
  "default_completion_url": "https://api.sandbox.spider.gr4vy.app/transactions/approve/some-token",
  "integration_client": "web"
}
{
  "session_data": {
    "sessionId": "CS04C0B8AC9849A7D8E25B20D",
    "sessionData": "Ab02b4c0!BQABAgBLgbLpvkt1r3",
    "environment": "live",
    "clientKey": "client-key",
    "returnUrl": "yourapp://",
    "paymentMethod": "blik",
    "storePaymentMethod": true
  },
  "default_completion_url": "https://api.sandbox.spider.gr4vy.app/transactions/approve/some-token",
  "integration_client": "ios"
}
{
  "session_data": {
    "sessionId": "CS04C0B8AC9849A7D8E25B20D",
    "sessionData": "Ab02b4c0!BQABAgBLgbLpvkt1r3",
    "environment": "live",
    "clientKey": "client-key",
    "returnUrl": "yourapp://",
    "paymentMethod": "blik",
    "storePaymentMethod": true
  },
  "default_completion_url": "https://api.sandbox.spider.gr4vy.app/transactions/approve/some-token",
  "integration_client": "android"
}
This session data provides the sessionId and sessionData required to load the Adyen SDK.
const adyenEnvironment = sessionData.environment;
const clientKey = sessionData.clientKey;
const sessionId = sessionData.sessionId;
const adyenSessionData = sessionData.sessionData;
const returnUrl = sessionData.returnUrl;
const paymentMethod = sessionData.paymentMethod;
const storePaymentMethod = sessionData.storePaymentMethod;
const configuration = {
    environment: adyenEnvironment,
    clientKey,
    analytics: {
      enabled: false,
    },
    session: {
      id: sessionId,
      sessionData: adyenSessionData,
    },
}
AdyenCheckout(configuration).then(function (checkout) {
  let component = checkout
    .create(paymentMethod)
    .mount('#component');
  });
var adyenEnvironment = sessionData.environment;
var clientKey = sessionData.clientKey;
var sessionId = sessionData.sessionId;
var adyenSessionData = sessionData.sessionData;
var returnUrl = sessionData.returnUrl;
var paymentMethod = sessionData.paymentMethod;
var storePaymentMethod = sessionData.storePaymentMethod;

override func viewDidLoad() {
  super.viewDidLoad()

  let configuration = AdyenSession.Configuration(sessionIdentifier: sessionId,
    initialSessionData: adyenSessionData)

  AdyenSession.initialize(with: configuration, delegate: self, presentationDelegate: self) { [weak self] result in
    switch result {
      case let .success(session):
          //Store the session object.
          self?.session = session
      case let .failure(error):
          //Handle the error.
    }
  }
}   
val adyenEnvironment = sessionData.environment;
val clientKey = sessionData.clientKey;
val sessionId = sessionData.sessionId;
val adyenSessionData = sessionData.sessionData;
val returnUrl = sessionData.returnUrl;
val paymentMethod = sessionData.paymentMethod;
val storePaymentMethod = sessionData.storePaymentMethod;

// Create the session object
val checkoutSession = CheckoutSession(
    session = Session(id = sessionId, sessionData = adyenSessionData),
    environment = Environment.TEST,
    clientKey = clientKey
)

when (result) {
    is CheckoutSessionResult.Success -> handleCheckoutSession(result.checkoutSession)
    is CheckoutSessionResult.Error -> handleError(result.exception)
}

Complete the transaction

Recommended On mobile integrations, after the buyer completes the payment flow, the Adyen SDK provides the developer with an onFinished call, which includes a statusCode. The system automatically syncs the status through webhooks, but to complete the transaction it is also recommended sending a GET request to the default_completion_url provided in the session response with the sessionId and the sessionResult as query parameters to finalize the transaction. This also moves the transaction to a completed status without waiting for the webhook to be sent. The call returns a 204 No Content response. After receiving this response, you can also optionally fetch the transaction to confirm final status.
func didComplete(with result: AdyenSessionResult,
            component: Component,
            session: AdyenSession)
{
    var urlComponents = URLComponents(string: defaultCompletionUrl)!
    urlComponents.queryItems = [
        URLQueryItem(name: "sessionId", value: session.session.id),
        URLQueryItem(name: "sessionResult", value: result.sessionResult)
    ]
    
    var request = URLRequest(url: urlComponents.url!)
    request.httpMethod = "GET"
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        // Handle 204 response, you can now poll the transaction
    }
    task.resume()
}
override fun onFinished(result: SessionPaymentResult) {
    val sessionResult = result.sessionResult
    val uri = Uri.parse(defaultCompletionUrl)
        .buildUpon()
        .appendQueryParameter("sessionId", result.sessionId)
        .appendQueryParameter("sessionResult", sessionResult)
        .build()
    val url = URL(uri.toString())
    val urlConnection = url.openConnection() as HttpURLConnection
    urlConnection.requestMethod = "GET"
    val responseCode = urlConnection.responseCode
    if (responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
        // Handle 204 response, you can now poll the transaction
    }
}
Please refer to the Adyen documentation for the web, Android and iOS for further guidance.

Testing

In a test environment, you can simulate a BLIK payment. Adyen has extensive instructions on how to help with this.