NAV Navbar
PHP Java cURL NodeJS

Introduction

PHP library covers all the functionality provided by Cardinity API. 

Library source code and releases can be obtained from GitHub: 
https://github.com/cardinity/cardinity-sdk-php

Installing via Composer:
$ php composer.phar require cardinity/cardinity-sdk-php

Bundle for Symfony2 project is also available:
https://github.com/cardinity/client-bundle

A complete example of integrating and using cardinity-sdk-php library is available:
https://github.com/cardinity/cardinity-example-php

Java library covers all the functionality provided by Cardinity API. 

Library source code and releases can be obtained from GitHub: 
https://github.com/cardinity/cardinity-sdk-java
NodeJS library covers all the functionality provided by Cardinity API. 

Install via npm:
$ npm i cardinity-nodejs

Cardinity API is organized around REST. OAuth 1.0 is used as the API Authentication framework. Request and response payloads are formatted as JSON. Error details are also provided as JSON. API uses resource-oriented URLs and HTTP response codes to indicate API errors and successful actions.

Authentication

Authentication Example

<?php

/** 
* You don't have to bother about authentication. 
* It is handled auto-magically behind the scenes.
* You just have to initialize the client object. 
*/
use Cardinity\Client;
$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

?>
/** 
* You don't have to bother about authentication. 
* It is handled auto-magically behind the scenes.
* You just have to initialize the client object. 
*/
CardinityClient client = new CardinityClient(consumerKey, consumerSecret);
# With cURL, you need to pass the correct header with each request

curl https://api.cardinity.com/v1/<endpoint> \
  -H "Content-Type: application/json" \
  -H 'Authorization: OAuth oauth_consumer_key="<your_consumer_key>", \
      oauth_signature_method="HMAC-SHA1", \
      oauth_timestamp="<timestamp>", \
      oauth_nonce="<unique_random_string>", \
      oauth_version="1.0", \
      oauth_signature="<computed_oauth_signature>"'
/**
* You don't have to bother about authentication.
* It is handled auto-magically behind the scenes.
* You just have to initialize the client object.
*/

const Cardinity = require('cardinity-nodejs')
const Client = Cardinity.client()
const client = new Client('YOUR_CONSUMER_KEY','YOUR_CONSUMER_SECRET');

Cardinity uses OAuth 1.0 to authorize all API requests. 0-legged (sometimes called 1-legged) OAuth scheme is used. Picture below describes basics of an authorization flow using 0-legged OAuth.

To learn more about OAuth you can visit: OAuth Bible, The OAuth 1.0 Protocol.

alt 0-legged

Cardinity expects for the OAuth details to be included in all API requests to the server in a header that looks like the following:

Authorization: OAuth {OAUTH_DETAILS}

OAuth Parameters

Name Description
oauth_consumer_key Identifier string provided by Cardinity for use in OAuth 1.0 handshake. Equivalent to a username.
oauth_signature_method Always HMAC-SHA1.
oauth_timestamp Timestamp when the request was generated. Timestamp is valid for 5 minutes.
oauth_nonce Uniquely generated random string. Recommended length 32 characters.
Note: same value can not be used more than once.
oauth_version Always 1.0.
oauth_signature String made up of Request Method, URL and Parameters joined in a single string which is then encrypted against your Consumer Secret.
Note: request body is not included in a signature string.
oauth_token Can be omitted. Otherwise left blank.

Testing

You'll receive special Consumer Key and Consumer Secret for the testing environment. Endpoint URLs are the same as used in production. All the payments made in testing environment never hit real bank networks, so card is never charged.

Testing Cards

Basically you can use any valid VISA or MasterCard card number, however for your convenience we provide sample ones you can use:

Number Brand Test
4111111111111111 Visa *
4200000000000000 Visa 3D-Secure enrolled, authorization failed
4222222222222 Visa *
5555555555554444 MasterCard *
5454545454545454 MasterCard 3D-Secure enrolled, authorization passed
4200000000000018 Visa Returns merchant_advice_code parameter for declined transactions

holder, exp_month, exp_year, cvc values can be set to any data you want. If those values pass validation and payment amount is less than 150.00 payment will be approved.

Test Cases

There is a variety of test cases which you can use to validate your integration with Cardinity payment processing gateway.

Successful Payment

Failed Payment

3D Secure Payment

Failed refund / void / settlement

Payments

To process a payment you have to create a new payment object. You can retrieve individual payments as well as a list of all payments. Payments are identified by a UUID.

Payment Object

Example: Approved Payment JSON

{
    "id": "90095d47-11bb-468b-8764-fd4fbb49a9f9",
    "amount": "15.00",
    "currency": "EUR",
    "created": "2014-12-19T11:52:53Z",
    "type": "authorization",
    "live": false,
    "status": "approved",
    "order_id": "123456",
    "description": "some description",
    "country": "LT",
    "payment_method": "card",
    "payment_instrument": {
        "card_brand": "Visa",
        "pan": "0026",
        "exp_year": 2021,
        "exp_month": 12,
        "holder": "Mike Dough"
    }
}

Example: Pending Payment JSON

{
    "id": "8e037fbb-fe5b-4781-b109-b3e93d5f2c0d",
    "amount": "20.00",
    "currency": "EUR",
    "created": "2014-12-17T09:43:31Z",
    "type": "authorization",
    "live": false,
    "status": "pending",
    "order_id": "1234567",
    "description": "some description",
    "country": "LT",
    "payment_method": "card",
    "payment_instrument": {
        "card_brand": "Visa",
        "pan": "4447",
        "exp_year": 2017,
        "exp_month": 5,
        "holder": "John Smith"
    },
    "threeds2_data": {
        "acs_url": "https://authorization.url/auth",
        "creq": "eJxdUl1vwj......."
    }
}

Example Declined Payment JSON

{
    "id": "3c4e8dcf-4e3e-4df0-9acb-622868c6c67b",
    "amount": "150.00",
    "currency": "EUR",
    "created": "2015-01-07T12:23:11.569Z",
    "type": "authorization",
    "live": false,
    "status": "declined",
    "error": "3000: Rejected by issuer",
    "merchant_advice_code": "03: Do not try again",
    "country": "LT",
    "order_id": "12345678",
    "description": "some description",
    "payment_method": "card",
    "payment_instrument": {
        "card_brand": "Visa",
        "pan": "0067",
        "exp_year": 2021,
        "exp_month": 11,
        "holder": "Mike Dough"
    }
}

Attributes

Name Type Description
id UUID ID of the payment.
Value assigned by Cardinity.
amount decimal Amount charged shown in #0.00 format.
currency string Three-letter ISO currency code representing the currency in which the charge was made.
created datetime Payment creation time as defined in RFC 3339 Section 5.6. UTC timezone.
Value assigned by Cardinity.
type string Payment type. Can be one of the following: authorization, purchase.
Value assigned by Cardinity.
live boolean Indicates whether a payment was made in live or testing mode.
Value assigned by Cardinity.
settle boolean Optional. Default: true.
Used to indicate a transaction type while creating a payment: true - purchase, false - authorization.
status string Payment status. Can be one of the following: pending, approved, declined.
Value assigned by Cardinity.
error string Error message. Returned only if status is declined. Provides human readable information why the payment failed.
Value assigned by Cardinity.
merchant_advice_code string Merchant advice code for a transaction. Provides information about transaction or the reason why transaction was declined.
Value assigned by Cardinity.
order_id string Optional. Order ID provided by a merchant. Must be between 2 and 50 characters [A-Za-z0-9'.-].
description string Payment description provided by a merchant. Maximum length 255 characters.
country string Country of a customer provided by a merchant. ISO 3166-1 alpha-2 country code.
payment_method string Can be one the following: card, recurring.
payment_instrument object Payment instrument representing earlier described payment_method. Can be one of the following: card or recurring. See object descriptions below.
threeds2_data object Used in 3D Secure V2 flow to provide and return authorization information. See object description for sending data below. In case additional payment authorization is needed (i.e. payment status is pending) object is used as described here.
cres string Used in 3D Secure V2 flow to provide challenge response value (PATCH verb) once customer completes authorization process.

Payment Instrument - card

Name Type Description
brand string Card brand.
Value assigned by Cardinity.
pan string Card number. When creating a payment provide full card number. However while retrieving an existing payments only last 4 digits are returned.
exp_year integer Expiration year. 4 digits, e.g. 2021.
exp_month integer Expiration month, e.g. 9.
cvc string Card security code. Only used when creating a payment.
holder string Card holder's name. Max length 32 characters.

Payment Instrument - recurring

Name Type Description
payment_id UUID ID of the approved payment in the past. Same card data will be used to create a new payment.

Create new payment

Example Request

<?php

use Cardinity\Client;
use Cardinity\Method\Payment;
use Cardinity\Exception;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$method = new Payment\Create([
    'amount' => 50.00,
    'currency' => 'EUR',
    'settle' => false,
    'description' => 'some description',
    'order_id' => '12345678',
    'country' => 'LT',
    'payment_method' => Payment\Create::CARD,
    'payment_instrument' => [
        'pan' => '4111111111111111',
        'exp_year' => 2021,
        'exp_month' => 12,
        'cvc' => '456',
        'holder' => 'Mike Dough'
    ],
    'threeds2_data' =>  [
        "notification_url" => "your_url_for_handling_callback", 
        "browser_info" => [
            "accept_header" => "text/html",
            "browser_language" => "en-US",
            "screen_width" => 600,
            "screen_height" => 400,
            'challenge_window_size' => "600x400",
            "user_agent" => "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:21.0) Gecko/20100101 Firefox/21.0",
            "color_depth" => 24,
            "time_zone" => -60
        ],
    ],
]);

/**
* In case payment could not be processed exception will be thrown.
* In this example only Declined and ValidationFailed exceptions are handled. However there is more of them.
* See Error Codes section for detailed list.
*/
try {
    /** @type Cardinity\Method\Payment\Payment */
    $payment = $client->call($method);
    $status = $payment->getStatus();

    if ($status == 'approved') {
      // Payment is approved
    } elseif ($status == 'pending') {
      // get data required to finalize payment
      $creq = $payment->getThreeds2Data()->getCreq();
      $paymentId = $payment->getId();
      // finalize process should be done here.
    }
} catch (Exception\Declined $exception) {
    /** @type Cardinity\Method\Payment\Payment */
    $payment = $exception->getResult();
    $status = $payment->getStatus(); // value will be 'declined'
    $errors = $exception->getErrors(); // list of errors occurred
} catch (Exception\ValidationFailed $exception) {
    /** @type Cardinity\Method\Payment\Payment */
    $payment = $exception->getResult();
    $status = $payment->getStatus(); // value will be 'declined'
    $errors = $exception->getErrors(); // list of errors occurred
}

?>
CardinityClient client = new CardinityClient(consumerKey, consumerSecret);

Payment payment = new Payment();
payment.setAmount(new BigDecimal(10));
payment.setCurrency("EUR");
payment.setCountry("LT");
payment.setPaymentMethod(Payment.Method.CARD);
Card card = new Card();
card.setPan("4111111111111111");
card.setCvc(123);
card.setExpYear(2021);
card.setExpMonth(1);
card.setHolder("John Doe");
payment.setPaymentInstrument(card);

// Set threeds2Data to enable 3D Secure V2 flow
Threeds2Data threeds2Data = new Threeds2Data();
// Populate threeds2Data object with available data
payment.setThreeds2Data(threeds2Data);

Result<Payment> result = client.createPayment(payment);

/** Request was valid and payment was approved. */
if (result.isValid() && result.getItem().getStatus() == Payment.Status.APPROVED) {
    UUID paymentId = result.getItem().getId();
    // proceed with successful payment flow
}

/** Request was valid but payment requires additional authentication. */
else if (result.isValid() && result.getItem().getStatus() == Payment.Status.PENDING) {
    UUID paymentId = result.getItem().getId();
    String acsURL = result.getItem().getThreeds2AuthorizationInformation().getAcsUrl();
    String challengeRequest = result.getItem().getThreeds2AuthorizationInformation().getCReq();
    // redirect customer to ACS server for 3D Secure authentication
}

/** Request was valid but payment was declined. */
else if (result.isValid()) {
    String declineReason = result.getItem().getError();
    // proceed with declined payment flow
}

/** Request was invalid. Possible reasons: wrong credentials, unsupported currency, suspended account, etc. */
else {
    CardinityError error = result.getCardinityError();
    // log error details for debugging
    // proceed with error handling flow
}
curl https://api.cardinity.com/v1/payments \
-H "Content-Type: application/json" \
-H "Authorization: OAuth <OAuth Details>" \
-d '{
    "amount": "50.00",
    "currency": "EUR",
    "settle": false,
    "description": "some description",
    "order_id": "12345678",
    "country": "LT",
    "payment_method": "card",
    "payment_instrument": {
        "pan": "4111111111111111",
        "exp_year": 2021,
        "exp_month": 11,
        "cvc": "999",
        "holder": "Mike Dough"
    },
    "threeds2_data": {
        "notification_url": "https://www.myonlineshop.com/callback/3dsv2",
        "browser_info": {
            "accept_header": "text/html",
            "browser_language": "en-US",
            "screen_width": 1920,
            "screen_height": 1040,
            "challenge_window_size": "full-screen",
            "user_agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:21.0) Gecko/20100101 Firefox/21.0",
            "color_depth": 24,
            "time_zone": -60
        }
    }
}'

