# Building an Adapter

# Operations

Operations are the basic unit of execution of an adapter.

An operation consists of four main parts:

  • Request message

  • Pre-flight online script

  • Response message

  • Respose handler script

# Execution

Adapter Execution

The above diagram shows the execution sequence of an operation. At the start of an operation, a context is built containing the global Javascrip variable bindings. Each operation will contain a set of predefined global variable names starting with $ prefix that the framework will provide i.e. $TRANSACTION. In addition, any constants defined by the developer will also be added to the context. Throughout the execution of an operation, your Javascript will have access to all these global variables. Your script will be able to read from as well as modify these variables as they execute.

NOTE

The scope of a context is within a single transaction. Once a transaction executes to completion, the context will be discarded. Any new execution will begin with a new context.

# Request

A request message is sent to the acquiring host to request a financial transaction. The request is defined by the format and consists of many fields making up the request defined by the developer. Each field will contain either a constant or a Javascript expression to calculate its value during execution time.

# Pre-flight Online Script

A request is considered online only if it requires an explicit call out to the acquiring host. The pre-flight Online Script is responsible for determining whether the transaction should be online or not. Certain acquirers does not require all transactions to be online. For example, the refund operation does not require an online call in certain scenarios for some acquirer. If the transaction is offline, this script logic should return as its value a false to signal to the Letgo framework that an external call is not necessary and that the transaction should just be logged at Poynt.

NOTE

If undefined, the default behavior is to always go online.

# Response

All operations, in additional to having a request, must also have a response. The response message defines the format and the fields that makes up the message from the acquiring host. Unlike the request, the response only contains the field definition format (without any script). The Letgo framework will parse the acquiring host's response based on this definition.

# Response Handler Script

A response handler script is responsible for determining whether the operation execution was a success. It is always required and is executed right after the response message is parsed.

# Standard Operations

The following are standard operations that all adapters should define:

  • Authorization: to reserved or debit funds from a card
  • Adjust: to modify the authorized funds.
  • Capture: to confirm the debit of funds from an authorization
  • Void: to cancel a previous authorization.
  • Refund: to return funds from the merchant to a card. Can be referened against a previous transaction or non-referenced.
  • Balance Inquiry: query the card issuer the balance of the acccount on the card.
  • Card Verification: query the card issuer on the validity of the card info.
  • Exchange Rate: before performing dynamic-currency-conversion (DCC), to obtain the exchange rate for DCC.

# Settlement

In addition to the above standard operations, all adapter must also define how transactions are settled for a merchant.

The Poynt Cloud Adapter Development framework supports three different modes of settlement:

  • Terminal - the terminal is the system of record and initiate settlement by sending transactions to the host periodically.
  • Automatic Host - the host is the system of record and automatic periodic settlement happens from the acquiring host.
  • Terminal-initiated Host - the host is the system of record but settlement is initiated from the terminal.

The Poynt Cloud Adapter Development frameworks allow you to define up to three different message-pair types as part of the settlement process: header, transactions, and trailer message. In ISO 8583 terminology:

  • Header - corresponds to a typical 0500 MTI
  • Transaction Details - corresponds to a typical 0300 MTI
  • Trailer - corresponds to a typical 0500 MTI with slightly different processing code.

These messages can be configured to be sent all together as one request or as individual requests on the network to the acquiring host. For each request, a handler script is required to be define like a standard operation to determine whether it was successful or not.

# Message

Messages are the basic unit of communications between the adapter and a remote host. Every adapter operation must have one request and one response.

Messages are defined by its formatting and the fields that make up the message.

Message Fields

# Formats

Poynt currently support the following message format:

  • ISO 8583 ( all versions)

  • VISA GEN II

  • JSON

  • XML

NOTE

Additional message format will be added in the future.

# Checksum

An optional checksum value can be automatically calculated by the framework and appended to your message if specified. The currently supported checksum algorithms are:

  • LRC

# Fields

