Paylink Api

CityPay Paylink makes online e-commerce easier to implement by providing a hosted form to handle the card payment process directly with the cardholder's browser, allowing you to concentrate on your business whilst allowing CityPay to manage the payment process on your behalf.

  1. Simplified payment solutions.

  2. payment processing is handled by our secure web servers adding security and confidence to your shoppers.

  3. 3D-Secure authentication is available within the application without any difficult MPI integration, allowing for immediate Verified by Visa and MasterCard SecureCode processing.

  4. customisation may be performed on the secure payment form.

  5. significantly reduced technical and financial overheads associated with software implementation and PCI compliance.

  6. reduced time-to-market.

PUT/paylink/{token}/cancel

Marks a Paylink Token as cancelled. This cancels the Token for any future request for processing.

    Path Attributes

200 OK Acknowledgement

    Response Attributes

Response

Acknowledgement
{
  "code":"1201",
  "context":"aspiu352908ns47n343598bads",
  "identifier":"95b857a1-5955-4b86-963c-5a6dbfc4fb95",
  "message":"Token Cancelled"
}
PUT/paylink/{token}/close

Marks a Paylink Token as closed. This closes the Token for any future action and the Token will not appear in any status request calls.

    Path Attributes

200 OK Acknowledgement

    Response Attributes

Response

Acknowledgement
{
  "code":"1201",
  "context":"aspiu352908ns47n343598bads",
  "identifier":"95b857a1-5955-4b86-963c-5a6dbfc4fb95",
  "message":"Token closed"
}
POST/paylink/bill-payment

CityPay Paylink supports invoice and bill payment services by allowing merchants to raise an invoice in their systems and associate the invoice with a Paylink checkout token. CityPay will co-ordinate the checkout flow in relationship with your customer. Our bill payment solution may be used to streamline the payment flow with cardholders to allow your invoice to be paid promptly and via multiple payment channels such as Card Payment, Apple Pay or Google Pay.

The bill payment service allows

  1. setting up notification paths to an end customer, such as SMS or Email
  2. enabling attachments to be included with Paylink tokens
  3. produce chaser notifications for unpaid invoices
  4. provide callbacks for notification of the payment of an invoice
  5. support part payments against an invoice
  6. support of field guards to protect the payment screen
  7. support of status reporting on tokens
  8. URL short codes for SMS notifications
Paylink BPSv2 Overview

Notification Paths

Notification paths can be provided which identify the channels for communication of the invoice availability. Up to 3 notification paths may be provided per request.

Each notification uses a template to generate the body of the message. This allows for variable text to be sent out and customised for each call.

SMS messages use URL Short Codes (USC) as a payment link to the invoice payment page. This allows for a standard payment URL to be shortened for optimised usage in SMS. For instance a URL of https://checkout.citypay.com/PL1234/s348yb8yna4a48n2f8nq2f3msgyng-psn348ynaw8ynaw/en becomes citypay.com/Za48na3x. Each USC is unique however it is a requirement that each USC generated is protected with Field Guards to ensure that sensitive data (such as customer contact details and GDPR) is protected.

To send a notification path, append a notification-path property to the request.

 {
  "sms_notification_path": {
      "to": "+441534884000"
  },
  "email_notification_path": {
      "to": ["help-desk@citypay.com"],
      "cc": ["third-party@citypay.com"],
      "reply": ["help@my-company.com"]
  }
}

Notification paths trigger a number of events which are stored as part of the timeline of events of a Paylink token

  • BillPaymentSmsNotificationQueued - identifies when an SMS notification has been queued for delivery

  • BillPaymentSmsNotificationSent - identifies when an SMS notification has been sent to the upstream network

  • BillPaymentSmsNotificationDelivered - identifies when an SMS notification has been delivered as notified by the upstream network

  • BillPaymentSmsNotificationUndelivered - identifies when an SMS notification has undelivered notification is provided by the upstream network

  • BillPaymentSmsNotificationFailure - identifies when an SMS notification has failed

  • BillPaymentEmailNotificationQueued - identifies when an email notification has been queued for delivery

  • BillPaymentEmailNotificationSent - identifies when an email notification has been accepted by our SMS forwarder

  • BillPaymentEmailNotificationFailure - identifies when an email notification has failed delivery

SMS Notification Path

SMS originated from a CityPay pool of numbers and by default only sends to country codes where the service is registered. SMSs may contain a From field which is configured as part of you onboarding and have a name associated to identify the service origin. For example if your business is titled Health Surgery Ltd the SMS may be sent to originate from Health Surgery.

SMS is also configured for a "polite mode". This mode ensures that SMSs aren't sent in the middle of the night when backend services ordinarily run. SMSs will be queued until the time range is deemed as polite. Normally this is between 8am and 9pm.

