CoolPay Form

The CoolPay Form invokes our hosted payment window simply by submitting an HTML form.

The Payment Window is in reality just an API-client hosted in a PCI Level 1 certified environment.

Please see acquirer details for acquirer specific requirements.

Simple example

<!--
TIP: Append "/framed" to the action URL if you want to show the payment window in an iframe:

<form method=”POST” action=”https://payment.coolpay.com/framed”>
–>
<form action=”https://payment.coolpay.com” method=”POST”><input name=”version” type=”hidden” value=”v10″ />
<input name=”merchant_id” type=”hidden” value=”1″ />
<input name=”agreement_id” type=”hidden” value=”1″ />
<input name=”order_id” type=”hidden” value=”0001″ />
<input name=”amount” type=”hidden” value=”100″ />
<input name=”currency” type=”hidden” value=”DKK” />
<input name=”continueurl” type=”hidden” value=”http://shop.domain.tld/continue” />
<input name=”cancelurl” type=”hidden” value=”http://shop.domain.tld/cancel” />
<input name=”callbackurl” type=”hidden” value=”http://shop.domain.tld/callback” />
<input name=”checksum” type=”hidden” value=”ed93f788f699c42aefa8a6713794b4d347ff493ecce1aca660581fb1511a1816″ />
<input type=”submit” value=”Continue to payment…” /></form>

Parameters

ParameterValidationDescription
Rversion/^v[\d]{1,}b?$/The payment window version. Must currently be set to “v10”.
Rmerchant_id/^\d+$/This is your Merchant Account id
Ragreement_id/^\d+$/This is the User Agreement id. The checksum must be signed with the API-key belonging to this Agreement
Rorder_id/^[a-zA-Z0-9]{4,20}$/This is the order id generated in your system
Ramount/^[0-9]{1,9}$/The order total amount in its smallest unit
Rcurrency/^[A-Z]{3}$/The payment currency as the 3-letter ISO 4217 alphabetical code
Rcontinueurl!^https?://!The customer will be redirected to this URL upon a succesful payment. No data will be send to this URL.
Rcancelurl!^https?://!The customer will be redirected to this URL if the customer cancels the payment. No data will be send to this URL.
Ocallbackurl!^https?://!CoolPay will make a call back to this URL with the result of the payment. Overwrites the default callback url.
Otype!^(payment|subscription)!Type of transaction. Defaults to payment
language/^[a-z]{2}$/Set the language of the user interface. Defaults to English.
autocapture/^[0-1]{1}$/If set to 1, the payment will be captured automatically
autofee/^[0-1]{1}$/If set to 1, the fee charged by the acquirer will be calculated and added to the transaction amount
subscription/^[0-1]{1}$/DEPRECATED Create a subscription instead of a standard payment. Overrides type
Ddescription/^[\w\s\-\.]{1,20}$/A value by the merchant’s own choise. Used for identifying a subscription payment. Note: Required when ‘subscribe’ is set
payment_methods/^[a-zA-Z,\-]$/Lock to some payment method(s). Multiple payment methods allowed by comma separation
acquirer/^[a-z]+$/Lock to a specific acquirer.
Obranding_id/[^d]$/Use this branding. Overwrites the default branding
google_analytics_tracking_id/[^d]$/Your Google Analytics tracking ID
google_analytics_client_id/[^d]$/Your Google Analytics client ID
variablesCustom variables set on the created payment. Submit them as nested params: variables[myvar]=somevalue
deadline/^\d+$/Deadline in seconds for the cardholder to complete the order. If deadline is reached, cardholder will be taken to cancelurl and a callback is sent. The operation type of the callback is deadline
text_on_statementText that will be placed on cardholder’s bank statement (MAX 22 ASCII characters and only supported by Clearhaus currently).
customer_emailCustomer email address (Required for PayPal credit-card payments)
Invoice address
invoice_address_selection/^[0|1]$Receive invoice address information from acquirer.
Will be available and fetchable on transaction upon authorization(Currently only MobilePay and PayPal)
invoice_address[name]Invoice – Name
invoice_address[att]Invoice – Attention
invoice_address[street]Invoice – Street
invoice_address[house_number]Invoice – House number (DEU and NLD)
invoice_address[house_extension]Invoice – House extension (NLD)
invoice_address[zip_code]Invoice – ZIP code
invoice_address[city]Invoice – City
invoice_address[region]Invoice – Region
invoice_address[country_code]Invoice – Country code (ISO-3166-1 Alpha 3)
invoice_address[vat_no]Invoice – VAT number
invoice_address[phone_number]Invoice – Phone number
invoice_address[mobile_number]Invoice – Mobile number
invoice_address[email]Invoice – Email address
Shipping address
invoice_address_selection/^[0|1]$Receive shipping address information from acquirer.
Will be available and fetchable on transaction upon authorization(Currently only MobilePay and PayPal)
shipping_address[name]Shipping – Name
shipping_address[att]Shipping – Attension
shipping_address[street]Shipping – Street
shipping_address[house_number]Shipping – House number (DEU and NLD)
shipping_address[house_extension]Shipping – House extension (NLD)
shipping_address[zip_code]Shipping – ZIP code
shipping_address[city]Shipping – City
shipping_address[region]Shipping – Region
shipping_address[country_code]Shipping – Country code (ISO-3166-1 Alpha 3)
shipping_address[vat_no]Shipping – VAT number
shipping_address[phone_number]Shipping – Phone number
shipping_address[mobile_number]Shipping – Mobile number
shipping_address[email]Shipping – Email address
Basket
basket[[0-9]+]Array of basket items
basket[[0-9]+][qty]/^[0-9]+$/Basket item quantity
basket[[0-9]+][item_no]Basket item number (SKU)
basket[[0-9]+][item_name]Basket item Name
basket[[0-9]+][item_price]/^[0-9]{1,9}$/Basket item total price in its smallest unit (including VAT)
basket[[0-9]+][vat_rate]/^0\.[0-9]{2}$/Basket item VAT rate (ex. 0.25 for 25%)
Branding Config
branding_config[enable_card_holder_field]/^[0-1]{1}$/If set to 1, the card holder can fill in their name in the payment window
branding_config[enable_3d_card_field]/^[0-1]{1}$/If set to 1, the card holder can choose to pay using 3D Secure.
branding_config[title]Set title of payment window
branding_config[autojump]/^[0-1]{1}$/It set to 1, the browser autojumps between input fields
Shop system
shopsystem[name]Shop system module name
shopsystem[version]Shop system module version
Checksum
Rchecksum/^[a-z0-9]{64}$/The calculated checksum of your form data