# Response JSON
{
    "id": "90095d47-11bb-468b-8764-fd4fbb49a9f9",
    "amount": "50.00",
    "currency": "EUR",
    "created": "2014-12-19T11:52:53Z",
    "type": "authorization",
    "live": false,
    "status": "approved",
    "order_id": "12345678",
    "description": "some description",
    "country": "LT",
    "payment_method": "card",
    "payment_instrument": {
        "card_brand": "Visa",
        "pan": "1111",
        "exp_year": 2021,
        "exp_month": 11,
        "holder": "Mike Dough"
    }
}
const Cardinity = require('cardinity-nodejs')
const Client = Cardinity.client()
const Payment = Cardinity.payment()

const purchase = new Payment({
    'amount': '50.00',
    'currency': 'EUR',
    'settle': true,
    'description': 'Payment from NodeJS',
    'order_id': 'NodeJS1',
    'country': 'LT',
    'payment_method': 'card',
    'payment_instrument': {
        'pan': '5555555555554444',
        'exp_year': 2022,
        'exp_month': 2,
        'cvc': '222',
        'holder': 'John Doe',
    },
    'threeds2_data': {
        'notification_url': 'https://www.myonlineshop.com/callback/3dsv2',
        'browser_info': {
            'accept_header': 'text/html',
            'browser_language': 'en-US',
            'screen_width': 1920,
            'screen_height': 1040,
            'challenge_window_size': '500x600',
            'user_agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:21.0) Gecko/20100101 Firefox/21.0',
            'color_depth': 24,
            'time_zone': -60,
            'ip_address': '192.168.0.1',
            'javascript_enabled': true,
            'java_enabled': false
        }
    }
});
// check if there is any data validation errors.
if (purchase.errors) {
    // show errors or print errors to logs here.
} else {
    const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
    client.call(purchase).then(function(response){
        if (response.status == 'approved') {
            // handle approved payment
        } else if (response.status == 'pending') {
            res.setHeader('Content-Type', 'text/html');
            form = '<html><head>'+
                '<title>3-D Secure Example</title>'+
                '<script type="text/javascript">'+
                +'function OnLoadEvent(){'+
                    // Make the form post as soon as it has been loaded.
                    +'document.ThreeDForm.submit();'+
                +'}'+
                '</script>'+
                '</head>'+
                '<body onload="OnLoadEvent();">'+
                '<form name="ThreeDForm" method="POST" action="'+ response.threeds2_data.acs_url +'">'+
                    '<button type=submit>Click Here</button>'+
                    '<input name="creq" value="'+ response.threeds2_data.creq +'" />' +
                    '<input type="hidden" name="threeDSSessionData" value="'+ 
                        response.id +'" />'+
                '</form>'+
                '</body></html>';
            res.end(form);
        } else {
            res.setHeader('Content-Type', 'text/plain')
            res.end(JSON.stringify(response, null, 2))
        }
    }).catch(function(error){
        // Deal with error
    });
}

To process a payment you have to create a new payment object. If your API Consumer Key key is in a test mode the supplied card won't be charged, though everything else will occur as if in a live mode.

HTTP Request

POST https://api.cardinity.com/v1/payments

Request Attributes

Name Type Required Description
amount decimal Yes Amount to charge. Only positive values are allowed. Format: #0.00, two decimal places precision is required.
currency string Yes Three-letter ISO currency code representing the currency of the amount.
settle boolean No Default: true.
Indicates payment type: true - purchase, false - authorization. Purchase encapsulates authorization and settlement steps in one action.
order_id string No Order ID provided by a merchant. Must be between 2 and 50 characters [A-Za-z0-9'.-].
description string No Payment description provided by a merchant. Maximum length 255 characters.
country string Yes Country of a customer obtained via geolocation services or entered manually. ISO 3166-1 alpha-2 country code.
payment_method string Yes Can only be: card.
payment_instrument object Yes Payment instrument representing earlier described payment_method. For now only card is supported. See object description below.
threeds2_data object No Data required for 3DS V2 Authentication. Check the table below for required and optional parameters for the 3DS V2 flow.
statement_descriptor_suffix string No Optional text that will be displayed in the bank statement.

Payment Instrument - card

Name Type Required Description
pan string Yes Card number.
exp_year integer Yes Expiration year. 4 digits.
exp_month integer Yes Expiration month.
cvc string Yes Card security code.
holder string Yes Card holder's name. Max length 32 characters.

3DS V2 Data

This information is used for 3D-Secure authorization. Only notification_url and browser_info fields are required. Other fields will be used by card issuing bank to determine whether the transaction qualifies for frictionless flow. Cardinity recommends filling as much of the available parameters as possible, to ensure maximum possibility of frictionless transaction flow. Bear in mind that the transaction eligibility for frictionless flow is determined by the card issuing bank.

Name Type Required Description
notification_url string Yes Fully qualified URL to a location where 3D Secure challenge response will be sent. URL data must be encoded. Make sure to use a public address - for local development, we suggest using ngrok. Max length 256 characters.
browser_info object Yes Client browser settings, that will be used during 3DS V2 Authentication.
billing_address object No Billing address of the cardholder.
delivery_address object No Delivery address of the purchased product.
cardholder_info object No Additional information about the cardholder.

3DS V2 Browser Info Data

Example browser_info object

"threeds2_data": {
    ...,
    "browser_info": {
      "accept_header": "text/html",
      "browser_language": "en-US",
      "screen_width": 1920,
      "screen_height": 1040,
      "challenge_window_size": "500x600",
      "user_agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:21.0) Gecko/20100101 Firefox/21.0",
      "color_depth": 24,
      "time_zone": -60,
      "ip_address": "216.58.207.35",
      "javascript_enabled": true,
      "java_enabled": true
    },
    ...
}

This information is required for displaying the 3D-Secure challenge for the cardholder.

Name Type Required Description
accept_header string Yes HTTP accept header sent from the cardholder's browser.
browser_language string Yes The cardholder's browser language as defined in IETF BCP 47. Returned from navigator.language property. Must not exceed 8 characters.
screen_width integer Yes The screen width of the cardholder's browser. Value is obtained from the screen.width property.
screen_height integer Yes The screen height of the cardholder's browser. Value is obtained from the screen.height property.
challenge_window_size string Yes Dimensions of the challenge window to be displayed to the cardholder. Supported values: 250x400, 390x400, 500x600, 600x400, full-screen.
user_agent string Yes The User-Agent provided by the cardholder's browser.
color_depth integer Yes The screen color depth of the cardholder's browser. Obtained using the screen.colorDepth property. Accepted values: 1, 4, 8, 15, 16, 24, 32, 48.
time_zone integer Yes The time difference between UTC time cardholder's browser time in minutes. Value is obtained from the getTimezoneOffset() method.
Note that the offet is positive if the local time zone is behind UTC and negative if it is ahead (For example, for UTC -5 timezone allowed values are 300 and +300, and for UTC +5 timezone allowed value is -300).
ip_address string No IP address of the cardholder's browser.
javascript_enabled boolean No Indicates whether JavaScript is enabled in the cardholder's browser. Default true
java_enabled boolean No Indicates whether Java is enabled in the cardholder's browser. Default false

(Optional) 3DS V2 Address Data

Example address_info objects, used both for billing and delivery address

"threeds2_data": {
  ...,
  "billing_address": {
    "address_line1": "8239 Louie Street",
    "city": "Coltenburgh",
    "country": "US",
    "postal_code": "84603",
    "state": "DC"
  },
  "delivery_address": {
    "address_line1": "Schallerallee 33",
    "city": "Ravensburg",
    "country": "DE",
    "postal_code": "82940"
  },
  ...
}

Address data is used in determining risk level for the transaction. This information is used by the card issuer and might result in a higher amount of frictionless transactions.

Name Type Required Description
address_line1 string Yes First line of the address. Maximum length is 50 characters.
address_line2 string No Second line of the address. Maximum length is 50 characters.
address_line3 string No Third line of the address. Maximum length is 50 characters.
city string Yes City of the address. Maximum length is 50 characters.
country string Yes Country of the address. Must be a ISO 3166-1 alpha-2 country code.
postal_code string Yes Postal code of the address. Maximum length is 16 characters.
state string No State of the address. Maximum length is 3 characters. Must be a country subdivision code defined in ISO 3166-2.

(Optional) 3DS V2 Cardholder Info

Example cardholder_info object

"threeds2_data": {
    ...,
    "cardholder_info": {
      "email_address": "[email protected]",
      "mobile_phone_number": "+353209120599",
      "home_phone_number": "+353209174412",
      "work_phone_number": "+353209134251"
    }
    ...
}

Additional info about the cardholder, that is used by card issuer to determine the risk level of the transaction.

Name Type Required Description
email_address string Yes for Visa cards 1 Email address of the cardholder. Max length 254 characters.
mobile_phone_number string Yes for Visa cards 1 Mobile phone number provided by the cardholder. Max length 20 characters.
work_phone_number string Yes for Visa cards 1 Work phone number provided by the cardholder. Max length 20 characters.
home_phone_number string Yes for Visa cards 1 Home phone number provided by the cardholder. Max length 20 characters.

1 At least one parameter - email or a phone number (mobile, work or home) - is required for Visa transactions

Response

Returns a payment object if:

Returns an error object otherwise. Response codes: 400, 401, 405, 500, 503.

If a payment is in a pending state (status: pending) additional threeds2_data (3D Secure V2 flow) attribute is provided. Merchant must use provided information to redirect customer for an additional payment authorization steps. See: 3D Secure Program and Finalize Pending Payment

If a payment was declined (status: declined) payment object contains error attribute explaining why this happened. A common reason for payment being declined is an invalid or expired card, or a valid card with insufficient available balance.

3D Secure Program

3D Secure Flow

alt 3D Secure Flow

3D Secure Integration Steps

Example: 3D Secure v2 Redirection Page

<html>
   <head>
      <title>3-D Secure Example</title>
      <script type="text/javascript">
          function OnLoadEvent()
          {
            // Make the form post as soon as it has been loaded.
            document.ThreeDForm.submit();
          }
      </script>
   </head>
   <body onload="OnLoadEvent();">
      <p>
          If your browser does not start loading the page,
          press the button below.
          You will be sent back to this site after you
          authorize the transaction.
      </p>
      <form name="ThreeDForm" method="POST" action="{acs_url}">
          <button type=submit>Click Here</button>
          <input type="hidden" name="creq" value="{creq}" />
          <input type="hidden" name="threeDSSessionData" value="{your_identifier}" />
      </form>
   </body>
</html>

3D-Secure V2

  1. Create a new payment providing threeds2_data parameter.
  2. Check the returned payment object status
    • If the status is approved or declined, the payment process is complete and no further steps are required.
    • If the status is pending (HTTP Response code 202), 3D-Secure authorization is required.
  3. The returned payment object will have threeds2_data object assigned, which will have acs_url and creq attributes assigned.
  4. The next step is to initiate the redirect to customer's issuing bank ACS (Access Control Server) to perform 3D-Secure authorization. This should be done by making a POST request to the ACS. The example can be seen on the right.
    • Set form action parameter to the acs_url value received in payment response
    • Set creq parameter to the creq value received in payment response.
    • The threeDSSessionData parameter could be set to freely chosen value. It is advisable to set a unique identifier (for example, order ID) of the payment in your system. This way the incoming callback could be mapped to the exact payment request. Note that this parameter should be Base64URL-encoded without padding, as specified in RFC 7515.
  5. Once redirected, the cardholder will perform necessary steps to authenticate. The exact steps are determined by the issuing bank.
  6. If the cardholder performs the authentication successfully, you will receive a callback to the notification_url provided in the initial payment request. The callback consists of the following parameters:
    • cres - challenge response. This value should be sent to Cardinity during the payment finalization.
    • threeDSSessionData - unique identifier echoed back. This value is not processed by the ACS and is returned unchanged.
  7. Send a PATCH request to Cardinity as described in Finalize Pending Payment providing cres parameter data received from ACS as cres attribute.
  8. Cardinity will finalize the payment and return back it's result.

3D-Secure V1

3D-Secure V1 is no longer supported by VISA and Mastercard.

Finalize pending payment

3D Secure V2 Example Request

<?php
use Cardinity\Client;
use Cardinity\Method\Payment;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$method = new Payment\Finalize($payment->getId(), 'PARES_RECEIVED_FROM_ACS');
/** @type Cardinity\Method\Payment\Payment */
$payment = $client->call($method);

/** @type Cardinity\Method\Payment\Payment */
$method = new Payment\Finalize(
    $payment->getId(), // payment object received from API call
    $auth->getCreq(), // payment object received from API call
    true // BOOL `true` to enable 3D secure V2 parameters
);
// again use same try ... catch block
try {
    $payment = $client->call($method);
}
// same catch blocks as in Payment\Create...
CardinityClient client = new CardinityClient(consumerKey, consumerSecret);

/**
 * paymentId - ID of a pending payment
 * cRes - data received from ACS
 */
Result<Payment> result = client.finalizePaymentV2(paymentId, cRes);

if (result.isValid()) {
    /** Request was valid and payment was approved. */
    if (result.getItem().getStatus() == Payment.Status.APPROVED) {
        UUID paymentId = result.getItem().getId();
        // proceed with successful payment flow
    }
}

/** Request was valid but payment was declined. */
else if (result.isValid()) {
    String declineReason = result.getItem().getError();
    // proceed with declined payment flow
}

/** Request was invalid. */
else {
    CardinityError error = result.getCardinityError();
    // log error details for debugging
    // proceed with error handling flow
}
curl --request PATCH https://api.cardinity.com/v1/payments/cb5e1c95-7685-4499-a2b1-ae0f28297b92 \
-H "Content-Type: application/json" \
-H "Authorization: OAuth <OAuth Details>" \
-d '{
    "cres": "kjhdH9sd89dsoi.......",
}'
const Cardinity = require('cardinity-nodejs')
const Client = Cardinity.client()
const Finalize = Cardinity.finalize()

