Skip to main content

Integration

Integration checklist

Use the checklist below to make sure that you have correctly integrated with Paynow services.

  1. Create Sandbox account here
  2. Find your API credentials
  3. Integrate with API directly or using one of our SDKs or plugins to the most popular ecommerce platforms
  4. Configure notification address
  5. Make a payment - test positive and negative payment path
  6. Make a refund

API access

Credentials

Api-Key and Signature-Key can be found in the Settings > Shops and poses > Authentication tab in your Merchant Panel.

Environments

Production

For production, please use the following URL address: https://api.paynow.pl

To access the Production environment:

  1. Follow the instructions available on Paynow website to activate the paynow service.
  2. Once the service is activated, you will get access to Merchant Panel under the Finance > Paynow tab.

Sandbox

The following examples refer to the Sandbox environment: https://api.sandbox.paynow.pl

To use the Sandbox you first need to register a new account and use the API key as provided in the Merchant Panel of the Sandbox environment or use a public test credentials without registering:

Use caseCredentials
Standard integrationApi-Key: 97a55694-5478-43b5-b406-fb49ebfdd2b5
Signature-Key: b305b996-bca5-4404-a0b7-2ccea3d2b64b
White Label integrationApi-Key: a5346108-639d-4a34-b408-afe86d89071f
Signature-Key: 7201572b-1234-4853-8437-dd038a28a31d
Important

Sandbox should NOT be used in your production system.

Special behaviors

There is almost no difference between Sandbox and Production environments.

In the Sandbox environment, some payment methods exhibit special behavior if particular request preconditions are met. This allows us to test specific cases or get acquainted with paywall behavior in case of specific scenarios:

BLIK

In the case of BLIK payments, providing specific BLIK codes results in different responses:

CodeDescription
111111Payment finishes successfully
222222Payment remains in status PENDING
333333payment authorization fails because a wrong authorization code was provided
333334payment authorization fails because an expired authorization code was provided
333335payment authorization fails because an already used authorization code was provided
333336payment authorization fails because some other problems occurred during the payment process
444444payment remains in status NEW for 20 seconds, then transitions into ERROR and remains in that status

In the case of pay-by-link payments, payment with the amount equal to 9999.99 PLN fails and an error message is shown in the Paywall. This scenario is handled for all pay-by-link payment methods except mTransfer.

Cards

To simulate card payment you can use the card details:

Successful payment

Card number: 4444 4444 4444 4000
Card name: any
Card date: any in future / any in future
CVC: 111

Signature header

To ensure the integrity of the exchanged messages and to confirm that their content has not been modified during transmission, an additional header: Signature must be appended in sent POST requests and verified in received messages. For the v3 API version in GET requests also.

Calculating Signature

The payload object for which we are calculating the Signature should be constructed from the following elements (note their order):

  • headers - Api-Key (available in the Merchant Panel) and Idempotency-Key (a unique value for the query). Headers should be used in alphabetical order. Do not use other headers when counting the signature,
  • parameters - list of used query params in alphabetical order. If there are no parameters, use an empty parameters map: parameters: ,
  • body - should be expressed as a string object: "body":"" and formatted as follows: tabbing should be expressed as \t, newlines as \n (UNIX) or \r\n (Microsoft Windows). Quotation marks should be escaped: e.g.: "response_type".

Example of payload for getting the payment methods:

{
"headers": {
"Api-Key": "97a55694-5478-43b5-b406-fb49ebfdd2b5",
"Idempotency-Key": "d243fdb3-c287-484a-bb9c-58536f2794c1"
},
"parameters": {},
"body": ""
}

The Signature should be calculated using the HMAC SHA256 algorithm using the constructed payload and Signature-Key. The binary result of the hash function should be encoded using Base64 and sent to Paynow in the Signature header.

For the above example payload and Signature-Key with the value b305b996-bca5-4404-a0b7-2ccea3d2b64b, the calculated and encoded signature should take the following value: fXwLZRwo0WiGll90PPl5oULX9VKA0gpFA/3+E+NRp5E=.

Tip

Please remember that marks of the new lines, tabs, and spaces must be exactly in the same places as in the payload request.

Example of Signature calculating using the PHP SDK:

$idempotencyKey = '';
$body = [];
$parameters = []
$signature = SignatureCalculator::generateV3(
'97a55694-5478-43b5-b406-fb49ebfdd2b5',
'b305b996-bca5-4404-a0b7-2ccea3d2b64b,
$idempotencyKey,
$body ? json_encode($body, JSON_UNESCAPED_SLASHES) : '',
$parameters
);

Notifications

During the payment process, Paynow delivers asynchronous notifications about the current payment status each time the status is changed. Notifications are sent to the given notification-url as an HTTP POST request.