Messages are composed of a list of fields. Depending on the message format, the order in which the fields are defined in the IDE matters. For example, if the format is ISO 8583, the position of the field definitions will determine the order that the framework will serialize them. Putting them in the incorrect order will result in an error. However, JSON message format does not require any particular field ordering.

# Request vs Response

Request message fields requires the developer to define how the value of the field will be calculated. Response message fields only require the developer to define the basic format of the message but not how the value is calculated. The values will be deserialized by the framework from the response payload.

Message fields makes up a message. Request message fields are defined by the adapter developer with the appropriate value calculation mechanism.

Request Response

# Formats

All request/response message field have standard formats like:

  • Name - the name of the field

  • Type

    • Constant

    • Variable length numeric

    • Fixed length numeric

    • Variable length alphanumeric

    • Fixed length alphanumeric

    • Bitmap

    • JSON Object

    • XML Object

  • Length

  • Length Encoding - BCD, ASCII, BCD_UNPACKED, BINARY

Depending on the message format and field types, certain field definitions are required or optional.

# Evaluation

Every request message field MUST have a way to evaluate to a value. If the field is a constant type, then the value is simply a constant string. All other field types can be evaluated by two other methods:

  • Javascript Expression

  • Javascript Funding

# Expression Eval

If the value of the field can be simply expressed as a single Javascript expression, just specify it.

# Function Eval

More complex fields that require calculation can be evaluated using a Javascript function. The function must return a value once it finishes the calculation

# Miscellaneous

# Mask

Ensure that all sensitive fields like PAN or track data have the Mask flag enabled. Masked fields will have it's payload ofuscated.

# Required

Fields marked as required cannot have an empty or null value. If this occurs, the framework will treat it as an error and will not process the message.

# Context

Each execution of an adapter operation is made against a context. A context is the set of global variables that are available to the Javascript code of an adapter during execution. All context variables from the framework begins with the special character $.

Format Context

The framework will construct a new context for each execution containing an appropriate set of variables for each operations.

# Variables

# Common Variables

The following variables will always be available to all operations:

  • $BUSINESS - the business

  • $STORE - the store

  • $TERMINAL - the terminal

  • $MID - the Merchant ID as assigned by the processor. This is normally equivalent to $STORE.getExternalStoreId()

  • $TID - the Terminal ID as assigned by the processor. This is normally equivalent to $TERMINAL.getExternalTerminalId()

  • $PROCESSOR_PROP - the processor properties for the business, store, and terminal. The framework will filter this to include only those properties belonging to the currently executing $TERMINAL/$STORE/$BUSINESS.

  • $BCD - a utility for handling Binary Coded Decimal

  • $BINARY - a utility for handling raw binary bytes and hexidecimal strings.

  • $CRYPTO - a utility for handling cryptographic data.

  • $CURRENCY - a utility for handling currency code and ISO currency value.

  • $TLV - a utility for handling Tag-Length-Value data.

  • $XML - a utility for handling XML data.

  • $REQUEST - the request message itself. This is useful for referencing the request from the Response Handler script. However, this is not available to any script inside the request message itself.

  • $SELF - this is a special variable that is bounded to different values depending on the stage of the execution. During message generation and pre flight script, $SELF is equivalent to $REQUEST. However, during Response Handler execution, $SELF is bounded to the response message.

  • $TRANSACTION - the transaction the operation is operating against. This has different meaning in different operation context.

  • $NOW - a utility for formatting time of the transaction.

  • $PROCESSOR_RESPONSE - a pre-instantiated object containing some key variables Poynt expect acquiring host will return. This includes the acquiring transactionId, statusCode, approvalCode, etc... It is the responsibility of the Response Handler script to fill this object with the correct info. Most importantly, the Response Handler script must call either $PROCESSOR_RESPONSE.setStatus($SUCCESSFUL) or $PROCESSOR_RESPONSE.setStatus($FAILURE) to indicate the outcome of the execution.

  • $COUNTER - a utility for managing and storing numeric (i.e. counters) values in a persistent storage that can be carried across transactions.