// callback listening function
app.post('/', function (req, res) {
    if (req.body.PaRes) {
        // finalize 3dsv1 if `PaRes` parameter is received
        var finalize_obj = new Finalize({
        'id': req.body.MD,
        'authorize_data': req.body.PaRes
    })
    } else if (req.body.cres) {
        // finalize 3dsv1 if `cres` parameter is received
        var finalize_obj = new Finalize({
            'id': req.body.threeDSSessionData,
            'cres': req.body.cres,
            'threedsv2': true
        });
    }
    if (finalize_obj.errors) {
        // show errors if exist
        res.end(JSON.stringify(finalize_obj.errors, null, 2));
    } else {
        client.call(finalize_obj).then(function (response) {
            if (response.status == 'approved')  {
                // handle successfully finished payment.
            }
        }).catch(function (error) {
            // show errors if exist
            res.end(JSON.stringify(error, null, 2));
        });
    }
});

To finalize a pending payment you have to send a PATCH request for that payment providing authorization information.

3D Secure V2

Send only cres parameter and its value as received from 3D Secure ACS.

HTTP Request

PATCH https://api.cardinity.com/v1/payments/{PAYMENT_ID}

Response

Returns a payment object if:

Returns an error object otherwise. Response codes: 400, 401, 405, 500, 503.

If a payment was declined (status: declined) payment object contains error attribute explaining why this happened. A common reason for payment being declined is an invalid or expired card, or a valid card with insufficient available balance.

Create recurring payment

Example Request

<?php

use Cardinity\Client;
use Cardinity\Method\Payment;
use Cardinity\Exception;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$method = new Payment\Create([
    'amount' => 50.00,
    'currency' => 'EUR',
    'settle' => false,
    'description' => 'some description',
    'order_id' => '12345678',
    'country' => 'LT',
    'payment_method' => Payment\Create::RECURRING,
    'payment_instrument' => [
        'payment_id' => $paymentId
    ],
]);

/**
* In case payment could not be processed exception will be thrown.
* In this example only Declined exception is handled. However there is more of them.
* See Error Codes section for detailed list.
*/
try {
    /** @type Cardinity\Method\Payment\Payment */
    $payment = $client->call($method);
} catch (Exception\Declined $exception) {
    /** @type Cardinity\Method\Payment\Payment */
    $payment = $exception->getResult();
    $status = $payment->getStatus(); // value will be 'declined'
    $errors = $exception->getErrors(); // list of errors occurred
}

?>
CardinityClient client = new CardinityClient(consumerKey, consumerSecret);

Payment payment = new Payment();
payment.setAmount(new BigDecimal(10));
payment.setCurrency("EUR");
payment.setCountry("LT");
payment.setPaymentMethod(Payment.Method.RECURRING);
Recurring recurringPayment = new Recurring();
// set to ID of a previous payment
recurringPayment.setPaymentId(previousPaymentId);
payment.setPaymentInstrument(recurringPayment);

Result<Payment> result = client.createPayment(payment);

/** Request was valid and payment was approved. */
if (result.isValid() && result.getItem().getStatus() == Payment.Status.APPROVED) {
    UUID paymentId = result.getItem().getId();
    // proceed with successful payment flow
}

/** Request was valid but payment was declined. */
else if (result.isValid()) {
    String declineReason = result.getItem().getError();
    // proceed with declined payment flow
}

/** Request was invalid. */
else {
    CardinityError error = result.getCardinityError();
    // log error details for debugging
    // proceed with error handling flow
}
curl https://api.cardinity.com/v1/payments \
-H "Content-Type: application/json" \
-H "Authorization: OAuth <OAuth Details>" \
-d '{
    "amount": "50.00",
    "currency": "EUR",
    "settle": false,
    "description": "some description",
    "order_id": "12345678",
    "country": "LT",
    "payment_method": "recurring",
    "payment_instrument": {
        "payment_id": "ba3119f2-9a73-11e4-89d3-123b93f75cba"
    }
}'

# Response JSON
{
    "id": "ba31174a-9a73-11e4-89d3-123b93f75cba",
    "amount": "50.00",
    "currency": "EUR",
    "created": "2014-12-19T11:52:53Z",
    "type": "authorization",
    "live": false,
    "status": "approved",
    "order_id": "12345678",
    "description": "some description",
    "country": "LT",
    "payment_method": "card",
    "payment_instrument": {
        "card_brand": "Visa",
        "pan": "1111",
        "exp_year": 2021,
        "exp_month": 11,
        "holder": "Mike Dough"
    }
}
const Cardinity = require('cardinity-nodejs')
const Client = Cardinity.client()
const Recurring = Cardinity.recurring()

const recurring = new Recurring({
    "amount": "50.00",
    "currency": "EUR",
    "settle": false,
    "description": "some description",
    "order_id": "12345678",
    "country": "LT",
    "payment_instrument": {
        "payment_id": "INITAL_PAYMENT_ID",
    },
})

const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
client.call(recurring).then(function(response){
    // Deal with response
}).catch(function (error){
    // Deal with error
});

To process a recurring payment you have to create a new payment object with payment_method attribute set to recurring and provide ID of the previous successful payment in a payment_instrument object. Same card will be used to create a new payment.

HTTP Request

POST https://api.cardinity.com/v1/payments

Request Attributes

