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.
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 |
holder
, exp_month
, exp_year
, cvc
values can be set to any data you want. If those values passes 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
- create a valid payment with
amount
less than150.00
.
Failed Payment
- status
declined
: Amount larger than150.00
will trigger a declined payment e.g.150.01
. - incorrect
pan
: Use a number that fails the Luhn check, e.g.4242424242424241
. - invalid
exp_month
: Use an invalid month e.g.13
. - invalid_
exp_year
: Use a year in the past e.g.1970
. - invalid
cvc
: Use a two digit number e.g.99
. - invalid
amount
: Use less than0.50
e.g.0.49
.
3D Secure Payment
- create a valid payment with
description
attribute set to3ds2-pass
or3ds2-fail
(depending on the outcome you want). - response will be a payment in a pending state with
authorization_information
object provided. - afterwards finalize the payment (send a PATCH request) with
cres
set to3ds2-pass
or3ds2-fail
. - the outcome of the 3D Secure authorization will be decided by
cres
value sent.
Failed refund / void / settlement
- set description attribute to
fail
.
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: Do not Honor",
"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._ |
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 | No | Email address of the cardholder. |
mobile_phone_number | string | No | Mobile phone number provided by the cardholder. |
work_phone_number | string | No | Work phone number provided by the cardholder. |
home_phone_number | string | No | Home phone number provided by the cardholder. |
Response
Returns a payment object if:
- Payment was successful - response code:
201
- Payment is in a pending state - response code:
202
- Payment was declined - response code:
402
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
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
- Create a new payment providing
threeds2_data
parameter. - Check the returned payment object status
- If the status is
approved
ordeclined
, the payment process is complete and no further steps are required. - If the status is
pending
(HTTP Response code202
), 3D-Secure authorization is required.
- If the status is
- The returned payment object will have
threeds2_data
object assigned, which will haveacs_url
andcreq
attributes assigned. - 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 thecreq
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.
- Set form action parameter to the
- Once redirected, the cardholder will perform necessary steps to authenticate. The exact steps are determined by the issuing bank.
- 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.
- Send a PATCH request to Cardinity as described in Finalize Pending Payment providing
cres
parameter data received from ACS ascres
attribute. - 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:
- Payment was successful - response code:
201
- Payment was declined - response code:
402
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:
- Payment was successful - response code:
201
- Payment was declined - response code:
402
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 or declined ._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:
- Refund succeeded - response code:
201
- Refund was declined - response code:
402
Returns an error object otherwise. Response codes: 400
, 401
, 405
, 500
, 503
.
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:
- Settlement succeeded - response code:
201
- Settlement was declined - response code:
402
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:
- Void succeeded - response code:
201
- Void was declined - response code:
402
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 accepted but is in a pending state. You must provide additional information to complete this payment. |
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
All requests and responses must be signed and verified using HMAC-SHA256
- key - Project Secret
- message - String made up of request/response key-value pairs that are not empty, joined in a single string in ascending order, according to the key
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",
"language": "EN",
"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";
$language = "EN";
$currency = "EUR";
$description = "Purchase Description";
$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,
"language" => $language,
"order_id" => $order_id,
"description" => $description,
"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("language", "GB");
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 language = "EN"
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,
language: language,
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="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. |
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. |
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.
Payment Link Object
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 |
Create new payment link
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
.
Update existing payment link
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
.
Get existing payment link
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.