To enable notification you must specify the notification-url in the Merchant Panel in Settings > Shops and poses tab, fulfilling the field Notification address for shop configuration.

Example of notification message:

For the below examples payload and Signature-Key with the value b305b996-bca5-4404-a0b7-2ccea3d2b64b, the calculated and encoded signature should take the following value: F69sbjUxBX4eFjfUal/Y9XGREbfaRjh/zdq9j4MWeHM=.

  curl -X POST \
<notification-url> \
-H 'Signature: F69sbjUxBX4eFjfUal/Y9XGREbfaRjh/zdq9j4MWeHM=' \
-H 'Content-Type: application/json' \
-d \
'{
"paymentId": "NOLV-8F9-08K-WGD",
"externalId": "9fea23c7-cd5c-4884-9842-6f8592be65df",
"status": "CONFIRMED",
"modifiedAt": "2018-12-12T13:24:52"
}'

Notifications signature

The Signature should be calculated using the HMAC SHA256 algorithm using the message body and Signature-Key. The binary result of the hash function should be encoded using Base64 and sent in the Signature header.

Examples of Notification Signature calculating:

PHP SDK

$signatureCalculator = new SignatureCalculator(
'b305b996-bca5-4404-a0b7-2ccea3d2b64b',
json_encode([
'paymentId' => 'NOLV-8F9-08K-WGD',
'externalId' => '12345',
'status' => 'CONFIRMED',
'modifiedAt' => '2018-12-12T13:24:52',
], JSON_UNESCAPED_SLASHES)
);

Java

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class HashCalculator {

private static final String HMAC_SHA256_ALGORITHM_NAME = "HmacSHA256";

public static void main(String[] args) throws Exception {
String dataToHash =
'{"paymentId":"NOLV-8F9-08K-WGD","externalId":"12345","status":"CONFIRMED","modifiedAt":"2018-12-12T13:24:52"}';
String key = "b305b996-bca5-4404-a0b7-2ccea3d2b64b";
String hmacHash = calculateHMAC(dataToHash.getBytes(), key.getBytes());
System.out.println(hmacHash);
}

private static String calculateHMAC(byte[] data, byte[] key)
throws NoSuchAlgorithmException, InvalidKeyException {
SecretKeySpec signingKey = new SecretKeySpec(key, HMAC_SHA256_ALGORITHM_NAME);
Mac mac = Mac.getInstance(HMAC_SHA256_ALGORITHM_NAME);
mac.init(signingKey);
byte[] hashedBytes = mac.doFinal(data);
return Base64.getEncoder().encodeToString(hashedBytes);
}
}

Python

import hmac
import hashlib
import base64

data_to_hash = '{"paymentId":"NOLV-8F9-08K-WGD","externalId":"12345","status":"CONFIRMED","modifiedAt":"2018-12-12T13:24:52"}'
key = 'b305b996-bca5-4404-a0b7-2ccea3d2b64b'


def calculate_hmac(data, key):
hashed_object = hmac.new(key, data, hashlib.sha256).digest()
return base64.b64encode(hashed_object)


hmac_hash = calculate_hmac(data_to_hash.encode(), key.encode())
print(hmac_hash.decode())
Verifying the Signature header in received messages

Each time Paynow sends a notification, your system must verify the integrity of an incoming message by validating it.
DO NOT PROCESS that message if the calculated signature doesn't correspond to the value present in the Signature header.

Notifications schedule

After sending a notification Paynow system requires an HTTP response with a 200 OK or 202 Accepted status (with the empty body). If Paynow doesn't receive the correct response, it will retry to deliver the notification according to the following schedule:

AttemptIncremental time since status change
1immediately
21min
31min
41min
52min
65min
715min
830min
91h
102h
114h
128h
1316h
1424h
1548h

If for some reason, the notification cannot be successfully delivered, the Merchant should synchronously poll for transaction status through payment status endpoint to check the final payment status.

Important

Remember that the same notification may be sent more than once and that notifications may arrive at your endpoint out of order. Your code needs to be prepared for such scenarios.

Check it

If your system filters incoming traffic, contact our support at support@paynow.pl to obtain a list of IP addresses you should add to your whitelist.

Payout schedule

You can choose one of two variants of withdrawal frequency to your bank account:

VariantDescription
immediatelyReceive payout immediately after buyer finishes the transaction (available only for mBank retail clients)
once a dayFunds are accumulated on your balance, payout is performed once a day.

You can configure payout schedule in the Merchant Panel, Settings > Payouts schedule tab.

Important

Please note that payouts are unavailable while using the Mass Collect mechanism once a day.

SDKs and Plugins

All available plugins and Software Development Kits(SDK) are available on the GitHub:

Postman collection

Please check our Postman collection with basic requests that could help you create the first requests with our API on the Sandbox environment.