Name Type Required Description
amount decimal Yes Amount to charge. Only positive values are allowed. Format: #0.00, two decimal places precision is required.
currency string Yes Three-letter ISO currency code representing the currency of the amount.
settle boolean No Default: true.
Indicates payment type: true - purchase, false - authorization. Purchase encapsulates authorization and settlement steps in one action.
order_id string No Order ID provided by a merchant. Must be between 2 and 50 characters [A-Za-z0-9'.-].
description string No Payment description provided by a merchant. Maximum length 255 characters.
country string Yes Country of a customer obtained via geolocation services or entered manually. ISO 3166-1 alpha-2 country code.
payment_method string Yes Can only be: recurring.
payment_instrument object Yes Payment instrument representing earlier described payment_method. See object description below.

Payment Instrument - recurring

Name Type Required Description
payment_id string Yes ID of the successful payment in the past.

Response

Returns a payment object if:

Returned payment object contains payment_instrument which was used in the initial payment.

Returns an error object otherwise. Response codes: 400, 401, 405, 500, 503.

If a payment was declined (status: declined) payment object contains error attribute explaining why this happened. A common reason for payment being declined is an invalid or expired card, or a valid card with insufficient available balance.

Get existing payment

Request Example

<?php

use Cardinity\Client;
use Cardinity\Method\Payment;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$method = new Payment\Get($payment->getId());
/** @type Cardinity\Method\Payment\Payment */
$payment = $client->call($method);

?>
CardinityClient client = new CardinityClient(consumerKey, consumerSecret);

Result<Payment> result = client.getPayment(paymentId);
if (result.isValid()) {
    Payment payment = result.getItem();
}
else {
    CardinityError error = result.getCardinityError();
}
curl https://api.cardinity.com/v1/payments/cb5e1c95-7685-4499-a2b1-ae0f28297b92 \
  -H "Content-Type: application/json" \
  -H "Authorization: OAuth <OAuth Details>"
const Cardinity = require('cardinity-nodejs')
const Client = Cardinity.client()
const GetPayment = Cardinity.getPayment()

const payments = new GetPayment({
    "id": "PAYMENT_UUID",
})

const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
client.call(payments).then(function(response){
    // Deal with response
}).catch(function (error){
    // Deal with error
});

To retrieve a specific payment you have to send GET request providing an ID of a payment.

HTTP Request

GET https://api.cardinity.com/v1/payments/{PAYMENT_ID}

Response

Returns a payment object if payment was found. Response code: 200.

Returns an error object if payment was not found. Response code: 404.

Get all payments

Example Request

<?php

use Cardinity\Client;
use Cardinity\Method\Payment;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$method = new Payment\GetAll();
$result = $client->call($method);
/** @type Cardinity\Method\Payment\Payment */
$payment = $result[0];

?>
CardinityClient client = new CardinityClient(consumerKey, consumerSecret);

Result<List<Payment>> result = client.getPayments();
if (result.isValid()) {
    List<Payment> payments = result.getItem();
}
else {
    CardinityError error = result.getCardinityError();
}
curl https://api.cardinity.com/v1/payments \
  -H "Content-Type: application/json" \
  -H "Authorization: OAuth <OAuth Details>"

# Response JSON
[
   {
      "id": "cb5e1c95-7685-4499-a2b1-ae0f28297b92",
      "amount": "20.00",
      "currency": "EUR",
      "created": "2014-12-17T09:46:11Z",
      "type": "authorization",
      "live": false,
      "description": "some description",
      "status": "declined",
      "error": "33333: 3D Secure Authorization Failed.",
      "country": "LT",
      "payment_method": "card",
      "payment_instrument":{
         "card_brand": "Visa",
         "pan": "0006",
         "exp_year": 2017,
         "exp_month": 5,
         "holder": "John Smith"
      }
   },
   {
      "id": "1379c6bb-dcd9-4669-8846-85a278c2aa7f",
      "amount": "20.00",
      "currency": "EUR",
      "created": "2014-12-17T09:44:01Z",
      "type": "authorization",
      "live": false,
      "description": "some description",
      "status": "approved",
      "country": "LT",
      "payment_method": "card",
      "payment_instrument":{
         "card_brand": "Visa",
         "pan": "4447",
         "exp_year": 2017,
         "exp_month": 5,
         "holder": "John Smith"
      }
   }
]
const Cardinity = require('cardinity-nodejs')
const Client = Cardinity.client()
const GetPayment = Cardinity.getPayment()

const payments = new GetPayment(NUMBER_OF_PAYMENTS_TO_GET)

const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
client.call(payments).then(function(response){
    // Deal with response
}).catch(function (error){
    // Deal with error
});

To retrieve all payments you have to send a GET request. An optional limit parameter can be used to specify a number of last payments to be returned. Default: 10 last payments.

HTTP Request

GET https://api.cardinity.com/v1/payments

Query Parameters

Parameter Default Description
limit 10 Number of last payments to be returned.

Response

Returns a list of payment objects. Response code: 200.

Refunds

To process a refund you have to create a new refund object. You can retrieve individual refund for a specific payment as well as a list of all refunds for a specific payment. Refunds are identified by a UUID.

Refund Object

Example: Approved Refund JSON

{  
   "id": "25e6f869-6675-4488-bd47-ccd298f74b3f",
   "amount": "0.50",
   "currency": "EUR",
   "type": "refund",
   "created": "2015-01-16T09:05:27Z",
   "live": false,
   "parent_id": "f02862aa-5dcc-4637-9ddf-b9140c2b4b06",
   "status": "approved"
}

Attributes

Name Type Description
id UUID ID of the refund.
Value assigned by Cardinity.
amount decimal Amount refunded shown in #0.00 format.
currency string Three-letter ISO currency code representing the currency in which the refund was made.
Value assigned by Cardinity.
type string Can only be: refund.
Value assigned by Cardinity.
created datetime Refund creation time as defined in RFC 3339 Section 5.6. UTC timezone.
Value assigned by Cardinity.
live boolean Indicates whether a refund was made in live or testing mode.
Value assigned by Cardinity.
parent_id UUID ID of the refunded payment.
Value assigned by Cardinity.
status string Refund status. Can be one of the following: approved, declined or processing.
Value assigned by Cardinity.
error string Error message. Returned only if status is declined. Provides human readable information why a refund failed.
Value assigned by Cardinity.
order_id string Optional. Order ID provided by a merchant in initial payment. Must be between 2 and 50 characters [A-Za-z0-9'.-].
Value assigned by Cardinity.
description string Optional. Refund description provided by a merchant. Maximum length 255 characters.

Create new refund

Example Request

<?php

use Cardinity\Client;
use Cardinity\Method\Refund;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$method = new Refund\Create(
    $payment->getId(),
    10.00,
    'my description'
);
/** @type Cardinity\Method\Refund\Refund */
$refund = $client->call($method);

?>
CardinityClient client = new CardinityClient(consumerKey, consumerSecret);

Refund refund = new Refund(new BigDecimal(10));
Result<Refund> result = client.createRefund(paymentId, refund);

/** Request was valid and refund was approved. */
if (result.isValid() && result.getItem().getStatus() == Refund.Status.APPROVED) {
    refund = result.getItem();
    // proceed with successful refund flow
}

/** Request was valid but refund was declined. */
else if (result.isValid()) {
     String declineReason = result.getItem().getError();
     // proceed with declined refund flow
}

/** Request was invalid. */
else {
    CardinityError error = result.getCardinityError();
    // handle error
}
curl https://api.cardinity.com/v1/payments/90ebe1a8-ebaf-48c5-b654-19c8e6ae5368/refunds \
-H "Content-Type: application/json" \
-H "Authorization: OAuth <OAuth Details>" \
-d '{
    "amount": "10.00",
    "description": "some description"
}'

# Response JSON
{
   "id": "25e6f869-6675-4488-bd47-ccd298f74b3f",
   "amount": "10.00",
   "currency": "EUR",
   "type": "refund",
   "created": "2015-01-16T09:05:27Z",
   "live": false,
   "parent_id": "90ebe1a8-ebaf-48c5-b654-19c8e6ae5368",
   "status": "approved",
   "description": "some description"
}
const Cardinity = require('cardinity-nodejs')
const Client = Cardinity.client()
const Refund = Cardinity.refund()

const refund = new Refund({
    "amount": "50.00",
    "description": "some optional description",
    "id": 'PAYMENT_UUID',
})

const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
client.call(refund).then(function(response){
    // Deal with response
}).catch(function (error){
    // Deal with error
});

To process a refund you have to create a new refund object providing Payment ID and amount to be refunded. Partial refunds can be made thus one payment might have more than one refund.

HTTP Request

POST https://api.cardinity.com/v1/payments/{PAYMENT_ID}/refunds

Request Attributes

Name Type Required Description
amount decimal Yes Amount to be refunded. Only positive values are allowed. Format: #0.00, two decimal places precision is required.
description string No Refund description provided by a merchant. Maximum length 255 characters.

Response

Returns a refund object if:

Returns an error object otherwise. Response codes: 400, 401, 405, 500, 503.

# Example Response JSON (HTTP response code: 202, status: processing)
{
    "id": "9bf6ed75-c6de-41f0-998b-f859cc51e2b2",
    "amount": "0.50",
    "currency": "EUR",
    "type": "refund",
    "created": "2024-02-21T14:13:22.4Z",
    "live": false,
    "parent_id": "07ab51f4-98c3-43de-8dbb-be9c542afa65",
    "status": "processing",
    "description": "some description"
}

If a refund was marked as processing (status: processing) refund object is returned and the refund was successfully submitted to our system. Processing status means that our system is currently unable to finalize it and is waiting for confirmation. No further actions are needed. After at most 24 hours the refund will be updated with final status (either approved or declined)

If a refund was declined (status: declined) refund object contains error attribute explaining why this happened.

Get existing refund

Request Example

<?php

use Cardinity\Client;
use Cardinity\Method\Refund;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$method = new Refund\Get(
    $payment->getId(),
    $refund->getId()
);
/** @type Cardinity\Method\Refund\Refund */
$refund = $client->call($method);

?>
CardinityClient client = new CardinityClient(consumerKey, consumerSecret);

Result<Refund> result = client.getRefund(paymentId, refundId);

if (result.isValid()) {
    Refund refund = result.getItem();
}
else {
    CardinityError error = result.getCardinityError();
} 
curl https://api.cardinity.com/v1/payments/cb5e1c95-7685-4499-a2b1-ae0f28297b92/refunds/25e6f869-6675-4488-bd47-ccd298f74b3f \
  -H "Content-Type: application/json" \
  -H "Authorization: OAuth <OAuth Details>"
const Cardinity = require('cardinity-nodejs')
const Client = Cardinity.client()
const GetRefund = Cardinity.getRefund()

const refunds = new GetRefund({
    "id": "PAYMENT_UUID",
    "refund_id": "REFUND_UUID"
})

const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
client.call(refunds).then(function(response){
    // Deal with response
}).catch(function (error){
    // Deal with error
});

To retrieve a specific refund you have to send a GET request providing an ID of a payment and ID of a refund.

HTTP Request

GET https://api.cardinity.com/v1/payments/{PAYMENT_ID}/refunds/{REFUND_ID}

Response

Returns a refund object if refund was found. Response code: 200.

Returns an error object if refund was not found. Response code: 404.

Get all refunds

Request Example

<?php

use Cardinity\Client;
use Cardinity\Method\Refund;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$method = new Refund\GetAll(
    $payment->getId()
);
$result = $client->call($method);
/** @type Cardinity\Method\Refund\Refund */
$refund = $result[0];

?>
CardinityClient client = new CardinityClient(consumerKey, consumerSecret);

Result<List<Refund>> result = client.getRefunds(paymentId);

if (result.isValid()) {
    List<Refund> refunds = result.getItem();
}
else {
    CardinityError error = result.getCardinityError();
}
curl https://api.cardinity.com/v1/payments/90ebe1a8-ebaf-48c5-b654-19c8e6ae5368/refunds \
  -H "Content-Type: application/json" \
  -H "Authorization: OAuth <OAuth Details>"

# Response JSON
[  
   {
       "id": "25e6f869-6675-4488-bd47-ccd298f74b3f",
       "amount": "5.00",
       "currency": "EUR",
       "type": "refund",
       "created": "2015-01-16T09:05:27Z",
       "live": false,
       "parent_id": "90ebe1a8-ebaf-48c5-b654-19c8e6ae5368",
       "status": "approved",
       "description": "some description"
   },
   {  
       "id": "12e6f869-6675-4488-bd47-ccd298f55b3f",
       "amount": "1.00",
       "currency": "EUR",
       "type": "refund",
       "created": "2015-01-17T09:15:27Z",
       "live": false,
       "parent_id": "90ebe1a8-ebaf-48c5-b654-19c8e6ae5368",
       "status": "approved",
       "description": "some description"
   }
]
const Cardinity = require('cardinity-nodejs')
const Client = Cardinity.client()
const GetRefund = Cardinity.getRefund()

const refund = new GetRefund({
    "id": "PAYMENT_UUID"
})

const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
client.call(refund).then(function(response){
    // Deal with response
}).catch(function (error){
    // Deal with error
});

To retrieve all refunds for a specific payment you have to send a GET request providing a payment id.

HTTP Request

GET https://api.cardinity.com/v1/payments/{PAYMENT_ID}/refunds

Response

Returns a list of refund objects. Response code: 200.

Settlements

To settle a payment you have to create a new settlement object. You can retrieve individual settlement for a specific payment. Settlements are identified by a UUID.

Settlement Object

Example: Approved Settlement

{  
   "id": "25e6f869-6675-4488-bd47-ccd298f74b3f",
   "amount": "0.50",
   "currency": "EUR",
   "type": "settlement",
   "created": "2015-01-16T09:05:27Z",
   "live": true,
   "parent_id": "f02862aa-5dcc-4637-9ddf-b9140c2b4b06",
   "status": "approved"
}

Attributes

Name Type Description
id UUID ID of the settlement.
Value assigned by Cardinity.
amount decimal Amount settled shown in #0.00 format.
currency string Three-letter ISO currency code representing the currency in which the settlement was made.
Value assigned by Cardinity.
type string Can only be: settlement.
Value assigned by Cardinity.
created datetime Settlement creation time as defined in RFC 3339 Section 5.6. UTC timezone.
Value assigned by Cardinity.
live boolean Indicates whether settlement was made in live or testing mode.
Value assigned by Cardinity.
parent_id UUID ID of the settled payment.
Value assigned by Cardinity.
status string Settlement status. Can be one of the following: approved or declined.
Value assigned by Cardinity.
error string Error message. Returned only if status is declined. Provides human readable information why a settlement failed.
Value assigned by Cardinity.
order_id string Optional. Order ID provided by a merchant in initial payment. Must be between 2 and 50 characters [A-Za-z0-9'.-].
Value assigned by Cardinity.
description string Optional. Settlement description provided by a merchant. Maximum length 255 characters.

Create new settlement

Example Request

<?php

use Cardinity\Client;
use Cardinity\Method\Settlement;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$method = new Settlement\Create(
    $payment->getId(),
    10.00,
    'my description'
);
/** @type Cardinity\Method\Settlement\Settlement */
$result = $client->call($method);

?>
CardinityClient client = new CardinityClient(consumerKey, consumerSecret);

Settlement settlement = new Settlement(new BigDecimal(10));
Result<Settlement> result = client.createSettlement(paymentId, settlement);

/** Request was valid and settlement was approved. */
if (result.isValid() && result.getItem().getStatus() == Settlement.Status.APPROVED) {
    settlement = result.getItem();
    // proceed with successful settlement flow
}

/** Request was valid but settlement was declined. */
else if (result.isValid()) {
     String declineReason = result.getItem().getError();
     // proceed with declined settlement flow
}

/** Request was invalid. */
else {
    CardinityError error = result.getCardinityError();
    // handle error
}
curl https://api.cardinity.com/v1/payments/90ebe1a8-ebaf-48c5-b654-19c8e6ae5368/settlements \
-H "Content-Type: application/json" \
-H "Authorization: OAuth <OAuth Details>" \
-d '{
    "amount": "10.00",
    "description": "some description"
}'

# Response JSON
{
   "id": "25e6f869-6675-4488-bd47-ccd298f74b3f",
   "amount": "10.00",
   "currency": "EUR",
   "type": "settlement",
   "created": "2015-01-16T09:05:27Z",
   "live": false,
   "parent_id": "90ebe1a8-ebaf-48c5-b654-19c8e6ae5368",
   "status": "approved",
   "description": "some description"
}
const Cardinity = require('cardinity-nodejs')
const Client = Cardinity.client()
const Settlement = Cardinity.settlement()

const settle = new Settlement({
    "id": "PAYMENT_UUID",
    "amount": "50.00",
    "description": "optional description"
})

const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
client.call(settle).then(function(response){
    // Deal with response
}).catch(function (error){
    // Deal with error
});

To settle authorized payment you have to create a new settlement object providing Payment Id and amount to be settled. Only one settlement for a payment is allowed. You can not settle larger amount than it was authorized.

HTTP Request

POST https://api.cardinity.com/v1/payments/{PAYMENT_ID}/settlements

Request Attributes

Name Type Required Description
amount decimal Yes Amount to be settled. Only positive values are allowed. Format: #0.00, two decimal places precision is required.
description string No Settlement description provided by a merchant. Maximum length 255 characters.

Response

Returns a settlement object if:

Returns an error object otherwise. Response codes: 400, 401, 405, 500, 503.

If a Settlement was declined (status: declined) Settlement object contains error attribute explaining why this happened.

Get existing settlement

Request Example

<?php

use Cardinity\Client;
use Cardinity\Method\Settlement;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$method = new Settlement\Get(
    $payment->getId(),
    $settlement->getId()
);
/** @type Cardinity\Method\Settlement\Settlement */
$settlement = $client->call($method);

?>
CardinityClient client = new CardinityClient(consumerKey, consumerSecret);

Result<Settlement> result = client.getSettlement(paymentId, settlementId);

if (result.isValid()) {
    Settlement settlement = result.getItem();
}
else {
    CardinityError error = result.getCardinityError();
}  
curl https://api.cardinity.com/v1/payments/cb5e1c95-7685-4499-a2b1-ae0f28297b92/settlements/25e6f869-6675-4488-bd47-ccd298f74b3f \
  -H "Content-Type: application/json" \
  -H "Authorization: OAuth <OAuth Details>"
const Cardinity = require('cardinity-nodejs')
const Client = Cardinity.client()
const GetSettlement = Cardinity.getSettlement()

const settle = new GetSettlement({
    "id": "PAYMENT_UUID",
    "settlement_id": "SETTLEMENT_UUID"
})

const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
client.call(settle).then(function(response){
    // Deal with response
}).catch(function (error){
    // Deal with error
});

To retrieve a specific settlement you have to send GET request providing an ID of a payment and ID of a settlement.

HTTP Request

GET https://api.cardinity.com/v1/payments/{PAYMENT_ID}/settlements/{SETTLEMENT_ID}

Response

Returns a settlement object if settlement was found. Response code: 200.

Returns an error object if settlement was not found. Response code: 404.

Get all settlements

Request Example

<?php

use Cardinity\Client;
use Cardinity\Method\Settlement;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$method = new Settlement\GetAll(
    $payment->getId()
);
$result = $client->call($method);
/** @type Cardinity\Method\Settlement\Settlement */
$settlement = $result[0];

?>
CardinityClient client = new CardinityClient(consumerKey, consumerSecret);

Result<List<Settlement>> result = client.getSettlements(paymentId);

if (result.isValid()) {
    List<Settlement> settlements = result.getItem();
}
else {
    CardinityError error = result.getCardinityError();
}
curl https://api.cardinity.com/v1/settlements/90ebe1a8-ebaf-48c5-b654-19c8e6ae5368/settlements \
  -H "Content-Type: application/json" \
  -H "Authorization: OAuth <OAuth Details>"

# Response JSON
[  
   {
       "id": "25e6f869-6675-4488-bd47-ccd298f74b3f",
       "amount": "5.00",
       "currency": "EUR",
       "type": "settlement",
       "created": "2015-01-16T09:05:27Z",
       "live": false,
       "parent_id": "90ebe1a8-ebaf-48c5-b654-19c8e6ae5368",
       "status": "approved",
       "description": "some description"
   }
]
const Cardinity = require('cardinity-nodejs')
const Client = Cardinity.client()
const GetSettlement = Cardinity.getSettlement()

const settle = new GetSettlement({
    "id": "PAYMENT_UUID"
})

const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
client.call(settle).then(function(response){
    // Deal with response
}).catch(function (error){
    // Deal with error
});

To retrieve a settlement for a specific payment you have to send GET request providing a payment id.

HTTP Request

GET https://api.cardinity.com/v1/payments/{PAYMENT_ID}/settlements

Response

Returns a list of settlement objects. Response code: 200.

Voids

To void an authorized payment you have to create a new void object. You can retrieve individual void for a specific payment. Voids are identified by a UUID.

Void Object

Example: Approved Void

{  
   "id": "25e6f869-6675-4488-bd47-ccd298f74b3f",
   "type": "void",
   "created": "2015-01-16T09:05:27Z",
   "live": true,
   "parent_id": "f02862aa-5dcc-4637-9ddf-b9140c2b4b06",
   "status": "approved"
}

Attributes

Name Type Description
id UUID ID of the void.
Value assigned by Cardinity.
type string Can only be: void.
Value assigned by Cardinity.
created datetime Void creation time as defined in RFC 3339 Section 5.6. UTC timezone.
Value assigned by Cardinity.
live boolean Indicates whether void was made in live or testing mode.
Value assigned by Cardinity.
parent_id UUID ID of the voided payment.
Value assigned by Cardinity.
status string Void status. Can be one of the following: approved or declined.
Value assigned by Cardinity.
error string Error message. Returned only if status is declined. Provides human readable information why a void failed.
Value assigned by Cardinity.
order_id string Optional. Order ID provided by a merchant in initial payment. Must be between 2 and 50 characters [A-Za-z0-9'.-].
Value assigned by Cardinity.
description string Optional. Void description provided by a merchant. Maximum length: 255 characters.

Create new void

Example Request

<?php

use Cardinity\Client;
use Cardinity\Method\VoidPayment;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$method = new VoidPayment\Create(
    $payment->getId(),
    'my description'
);
/** @type Cardinity\Method\VoidPayment\VoidPayment */
$result = $client->call($method);

?>
CardinityClient client = new CardinityClient(consumerKey, consumerSecret);

Result<Void> result = client.createVoid(paymentId, new Void());

/** Request was valid and void was approved. */
if (result.isValid() && result.getItem().getStatus() == Void.Status.APPROVED) {
    Void voidPayment = result.getItem();
    // proceed with successful void flow
}

/** Request was valid but void was declined. */
else if (result.isValid()) {
     String declineReason = result.getItem().getError();
     // proceed with declined void flow
}

/** Request was invalid. */
else {
    CardinityError error = result.getCardinityError();
    // handle error
}
curl https://api.cardinity.com/v1/payments/90ebe1a8-ebaf-48c5-b654-19c8e6ae5368/voids \
-H "Content-Type: application/json" \
-H "Authorization: OAuth <OAuth Details>" \
-d '{
    "description": "some description"
}'

# Response JSON
{
   "id": "25e6f869-6675-4488-bd47-ccd298f74b3f",
   "type": "void",
   "created": "2015-01-16T09:05:27Z",
   "live": false,
   "parent_id": "90ebe1a8-ebaf-48c5-b654-19c8e6ae5368",
   "status": "approved",
   "description": "some description"
}
const Cardinity = require('cardinity-nodejs')
const Client = Cardinity.client()
const Voids = Cardinity.voids()

const voids = new Voids({
    "id": "PAYMENT_UUID",
})

const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
client.call(voids).then(function(response){
    // Deal with response
}).catch(function (error){
    // Deal with error
});

To void an authorized payment you have to create a new void object providing Payment Id.

HTTP Request

POST https://api.cardinity.com/v1/payments/{PAYMENT_ID}/voids

Request Attributes

Name Type Required Description
description string No Void description provided by a merchant. Maximum length: 255 characters.

Response

Returns a void object if:

Returns an error object otherwise. Response codes: 400, 401, 405, 500, 503.

If a void was declined (status: declined) Void object contains error attribute explaining why this happened.

Get existing void

Request Example

<?php

use Cardinity\Client;
use Cardinity\Method\VoidPayment;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$method = new VoidPayment\Get(
    $payment->getId(),
    $void->getId()
);
/** @type Cardinity\Method\VoidPayment\VoidPayment */
$void = $client->call($method);

?>
CardinityClient client = new CardinityClient(consumerKey, consumerSecret);

Result<Void> result = client.getVoid(paymentId, voidId);

if (result.isValid()) {
    Void voidPayment = result.getItem();
}
else {
    CardinityError error = result.getCardinityError();
} 
curl https://api.cardinity.com/v1/payments/cb5e1c95-7685-4499-a2b1-ae0f28297b92/voids/25e6f869-6675-4488-bd47-ccd298f74b3f \
  -H "Content-Type: application/json" \
  -H "Authorization: OAuth <OAuth Details>"
const Cardinity = require('cardinity-nodejs')
const Client = Cardinity.client()
const GetVoids = Cardinity.getVoids();

const voids = new GetVoids({
    "id": "PAYMENT_UUID",
    "void_id": "VOID_UUID"
})

const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
client.call(voids).then(function(response){
    // Deal with response
}).catch(function (error){
    // Deal with error
});

To retrieve a specific void you have to send GET request providing an ID of a payment and ID of a void.

HTTP Request

GET https://api.cardinity.com/v1/payments/{PAYMENT_ID}/voids/{VOID_ID}

Response

Returns a void object if void was found. Response code: 200.

Returns an error object if void was not found. Response code: 404.

Get all voids

Request Example

<?php

use Cardinity\Client;
use Cardinity\Method\VoidPayment;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$method = new VoidPayment\GetAll(
    $payment->getId()
);
$result = $client->call($method);
/** @type Cardinity\Method\VoidPayment\VoidPayment */
$void = $result[0];

?>
CardinityClient client = new CardinityClient(consumerKey, consumerSecret);

Result<List<Void>> result = client.getVoids(paymentId);

if (result.isValid()) {
    List<Void> voids = result.getItem();
}
else {
    CardinityError error = result.getCardinityError();
}
curl https://api.cardinity.com/v1/payments/90ebe1a8-ebaf-48c5-b654-19c8e6ae5368/voids \
  -H "Content-Type: application/json" \
  -H "Authorization: OAuth <OAuth Details>"

# Response JSON
[  
   {
       "id": "25e6f869-6675-4488-bd47-ccd298f74b3f",
       "type": "void",
       "created": "2015-01-16T09:05:27Z",
       "live": false,
       "parent_id": "90ebe1a8-ebaf-48c5-b654-19c8e6ae5368",
       "status": "approved",
       "description": "some description"
   }
]
const Cardinity = require('cardinity-nodejs')
const Client = Cardinity.client()
const GetVoids = Cardinity.getVoids();

const voids = new GetVoids({
    "id": "PAYMENT_UUID"
})

const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
client.call(voids).then(function(response){
    // Deal with response
}).catch(function (error){
    // Deal with error
});

To retrieve a void for a specific payment you have to send GET request providing payment id.

HTTP Request

GET https://api.cardinity.com/v1/payments/{PAYMENT_ID}/voids

Response

Returns a list of void objects. Response code: 200.

Chargebacks

You can retrieve individual chargeback for a specific payment, a list of all chargebacks for a specific payment as well as all existing chargebacks of your processed payments. Chargebacks are identified by a UUID.

Chargeback Object

Example: Chargeback

{
  "id": "1be645ca-12e5-4b6e-86ab-a868435d9875",
  "amount": "0.50",
  "currency": "EUR",
  "type": "chargeback",
  "created": "2022-12-01T09:45:31Z",
  "live": false,
  "parent_id": "cb7afe8c-4ac5-449b-9574-c033256b8690",
  "status": "approved",
  "reason": "123: 456",
  "description": "First chargeback"
}

Attributes

Name Type Description
id UUID ID of the chargeback.
amount decimal Amount charged shown in #0.00 format.
currency string Three-letter ISO currency code representing the currency in which the charge was made.
type string Can only be: chargeback.
created datetime Chargeback creation time as defined in RFC 3339 Section 5.6. UTC timezone.
live boolean Indicates whether chargeback was made in live or testing mode.
parent_id UUID ID of the chargebacked payment.
status string Chargeback status. Can be one of the following: approved or declined.
reason string Chargeback reason (Only present if chargeback status is approved). Format is "reason_code: reason_message".
description string Chargeback description.

Get chargebacks of a payment

Request Example

<?php

use Cardinity\Client;
use Cardinity\Method\Chargeback;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$limit = 10;
$method = new Chargeback\GetAll($limit, 'your-parent-payment-id');
/** @type Cardinity\Method\Chargeback\Chargeback */
$result = $client->call($method);

?>

CardinityClient client = new CardinityClient(consumerKey, consumerSecret);

Result<List<Chargeback>> result = client.getChargebacks(paymentId);

if (result.isValid()) {
    List<Chargeback> chargebacks = result.getItem();
}
else {
    CardinityError error = result.getCardinityError();
}
curl https://api.cardinity.com/v1/payments/8f684056-5a8f-46ac-b02c-1133b63285a5/chargebacks \
  -H "Content-Type: application/json" \
  -H "Authorization: OAuth <OAuth Details>"

# Response JSON
[
    {
        "id": "5dd5a227-85ba-4909-b50a-613b09799a65",
        "amount": "0.50",
        "currency": "EUR",
        "type": "chargeback",
        "created": "2022-12-01T14:51:01Z",
        "live": false,
        "parent_id": "8f684056-5a8f-46ac-b02c-1133b63285a5",
        "status": "approved",
        "reason": "123: 456",
        "description": "First chargeback"
    },
    ...
]
const Cardinity = require('cardinity-nodejs')
const GetChargeback = Cardinity.getChargeback()

const getChargeback = new GetChargeback({
    'payment_id': 'PAYMENT_UUID'
})

if (getChargeback.errors) {
    // Deal with validation errors
} else {
    const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
    client.call(getChargeback).then(function(response){
        // Deal with response
    }).catch(function (error){
        // Deal with error
    });
}

To retrieve all chargebacks for a specific payment you have to send GET request providing an ID of a payment.

HTTP Request

GET https://api.cardinity.com/v1/payments/{PAYMENT_ID}/chargebacks

Response

Returns a list of chargeback object with all chargebacks that were found for specific payment. Response code: 200.

Get specific chargeback of a payment

Request Example

<?php

use Cardinity\Client;
use Cardinity\Method\Chargeback;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$method = new Chargeback\Get(
    'parent_payment_id',
    'charegeback_id'
);
/** @type Cardinity\Method\Chargeback\Chargeback */
$result = $client->call($method);

?>
CardinityClient client = new CardinityClient(consumerKey, consumerSecret);

Result<Chargeback> result = client.getChargeback(paymentId, chargebackId);

if (result.isValid()) {
    Chargeback chargeback = result.getItem();
}
else {
    CardinityError error = result.getCardinityError();
}
curl https://api.cardinity.comhttp:/v1/payments/8f684056-5a8f-46ac-b02c-1133b63285a5/chargebacks/5dd5a227-85ba-4909-b50a-613b09799a6a \
  -H "Content-Type: application/json" \
  -H "Authorization: OAuth <OAuth Details>"

# Response JSON
{
    "id": "5dd5a227-85ba-4909-b50a-613b09799a65",
    "amount": "0.50",
    "currency": "EUR",
    "type": "chargeback",
    "created": "2022-12-01T14:51:01Z",
    "live": false,
    "parent_id": "8f684056-5a8f-46ac-b02c-1133b63285a5",
    "status": "approved",
    "reason": "123: 456",
    "description": "First chargeback"
}
const Cardinity = require('cardinity-nodejs')
const GetChargeback = Cardinity.getChargeback()

const getChargeback = new GetChargeback({
    'payment_id': 'PAYMENT_UUID',
    'chargeback_id': 'CHARGEBACK_UUID'
})

if (getChargeback.errors) {
    // Deal with validation errors
} else {
    const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
    client.call(getChargeback).then(function(response){
        // Deal with response
    }).catch(function (error){
        // Deal with error
    });
}

To retrieve all chargebacks for a specific payment you have to send GET request providing an ID of a payment and ID of a chargeback.

HTTP Request

GET https://api.cardinity.com/v1/payments/{PAYMENT_ID}/chargebacks/{CHARGEBACK_ID}

Response

Returns a chargeback object if chargeback was found. Response code: 200.

Returns an error object if chargeback was not found. Response code: 404.

Get all chargebacks

Request Example

<?php

use Cardinity\Client;
use Cardinity\Method\Chargeback;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$method = new Chargeback\GetAll();
/** @type Cardinity\Method\Chargeback\Chargeback */
$result = $client->call($method);

?>
CardinityClient client = new CardinityClient(consumerKey, consumerSecret);

int limit = 10;
Result<List<Chargeback>> result = client.getAllChargebacks(limit);

if (result.isValid()) {
    List<Chargeback> chargebacks = result.getItem();
}
else {
    CardinityError error = result.getCardinityError();
}
curl https://api.cardinity.com/v1/payments/chargebacks \
  -H "Content-Type: application/json" \
  -H "Authorization: OAuth <OAuth Details>"

# Response JSON
[
    {
        "id": "5dd5a227-85ba-4909-b50a-613b09799a65",
        "amount": "0.50",
        "currency": "EUR",
        "type": "chargeback",
        "created": "2022-12-01T14:51:01Z",
        "live": false,
        "parent_id": "8f684056-5a8f-46ac-b02c-1133b63285a5",
        "status": "approved",
        "reason": "123: 456",
        "description": "First chargeback"
    },
    ...
]
const Cardinity = require('cardinity-nodejs')
const GetChargeback = Cardinity.getChargeback()

const limit = 10
const getChargeback = new GetChargeback(limit)

if (getChargeback.errors) {
    // Deal with validation errors
} else {
    const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
    client.call(getChargeback).then(function (response) {
        // Deal with response
    }).catch(function (error) {
        // Deal with error
    });
}

To retrieve all chargebacks you have to send a GET request. An optional request parameter limit can be used to specify a number of last chargebacks to be returned (1-100). Default: 10 last chargebacks.

HTTP Request

GET https://api.cardinity.com/v1/payments/chargebacks

Query Parameters

Parameter Default Description
limit 10 Number of last chargebacks to be returned.

Response

Returns a list of chargeback objects. Response code: 200.

Response / Error Codes

In case of an error Cardinity API returns JSON structured like this:

{
    "type": "https://developers.cardinity.com/api/v1/#400",
    "title": "Validation Failed",
    "status": 400,
    "detail": "The content you've send contains 2 validation errors.",
    "errors": [
        {
            "field": "currency",
            "rejected": "EGR",
            "message": "invalid or unsupported currency"
        },
        {
            "field": "payment_instrument.exp_month",
            "rejected": 13,
            "message": "must be between 1 and 12"
        }
    ]
}

Cardinity uses RFC 7231 HTTP response codes to indicate success or failure of an API request.

Codes in the 2xx range indicate success, codes in the 4xx range indicate an error that resulted from the provided information (e.g. a required parameter was missing, a credit card was declined, etc.), and codes in the 5xx range indicate an error on Cardinity's end.

In case of an error, specific object is returned which contains detailed information about the error which occurred.

Error Object Attributes

Attribute Description
type URL to error's documentation page
title Title of an error
status HTTP response code
detail Human readable information about the error
errors Optional. In case of validation errors all the fields with incorrect information are returned.

Response Codes

Code Meaning
200 OK -- Indicates successful retrieval of a resource. Used only in response for GET method requests.
201 Created -- Successful creation of a resource (e.g. successful payment, refund, etc). Used in response for POST and PATCH method requests.
202 Accepted -- Payment was submitted to system, but is not yet complete. Either there is a need for you to provide additional information or there is a delay before final confirmation.

Error Codes

Base exception class for Cardinity client: Cardinity\Exception\Runtime
Catching this exception ensures that you handle all cardinity failure use cases.

Base class for API error response exceptions: Cardinity\Exception\Request

Methods:
* getErrors() returns list of errors occured
* getErrorsAsString() returns list of errors occured in string form
* getResult() returns object, the instance of ResultObjectInterface.

All classes

Class: Cardinity\Exception\ValidationFailed
HTTP status: 400

Class: Cardinity\Exception\Unauthorized
HTTP status: 401

Class: Cardinity\Exception\Declined
HTTP status: 402

Class: Cardinity\Exception\Forbidden
HTTP status: 403

Class: Cardinity\Exception\NotFound
HTTP status: 404

Class: Cardinity\Exception\MethodNotAllowed
HTTP status: 405

Class: Cardinity\Exception\NotAcceptable
HTTP status: 406

Class: Cardinity\Exception\InternalServerError
HTTP status: 500

Class: Cardinity\Exception\ServiceUnavailable
HTTP status: 503


Cardinity client exceptions

Request timed out: Cardinity\Exception\RequestTimeout

Before-request data validation failed: Cardinity\Exception\InvalidAttributeValue
Methods:
* getViolations() returns list of validation violations

Response mapping to result object failure: Cardinity\Exception\ResultObjectInterfacePropertyNotFound

Unexpected error: Cardinity\Exception\UnexpectedError
Call of CardinityClient methods may result in unchecked exception being thrown. 

Base exception class is CardinityException

There can be two types of exceptions thrown:

* ValidationException - validation of data passed to method has failed.
* CardinityClientException - network errors, internal client errors, etc.
Any error that may appear while calling the Cardinity API will be documented in the response
Code Meaning
400 Bad Request -- Your request contains field or business logic validation errors or provided JSON is malformed.
401 Unauthorized -- Your authorization information was missing or wrong.
402 Request Failed -- Your request was valid but it was declined.
403 Forbidden -- You do not have access to this resource.
404 Not Found -- The specified resource could not be found.
405 Method Not Allowed -- You tried to access a resource using an invalid HTTP method.
406 Not Acceptable -- Wrong Accept headers sent in the request.
415 Unsupported Media Type -- Wrong Content-Type headers sent in the request.
500 Internal Server Error -- We had a problem on our end. Try again later.
503 Service Unavailable -- We're temporarily off-line for maintenance. Please try again later.

Hosted Payment Page

Hosted Payment Page

All requests and responses must be signed and verified using HMAC-SHA256

Checkout HTTP Request

Example Request

curl https://checkout.cardinity.com \
-H "Content-Type: application/json" \
-d '{
    "amount": "1.00",
    "cancel_url": "https://your-shop.com/payment-cancelled",
    "country": "LT",
    "email_address": "[email protected]",
    "language": "EN",
    "mobile_phone_number": "+37061111111",
    "currency": "EUR",
    "description": "some description",
    "order_id": "12345678",
    "project_id": "test_pr_123",
    "return_url": "https://your-shop.com/payment-complete",
    "signature": {your_signature}
}'
<?php

