Integration
Integration checklist
Use the checklist below to make sure that you have correctly integrated with Paynow services.
- Create Sandbox account here
- Find your API credentials
- Integrate with API directly or using one of our SDKs or plugins to the most popular ecommerce platforms
- Configure notification address
- Make a payment - test positive and negative payment path
- Make a refund
API access
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:
- Follow the instructions available on Paynow website to activate the paynow service.
- 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 case | Credentials |
---|---|
Standard integration | Api-Key: 97a55694-5478-43b5-b406-fb49ebfdd2b5 Signature-Key: b305b996-bca5-4404-a0b7-2ccea3d2b64b |
White Label integration | Api-Key: a5346108-639d-4a34-b408-afe86d89071f Signature-Key: 7201572b-1234-4853-8437-dd038a28a31d |
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:
Code | Description |
---|---|
111111 | Payment finishes successfully |
222222 | Payment remains in status PENDING |
333333 | payment authorization fails because a wrong authorization code was provided |
333334 | payment authorization fails because an expired authorization code was provided |
333335 | payment authorization fails because an already used authorization code was provided |
333336 | payment authorization fails because some other problems occurred during the payment process |
444444 | payment remains in status NEW for 20 seconds, then transitions into ERROR and remains in that status |
Pay-By-Link
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=
.
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())
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:
Attempt | Incremental time since status change |
---|---|
1 | immediately |
2 | 1min |
3 | 1min |
4 | 1min |
5 | 2min |
6 | 5min |
7 | 15min |
8 | 30min |
9 | 1h |
10 | 2h |
11 | 4h |
12 | 8h |
13 | 16h |
14 | 24h |
15 | 48h |
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.
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.
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:
Variant | Description |
---|---|
immediately | Receive payout immediately after buyer finishes the transaction (available only for mBank retail clients) |
once a day | Funds are accumulated on your balance, payout is performed once a day. |
You can configure payout schedule in the Merchant Panel, Settings > Payouts schedule
tab.
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.