R = Required field

O = Overwrites standard/configured value

D = Depends on other fields


Checksum

The CoolPay Form employs a checksum mechanism to

  • authenticate you and your system
  • ensure that the data has not been tangled with

To calculate the checksum you must

  • sort the request data key/value-pairs in the keys’ alphabetical order – All request data must be included in the checksum calculation
  • concatenate the values (including empty values as empty strings) seperated by a single space
  • calculate the checksum by using HMAC with SHA256 as the cryptographic hash function. The HMAC is signed with a API key from one of your User Agreements – most likely the “Payment Window” system user.

The checksum is added to the request data. When CoolPay receives the request a checksum is calculated in the exact same way. If this checksum matches the one provided in the request data the processing of the request continues.

Note: The checksum is calculated only from CoolPay specific parameters. If you for some reason submit other parameters, those will not be part of the checksum.

 

RubyPHPPerlPython.NETNodejS

<code>
require 'openssl'

def sign(params, api_key)
  flattened_params = flatten_params(params)
  values = flattened_params.sort.map { |_, value| value }
  base = values.join(' ')

  OpenSSL::HMAC.hexdigest('sha256', api_key, base)
end

def flatten_params(obj, result = {}, path = [])
  case obj
  when Hash
    obj.each do |k, v|
      flatten_params(v, result, [*path, k])
    end
  when Array
    obj.each_with_index do |v, i|
      flatten_params(v, result, [*path, i])
    end
  else
    result[path.map{|p| "[#{p}]"}.join.to_sym] = obj
  end
  result
end

params = {
  :version      => "v10",
  :merchant_id  => 1,
  :agreement_id => 1,
  :order_id     => "0001",
  :amount       => 100,
  :currency     => "DKK",
  :continueurl  => "http://shop.domain.tld/continue",
  :cancelurl    => "http://shop.domain.tld/cancel",
  :callbackurl  => "http://shop.domain.tld/callback",
  :variables    => {
    :a => 'b',
    :c => 'd'
  }
}

params[:checksum] = sign(params, "your_secret_payment_window_api_key")
</code>

<code>
<?php
function sign($params, $api_key) {
    $flattened_params = flatten_params($params);
    ksort($flattened_params);
    $base = implode(" ", $flattened_params);

    return hash_hmac("sha256", $base, $api_key);
}

function flatten_params($obj, $result = array(), $path = array()) {
    if (is_array($obj)) {
        foreach ($obj as $k => $v) {
            $result = array_merge($result, flatten_params($v, $result, array_merge($path, array($k))));
        }
    } else {
        $result[implode("", array_map(function($p) { return "[{$p}]"; }, $path))] = $obj;
    }

    return $result;
}