$amount = "0.50";
$cancel_url = "https://your-shop.com/payment-cancelled";
$country = "LT";
$emailAddress = "[email protected]";
$language = "EN";
$currency = "EUR";
$description = "Purchase Description";
$mobilePhoneNumber = "+37061111111";
$order_id = "123";
$return_url = "https://your-shop.com/payment-complete";

$project_id = "your-project-id";
$project_secret = "your-project-secret";

$attributes = [
    "amount" => $amount,
    "currency" => $currency,
    "country" => $country,
    "email_address" => $emailAddress,
    "language" => $language,
    "order_id" => $order_id,
    "description" => $description,
    "mobile_phone_number" => $mobilePhoneNumber,
    "project_id" => $project_id,
    "cancel_url" => $cancel_url,
    "return_url" => $return_url,
];

ksort($attributes);

$message = '';
foreach($attributes as $key => $value) {
    $message .= $key.$value;
}

$signature = hash_hmac('sha256', $message, $project_secret);

?>
try {
    Map<String, String> attributes = new HashMap<>();

    attributes.put("amount", "10.00");
    attributes.put("currency", "EUR");
    attributes.put("country", "LT");
    attributes.put("email_address", "[email protected]")
    attributes.put("language", "GB");
    attributes.put("mobile_phone_number", "+37061111111")
    attributes.put("order_id", "99999");
    attributes.put("project_id", projectId);
    attributes.put("return_url", returnUrl);

    String message = attributes.entrySet().stream()
        .sorted(Map.Entry.comparingByKey())
        .map(e -> e.getKey() + e.getValue())
        .collect(Collectors.joining(""));

    Mac hasher = Mac.getInstance("HmacSHA256");
    hasher.init(new SecretKeySpec(projectSecret.getBytes(), "HmacSHA256"));

    byte[] hash = hasher.doFinal(message.getBytes());

    String signature = DatatypeConverter.printHexBinary(hash).toLowerCase();
} catch (NoSuchAlgorithmException e) {
} catch (InvalidKeyException e) {
}
var sha256 = require('js-sha256');
var amount = "0.50"
var cancel_url = "https://your-shop.com/payment-cancelled"
var currency = "EUR"
var country = "LT"
var email_address = "[email protected]"
var language = "EN"
var mobile_phone_number = "+37061111111"
var description = "Purchase Description"
var order_id = "123"
var return_url = "https://your-shop.com/payment-complete"

