When a customer is ready to checkout from your store, you should provide a HTML form or link that submits the required purchase information to the CityPay Paylink server. You can use whatever technology you desire however it is recommended that the page before submitting is kept to a standard HTML form.
Requests should be forward to the URL https://secure.citypay.com/paylink/paylink
Simple Html Form Integration
To pass information about a purchase to Paylink for payment processing, you must create a standard HTML form on your website encoded with application/x-www-form-urlencoded
which will POST
the required data.
Example Payment Form
<form action="https://secure.citypay.com/paylink/paylink" method="POST">
<input type="hidden" name="merchantid" value="12345" />
<input type="hidden" name="amount" value="19975" />
<input type="hidden" name="identifier" value="YOURID" />
<input type="hidden" name="email" value="merchant email address for payment notification" />
<input type="hidden" name="productInformation" value="Product information regarding the payment" />
<input type="submit" value="Pay By Card»" />
</form>
You will need to publish a page on your website similar to the example above.
You do not need to host the form on a secure server as all sensitive information is processed and obtained on the CityPay secure server. Paylink will still integrate with secure servers if you prefer to keep the checkout process secure.
When a customer is ready to pay, the customer presses a button on your site which when clicked submits the information for payment to the CityPay secure server which delivers the Paylink application. The form submission indicates a single purchase and a single total amount.
It is recommended to use a process which hides the data being sent, preventing the data being readily available using the view source feature of the browser. Paylink offers to options;
- A base64/xor encoding of the data
- A base64/AES cipher text of the data
Base64/XOR data encoding
As form details are displayed in your website source, CityPay also offer the ability to encode data between your site and Paylink using a tokenised method. This is recommended over the basic integration method to reduce the potential for tampering with the data. This method is not secure due to the simplicity of the encoding process used, for a more secure version use the AES cipher.
To be able to provide a token based integration method, integrators will provide all parameters tokenized into a simple password based xor and base64 token encoding system. Code is available in many languages for integrators to use. An example is included later in the document.
Integrators should follow the same parameter requirements as per a standard form integration however this encodes all http parameters such as: amount=9950&identifier=yourident into an xor and base64 encoded token, the end encoded string is provided as a parameter named "token".
The xor process uses the merchant licence key as the encryptor which is not known within the request.
The merchantid however must be still provided as a request parameter to ensure we are able to determine the account this is encoded for.
Example Encoded Payment Form
<form action="https://secure.citypay.com/paylink/paylink" method="POST">
<input type="hidden" name="merchantid" value="12345" />
<input type="hidden" name="token" value="GgkEFlhOFw8JGwZDXx4...VBApcdhMYGB0MQQ==" />
<input type="submit" value="Pay By Card»" />
</form>
When submitted a request that is xor encoded, the response data will be xor encoded as a token response parameter. A post back however will remain plain text
AES Encrypted Request
Although data is encrypted to our server, data is available within the view source of the browser. For a more secure solution, it is recommended to encrypt the contents of the payment request using strong encryption.
A payment request may be forwarded by encrypting the request parameters as a value. This data should be sent as a parameter called ciphertext
.
Example Encoded Payments Form
<form action="https://secure.citypay.com/paylink/paylink" method="POST">
<input type="hidden" name="merchantid" value="12345" />
<input type="hidden" name="ciphertext" value="ZDXx4GgkEFlhOFw8JGw...BApcdhMYGB0MQVA==" />
<input type="submit" value="Pay By Card»" />
</form>
You will require the following
- Your merchant id
- Your merchant licence key
- A salt provided by CityPay for each merchant account. The salt is linked to your licence key and will change on a licence key change.
The cipher algorithm
- Password based, in accordance with RFC2898 (PKCS#5 V2.0 Scheme 2). Your merchant licence key is your password.
- SHA-1 is used for the H-MAC calculation function
- Salt is provided to you in base64 encoding and should be kept secret.
- Iteration count is 10
- Key size is 256
- IV size is 128
- uses CBC block cipher
- uses PKCS#7 padding
- the resultant cipher is base64 encoded
NOTE: You are able to forward your own base64 salt as the parameter "random". You should encrypt the cipher text using this salt and send the cipher text base64 encoded as the parameter "ciphertext". Sending no random parameter will result in the default salts being used which are generated using internal logic to CityPay.
On the response/postback only the ciphertext is returned using your original salt.
The following examples illustrate the values that should be produced. To aid in debugging, the following values are determined by this process:
Key |
VGn54bfnAO7k6T/aKs46l0pAnCVPaPp1QdsFUFFnnUQ= |
IV |
Xze4Rc32CVu2OmnWIHFH8g== |
Ciphertext |
06uVHMiWUY7uWmbDvgzxLBbr75M7x3IcQQYONIg/H5lahvp7wQZ4u6pZY68SdqmHjftlvSEX7117r3FukI/VsQ== |
Java Encryption Example
private byte[] exampleEncryption() {
byte[] password = "thisisapassword".getBytes("UTF-8");
byte[] plaintext = "this is plaintext that is to be encrypted by the process".getBytes("UTF-8");
byte[] salt = Base64.decodeBase64FromString("QF1aFl1wOVtQQCJoeGpubzVpfGhocnMzezxLJFFzT2Y=");
// example using bouncy castle
PKCS5S2ParametersGenerator generator = new PKCS5S2ParametersGenerator();
generator.init(password, salt, 10);
ParametersWithIV iv = (ParametersWithIV) generator.generateDerivedParameters(256, 128);
RijndaelEngine engine = new RijndaelEngine();
BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(engine));
cipher.init(encrypt, iv);
byte[] out = new byte[cipher.getOutputSize(in.length)];
int outputLength = cipher.processBytes(in, 0, in.length, out, 0);
outputLength += cipher.doFinal(out, outputLength);
if (out.length == outputLength) { return out;}
byte[] finalBytes = new byte[outputLength];
System.arraycopy(out, 0, finalBytes, 0, outputLength);
return finalBytes;
}
C# Encryption Example
byte[] salt = Convert.FromBase64String("QF1aFl1wOVtQQCJoeGpubzVpfGhocnMzezxLJFFzT2Y=");
byte[] pass = Encoding.UTF8.GetBytes("thisisapassword");
byte[] plaintext = Encoding.UTF8.GetBytes("this is plaintext that is to be encrypted by the process");
Rfc2898DeriveBytes pkcs5 = new Rfc2898DeriveBytes(pass, salt, 10);
Rijndael aes = Rijndael.Create();
aes.Key = pkcs5.GetBytes(aes.KeySize / 8);
aes.IV = pkcs5.GetBytes(aes.BlockSize / 8);
// convert to ciphertext
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(plaintext, 0, plaintext.Length);
cs.Close();
// return the base64 version
return Convert.ToBase64String(ms.ToArray());
When sending an encrypted request, both the post back and redirect response data are encrypted using the ciphertext
parameter. This will require decryption before obtaining the necessary data.
Paylink Payment Request Parameters
The following parameters are the basic parameters required for every purchase request.
Name |
Data Type |
Requirement |
Definition |
---|---|---|---|
merchantid |
integer |
Required |
The merchant id issued by CityPay. Accounts that use multiple currencies may require multiple merchant ids. |
amount |
integer |
Required |
The payment amount must be provided in the lowest unit of currency for the specific currency of the merchant, with a variable length to a maximum of 12 digits. No decimal points to be included. For example with USD $10.24 insert amount=1024 |
identifier |
String |
Required |
The identifier as set by the merchant. This field can be used to cross reference between the merchant's system and the CityPay system. The identifier can be used to lookup transactions in the system. The provided String must be between 5 and 50 ASCII characters |
String |
Required |
The email address to forward a confirmation email to. Please note that this is an email for merchant use and contains information about the transaction this should not be supplied to the shopper. | |
productInformation |
String |
Required |
Information about the product that will be displayed back to the user. This information should be informative. The String must only be up to 50 ASCII characters |
paylink_meta_refresh_delay |
int |
Optional |
Provides the delay in seconds between redirecting from the confirmation page to your store. The default value is 7 |
Parameters provided are case-sensitive
Controlling the payment description
As an alternative to the productInformation
field, you are able to provide the parameter productDescription
. This will alow you to add text of your choice to the header of Paylink.
Due to potential cross site scripting attacks into paylink, no html tags are permitted in this field.
Custom Parameters
You are able to create your own custom set of parameters that are passed through the Paylink system and displayed to the user for completion. Additional information such as "company" etc can be added to the site for input by the card holder.
In addition, custom parameters may be passed through the system and returned within the response mechanism. Any unregisted parameter may be used for a displayed field. A field value which should be hidden from the user and used purely for callback should be prefixed with either '_' or 'paylink_callback'. This value will remain in the user's Paylink session and never be rendered to screen.
Optional Parameters
The following parameters are in addition to the default parameter listed.
Name |
Data Type |
Definition |
---|---|---|
billToAddress |
String |
You may pass the billing address of your customer through to the Paylink pages to save the user from completing their details |
billToPostcode |
String |
You may pass the billing postcode of your customer through to the Paylink pages to save the user from completing their details |
billToCountry |
String |
You may pass the billing country of your customer through to the Paylink pages to save the user from completing their details |
cardHolderName |
String |
You may pass the customer name through to the Paylink pages to save the user from completing their details |
customerEmail |
String |
You may pass the customer email address through to the Paylink pages to save the user from completing their details |
acsmode |
int |
For 3d secure transactions, you are provided with access to the CityPay merchant plug-in (MPI) which manages transactions through 3d secure authorisation. The subsequent access control server (ACS) may be shown embedded (iframe) or inline (as an entire page within the browser) within the page. A value of 1 will render the ACS inline and 0 embedded. The default value is inline. |
test |
boolean |
You may run a test against Paylink at any point by setting a value as test = true. Other values will be live. You will notice that paylink is in test mode by a banner displaying test mode in the application. If no parameter is supplied the default is test=true. |
paylink_postback |
URL |
The postback url for this request. The url may be provided to CityPay for configuration for the account however a request may override this by providing the parameter on the initial request. |
paylink_redirect |
URL |
The redirect URL for this request on completion or non completion of the transaction. If no alternative URL is provided to CityPay for configuration then CityPay will use the default Domain of the URL supplied for the account. However we strongly recommend that you override this by providing the parameter on the initial request. |
lock |
String |
You may provide the ability to prevent users from entering data in certain fields. Supply multiple values to the lock value which specify the name of the field to lock. Such as locking the customerEmail and billing details, provide 4 parameters named 'lock' with the value set as the parameter name. |
expireIn | int | An optional value in seconds which can be provided to force a payment session to expire in a given period of time. i.e. a value of 900 would be 15 minutes. Ordinarily sessions are maintained for 30 minutes from the last action that the user performed. This therefore could maintain the payment process over a longer than expected period should a card holder maintain session state. Using this value forces Paylink to calculate an expiry point based on the time that the request was received. Should a request to Paylink be made from the same session (and the session still exist), Paylink will notify the user that their payment time has expired. If no value or an invalid integer is supplied, the default session handling will be in place. |
Example Field Locking
...
<input type="hidden" name="lock" value="customerEmail" />
<input type="hidden" name="lock" value="billToAddress" />
<input type="hidden" name="lock" value="billToPostcode" />
<input type="hidden" name="lock" value="billToCountry" />
...
Sending a Test Request
See Testing Best Practices for further information
Using Pre-Auth with Paylink
Paylink can be configured using pre-authorisation allowing you to take payments which are not captured for settlement. Transactions will remain open until a corresponding completion or cancellation call is made. This may contain an amount that differs from the initial call.
The completion calls are made using other APIs other than Paylink.
Operational Policy Settings
Should you wish to bypass settings of your account, these can be provided using a bypass option. This should be provided as one or more option
parameters. The following values are supported:
value |
Description |
---|---|
BYPASS_AVS_POSTCODE |
Will bypass any AVS postcode requirement |
BYPASS_AVS_ADDRESS |
Will bypass any AVS address requirement |
BYPASS_CSC_REQUIRED |
Will bypass any CSC requirement |
BYPASS_3DSECURE |
Will bypass any 3DSecure requirement |
These values are considered sensitive as it can drastically affect your fraud settings. It is therefore recommended to ensure your request is AES encrypted when using these options