FieldTypeUsageDescription
templatestringReservedAn optional template name to use a template other than the default.
tostringReservedThe phone number in E.164 format to send the message to.

Email Notification Paths

FieldTypeUsageDescription
templatestringReservedAn optional template name to use a template other than the default.
tostring[]RequiredAn array of email addresses to be used for delivery. A maximum of 5 addresses can be added.
ccstring[]RequiredAn array of email addresses to be used for cc delivery. A maximum of 5 addresses can be added.
bccstring[]RequiredAn array of email addresses to be used for bcc delivery. A maximum of 5 addresses can be added.
reply_tostring[]RequiredAn array of email addresses to be used for the Reply-To header of an email.

Field Guards

To ensure that invoices are paid by the intended recipient, Paylink supports the addition of Field Guards.

A Field Guard is an intended field which is to be used as a form of guarded authentication. More than 1 field can be requested.

Paylink Field Guards

To determine the source value of the field, each field name is searched in the order of

  • identifier
  • cardholder data such as name
  • custom parameters
  • pass through data

If no field values are found, the token request returns a D041 validation error.

Authentication and Validation

When values are entered by the user, resultant comparisons are performed by

  1. Transliteration of both the source value and entered value. For example, names with accents (e.g. é will become e)
  2. Only Alphanumeric values are retained any whitespace or special characters are ignored
  3. Case is ignored

Should all values match, the user is authenticated and can continue to the payment form rendered by the Paylink server.

On successful login, an event will be added to include that the access guard validated access.

Access-Key

To ensure that a user does not need to re-enter these values multiple times, a cookie is pushed to the user’s browser with an access-key digest value. This value will be presented to the server on each refresh therefore allowing the guard to accept the call. Each value is uniquely stored per merchant account and cannot be shared cross merchant. The lifetime of the cookie is set to 24 hours.

Brute Force Prevention

To prevent multiple calls hitting the server, attempting a brute force attack, the login process

  1. is fronted by a contemporary web application firewall
  2. creates an event for each token when access was denied
  3. should the number of failed events breach more than 5 in 30 minutes, the token is locked for an hour
  4. should the number of events breach more than 20 the token is fully locked

Attachments

Attachments can be included in the request in 2 ways

  1. Via a data element direct in the request
  2. Via a URL upload to a provided pre-signed URL

The decision of which option is dependent on the size of the attachments. Should the attachment size be greater than 32kb a URL upload is required. Small attachments can be included in the JSON request. This is to prevent our web firewall from blocking your request and to also ensure efficiency of larger file uploads.

There is a maximum of 3 attachments that can be added to a request.

    [{
      "filename": "invoice1.pdf",
      "mime-type": "application/pdf"
    },{
      "filename": "invoice2.pdf",
      "data": "b4sE64Enc0dEd...=",
      "mime-type": "application/pdf"
    }]
FieldTypeUsageDescription
filenamestringRequiredThe name of the attachment normally taken from the filename. You should not include the filename path as appropriate
datastringOptionalbase64 encoding of the file if less than 32kb in size
mime-typestringRequiredThe mime type of the attachment as defined in RFC 9110. Currently only application/pdf is supported

Attachment Result

A result of an attachment specifies whether the attachment was successfully added or whether a further upload is requried

FieldTypeUsageDescription
resultstringRequiredOK should the file have uploaded or UPLOAD if the file is required to be uploaded.
namestringRequiredThe filename that was specified in the upload process
urlstringOptionalShould an upload be required, this URL is available for an upload to be issued. The URL is only available for uploads for 24 hours from creation.

    Request Attributes

200 OK PaylinkTokenCreated

    Response Attributes

Request

