Payment Bridge API stable

Note

While this API is currently availalbe at no charge, Poynt reserves the right to introduce an API usage fee in the future.

Overview

Payment Bridge API provides a way for external systems (e.g. web-based point-of-sale systems) to start a transaction flow on Poynt Terminal using Poynt cloud APIs.

Here is how it works:

  1. External System sends a Poynt Cloud Message with a payment request containing business id, store id and terminal id of the merchant
  2. Poynt Cloud authorizes the caller and routes the message to the corresponding merchant terminal
  3. Poynt Payment Bridge receives the incoming message and starts the necessary payment flows on the device.

Prerequites

  1. Create a developer account and activate your developer terminal. (Note: if you don't have a developer unit you can use emulator)
  2. Generate API credentials (i.e. appId and private key) by creating an app. Make sure it has "Cloud Messages" WRITE permission
  3. Use "Merchant Login Url" of your app to Authorize one of your test merchants

Payment Bridge Message Flow

PaymentBridgeSequenceDiagram

Request Message format

Common parameters for Sale, AuthOnly and Non-Referenced Refund messages

  • storeId and businessId of the merchant (and optionally deviceId. If not included the payment request will be sent to all terminals in the store).
  • ttl If the Poynt server was unable to deliver the message to the terminal, after TTL (in seconds) is reached the request will be discarded
  • data is the actual payload:
    • Format: {"action":"sale", "purchaseAmount": 1000, "tipAmount": 100, "currency":"USD", "referenceId":”ABC1234”, “callbackUrl”: “-urlencoded-url-"}

Common "data" parameters

  • action: authorize, sale, void, refund, non-referenced-credit
  • purchaseAmount: transaction amount (excluding tip)
  • tipAmount: tip amount if enabled for merchant
  • currency: 3 digit currency value (e.g. "USD")
  • referenceId: external referenceId that you can use to correlate transactions across systems
  • orderId: order id of a previously created order or order that will be created after the payment
  • callbackUrl: where you will receive a callback (HTTP POST) with Poynt Payment object
  • transactionId: transactionId to use for void, refund operations
  • custom-http-header: Custom HTTP header name and value that will be set by Poynt in the callback request
  • skipReceiptScreen: value of true will force the receipt options screen to be skipped
  • debit: value of true will default payment method to debit

Payment Actions

Sale

"data" PARAMETERS

  • payment serialized payment object. The payment object contains options to configure the payment session. For the list of supported options please refer to this article.
{
  "ttl": 30,
  "businessId": "d9f90edd-53d0-49ed-9589-22d92b9bfda4",
  "storeId": "8a545d2b-e5d8-4cf0-b766-0fe32870813b",
  "deviceId": "urn:tid:9a645d2b-e3c8-7cf0-d766-9fe32870813b",
  "data": "{\"callbackUrl\":\"https://www.domain.com/callback\",\"custom-http-header\":\"Headername: HeaderValue\",\"payment\":\"{\\\"amount\\\":345,\\\"currency\\\":\\\"USD\\\",\\\"multiTender\\\":\\\"true\\\",\\\"skipReceiptScreen\\\":true,\\\"skipSignatureScreen\\\":true,\\\"disableTip\\\":true,\\\"notes\\\":\\\"A note about my txn\\\",\\\"referenceId\\\":\\\"6199fce8-c434-4a06-a13e-f95396c1d3ab\\\"}\"}"
}
1
2
3
4
5
6
7

AuthOnly

"data" PARAMETERS

  • payment serialized payment object.
{
  "ttl": 30,
  "businessId": "d9f90edd-53d0-49ed-9589-22d92b9bfda4",
  "storeId": "8a545d2b-e5d8-4cf0-b766-0fe32870813b",
  "deviceId": "urn:tid:9a645d2b-e3c8-7cf0-d766-9fe32870813b",
  "data": "{\"callbackUrl\":\"https://www.domain.com/callback\",\"custom-http-header\":\"Headername: HeaderValue\",\"payment\":\"{\\\"amount\\\":345,\\\"currency\\\":\\\"USD\\\",\\\"multiTender\\\":\\\"true\\\",\\\"skipReceiptScreen\\\":true,\\\"skipSignatureScreen\\\":true,\\\"disableTip\\\":true,\\\"notes\\\":\\\"A note about my txn\\\",\\\"authzOnly\\\":true,\\\"referenceId\\\":\\\"6199fce8-c434-4a06-a13e-f95396c1d3ab\\\"}\"}"
}
1
2
3
4
5
6
7

Refund

"data" PARAMETERS

  • referenceId unique id returned in the postback response
  • transactionId id of the SALE or CAPTURE to refund
  • action should be set to "refund"
{
  "ttl": 30,
  "businessId": "d9f90edd-53d0-49ed-9589-22d92b9bfda4",
  "storeId": "8a545d2b-e5d8-4cf0-b766-0fe32870813b",
  "deviceId": "urn:tid:9a645d2b-e3c8-7cf0-d766-9fe32870813b",
  "data": "{\"callbackUrl\":\"https://www.domain.com/callback\",\"referenceId\":\"8a545d2b-e5d8-aabb-b766-0fe32870813b\",\"transactionId\":\"f24bc381-adb7-481c-9ae9-761275bb0c0a\",\"action\":\"refund\"}"
}
1
2
3
4
5
6
7

Non-Referenced Refund (Credit)

"data" PARAMETERS

  • payment serialized payment object.
{
  "ttl": 30,
  "businessId": "803833ba-cb97-434d-b158-30db6973173b",
  "storeId": "b4c4d6e6-6a5e-4ca9-86ee-a086ff2fc9c9",
  "deviceId": "urn:tid:23df48cd-b11e-3ff2-b537-fdcc787ad21b",
  "data": "{\"callbackUrl\":\"https://www.domain.com/callback\",\"custom-http-header\":\"Headername: HeaderValue\",\"payment\":\"{\\\"amount\\\":345,\\\"currency\\\":\\\"USD\\\",\\\"nonReferencedCredit\\\":true}\"}"
}
1
2
3
4
5
6
7

Void

"data" PARAMETERS

  • referenceId unique id returned in the postback response
  • transactionId id of the AUTHORIZATION to void
  • action should be set to "void"
{
  "ttl": 30,
  "businessId": "803833ba-cb97-434d-b158-30db6973173b",
  "storeId": "b4c4d6e6-6a5e-4ca9-86ee-a086ff2fc9c9",
  "deviceId": "urn:tid:23df48cd-b11e-3ff2-b537-fdcc787ad21b",
  "data": "{\"callbackUrl\":\"https://www.domain.com/callback\",\"referenceId\":\"8a545d2b-e5d8-aabb-b766-0fe32870813b\",\"transactionId\":\"5805d5b4-016b-1000-4924-5a010638b565\",\"action\":\"void\"}"
}
1
2
3
4
5
6
7

Capture

"data" PARAMETERS

  • referenceId unique id returned in the postback response
  • transactionId id of the AUTHORIZATION to capture
  • action should be set to "capture"
{
  "ttl": 30,
  "businessId": "803833ba-cb97-434d-b158-30db6973173b",
  "storeId": "b4c4d6e6-6a5e-4ca9-86ee-a086ff2fc9c9",
  "deviceId": "urn:tid:23df48cd-b11e-3ff2-b537-fdcc787ad21b",
  "data": "{\"callbackUrl\":\"https://www.domain.com/callback\",\"referenceId\":\"8a545d2b-e5d8-aabb-b766-0fe32870813c\",\"transactionId\":\"4e75b270-016b-1000-9b65-3708f2205b64\",\"action\":\"capture\"}"
}
1
2
3
4
5
6
7

Cancel Payment

This API can be used to cancel a payment in progress. This API does not generate a callback response. However, the pending sale/auth/credit request will return a callback response with the status CANCELED.

"data" PARAMETERS

  • action cancelPayment
{
  "ttl": 30,
  "businessId": "803833ba-cb97-434d-b158-30db6973173b",
  "storeId": "b4c4d6e6-6a5e-4ca9-86ee-a086ff2fc9c9",
  "deviceId": "urn:tid:23df48cd-b11e-3ff2-b537-fdcc787ad21b",
  "data": "{\"action\":\"cancelPayment\"}"
}
1
2
3
4
5
6
7

Generate Receipt

PROCESSOR SPECIFIC

Please note that this API is currently only supported for processor NEXI.

"data" PARAMETERS

{
	"ttl": 500, 
	"businessId": "df5638be-faca-4367-84c9-b568b776f14a", 
	"storeId": "b63ca176-2875-41b9-814c-f207cb0c0ae9", 
	"deviceId": "urn:tid:cc60a9d8-7ef8-37ce-b469-84fc6c0264c5", 
	"data": "{\"action\":\"generateReceipt\", \"callbackUrl\":\"http://192.168.1.116:9999/\",\"transaction\":\"{\\\"action\\\":\\\"AUTHORIZE\\\",\\\"adjustmentHistory\\\":[],\\\"amounts\\\":{\\\"currency\\\":\\\"EUR\\\",\\\"orderAmount\\\":22,\\\"tipAmount\\\":0,\\\"transactionAmount\\\":22},\\\"authOnly\\\":false,\\\"context\\\":{\\\"businessId\\\":\\\"df5638be-faca-4367-84c9-b568b776f14a\\\",\\\"employeeUserId\\\":3692,\\\"mcc\\\":\\\"5812\\\",\\\"source\\\":\\\"INSTORE\\\",\\\"storeId\\\":\\\"b63ca176-2875-41b9-814c-f207cb0c0ae9\\\",\\\"tid\\\":\\\"d0up\\\",\\\"transmissionAtLocal\\\":{\\\"year\\\":2018,\\\"month\\\":9,\\\"dayOfMonth\\\":4,\\\"hourOfDay\\\":14,\\\"minute\\\":19,\\\"second\\\":40}},\\\"createdAt\\\":{\\\"year\\\":2018,\\\"month\\\":9,\\\"dayOfMonth\\\":4,\\\"hourOfDay\\\":14,\\\"minute\\\":19,\\\"second\\\":41},\\\"customerLanguage\\\":\\\"en\\\",\\\"fundingSource\\\":{\\\"card\\\":{\\\"numberFirst6\\\":\\\"370295\\\",\\\"numberLast4\\\":\\\"3111\\\",\\\"type\\\":\\\"AMERICAN_EXPRESS\\\"},\\\"emvData\\\":{\\\"emvTags\\\":{\\\"0x1F8103\\\":\\\"333730323935\\\",\\\"0x1F8206\\\":\\\"0F\\\",\\\"0x1F8151\\\":\\\"3C\\\",\\\"0x9F35\\\":\\\"22\\\",\\\"0x95\\\":\\\"8000000000\\\",\\\"0x5F30\\\":\\\"728F\\\",\\\"0x9F34\\\":\\\"1F0002\\\",\\\"0x9F39\\\":\\\"91\\\",\\\"0x1F8104\\\":\\\"33313131\\\",\\\"0x9F06\\\":\\\"A000000025010901\\\",\\\"0x1F8204\\\":\\\"25\\\"}},\\\"entryDetails\\\":{\\\"customerPresenceStatus\\\":\\\"PRESENT\\\",\\\"entryMode\\\":\\\"CONTACTLESS_MAGSTRIPE\\\"},\\\"type\\\":\\\"CREDIT_DEBIT\\\"},\\\"id\\\":\\\"40f35692-0166-1000-3741-56a451933b19\\\",\\\"processorResponse\\\":{\\\"avsResult\\\":{}},\\\"references\\\":[{\\\"customType\\\":\\\"referenceId\\\",\\\"id\\\":\\\"40f34377-0166-1000-3741-56a451933b19\\\",\\\"type\\\":\\\"CUSTOM\\\"}],\\\"signatureRequired\\\":false}\"}"
}
1
2
3
4
5
6
7

Callback

Callback allows the external system to get notified when the payment transaction requested is processed. The terminal will use the callback url provided in the request to POST the following json payload:

{"referenceId”:”<your-reference-id>","status":”CANCELED or PROCESSED”, “transactions”:[{<processed-transaction>}]}
Example of a canceled payment:

{
  "referenceId": "8c8cf949-4f5c-4aa4-8b90-05d43592bfbe",
  "status": "CANCELED"
}
1
2
3
4

Example response posted back to the callback url

POST /callback HTTP/1.1
Content-Type: application/json; charset=utf-8
Content-Length: 1510
Host: myserver.com:8080
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/2.5.0

{
  "readCardDataOnly": false,
  "transactions": [
    {
      "authOnly": false,
      "status": "AUTHORIZED",
      "customerLanguage": "en",
      "updatedAt": "2018-09-06T01:23:23Z",
      "id": "f24bc381-adb7-481c-9ae9-761275bb0c0a",
      "references": [
        {
          "type": "CUSTOM",
          "id": "b6c9f791-c3e8-4b8a-8eee-5567c2d7956c",
          "customType": "referenceId"
        }
      ],
      "customerUserId": 60731166,
      "amounts": {
        "tipAmount": 0,
        "transactionAmount": 4500,
        "orderAmount": 4500,
        "cashbackAmount": 0,
        "currency": "USD"
      },
      "createdAt": "2018-09-06T01:23:21Z",
      "signatureRequired": false,
      "context": {
        "storeDeviceId": "urn:tid:e9e65b1b-1a58-3e55-a828-3f49096cc661",
        "source": "INSTORE",
        "storeAddressTerritory": "California",
        "mcc": "5812",
        "storeAddressCity": "Palo Alto",
        "sourceApp": "co.poynt.services",
        "employeeUserId": 26835234,
        "businessType": "TEST_MERCHANT",
        "businessId": "803833b1-cb97-434d-b158-30db6973173b",
        "storeTimezone": "America/Los_Angeles",
        "storeId": "b4c4d6e6-6a1e-4ca9-86ee-a086ff2fc9c9",
        "transmissionAtLocal": "2018-09-06T01:23:21Z"
      },
      "action": "AUTHORIZE",
      "processorResponse": {
        "statusCode": "1",
        "transactionId": "0eb6c86b-73b1-e811-bc5d-0050569277e2",
        "avsResult": {
          
        },
        "status": "Successful",
        "emvTags": {
          "0x9F02": "000000004500"
        },
        "acquirer": "CHASE_PAYMENTECH",
        "approvedAmount": 4500,
        "approvalCode": "6A4FEE",
        "processor": "CREDITCALL"
      },
      "fundingSource": {
        "card": {
          "numberMasked": "370123******1111",
          "cardId": "daa2dbe1-0b61-423a-a46c-73647e1e58de",
          "numberFirst6": "370123",
          "cardHolderFullName": "VALUED CUSTOMER      00304",
          "expirationDate": 31,
          "cardHolderLastName": "VALUED CUSTOMER      00304",
          "type": "AMERICAN_EXPRESS",
          "id": 59070137,
          "encrypted": false,
          "expirationYear": 2022,
          "expirationMonth": 7,
          "serviceCode": "728",
          "numberLast4": "1111",
          "cardHolderFirstName": ""
        },
        "debit": false,
        "type": "CREDIT_DEBIT",
        "entryDetails": {
          "entryMode": "CONTACTLESS_MAGSTRIPE",
          "customerPresenceStatus": "PRESENT"
        },
        "emvData": {
          "emvTags": {
            "0x5F24": "220731",
            "0x95": "8000001000",
            "0x1F815D": "3C",
            "0x5F20": "56414C55454420435553544F4145522020202020203030333034",
            "0x1F8104": "33313131",
            "0x1F8103": "333731323935",
            "0x1F815F": "04",
            "0x1F8102": "FFFF9876541210E00062",
            "0x1F815E": "25",
            "0x5F30": "728F",
            "0x9F34": "1F0002",
            "0x9F35": "22",
            "0x9F06": "A000000025010901",
            "0x1F8160": "03",
            "0x1F8161": "00",
            "0x1F8162": "00",
            "0x57": "37F8DBB4289118DC0707827101BB3E7D0A4DAF62AA38DED4192FCDBFEA6E5AB78E1351E27A993E15",
            "0x9F39": "91",
            "0x56": "6881AE9183767E18358A391DB1D74914DC212BD7744BB160D1C16AF5BE490028143BAB50F4B9EEF103A6EE255E8028B4C975C74FCAEBDF6798DD15883CB2C38E"
          }
        }
      }
    }
  ],
  "disableManual": false,
  "authzOnly": false,
  "disableOther": false,
  "multiTender": true,
  "disableCheck": false,
  "nonReferencedCredit": false,
  "applicationIndex": -1,
  "currency": "USD",
  "disableDebit": false,
  "amount": 4500,
  "tipAmount": 0,
  "isBalanceInquiry": false,
  "creditOnly": false,
  "disableEbtVoucher": false,
  "disableMSR": false,
  "cashOnly": false,
  "disableEbtCashBenefits": false,
  "manualEntry": false,
  "disableChangeAmount": false,
  "skipReceiptScreen": false,
  "disableDebitCards": false,
  "disableEMVCL": false,
  "status": "PROCESSED",
  "disableCash": false,
  "callerPackageName": "co.poynt.services",
  "referenceId": "b6c9179b-c3e8-4b8a-8eee-5567c2d7956c",
  "disableTip": false,
  "debitOnly": false,
  "skipPaymentConfirmationScreen": false,
  "adjustToAddCharges": false,
  "disableEbtFoodStamps": false,
  "disableEMVCT": false,
  "disablePaymentOptions": false,
  "skipSignatureScreen": false,
  "voucher": false,
  "offlineAuth": false,
  "cashbackAmount": 0
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151

POSTBACK RETRY LOGIC

The terminal waits 3 seconds to get HTTP 200 from the postback listener. If your listener fails to repond within that timeframe the terminal will attempt to re-deliver 5 and 10 seconds later.

WARNING

Since the postback payload is a serialized version of the Payment object and from time to time we may add new parameters, it is important that you do not use strict validation while parsing the payload, which means ignoring unknown parameters.

Terminal Connectivity

Terminals maintain a persistent connection to the Poynt cloud but from time to time the connection may get dropped. By default, terminals send a ping message to check if the connection is active every 5 minutes. However you should set a more aggressive connectivity profile to ensure that the connection does not get dropped by sending the following message to the terminal:

{
	"ttl": 86400, 
	"businessId": "{{bizId}}", 
	"storeId": "{{strId}}", 
	"deviceId": "{{deviceId}}", 
	"data": "{\"action\":\"setCustomPcmProfile\"}"
}
1
2
3
4
5
6
7

The message does not use a callback url as it does not require a postback. If you are testing this on a developer terminal, you can confirm that the profile has been applied by checking the logcat:

I//PcmService.java:671( 2202): main PcmService: onStartCommand: ACTION_SET_PCM_PROFILE
I//PcmService.java:338( 2202): main PCM Saving profile to sys prop: PCM_PROFILE: PAYMENT BRIDGE,true,4000,30000,30000,30000,0,0
1
2

FAQ

Q: The body in the callback request is gzip compressed. How can I disable the compression?
A: Go to Developer Preferences > Poynt API. Toggle the switch for ENABLE HTTP COMPRESSION and tap SAVE. Check Dev FAQ page for instructions on accessing Developer Preferences.

Note

HTTP Compression can only be disabled on developer devices, make sure your backend supports compression before going live.

Q: My request fails with HTTP 401
A: This indicates that your appId does not have permission to send cloud messages to the merchant's terminals. Please refer to Step 3 of Prereqs.

Q: My API request returns HTTP 202 however the payment fragment does not come up on the terminal
A: First check the logcat to see if the message even makes it to the terminal adb logcat -v time | grep -i pcm. If you don't see the messages being logged it's likely because the connection between the terminal and the cloud was terminated. You can verify that by checking Poynt Settings:

Live Stream Disconnected
To reconnect you can double tap on the clock on the launcher:
Reset live stream connection
After that you can confirm that the connection has been re-established:
Live Stream Connected

Note

Please note that if you are using an emulator you need to check that the co.poynt.cloudmessaging package has been installed.

Last Update: 8/6/2019, 4:49:41 PM