var project_id = "your-project-id"
var project_secret = "your-project-secret"

var attributes = {
    return_url: return_url,
    amount: amount,
    cancel_url: cancel_url,
    country: country,
    email_address: email_address,
    language: language,
    mobile_phone_number: mobile_phone_number,
    currency: currency,
    description: description,
    order_id: order_id,
    project_id: project_id,
}

var keys = [], k, i, message = ''
for (k in attributes) {
    if (attributes.hasOwnProperty(k)) {
        keys.push(k);
    }
}
keys.sort();
for (i = 0; i < keys.length; i++) {
    message += keys[i] + attributes[keys[i]];
}
var signature = sha256.hmac(project_secret, message);

Example Request Form

<html>
   <head>
      <title>Request Example | Hosted Payment Page</title>
   </head>
   <body onload="document.forms['checkout'].submit()">
      <form name="checkout" method="POST" action="https://checkout.cardinity.com">
          <button type=submit>Click Here</button>
          <input type="hidden" name="amount" value="{amount}" />
          <input type="hidden" name="cancel_url" value="{cancel_url}" />
          <input type="hidden" name="country" value="{country}" />
          <input type="hidden" name="language" value="{language}" />
          <input type="hidden" name="email_address" value="{email_address}" />
          <input type="hidden" name="mobile_phone_number" value="{mobile_phone_number}" />
          <input type="hidden" name="currency" value="{currency}" />
          <input type="hidden" name="description" value="{description}" />
          <input type="hidden" name="order_id" value="{order_id}" />
          <input type="hidden" name="project_id" value="{project_id}" />
          <input type="hidden" name="return_url" value="{return_url}" />
          <input type="hidden" name="signature" value="{signature}" />
      </form>
   </body>