The IDE has the ability to display the available methods to invoke whenever you type in these variable names. Please use the IDE to help show the latest available methods of each variables.

Variables

# Authorization Variables

The following variables are available during the Authorization operations in addition to the common variables:

  • $TRANSACTION - the transaction being authorized.

# Capture Variables

The following variables are available during the Capture operations in addition to the common variables:

  • $TRANSACTION - the original authorization transaction that is being captured.

  • $TRANSACTION_RESPONSE - the original response message of the authorization transaction.

  • $ADJUSTMENTS - any adjustment to the original authorization needed (i.e. tips) to be made.

# Adjustment Variables

The following variables are available during the Adjustment operations in addition to the common variables:

  • $TRANSACTION - the original authorization transaction that is being captured.

  • $TRANSACTION_RESPONSE - the original response message of the authorization transaction.

  • $ADJUSTMENTS - any adjustment to the original authorization needed (i.e. tips) to be made.

# Void Variables

The following variables are available during the Void operations in addition to the common variables:

  • $TRANSACTION - the original authorization transaction that is being captured.

  • $TRANSACTION_RESPONSE - the original response message of the authorization transaction.

# Refund Variables

The following variables are available for all refunds:

  • $REFUND_FUNDINGSOURCE - when a card insert/swipe is made on the terminal during a refund, this is the funding source to return the funds to.

The following variables are available for a non-reference refund:

  • $TRANSACTION - the new non-reference refund transaction. This will contain the card to return the funds to.

The following variables are available for a referenced refund:

  • $TRANSACTION - the original capture transaction to be refunded.

  • $TRANSACTION_RESPONSE - the original response message of the authorization transaction.

  • $REFUNDAMOUNT - the amount to be refunded if specified.

# Balance Inquiry Variables

The following variables are available during the Balance Inquiry operation in addition to the common variables:

  • $TRANSACTION - contains the funding source (i.e. Card) object to inquire the balance of.

# Card Verification Variables

The following variables are available during the Card Verification operation in addition to the common variables:

  • $TRANSACTION - contains the Card objec tto verify.

# Exchange Rate Variables

The following variables are available during the Exchange Rate operation in addition to the common variables:

  • $TRANSACTION - contains the potential transaction amounts to perform a Dynamic Currency Conversion (DCC) against.

  • $EXCHANGE_RATE - the resulting exchange rate to use for performing a transaction with DCC. The adapter Response Handler script for this operation is responsible for filling out this object.

# Settlement Variables

The following variables are available to all scripts during settlement for each header, transaction, and trailer request message evaluation:

  • $BATCH - an object containing various aggregated totals for the unsettled transactions.

  • $TRANSACTION_LIST - the set of transaction that needs to be settled.

When processing individual transaction in the transaction loop, the following variables are available:

  • $TRANSACTION - the transaction to be settled.

  • $TRANSACTION_RESPONSE - the original response message of the transaction to be settled.

# Utilities

# Counters

The framework provides a permanent storage facility for all adapters to store key-value pairs of integers called $COUNTER. Counter integer values are for the general purpose of counting various things like STAN, batch Numbers, etc... that the adapter must carries across transactions.

Each adapter, at runtime, will have access to its own $COUNTER instance that it can use to set, get, increment, or decrement values. The $COUNTER instance is bounded to the Business > Store > MID > TID. For example, if your business has two MID-TID pairs 1-1 and 1-2, calling $COUNTER.get('foo') during the processing of transaction for MID-TID 1-1 is a different value than those of MID-TID 1-2.

# Poynt APIs

A payment transaction may come to Poynt Cloud in one of the following data objects :

  • Transaction Data Object

  • Order Data Object

TIP

You can find more details in our Poynt APIs docs (opens new window)

# Transaction Data Object

This is the base object for the transactions resource. Transactions resource represents a financial transaction. It can be used to save the transaction in the Poynt system as well as initiate interaction with the acquirer to move funds.