PaylinkBillPaymentTokenRequest
{
  "addressee":"",
  "attachments":{
    "data":"",
    "filename":"",
    "mime_type":"",
    "name":"",
    "retention":808
  },
  "descriptor":"",
  "due":"2024-05-15",
  "email_notification_path":{
    "bcc":[
      "email@domain.com"
    ],
    "cc":[
      "email@domain.com"
    ],
    "reply_to":[
      "email@domain.com"
    ],
    "template":"",
    "to":[
      "email@domain.com"
    ]
  },
  "memo":"",
  "request":{
    "accountno":"",
    "amount":581,
    "cardholder":{
      "accept_headers":"",
      "address":{
        "address1":"79 Parliament St",
        "address2":"Westminster",
        "address3":"",
        "area":"London",
        "country":"GB",
        "label":"Head Office",
        "postcode":"L1 789"
      },
      "company":"Acme Ltd",
      "email":"card.holder@citypay.com",
      "firstname":"John",
      "lastname":"Smith",
      "mobile_no":"+447790123456",
      "remote_addr":"",
      "title":"Mr",
      "user_agent":""
    },
    "cart":{
      "contents":{
        "amount":1200,
        "brand":"",
        "category":"Fiction",
        "count":1,
        "label":"Percy Hotter",
        "max":113,
        "sku":"AO12345678",
        "variant":""
      },
      "coupon":"",
      "mode":2,
      "product_description":"Book Order",
      "product_information":"Book Order",
      "shipping":1500,
      "tax":1200
    },
    "client_version":"",
    "config":{
      "acs_mode":"iframe",
      "custom_params":{
        "entry_mode":"",
        "field_type":"text",
        "group":"Extra Information",
        "label":"Custom Field 1",
        "locked":true,
        "name":"custom_field_1",
        "order":1,
        "pattern":"",
        "placeholder":"Enter a Custom Value",
        "required":true,
        "value":"initial-value"
      },
      "descriptor":"",
      "expire_in":"1d",
      "field_guard":{
        "field_type":"",
        "label":"",
        "maxlen":352,
        "minlen":994,
        "name":"",
        "regex":"",
        "value":""
      },
      "lock_params":{
        
      },
      "merch_logo":"",
      "merch_terms":"",
      "options":{
        
      },
      "part_payments":{
        "enabled":"",
        "floor":"",
        "max":"",
        "max_rate":"",
        "min":"",
        "min_rate":""
      },
      "pass_through_data":{
        
      },
      "pass_through_headers":{
        
      },
      "postback":"",
      "postback_password":"",
      "postback_policy":"",
      "postback_username":"",
      "redirect_delay":592,
      "redirect_failure":"",
      "redirect_success":"",
      "renderer":"",
      "return_params":true,
      "ui":{
        "address_mandatory":true,
        "form_auto_complete":"on",
        "ordering":10,
        "postcode_mandatory":true
      }
    },
    "currency":"GBP",
    "email":"card.holder@citypay.com",
    "identifier":"95b857a1-5955-4b86-963c-5a6dbfc4fb95",
    "merchantid":11223344,
    "recurring":false,
    "subscription_id":"",
    "tx_type":""
  },
  "sms_notification_path":{
    "template":"",
    "to":""
  }
}

Response

PaylinkTokenCreated
{
  "date_created":"2024-05-15T19:03:19Z",
  "errors":{
    "code":"001",
    "msg":"An example error response"
  },
  "id":"00000000-0000-0000-0000-000000000000",
  "identifier":"95b857a1-5955-4b86-963c-5a6dbfc4fb95",
  "mode":"test",
  "qrcode":"https://payments.citypay.com/AAAAAAA/AAAZZZCCCDDDEEE/qrcode",
  "result":0,
  "server_version":"x.x.x",
  "source":"x.x.x.x",
  "token":"AAAZZZCCCDDDEEE",
  "url":"https://payments.citypay.com/AAAAAAA/AAAZZZCCCDDDEEE"
}
POST/paylink/create

Creates a Paylink token from the CityPay API.

    Request Attributes

200 OK PaylinkTokenCreated

    Response Attributes

Request

PaylinkTokenRequestModel
{
  "amount":806,
  "identifier":"95b857a1-5955-4b86-963c-5a6dbfc4fb95",
  "merchantid":11223344
}

Response

PaylinkTokenCreated
{
  "date_created":"2024-05-15T19:03:19Z",
  "errors":{
    "code":"001",
    "msg":"An example error response"
  },
  "id":"00000000-0000-0000-0000-000000000000",
  "identifier":"95b857a1-5955-4b86-963c-5a6dbfc4fb95",
  "mode":"test",
  "qrcode":"https://payments.citypay.com/AAAAAAA/AAAZZZCCCDDDEEE/qrcode",
  "result":0,
  "server_version":"x.x.x",
  "source":"x.x.x.x",
  "token":"AAAZZZCCCDDDEEE",
  "url":"https://payments.citypay.com/AAAAAAA/AAAZZZCCCDDDEEE"
}
POST/paylink/{token}/adjustment

Adjusts a TokenRequest's amount value when for instance

  1. a Token is created and the shopping cart is updated
  2. an invoice is adjusted either due to part payment or due to increased incurred costs.

    Path Attributes

    Request Attributes

200 OK Acknowledgement

    Response Attributes

Request

PaylinkAdjustmentRequest
{
  "amount":19995,
  "identifier":"95b857a1-5955-4b86-963c-5a6dbfc4fb95",
  "reason":""
}

Response

Acknowledgement
{
  "code":"701",
  "context":"aspiu352908ns47n343598bads",
  "identifier":"95b857a1-5955-4b86-963c-5a6dbfc4fb95",
  "message":"Amount changed to 199.95"
}
POST/paylink/token/changes

Allows for the changes to a pre-existing token.

    Request Attributes

200 OK PaylinkTokenStatusChangeResponse

    Response Attributes