</html>

POST https://checkout.cardinity.com

Request Attributes

Name Type Required Description
amount decimal Yes Amount to charge. Only positive values are allowed. Format: #0.00, two decimal places precision is required.
cancel_url string No URL to which customer is redirected upon canceling payment flow. Must be valid url address up to 500 characters. Make sure to use a public address - for local development, we suggest using ngrok.
country string Yes Country of a customer obtained via geolocation services or entered manually. ISO 3166-1 alpha-2 country code.
language string No Optional parameter for setting hosted payment page language. Could be obtained via geolocation services or entered manually. Should meet ISO 639-1 two-letter code requirements.
currency string Yes Three-letter ISO currency code representing the currency of the amount.
email_address string Yes for Visa cards 1 Email address of the cardholder. Max length 254 characters.
mobile_phone_number string Yes for Visa cards 1 Mobile phone number provided by the cardholder. Max length 20 characters.
description string No Payment description provided by a merchant. Maximum length 255 characters.
order_id string Yes Order ID provided by a merchant. Must be between 2 and 50 characters [A-Za-z0-9'.-].
project_id string Yes Project ID provided by Cardinity.
return_url string Yes URL to which customer is redirected upon completing payment flow. Must be valid url address up to 500 characters. Make sure to use a public address - for local development, we suggest using ngrok.
signature string Yes String made up of request parameters joined in a single string in ascending order, according to the key which is then encrypted via HMAC-SHA256 using your Project Secret.

1 At least one parameter - email or a phone number - is required for Visa transactions.

Signature calculation

All requests and responses must be signed and verified using HMAC-SHA256.

The signature is a string made up of request parameters joined in a single string in ascending order, according to the key. The string is then encrypted via HMAC-SHA256 using your Project Secret.

Please note that the signature should include all non-empty key-value pairs that are used in the POST request.

Checkout HTTP Response

Example Response

<?php

$message = '';
ksort($_POST);

foreach($_POST as $key => $value) {
    if ($key == 'signature') continue;
    $message .= $key.$value;
}

$signature = hash_hmac('sha256', $message, $projectSecret);

if ($signature == $_POST['signature']) {
    // Response valid
} else {
    // Response invalid or changed
}

?>
var sha256 = require('js-sha256');
var project_secret = "your-project-secret"
var keys = [], k, i, message = ''
for (k in request.body) {
    if (request.body.hasOwnProperty(k)) {
        keys.push(k)
    }
}
keys.sort();
for (i = 0; i < keys.length; i++) {
    if(keys[i] == 'signature') continue
    message += keys[i] + request.body[keys[i]]
}
var signature = sha256.hmac(project_secret, message);

if(signature == request.body.signature) {
    // Response valid
} else {
    // Response invalid or changed
}

Response Attributes for return_url

Name Type Required Description
amount decimal Yes Amount shown in #0.00 format.
country string Yes Country of a customer provided by a merchant. ISO 3166-1 alpha-2 country code.
created datetime Yes Payment creation time as defined in RFC 3339 Section 5.6. UTC timezone.
currency string Yes Three-letter ISO currency code representing the currency in which the charge was made.
description string No Payment description provided by a merchant.
error string No Error message. Returned only if status is declined.
id UUID Yes ID of the payment.
live boolean Yes Indicates whether a payment was made in live or testing mode.
order_id string Yes Order ID provided by a merchant.
payment_method string Yes Can be card only.
project_id string Yes Project ID provided by a merchant.
signature string Yes String made up of response parameters joined in a single string in ascending order, according to the key which is then encrypted via HMAC-SHA256 using your Project Secret.
status string Yes Payment status.
type string Yes Payment type.

Response Attributes for cancel_url

Name Type Required Description
order_id string Yes Order ID provided by a merchant.
project_id string Yes Project ID provided by a merchant.
signature string Yes String made up of response parameters joined in a single string in ascending order, according to the key which is then encrypted via HMAC-SHA256 using your Project Secret.

Payment links

To create a payment link you have to create a new payment link object. You can retrieve individual payment links and update payment link parameters. Payment links are identified by a UUID.

Example: Payment link JSON

{
    "id": "b6aca927-0a13-4b0f-8d71-d3d140143216",
    "url": "https://checkout.cardinity.com/link/b6aca927-0a13-4b0f-8d71-d3d140143216",
    "amount": "1.00",
    "currency": "EUR",
    "country": "LT",
    "description": "My order description",
    "expiration_date": "2023-01-06T15:26:03.702Z",
    "multiple_use": true,
    "enabled": true
}

Attributes

Name Type Description
id UUID ID of the payment link.
Value assigned by Cardinity.
url string URL of the payment link.
Value assigned by Cardinity.
amount decimal Amount charged shown in #0.00 format.
currency string Three-letter ISO currency code representing the currency in which the charge was made.
country string Country of a customer provided by a merchant. ISO 3166-1 alpha-2 country code.
description string Payment description provided by a merchant. Maximum length 255 characters.
expiration_date datetime Expiration date of the payment link as defined in RFC 3339 Section 5.6. UTC timezone.
multiple_use boolean Indicates whether the payment link can be used more than once
enabled boolean Indicates whether the payment link is enabled

Example Request

<?php

use Cardinity\Client;
use Cardinity\Method\PaymentLink;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$method = new PaymentLink\Create([
    'amount' => 50.00,
    'currency' => "USD",
    'description' => "Short description for the payment link",

    'country' => "LT", // ISO 3166-1 alpha-2 country code.
    'expiration_date' => "2023-01-06T15:26:03.702Z", //ISO 8601 datetime in UTC 
    'multiple_use' => true, //bool
]);

/** @type Cardinity\Method\PaymentLink\PaymentLink */
$result = $client->call($method);

?>
CardinityClient client = new CardinityClient(consumerKey, consumerSecret);

PaymentLink paymentLink = new PaymentLink();
paymentLink.setAmount(new BigDecimal("1.00"));
paymentLink.setCurrency("EUR");
paymentLink.setDescription("Product description");

Result<PaymentLink> result = client.createPaymentLink(paymentLink);

if (result.isValid()) {
    PaymentLink paymentLink = result.getItem();
}
else {
    CardinityError error = result.getCardinityError();
}
curl https://api.cardinity.com/v1/paymentLinks \
-H "Content-Type: application/json" \
-H "Authorization: OAuth <OAuth Details>" \
-d '{  
      "amount": "1.00",
      "currency": "EUR",
      "country": "LT",
      "description": "My order description"
    }
}'