Transaction Data Object includes following transaction attributes : Action, Status, ParentId, CustomerUserId, StayType, ReceiptEmailAddress, TransactionNumber, Notes, UpdatedAt, CreatedAt, ApprovalCode, Id and Signature.

Transaction Data Object includes following sub data objects : TransactionAmounts, TransactionReason, FundingSource, TransactionReference, ReceiptPhone, PoyntLoyalty, Link, ClientContext, ProcessorOptions and ProcessorResponse.

# FundingSource

The fundingSource includes the data related to the card, cardholder, EMV and EBT. It includes following sub objects : Card, EMVData, VerificationData, DebitEBTReEntry, CustomFundingSource, EBTDetails and EntryDetails.

# ProcessorOptions

The processorOptions is a map of key-value strings. It is used for various processor specific not being available in the main model. It may include processor-specific data like installment info and taxes. processorOptions data object also includes the custom fields to be printed on the receipt.

# ProcessorResponse

This is the data object filled with the authorization response data from the acquirer. It is filled by the ResponseHandler.

ProcessorRespose Data Object includes following transaction attributes : cvActualResult, statusCode, status, remainingBalance, retrievalRefNum, cardToken, emvTags, providerVerification, batchId, cvResult, avsResult, transactionId, processor, acquirer, approvedAmount, statusMessage and approvalCode

ProcessorRespose Data Object includes following sub data objects : EMV Tags (for authorization response), ProviderVerification and AVSResults.

Tree view of Transaction Data Object is as following :

# Step By Step Payment Transaction

The below diagram shows the execution sequence of a payment transaction. At the start of the transaction, user enters the transaction amount and transaction type to initiate the transaction. POS terminal processes the transaction, creates TRANSACTION data object and sends it to the Poynt Cloud. Poynt Cloud performs certain controls on the transaction data and decides whether to send it to online or decline. If the transaction will be declined, Poynt Cloud generates an error code listed in the Section “Error Codes”.

Step by Step

TRANSACTION DATA (RECEIVED FROM POS) Transaction POS

AUTHORIZATION REQUEST MESSAGE Auth request

AUTHORIZATION RESPONSE MESSAGE

Auth response

TRANSACTION RESPONSE DATA (SENT TO POS)

Auth response

::: details An Example of Transaction Data