$params = array(
  "version"      => "v10",
  "merchant_id"  => 1,
  "agreement_id" => 1,
  "order_id"     => "0001",
  "amount"       => 100,
  "currency"     => "DKK",
  "continueurl" => "http://shop.domain.tld/continue",
  "cancelurl"   => "http://shop.domain.tld/cancel",
  "callbackurl" => "http://shop.domain.tld/callback",
);

$params["checksum"] = sign($params, "your_secret_payment_window_api_key");
?>
</code>

<code>
use Digest::SHA qw(hmac_sha256_hex);

sub sign {
    my ($params, $api_key) = @_;
    my $base = join " ", @$params{ sort keys %$params };

    hmac_sha256_hex($base, $api_key);
}

my $params = {
    version      => "v10",
    merchant_id  => 1,
    agreement_id => 1,
    order_id     => "0001",
    amount       => 100,
    currency     => "DKK",
    continueurl => "http://shop.domain.tld/continue",
    cancelurl   => "http://shop.domain.tld/cancel",
    callbackurl => "http://shop.domain.tld/callback"
};

$params->{checksum} = sign($params, "your_secret_payment_window_api_key");
</code>

<code>
import hmac, hashlib, sys
PY3 = sys.version_info[0] >= 3

def sign(params, api_key):
  items = sorted(params.items(), key=lambda x: x[0])
  base = ' '.join([ str(pair[1]) for pair in items])

  if PY3:
    return hmac.new(
      bytes(api_key, "utf-8"),
      bytes(base, "utf-8"),
      hashlib.sha256
    ).hexdigest()
  else:
    return hmac.new(api_key, base, hashlib.sha256).hexdigest()

params = dict(
 version      = "v10",
 merchant_id  = 1,
 agreement_id = 1,
 order_id     = "0001",
 amount       = 100,
 currency     = "DKK",
 continueurl = "http://shop.domain.tld/continue",
 cancelurl   = "http://shop.domain.tld/cancel",
 callbackurl = "http://shop.domain.tld/callback"
)

params['checksum'] = sign(params, "your_secret_payment_window_api_key")
</code>

<code>

private string Sign(Dictionary<string, string> params, string api_key) {
    var result = String.Join(" ", params.OrderBy(c => c.Key).Select(c => c.Value).ToArray());
    var e = Encoding.UTF8;
    var hmac = new HMACSHA256(e.GetBytes(api_key));
    byte[] b = hmac.ComputeHash(e.GetBytes(result));
    var s = new StringBuilder();
    for (int i = 0; i < b.Length; i++)
    {
        s.Append(b[i].ToString("x2"));
    }
    return s.ToString();
}

public ActionResult CoolPay() {
    var params = new Dictionary<string, string>();
    params.Add("version", "v10");
    params.Add("merchant_id", "1");
    params.Add("agreement_id", "1");
    params.Add("order_id", "0001");
    params.Add("amount", "100");
    params.Add("currency", "DKK");
    params.Add("continueurl", "http://shop.domain.tld/continue");
    params.Add("cancelurl", "http://shop.domain.tld/cancel");
    params.Add("callbackurl", "http://shop.domain.tld/callback");
    params.Add("language", "da");
    params.Add("autocapture", "1");

    ViewBag.Language = language;
    ViewBag.Autocapture = autocapture;
    ViewBag.OrderId = orderId;
    ViewBag.MerchantId = merchantId;
    ViewBag.AgreementId = agreementId;
    ViewBag.Amount = amount;
    ViewBag.Currency = currency;
    ViewBag.ContinueUrl = continueUrl;
    ViewBag.CancelUrl = cancelUrl;
    ViewBag.CallbackUrl = callbackUrl;
    ViewBag.Checksum = Sign(params, "your_secret_payment_window_api_key");

    return View();
}
</code>

<code>
const crypto = require('crypto');

function sign(params, api_key) {
  var flattened_params = flatten_params(params);
  var values = Object.keys(flattened_params).sort().map(key => flattened_params[key]).join(' ');
  return crypto.createHmac('sha256', api_key).update(values).digest('hex');
}

function flatten_params(params, result, path) {
  result = result || {};
  path = path || [];
  if (params instanceof Object) {
    var k;
    for (k in params) {
      flatten_params(params[k], result, [...path, k]);
    }
  } else {
    result[path.map(key => '[' + key + ']').join()] = params;
  }
  return result;
}

var params = {
  version: 'v10',
  merchant_id: 1,
  agreement_id: 1,
  amount: 100,
  currency: 'DKK',
  order_id: '0001',
  callbackurl: 'http://shop.domain.tld/callback',
  cancelurl: 'http://shop.domain.tld/cancel',
  continueurl: 'http://shop.domain.tld/continue',
  variables: {
    a: 'b',
    c: 'd'
  }
};

params.checksum = sign(params, 'your_secret_payment_window_api_key');
</code>

Opret bruger