# Response JSON
{
    "id": "b6aca927-0a13-4b0f-8d71-d3d140143216",
    "url": "https://checkout.cardinity.com/link/b6aca927-0a13-4b0f-8d71-d3d140143216",
    "amount": "1.00",
    "currency": "EUR",
    "country": "LT",
    "description": "My order description",
    "expiration_date": "2023-01-06T15:26:03.702Z",
    "multiple_use": false,
    "enabled": true
}
const Cardinity = require('cardinity-nodejs')
const PaymentLink = Cardinity.paymentLink()

const now = new Date()
const paymentLink = new PaymentLink({
  'amount': '50.00',
  'currency': 'EUR',
  'description': 'PAYMENT_LINK_DESCRIPTION',
  'country': 'LT',
  'expiration_date': new Date(now.setDate(now.getDate() + 7)),//Expires 1 week from now
  'multiple_use': true
})

if (paymentLink.errors) {
  // Deal with validation errors
} else {
  const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
  client.call(paymentLink).then(function(response){
    // Deal with response
  }).catch(function (error){
    // Deal with error
  });
}

To create a payment link you have to create a new payment object.

HTTP Request

POST https://api.cardinity.com/v1/paymentLinks

Request Attributes

Name Type Required Description
amount decimal Yes Amount to charge. Only positive values are allowed. Format: #0.00, two decimal places precision is required.
currency string Yes Three-letter ISO currency code representing the currency of the amount.
description string Yes Payment description provided by a merchant. Maximum length 255 characters.
country string No Country of a customer obtained via geolocation services or entered manually. ISO 3166-1 alpha-2 country code.
expiration_date datetime No Inclusive expiration date of the payment link as defined in RFC 3339 Section 5.6. UTC timezone. Payment link will be valid for 7 days by default.
multiple_use boolean No Specifies whether the payment link can be used for multiple payments. Default value is false.

Response

Returns a payment link object with response code 201 if creating payment link was successful.

Returns an error object otherwise. Response codes: 400, 401, 405, 500, 503.

To update a specific payment link you have to send a PATCH request providing an ID of a payment link.

curl --request PATCH https://api.cardinity.com/v1/paymentLinks/{PAYMENT_LINK_ID} \
-H "Content-Type: application/json" \
-H "Authorization: OAuth <OAuth Details>" \
-d '{
    "enabled": false
}'
PaymentLinkUpdate paymentLinkUpdate = new PaymentLinkUpdate();
paymentLinkUpdate.setEnabled(false);

Result<PaymentLink> result = client.updatePaymentLink(existingPaymentLinkId, paymentLinkUpdate);

if (result.isValid()) {
    PaymentLink paymentLink = result.getItem();
}
else {
    CardinityError error = result.getCardinityError();
}
<?php

use Cardinity\Client;
use Cardinity\Method\PaymentLink;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);


$method = new PaymentLink\Update(
    $payment_link_id,
    [
        'expiration_date' => "2023-01-06T15:26:03.702Z", //ISO 8601 datetime in UTC 
        'enabled' => true,  // true or false
    ]
);

/** @type Cardinity\Method\PaymentLink\PaymentLink */
$result = $client->call($method);

?>
const Cardinity = require('cardinity-nodejs')
const UpdatePaymentLink = Cardinity.updatePaymentLink()

const now = new Date()
const updatePaymentLink = new UpdatePaymentLink({
  'id': 'PAYMENT_LINK_UUID',
  'expiration_date': new Date(now.setDate(now.getDate() + 7)),//Expires 1 week from now
  'enabled': true
})

if (updatePaymentLink.errors) {
  // Deal with validation errors
} else {
  const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
  client.call(updatePaymentLink).then(function(response){
    // Deal with response
  }).catch(function (error){
    // Deal with error
  });
}

HTTP Request

PATCH https://api.cardinity.com/v1/paymentLinks/{PAYMENT_LINK_ID}

Request Attributes

Name Type Required Description
expiration_date datetime No Inclusive expiration date of the payment link. Payment link will be valid for 7 days by default.
enabled boolean No Specifies whether the payment link is enabled.

Response

Returns a payment link object with response code 200 if payment link was updated.

Returns an error object otherwise. Response codes: 400, 404.

To retrieve a specific payment link you have to send a GET request providing an ID of a payment link.

curl https://api.cardinity.com/v1/paymentLinks/{PAYMENT_LINK_ID} \
  -H "Content-Type: application/json" \
  -H "Authorization: OAuth <OAuth Details>"
Result<PaymentLink> result = client.getPaymentLink(existingPaymentLinkId);

if (result.isValid()) {
    PaymentLink paymentLink = result.getItem();
}
else {
    CardinityError error = result.getCardinityError();
}
<?php

use Cardinity\Client;
use Cardinity\Method\PaymentLink;

$client = Client::create([
    'consumerKey' => 'YOUR_CONSUMER_KEY',
    'consumerSecret' => 'YOUR_CONSUMER_SECRET',
]);

$method = new PaymentLink\Get($linkid);

/** @type Cardinity\Method\PaymentLink\PaymentLink */
$result = $client->call($method);

?>
const Cardinity = require('cardinity-nodejs')
const GetPaymentLink = Cardinity.getPaymentLink()

const getPaymentLink = new GetPaymentLink({
  'id': 'PAYMENT_LINK_UUID'
})

if (getPaymentLink.errors) {
  // Deal with validation errors
} else {
  const client = new Client('YOUR_CONSUMER_KEY', 'YOUR_CONSUMER_SECRET')
  client.call(getPaymentLink).then(function(response){
    // Deal with response
  }).catch(function (error){
    // Deal with error
  });
}

HTTP Request

GET https://api.cardinity.com/v1/paymentLinks/{PAYMENT_LINK_ID}

Response

Returns a payment link object with response code 200 if payment link was found.

Returns an error object with response code 404 otherwise.