{
  "action": "AUTHORIZE",
  "amounts": {
    "cashbackAmount": 0,
    "currency": "USD",
    "orderAmount": 120,
    "tipAmount": 0,
    "transactionAmount": 120
  },
  "authOnly": false,
  "context": {
    "businessId": "b7098bb4-28a8-4b71-a102-cd8742a1ce4a",
    "businessType": "TEST_MERCHANT",
    "employeeUserId": 5379376,
    "mcc": "5999",
    "mid": "888000000058",
    "source": "INSTORE",
    "sourceApp": "co.poynt.terminal",
    "storeAddressCity": "Tempe",
    "storeAddressTerritory": "Az",
    "storeDeviceId": "urn:tid:72802d01-d574-391a-8cc2-047cd331e017",
    "storeId": "b4dabcff-ddfc-45c3-8ac8-a62e50218abb",
    "storeTimezone": "America/Los_Angeles",
    "tid": "0064-0064",
    "transactionInstruction": "ONLINE_AUTH_REQUIRED",
    "transmissionAtLocal": "2020-10-07T17:55:55Z"
  },
  "createdAt": "2020-10-07T17:55:55Z",
  "customerLanguage": "en",
  "customerUserId": 5611754,
  "fundingSource": {
    "card": {
      "cardBrand": {
        "createdAt": "2020-04-15T04:35:31Z",
        "displayName": "Mastercard",
        "id": "8cd7082b-2cdd-4264-a4e3-57f78851ead3",
        "logoUrl": "",
        "scheme": "MASTERCARD"
      },
      "cardHolderFirstName": "",
      "cardHolderFullName": "MTIP06 MCD 15A",
      "cardHolderLastName": "MTIP06 MCD 15A",
      "cardId": "311ed830-6854-4777-87e9-361e21682e4f",
      "encrypted": false,
      "expirationDate": 31,
      "expirationMonth": 12,
      "expirationYear": 2025,
      "id": 35964634,
      "numberFirst6": "541333",
      "numberHashed": "616FA70622054D895EF7D90EAB28B74A2EEF0C61332CD4025AB6420E071B789F",
      "numberLast4": "0011",
      "numberMasked": "541333******0011",
      "serviceCode": "601",
      "type": "MASTERCARD"
    },
    "debit": false,
    "emvData": {
      "emvTags": {
        "0x1F8231": "87",
        "0x50": "4D415354455243415244",
        "0x5F20": "4D5449503036204D434420313541",
        "0x5F24": "251231",
        "0x5F28": "0056",
        "0x5F2A": "0840",
        "0x5F34": "03",
        "0x82": "3000",
        "0x84": "A0000000041010",
        "0x95": "0000008000",
        "0x9A": "201007",
        "0x9B": "E800",
        "0x9C": "00",
        "0x9F02": "000000025000",
        "0x9F03": "000000000000",
        "0x9F06": "A0000000041010",
        "0x9F07": "FF00",
        "0x9F08": "0002",
        "0x9F09": "0002",
        "0x9F0D": "FC50A00000",
        "0x9F0E": "0000000000",
        "0x9F0F": "F870A49800",
        "0x9F10": "0210A5800F040000000000000000000000FF",
        "0x9F12": "4D617374657243617264",
        "0x9F1A": "0616",
        "0x9F26": "A8EC4378893D5E76",
        "0x9F27": "80",
        "0x9F33": "E0F0C8",
        "0x9F34": "410302",
        "0x9F35": "22",
        "0x9F36": "1301",
        "0x9F37": "3389E746"
      }
    },
    "entryDetails": {
      "customerPresenceStatus": "PRESENT",
      "entryMode": "INTEGRATED_CIRCUIT_CARD"
    },
    "type": "CREDIT_DEBIT"
  },
  "id": "0434923b-0175-1000-638e-e21517f8a9ce",
  "partiallyApproved": true,
  "processorResponse": {
    "acquirer": "TSYS",
    "approvalCode": "005452",
    "approvedAmount": 120,
    "batchId": "TSYS:100720-1",
    "emvTags": {
      "0x91": "BE672F8C568823D70012"
    },
    "processor": "TSYS",
    "retrievalRefNum": "028117401545",
    "status": "Successful",
    "statusCode": "10",
    "statusMessage": "PARTIAL APPROVAL",
    "transactionId": "1007MCC0117P6  "
  },
  "references": [
    {
      "customType": "referenceId",
      "id": "04344ae0-0175-1000-638e-e21517f8a9ce",
      "type": "CUSTOM"
    }
  ],
  "signatureRequired": false,
  "status": "AUTHORIZED",
  "updatedAt": "2020-10-07T17:56:00Z"
}

:::

# Order Data Object

This is the base object for the orders resource. Orders resource represents a purchase order for items or services. This object captures all items, amounts and transactions related to an order. One important point to note upfront is that all the order-level amount fields could be positive or negative. That is because unlike an item which is always either purchased or returned, an order could be a mixed bag of purchased or returned items. So the amounts could be positive or negative.

Order Data Object includes following transaction attributes : orderNumber, items, discounts, fees, parentId, customerUserId, stayType, notes, updatedAt, createdAt and id.

Order Data Object includes following sub data objects : Statuses, Transaction(see Transaction data object), Items, Link, Amount and Context.

::: details An Example of Order Data

