#
Introduction
Last update: 10.01.2025
The API is organized around REST. It accepts and returns JSON-encoded bodies and responses, uses standard HTTP response codes & authentication. Our API forces HTTPS to ensure the security of sensitive data.
All transaction data should only contain ASCII characters.
#
Authentication
#
Base URLs
Sandbox (dev):
API_BASE_URL='https://api-dev.cdnsoftwaretech.com/api/v1/merchant'
Production:
API_BASE_URL='https://api.cdnsoftwaretech.com/api/v1/merchant'
#
Public key (base64-encoded)
Sandbox (dev):
GET https://api-dev.cdnsoftwaretech.com/api/v1/p/key
Production:
GET https://api.cdnsoftwaretech.com/api/v1/p/key
#
Merchant registration
- After onboarding, our team provides a unique Merchant ID.
- Merchant generates a 2048-bit public-private keypair and provides the public key to CDN in PEM format.
- Merchant may delete the public key and provide a new one in case it is needed.
#
Making a request
All requests are private and should contain the following headers:
x-merchant-id- Merchant ID that our team provides (you can also see it in the dashboard)x-signature- Signature of the request generated using SHA256 with RSA (check the details on signature generation algorithm below)
#
Signature generation
#
x-signature
The entire HTTP request body is used to generate the signature. To generate the digital signature using Secure Hash Algorithm (SHA256RSA):
- Prepare the payload by concatenating method, full request URL with query string parameters and request body (if present). You can find the examples below.
- Obtain the hash of the string generated above using SHA256 algorithm. Data must be encoded using UTF8 while computing hash.
- Use the RSA signature algorithm to generate the digital signature using the hash produced above.
- The output generated is the signature.
- Pass this signature in the
x-signatureheader for all API requests, unlessx-short-signatureis used.
Note: in most programming languages steps 2 and 3 are combined into a single SHA256RSA function. Splitting them may help you debug the issues if you encounter them.
See code examples below
#
x-short-signature
Only the UUID of the transaction is used to generate the signature. To generate the digital signature using Secure Hash Algorithm (SHA256RSA):
Sample string - 3a5f04af-fb52-41ce-b9bc-283e72207cd5
- Obtain the hash of the string generated above using SHA256 algorithm. Data must be encoded using UTF8 while computing hash.
- Use the RSA signature algorithm to generate the digital signature using the hash produced above.
- The output generated is the signature.
- Pass this signature in the
x-short-signatureheader for all API requests that require this header.
Example code Python for x-signature
import base64
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15
client_public_key = "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmjioBgaues2Cv2jlnNnp
I8HXktevZzJJaaiPWIh6m8psyay4IuDscJM8DOYAat5pxwQBtqsP8iO0/wAtSfL7
eUD1ryIS47YRqi+pRFICfVT8Lno1hCJFTaP2CMPAYxmM5/5X43ChiR5e7ho8E+J9
iPmevDJEUBOQV17GGLrD7jzxbo62Pqv4lFt9PIuPV7LyagjrU+6ep0X3Ul82je7N
tvKhtMC6Y8GgbkjxTytvO6FaNJAx35PHRaZ55asA81xwWSqoH4hsM0PK2PGICqfR
mj4zu5mbGnTss7/2xnHkxGKXUTfzt8yi9wzI2fna0+SZVIxjO+HhVAig9EkUJSvh
KQIDAQAB
-----END PUBLIC KEY-----"
client_privat_key = "-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAmjioBgaues2Cv2jlnNnpI8HXktevZzJJaaiPWIh6m8psyay4
IuDscJM8DOYAat5pxwQBtqsP8iO0/wAtSfL7eUD1ryIS47YRqi+pRFICfVT8Lno1
hCJFTaP2CMPAYxmM5/5X43ChiR5e7ho8E+J9iPmevDJEUBOQV17GGLrD7jzxbo62
Pqv4lFt9PIuPV7LyagjrU+6ep0X3Ul82je7NtvKhtMC6Y8GgbkjxTytvO6FaNJAx
35PHRaZ55asA81xwWSqoH4hsM0PK2PGICqfRmj4zu5mbGnTss7/2xnHkxGKXUTfz
t8yi9wzI2fna0+SZVIxjO+HhVAig9EkUJSvhKQIDAQABAoIBABBUx5Y7xuZCNQJH
/WiqusGKmWV3aZ+n95Y0v1lEupcczIBexfELmH4jWUyUXp7yhokIp5XMb5fYqCYI
wsL99BtXAa1WEmICucQn3+jYNmNHSJ0zW89uQaCDKF6tPAZCgmVezbfMCY8XpD3a
kVoZtel3ZZPQTuOb7sERzDB6Np1XtJxvtF93td6GgW/Q3obfwU3VmSVjydVRG1Ui
CiACzsPZUobeqBrWHaYd0TyM3UfSpvUYfEivCiSuhiTxXntijXgvJxUu2cUrL410
U10II4eamV3ZwZm2DM2szoEvrr/WQP7tUGYnSv9I78HZEhQRz7LHWQJz18v0BnuV
xhfoaTECgYEA1Fn3igEPBxonmYjE175q8OcDnlkyFnY/KzmqM0+tqMxkbvVb8aZz
OhT6Taqjyu0pikrDeNswxr4LG7oP1+OMLTJv4m8+0+sOtvMd6lVmRRp6PffFQwlp
gF2CibF74TO5D7u/NUV4Xli2xE2Os6cTFIOmE0z3vGqmSARp7BBoojcCgYEAueva
3l1VVP3NyTSAsR2yh98h9o1d+xev3bhOWE3cQ83Hp79/YYvxRw9BrbyAyXbAc7Qc
pOg6w5oGrimO71d8IIYGMpGGkmEbrCVs5AodrGEk3WcNd13uaRnVGe/+Ia7fgJr+
TUuI5q5r4/wVbc9GiOz4LHRqk+CJp0z3cMLtZ58CgYEAzsCd3Hc1a4PSpJFennRe
6Rj0E/viYa5VyL9HcNgWTDBdZQ9tqvWWYSnFn1MSUOTiuiwa8BPyBL9KT3+0J038
0JC4EO6hbHIDjKtfKCZoAcZK2QThwmhqmTnyfCAbbmQOvjvdan+uN6YGpVCiLVbx
o9qeG1KoLoJkTeBGRTqgtbcCgYEAhrfgYEBBFNTTyHfCyJQ8STfl5EGLV+ZSCNcD
7fh9IqR5h5O7OXOt4U+sx7dPmqvxx+U63ENqUVHKhWiXqdY6m1aCJyJL4MV8x8BW
puatmbrKe6Ownk3x8zZEtAaynrWYPhgRLPEOwhihFRIUdP08nvsW2R+CGqUZGaEr
qwmT/QECgYBtSALhzndWGY0HA1Qim1PyrI9vW1hocPSRUZXCYy8ComSFKKbM9Ho+
si51JB+5db78c3ECiogfAYQ7PZWCwBPkVSK+nlLbMZg4+qZ2EdD3lsbj0BOwusfU
IsZgSztrFag/naKCJtqeHxhrDi4gqxAmQnBcObH+ouPbJ2k3DFjVbw==
-----END RSA PRIVATE KEY-----"
raw_text = 'POSThttps://api-dev.cdnsoftwaretech.com/api/v1/merchant/transactions/{"external_id":"24","amount":150.23,"currency":"eur","redirect_url_success":"https://example.com/successful_transaction","redirect_url_fail":"https://example.com/failed_transaction","expires_at":"2021-12-22T05:17:56.323","payer_details":{"external_id":"32556","first_name":"Edvard","last_name":"Munch","email":"ed.munch@gmail.com","address1":"Toyengata 53","city":"Oslo","state":"","country":"NO","zip":"0578","phone":"+4723493500","date_of_birth":"2019-08-24T14:15:22Z"}}'
def generate_signature(payload: str, rsa_key=None):
key = RSA.importKey(rsa_key or client_privat_key)
h = SHA256.new(payload.encode())
signature = pkcs1_15.new(key).sign(h)
return base64.b64encode(signature).decode("utf-8")
def verify_signature(payload: str, signature: str, rsa_key=None):
key = RSA.importKey(rsa_key or client_public_key)
h = SHA256.new(payload.encode())
try:
pkcs1_15.new(key).verify(h, base64.b64decode(signature))
return True
except (ValueError, TypeError):
return False
signature = generate_signature(raw_text)
print(f"{signature=}")
print("Is valid: ", verify_signature(raw_text, signature, client_public_key)) # True
Example code PHP for x-signature
<?php
// Replace with your actual private/public keys
$publicKey = <<<EOD
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmjioBgaues2Cv2jlnNnp
I8HXktevZzJJaaiPWIh6m8psyay4IuDscJM8DOYAat5pxwQBtqsP8iO0/wAtSfL7
eUD1ryIS47YRqi+pRFICfVT8Lno1hCJFTaP2CMPAYxmM5/5X43ChiR5e7ho8E+J9
iPmevDJEUBOQV17GGLrD7jzxbo62Pqv4lFt9PIuPV7LyagjrU+6ep0X3Ul82je7N
tvKhtMC6Y8GgbkjxTytvO6FaNJAx35PHRaZ55asA81xwWSqoH4hsM0PK2PGICqfR
mj4zu5mbGnTss7/2xnHkxGKXUTfzt8yi9wzI2fna0+SZVIxjO+HhVAig9EkUJSvh
KQIDAQAB
-----END PUBLIC KEY-----
EOD;
$privateKey = <<<EOD
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAmjioBgaues2Cv2jlnNnpI8HXktevZzJJaaiPWIh6m8psyay4
IuDscJM8DOYAat5pxwQBtqsP8iO0/wAtSfL7eUD1ryIS47YRqi+pRFICfVT8Lno1
hCJFTaP2CMPAYxmM5/5X43ChiR5e7ho8E+J9iPmevDJEUBOQV17GGLrD7jzxbo62
Pqv4lFt9PIuPV7LyagjrU+6ep0X3Ul82je7NtvKhtMC6Y8GgbkjxTytvO6FaNJAx
35PHRaZ55asA81xwWSqoH4hsM0PK2PGICqfRmj4zu5mbGnTss7/2xnHkxGKXUTfz
t8yi9wzI2fna0+SZVIxjO+HhVAig9EkUJSvhKQIDAQABAoIBABBUx5Y7xuZCNQJH
/WiqusGKmWV3aZ+n95Y0v1lEupcczIBexfELmH4jWUyUXp7yhokIp5XMb5fYqCYI
wsL99BtXAa1WEmICucQn3+jYNmNHSJ0zW89uQaCDKF6tPAZCgmVezbfMCY8XpD3a
kVoZtel3ZZPQTuOb7sERzDB6Np1XtJxvtF93td6GgW/Q3obfwU3VmSVjydVRG1Ui
CiACzsPZUobeqBrWHaYd0TyM3UfSpvUYfEivCiSuhiTxXntijXgvJxUu2cUrL410
U10II4eamV3ZwZm2DM2szoEvrr/WQP7tUGYnSv9I78HZEhQRz7LHWQJz18v0BnuV
xhfoaTECgYEA1Fn3igEPBxonmYjE175q8OcDnlkyFnY/KzmqM0+tqMxkbvVb8aZz
OhT6Taqjyu0pikrDeNswxr4LG7oP1+OMLTJv4m8+0+sOtvMd6lVmRRp6PffFQwlp
gF2CibF74TO5D7u/NUV4Xli2xE2Os6cTFIOmE0z3vGqmSARp7BBoojcCgYEAueva
3l1VVP3NyTSAsR2yh98h9o1d+xev3bhOWE3cQ83Hp79/YYvxRw9BrbyAyXbAc7Qc
pOg6w5oGrimO71d8IIYGMpGGkmEbrCVs5AodrGEk3WcNd13uaRnVGe/+Ia7fgJr+
TUuI5q5r4/wVbc9GiOz4LHRqk+CJp0z3cMLtZ58CgYEAzsCd3Hc1a4PSpJFennRe
6Rj0E/viYa5VyL9HcNgWTDBdZQ9tqvWWYSnFn1MSUOTiuiwa8BPyBL9KT3+0J038
0JC4EO6hbHIDjKtfKCZoAcZK2QThwmhqmTnyfCAbbmQOvjvdan+uN6YGpVCiLVbx
o9qeG1KoLoJkTeBGRTqgtbcCgYEAhrfgYEBBFNTTyHfCyJQ8STfl5EGLV+ZSCNcD
7fh9IqR5h5O7OXOt4U+sx7dPmqvxx+U63ENqUVHKhWiXqdY6m1aCJyJL4MV8x8BW
puatmbrKe6Ownk3x8zZEtAaynrWYPhgRLPEOwhihFRIUdP08nvsW2R+CGqUZGaEr
qwmT/QECgYBtSALhzndWGY0HA1Qim1PyrI9vW1hocPSRUZXCYy8ComSFKKbM9Ho+
si51JB+5db78c3ECiogfAYQ7PZWCwBPkVSK+nlLbMZg4+qZ2EdD3lsbj0BOwusfU
IsZgSztrFag/naKCJtqeHxhrDi4gqxAmQnBcObH+ouPbJ2k3DFjVbw==
-----END RSA PRIVATE KEY-----
EOD;
// Replace with your actual payload
$rawText = 'POSThttps://api-dev.cdnsoftwaretech.com/api/v1/merchant/transactions/{"external_id":"24","amount":150.23,"currency":"eur","redirect_url_success":"https://example.com/successful_transaction","redirect_url_fail":"https://example.com/failed_transaction","expires_at":"2021-12-22T05:17:56.323","payer_details":{"external_id":"32556","first_name":"Edvard","last_name":"Munch","email":"ed.munch@gmail.com","address1":"Toyengata 53","city":"Oslo","state":"","country":"NO","zip":"0578","phone":"+4723493500","date_of_birth":"2019-08-24T14:15:22Z"}}';
function gen_signature($rawText, $privateKey) {
// Sign the data using the private key
if (openssl_sign($rawText, $signature, $privateKey, OPENSSL_ALGO_SHA256)) {
return base64_encode($signature);
} else {
echo "Signature generation failed!";
return "";
}
};
function verify_signature($rawText, $signatureBase64, $publicKey) {
$signature = base64_decode($signatureBase64);
// Verify the signature using the public key
$verificationResult = openssl_verify($rawText, $signature, $publicKey, OPENSSL_ALGO_SHA256);
if ($verificationResult === 1) {
return "Signature is valid.";
} elseif ($verificationResult === 0) {
return "Signature is invalid.";
} else {
return "Error occurred during signature verification.";
}
};
$signatureBase64 = gen_signature($rawText, $privateKey);
echo $signatureBase64 . "\n";
echo str_repeat("_", 25);
echo verify_signature($rawText, $signatureBase64, $publicKey);
?>
#
Response Header
#
The x-signature response header is a signature generated from the response payload using the private key and is included in every API response. Merchant should use the public key to validate and verify the response message integrity. Although this step is optional, it is highly recommended for security reasons.
#
Core API requests
#
Payments
#
Create a transaction
POST {API_BASE_URL}/transactions/
Body:
Example:
Response:
If you don't plan to send card details via API, then you need to redirect the user or open a new browser window to/with the link {body.payment_url}. If you sent sending_card_details=true, then you need to proceed with sending card data to the endpoint from the response: {body.card_details_url}.
#
Payment methods
This list shows all the methods currently supported. However, some methods might not be available for your integration, please check with your account manager to confirm which methods are accessible for your setup.
If payment method is not specified in create transaction API request, then card is used by default.
#
Send card details
This request uses x-short-signature instead of x-signature.
POST {card_details_url}
Body:
Note:
Inside your integration (code) while sending card details on card_details_url use header:
accept-encoding: "gzip"
While using Postman - remove accept-encoding header completely
Example:
Response:
Then you need to redirect the user or open a new browser window to/with the link {body.payment_url}.
#
Check transaction
GET {API_BASE_URL}/transactions/:id
GET {API_BASE_URL}/transactions/?external_id={external_id}
Examples:
Response:
#
Payment statuses
#
#
Supported currencies
The list of supported currencies depends on your merchant configuration. Please check with the account manager or the integration support team.
#
Payouts
#
Create a payout transaction
POST {API_BASE_URL}/payouts/
Body:
Example:
Response:
If you don't plan to send card details via API, then you need to redirect the user or open a new browser window to/with the link {body.payout_url}. If you sent sending_card_details=true, then you need to proceed with sending card data to the endpoint from the response: {body.card_details_url}.
#
Send card details
This request uses x-short-signature instead of x-signature. It is calculated as a concatenation of multiple parameters. The concatenated string should consist of:
transaction_id + card bin (first 6 digits) + last4 digits
Then, as usual, this string is hashed with SHA256, signed with the private key, and encoded in base64
POST {card_details_url}
Body:
Note:
Inside your integration (code) while sending card details on card_details_url use header:
accept-encoding: "gzip"
While using Postman - remove accept-encoding header completely
Example:
Response:
Then you need to redirect the user or open a new browser window to/with the link {body.payout_url}.
#
Check transaction
This request uses x-signature header, where only the uuid or external_id (based on the query you use) of the transaction is used to generate the signature. Sign with your merchant's RSA private key using SHA-256 hashing, base64-encode the signature, and include it in the header.
GET {API_BASE_URL}/payouts?uuid={uuid}
GET {API_BASE_URL}/payouts?external_id={external_id}
Examples:
Response:
#
Payout statuses
#
#
Supported currencies
The list of supported currencies depends on your merchant configuration. Please check with the account manager or the integration support team.
#
iFrame
For merchant-server and user-server integrations iFrame is available.
You can open payment url like this:
<iframe src=“https://pay.domain.com/p/:uuid” />
#
Webhooks (server-2-server notifications)
#
Getting webhooks
Our service should be able to post webhooks to merchants' servers. If a merchant wants to add a webhook, he should set it up via the admin tool (at the moment, this can be done via the tech support team).
Webhooks are sent asynchronously and may arrive out of order. The merchant’s server should acknowledge the receipt of the webhook by sending an HTTP 200 OK response. If the server hasn't acknowledged the receipt of the webhook, we will start a backoff mechanism (immediately -> 10 minutes -> 15 minutes -> 30 minutes -> 1 hour -> 2 hours -> 6 hours -> 6 hours- > 6 hours -> 6 hours -> send an email notification about the server connection issue to the merchant's email address).
#
Webhook types
Webhook data may differ from the example above, please check with your account manager to clarify which additional fields can/will be sent (e.g. masked card number).
#
Verifying webhook/response sender (optional)
In order to make sure that a webhook is sent by CDN, you are strongly advised to check our digital signature. The x-signature header is included in every webhook & response. It is a signature generated from the webhook body using the standard signature generation algorithm with CDN’s private key.
Example body:
⬇️⬇️⬇️ (in the example we use the same private key as in Signature generation examples)
evRePZNKZxUK5ThSld2hcV5LXgwBzuErzaiOJadJP09DEG04C4Kg9XRN/yGiRmCFqTSrt/3b1NUO9yKdVc6bJTSKVp82iKwVTGoBEkT0lj/b/h2QKHc5dBhuwMmaopPbgs3KU7SWa0oqLpq6cRDzwb+G3pA2rrUyi9rnZS3pLtNMeBstte4Fbg1Fed09Xp6ZlFkFi9bVxkTrvy3z300nvabI9VNq86rEZpUPuQmIMYlCCTkDViGxpJPg+sIiEHpWf0RzeUaOZfR13oII88Zn2iRtRMg6OM615JRTzqnc4uZgf6BWJr56j2NJvHJZTUxU+vePWy1OaABJFyY0Ye2PuQ==
#
Errors
#
HTTP response codes:
#
200 OK
Everything works as expected.
#
400 Bad request
Invalid data was sent or some parameters are missing.
#
401 Unauthorized
No valid Bearer key provided.
#
403 Forbidden
The API key doesn't have a permission for this action.
#
404 Not found
The requested resource doesn't exist.
#
422 Unprocessable Entity
The request payload could not pass the validation (probably incorrect).
#
429 Too many requests
Too many requests hit the API too quickly.
#
5XX Server errors
Something went wrong on our side.
#
Internal error codes:
Payment Gateway Errors:
- GENERIC_DECLINE : 201001 : Generic Decline
- INSUFFICIENT_FUNDS : 201002 : Insufficient funds
- DO_NOT_HONOUR : 201003 : Do not honour
- NO_3DS_SUPPORT : 201004 : Card or Issuer Doesn't Support 3DS
- EXCEEDS_ACQUIRER_LIMIT : 201005 : Exceeds payment gateway limits
- SUSPECTED_FRAUD : 201006 : Suspected fraud
- AUTH_3DS_FAILED : 201007 : 3D authentication failed
- INVALID_CARD_NUMBER : 201008 : Invalid card number
- INVALID_CVV : 201009 : Invalid CVV
- INVALID_CARDHOLDER_NAME : 201010 : Invalid name on card
- CARD_IS_EXPIRED : 201011 : Expired card
- GATEWAY_TIMEOUT : 201012 : Timeout
- INVALID_AMOUNT : 201013 : Payment gateway declined transaction amount
- USER_IS_BLOCKED : 201014 : User is blocked
- INVALID_ADDRESS : 201015 : Invalid billing address
- INVALID_CURRENCY : 201016 : Invalid currency
- CANCELLED_BY_USER : 201017 : Cancelled by user on payment gateway page
- INVALID_CARD_NETWORK : 201018 : Invalid card network
- INVALID_CARD : 201019 : Invalid card
- ERROR_FROM_ISSUING_BANK : 201021 : Error from issuing bank
- RESTRICTED_CARD : 201023 : Card is restricted or blocked
- CARD_BLACKLISTED_BY_ACQUIRER : 201104 : Card is blacklisted on acquirer side
- CANNOT_AUTHORIZE : 201027 : Cannot authorize
- UNKNOWN_ERROR : 201028 : Unknown error
- EXCEEDS_CARD_LIMIT : 201030 : Exceeds card limits
- BLACKLISTED_BY_ACQUIRER : 201101 : User/Domain or card is blacklisted on acquirer side
- NOT_PERMITTED : 201104 : Transaction not permitted to cardholder
- VALIDATION_FAILED : 201105 : Validation failed
- BLACKLISTED_CARD : 201107 : Card is prohibited due to internal policy. Do not retry with this card.
- INVALID_CARD_EXP_DATE : 201106 : Invalid card expiration date
- USER_EMAIL_VALIDATION_FAILED: 201108 : User's email address validation has failed
- BLACKLISTED_IP_ADDRESS: 201109 : IP address is blacklisted.
Transaction Errors:
- NO_ACQUIRER_TO_CHOOSE : 100300 : No acquirers to choose
- CANCELED_BY_USER : 100302 : Transaction canceled by user
- EXPIRED : 100303 : Transaction expired
- CARD_IS_SUSPENDED : 100306 : Card is suspended
- CARD_COUNTRY_IS_RESTRICTED : 100307 : Card country is restricted
Generic Errors:
- TRANSACTION_DOES_NOT_EXIST : 100500 : Transaction does not exist
- INVALID_PAYMENT_METHOD : 100501 : Invalid payment method
- INVALID_CARD_DETAILS_LINK : 100502 : Invalid card details link
Transaction Creation Errors:
- UNFILLED_MERCHANT_DATA : 100100 : Merchant data unfilled
- MERCHANT_DOESNT_HAVE_KEYS : 100101 : Merchant does not have keys
- MERCHANT_WRONG_SIGNATURE : 100102 : Wrong Merchant's signature
- USER_COUNTRY_NOT_SUPPORTED : 100103 : User’s country is not supported
- INVALID_CURRENCY_SPECIFIED : 100104 : Invalid currency specified
- CURRENCY_NOT_SUPPORTED : 100106 : currency is not configured for your account. Please contact your account manager.
- EXTERNAL_TX_ID_DUPLICATE : 100107 : Transaction with specified external_id already exists
- USER_IS_BANNED : 100108 : This user is banned and cannot perform transactions on our service.
- NO_ACQUIRER_TO_CHOOSE : 100300 : No acquirer to choose
- WRONG_TRANSACTION_AMOUNT : 100110 : Transaction amount must be between {min_amount} and {max_amount}
- USER_IS_SUSPENDED : 100111 : User is suspended
- USER_NAME_VALIDATION_FAILED : 100112 : User's name validation has failed
Card Details Errors:
- CARD_NETWORK_NOT_SUPPORTED : 100204 : Your credit card network is not supported
- FAILED_TO_ADD_CARD : 100201 : Failed to add card. Try again or contact support
- MERCHANT_WRONG_SIGNATURE : 100102 : Wrong Merchant's signature
- TRANSACTION_ALREADY_HAS_CARD : 100202 : Card details were already provided
- CARD_COUNTRY_NOT_SUPPORTED : 100203 : Your credit card country is not supported
- BLACKLISTED_CARD : 201107 : Card is prohibited due to internal policy. Do not retry with this card.
Internal Errors:
- INTERNAL_ERROR : 300000 : Internal error
- PAYMENT_CREATION_ERROR : 300001 : Error during payment creation
- UNEXPECTED_RESPONSE_STATUS : 300004 : Unexpected response status:
#
Test credentials (dev)
#
Credit cards
Card number: 4000 0278 9138 0961
Date: any valid date in the future
CVV: 123
Card number: 4761 3441 3614 1390
Date: any valid date in the future
CVV: 123
Card number: 5101 0810 4600 6034
Date: any valid date in the future
CVV: 123
Card number: 4242 4242 4242 4242
Date: any valid date in the future
CVV: 123
If 3DS asks you for the confirmation code, use 4444.
Please check with our technical support team if the above cards do not work for you, sometimes we change the testing cards.
#
Signature generation examples
#
Payload preparation
You should use a minified JSON (no whitespaces!) for signature generation. The payload used for signature generation must be 100% the same as the payload sent in the request.
POST
https://api-dev.cdnsoftwaretech.com/api/v1/merchant/transactions/
⬇️⬇️⬇️
POSThttps://api-dev.cdnsoftwaretech.com/api/v1/merchant/transactions/{"external_id":"24","amount":150.23,"currency":"eur","redirect_url_success":"https://example.com/successful_transaction","redirect_url_fail":"https://example.com/failed_transaction","expires_at":"2021-12-22T05:17:56.323","payer_details":{"external_id":"32556","first_name":"Edvard","last_name":"Munch","email":"ed.munch@gmail.com","address1":"Toyengata 53","city":"Oslo","state":"","country":"NO","zip":"0578","phone":"+4723493500","date_of_birth":"2019-08-24T14:15:22Z"}}
GET https://api-dev.cdnsoftwaretech.com/api/v1/merchant/transactions/?external_id=24
⬇️⬇️⬇️
GEThttps://api-dev.cdnsoftwaretech.com/api/v1/merchant/transactions/?external_id=24
GET https://api-dev.cdnsoftwaretech.com/api/v1/merchant/transactions/3a5f04af-fb52-41ce-b9bc-283e72207cd5
⬇️⬇️⬇️
GEThttps://api-dev.cdnsoftwaretech.com/api/v1/merchant/transactions/3a5f04af-fb52-41ce-b9bc-283e72207cd5
#
Generating SHA-256 with RSA signature
Example public-private keypair
RSA signing (SHA256withRSA)
POSThttps://api-dev.cdnsoftwaretech.com/api/v1/merchant/transactions/{"external_id":"24","amount":150.23,"currency":"eur","redirect_url_success":"https://example.com/successful_transaction","redirect_url_fail":"https://example.com/failed_transaction","expires_at":"2021-12-22T05:17:56.323","payer_details":{"external_id":"32556","first_name":"Edvard","last_name":"Munch","email":"ed.munch@gmail.com","address1":"Toyengata 53","city":"Oslo","state":"","country":"NO","zip":"0578","phone":"+4723493500","date_of_birth":"2019-08-24T14:15:22Z"}}
⬇️⬇️⬇️
PPoh2Cpxj7xG0jKnFicX0Tv7D9P9Zo7vn7HK0e2+Xwbvao6MLWR39eLgqvxYjPY4LaAkggBuOPZFcJkdjBP2FPufbEbB0pKgie19Vcg/OANWlgk0d+snTwtdg0touY+VAmoj3gVfeHTSZpdntrF12jqKTx0Kq6HRaquzJ7hiJlulb0GoKwW+hVY5VOA+ulIg4XQvBn/runpKvQP2UkvSJw3aBD1GZBgzVXM8LW/u79QqopyZMFtI/mqAd583F0IYPB4nXZigpcf1Tq/ekmxsjBquMl54J8LekpuNXsaopcFuzlKplwjS7CH55VRrgNxPKeMMeWGPg5AOxLdE7uDN0w==
GEThttps://api-dev.cdnsoftwaretech.com/api/v1/merchant/transactions/?external_id=24
⬇️⬇️⬇️
Wn8e3M2C3VFILseo9qrplxVET4Wg7GXS+l3NCeiL3tk1ss67EKPIbWPZVrcnlR6L3s14MEiibeZJKfMxnJpwWNIAvx9SINOjwtCj07W3TowDUOpgzS09hJd3p57U2nhTjArm9MyoCCNruUwxr0qNE/v7poFIdOcR1AcqQVGLtBIUSIkDkyB7XeeynwCFNIX4CN6nP+WEhwKcZOGh4PmYrdL47FNcSVpEi0aWxOaP8sC28dbf+xUTQ6xFxEjDRXOlbyUsnMyFPbo8loAjgrRHqM+3hoQh1b38Uk06rzyBjwpKuXA6476VUkWkej+eCBWskxdRXk2WOTcw/YpqgTgCKQ==
GEThttps://api-dev.cdnsoftwaretech.com/api/v1/merchant/transactions/3a5f04af-fb52-41ce-b9bc-283e72207cd5
⬇️⬇️⬇️
fAzPzziFlwUM3iTO3gw32BzLSLupXaIeXOwVSuohnUY6OpAvZicftGKBYpPXDKzbTn/7sgils0LalukhnAHR0tEG6JHeiHjDh2G+hZeAElxJAnz7tBZ+rlyDlk1YBNvGq1YXHfZSbTCmVWEgHl8fSOdxSTvs2E40iXNvEEFlelUTkH80nX7WbKeTcBvObVW8+jnLBCMi4pp/ddDhnyRmgSGRh0NJzg+62z8NfF0zLOKu8QmRmkjFtmonhE6LAbJ9IYZiSSTSd3NDvL0jCvj+mFyu4d9GyJFwZGH5lZCYjjzvrFzLWV4+KtOpUf2Yo2j03/op6ESacG8QfU+H1CUn2Q==
#
Common questions and issues
#
Incorrect signature
Make sure you're signing the exact payload you're sending. Try minifying the JSON you're sending by removing all whitespaces (JSON formatting). Check if you've concatenated the method, full URL (of the correct environment) and request body, without using any extra characters (e.g. trailing slashes).
#
Incorrect amount (lower or higher than the limits)
If you're using a currency which is not EUR, the rate your system uses may differ from the rate in our system which can result in slight differences between the EUR equivalents. Feel free to contact our integration team to clarify this. In case you use non-EUR currencies, it is recommended to have higher minimum and lower maximum limits than your limits on CDN side to avoid such issues.
#
RSA keypair generation example
You can use the following commands:
openssl genrsa -out my-private-key.pem 2048
openssl rsa -in my-private-key.pem -pubout -out my-public-key.pem
Then you need to share the generated public key (my-public-key.pem) with our team.