Request

PaylinkTokenStatusChangeRequest
{
  "after":"2024-05-15T19:03:19Z",
  "maxResults":50,
  "merchantid":11223344,
  "nextToken":"n34liuwn435tUAGFNg34yn...",
  "orderBy":"date"
}

Response

PaylinkTokenStatusChangeResponse
{
  "count":25,
  "maxResults":50,
  "nextToken":"n34liuwn435tUAGFNg34yn...",
  "tokens":[
    {
      "amount_paid":252,
      "auth_code":"",
      "card":"Visa/0002",
      "created":"2024-05-15T19:03:19Z",
      "datetime":"2024-05-15T19:03:19Z",
      "identifier":"95b857a1-5955-4b86-963c-5a6dbfc4fb95",
      "is_attachment":true,
      "is_cancelled":true,
      "is_closed":true,
      "is_customer_receipt_email_sent":true,
      "is_email_sent":false,
      "is_expired":false,
      "is_form_viewed":true,
      "is_merchant_notification_email_sent":false,
      "is_open_for_payment":false,
      "is_paid":false,
      "is_payment_attempted":false,
      "is_postback_ok":false,
      "is_request_challenged":false,
      "is_sms_sent":true,
      "is_validated":false,
      "last_event_date_time":"2024-05-15T19:03:19Z",
      "last_payment_result":"",
      "mid":11223344,
      "payment_attempts_count":59,
      "state_history":[
        {
          "datetime":"2024-05-15T19:03:19Z",
          "message":"message on this state",
          "state":"FormInput"
        }
      ],
      "token":"",
      "trans_no":995
    }
  ]
}
GET/paylink/{token}/status

Obtains the full status of a given Paylink Token.

    Path Attributes

200 OK PaylinkTokenStatus

    Response Attributes

Response

PaylinkTokenStatus
{
  "amount_paid":237,
  "auth_code":"",
  "card":"Visa/0002",
  "created":"2024-05-15T19:03:19Z",
  "datetime":"2024-05-15T19:03:19Z",
  "identifier":"95b857a1-5955-4b86-963c-5a6dbfc4fb95",
  "is_attachment":false,
  "is_cancelled":true,
  "is_closed":false,
  "is_customer_receipt_email_sent":true,
  "is_email_sent":false,
  "is_expired":false,
  "is_form_viewed":true,
  "is_merchant_notification_email_sent":false,
  "is_open_for_payment":true,
  "is_paid":false,
  "is_payment_attempted":true,
  "is_postback_ok":false,
  "is_request_challenged":true,
  "is_sms_sent":true,
  "is_validated":false,
  "last_event_date_time":"2024-05-15T19:03:19Z",
  "last_payment_result":"",
  "mid":11223344,
  "payment_attempts_count":893,
  "state_history":[
    {
      "datetime":"2024-05-15T19:03:19Z",
      "message":"message on this state",
      "state":"FormInput"
    }
  ],
  "token":"",
  "trans_no":912
}
PUT/paylink/{token}/purge-attachments

Purges any attachments for a token for GDPR or DP reasons.

    Path Attributes

200 OK Acknowledgement

    Response Attributes

Response

Acknowledgement
{
  "code":"1204",
  "context":"aspiu352908ns47n343598bads",
  "identifier":"95b857a1-5955-4b86-963c-5a6dbfc4fb95",
  "message":"Purged 1 attachment"
}
PUT/paylink/{token}/reconciled

Marks a Paylink Token as reconciled when reconciliation is performed on the merchant's side.

    Path Attributes

200 OK Acknowledgement

    Response Attributes

Response

Acknowledgement
{
  "code":"1202",
  "context":"aspiu352908ns47n343598bads",
  "identifier":"95b857a1-5955-4b86-963c-5a6dbfc4fb95",
  "message":"Token Reconciled"
}
PUT/paylink/{token}/reopen

Allows for a Paylink Token to be reopened if a Token has been previously closed and payment has not yet been made.

    Path Attributes

200 OK Acknowledgement

    Response Attributes

Response

Acknowledgement
{
  "code":"1203",
  "context":"aspiu352908ns47n343598bads",
  "identifier":"95b857a1-5955-4b86-963c-5a6dbfc4fb95",
  "message":"Token Reopened"
}
POST/paylink/{token}/resend-notification

Resend a notification for Paylink Token.

    Path Attributes

    Request Attributes

200 OK Acknowledgement

    Response Attributes

Request

PaylinkResendNotificationRequest
{
  "email":true,
  "sms":false
}

Response

Acknowledgement
{
  "code":"1207",
  "context":"aspiu352908ns47n343598bads",
  "identifier":"95b857a1-5955-4b86-963c-5a6dbfc4fb95",
  "message":"Queued Email"
}