{
  "action": "SALE",
  "amounts": {
    "currency": "USD",
    "orderAmount": 1386,
    "tipAmount": 0,
    "transactionAmount": 1386
  },
  "authOnly": false,
  "context": {
    "businessId": "f69667c8-1d38-4af2-b3e9-ff4dee58003b",
    "businessType": "TEST_MERCHANT",
    "employeeUserId": 5604183,
    "mcc": "5812",
    "mid": "4549121212122",
    "source": "INSTORE",
    "sourceApp": "co.poynt.register",
    "storeAddressCity": "San Juan",
    "storeAddressTerritory": "Puerto Rico",
    "storeId": "1f7ba521-cb31-4a5e-b307-9af63ae3975b",
    "storeTimezone": "America/Puerto_Rico",
    "tid": "99999891",
    "transactionInstruction": "ONLINE_AUTH_REQUIRED",
    "transmissionAtLocal": "2020-10-08T19:25:00Z"
  },
  "customerLanguage": "en",
  "fundingSource": {
    "card": {
      "cardBrand": {
        "createdAt": "2020-04-15T04:35:00Z",
        "displayName": "American Express",
        "id": "67d3fe5c-2c36-4a6f-9bc4-93ee54a8ddd5",
        "logoUrl": "",
        "scheme": "AMERICAN_EXPRESS"
      },
      "encrypted": true,
      "expirationDate": 31,
      "expirationMonth": 1,
      "expirationYear": 2020,
      "keySerialNumber": "FFFF9876543210E00411",
      "numberFirst6": "374245",
      "numberLast4": "1006",
      "track2data": "35F0E91396AD6AEB29C3A07E7A4713687836084D53F79EA5142E4B0E0992A3FD13600E55EC8A9079",
      "type": "AMERICAN_EXPRESS"
    },
    "emvData": {
      "emvTags": {
        "0x1F8102": "FFFF9876543210E00411",
        "0x1F8103": "333734323435",
        "0x1F8104": "31303036",
        "0x1F815E": "25",
        "0x1F8160": "03",
        "0x1F8162": "00",
        "0x1F8206": "0F",
        "0x1F8231": "41",
        "0x50": "414D45524943414E2045585052455353",
        "0x57": "35F0E91396AD6AEB29C3A07E7A4713687836084D53F79EA5142E4B0E0992A3FD13600E55EC8A9079",
        "0x5F24": "200131",
        "0x5F2A": "0840",
        "0x5F34": "00",
        "0x82": "1C80",
        "0x84": "A000000025010402",
        "0x8C": "9F02069F03069F1A0295055F2A029A039C019F3704",
        "0x8D": "8A029F02069F03069F1A0295055F2A029A039C019F3704",
        "0x95": "8040008000",
        "0x9A": "201008",
        "0x9C": "00",
        "0x9F02": "000000001386",
        "0x9F06": "A000000025010402",
        "0x9F09": "0001",
        "0x9F10": "06020103A02800",
        "0x9F12": "416D65726963616E2045787072657373",
        "0x9F1A": "0630",
        "0x9F1E": "3132333435363738",
        "0x9F21": "152433",
        "0x9F26": "2666DA63DDA0E1A0",
        "0x9F27": "80",
        "0x9F33": "E068C8",
        "0x9F34": "5E0300",
        "0x9F35": "22",
        "0x9F36": "03D6",
        "0x9F37": "72BFCCD8",
        "0x9F39": "07",
        "0x9F6E": "D8F04000"
      }
    },
    "entryDetails": {
      "customerPresenceStatus": "PRESENT",
      "entryMode": "CONTACTLESS_INTEGRATED_CIRCUIT_CARD"
    },
    "type": "CREDIT_DEBIT"
  },
  "id": "09ac7cab-0175-1000-61ae-81d1fe0c3809",
  "processorOptions": {
    "municipalTaxAmount": "10",
    "stateTaxAmount": "36"
  },
  "references": [
    {
      "id": "09aa40e7-0175-1000-b412-abe8509b7fc9",
      "type": "POYNT_ORDER"
    }
  ],
  "signatureRequired": true
}

:::

Last Updated: 6/24/2022, 9:49:22 AM