Onboard Terminals

 Once a merchant orders a terminal from your platform, onboard that device for the merchant so that it is ready to go once they receive the hardware. The first step is to send a POST /terminals request with the previously collected merchant Account ID, terminal model and serial number, and the configurable settings. You can see what the POST /terminals request would look like below, but we'll start with terminal configuration.

Configure a Terminal

There is a series of options that get set for each terminal as part of onboarding, and can be updated with a POST /terminals/{id} request. Configurable options are all found in the terminal_configuration JSON block:
Copy
Copied
{
"terminal_configuration": {
	"currency": "{merchant's-currency}",
	"tip": {
		"mode": "prompt_on_terminal",
		"amount_guide_type": "percentage_guide",
		"terminal_display": {
			"percentage_guide": {
				"show_amount": true,
				"percentage_low": 15,
				"percentage_medium": 20,
				"percentage_high": 25
				}
			}
		},
	"signature_required": true,
	"contactless_payments": {
		"enabled": true,
		"credit_debit_preference": "debit"
		},
	"quick_chip": {
		"enabled": true
		},
	"deferred_authorization": {
		"enabled": true,
		"international_enabled": true,
		"max_transaction_count": 20,
		"max_total_amount": 250000,
		"max_transaction_amount": 12500,
		"supported_card_entry_modes": [
			"chip", 
			"magnetic_stripe", 
			"contactless"
			]
		},
	"name": "Front Desk"
	}
}

tip.mode

Choose whether you'd like to add the option for a tip on the terminal by choosing the setting tip.mode.prompt_on_terminal or on the receipt tip.mode.prompt_on_receipt, or not at all. This configuration depends entirely on the merchant's setup and preference.
Note
If you select a percentage_guide, the parameter show_amount will always be set to true, even when shown to be set to false for tip.mode.prompt_on_receipt. The percentage guide amount will be printed on the receipt.

amount_guide_type

If tip.mode is set to prompt_on_terminal, then tip.terminal_display.amount_guide_type is required to describe whether the terminal prompts for tip as a percentage of the total, or as a flat rate. Depending on the value here, you must then also send either the tip.terminal_display.percentage_guide or the tip.terminal_display.flat_guide structures. These structures allow your platform and/or merchants to customize the tip recommendations shown by the terminal UI.

signature_required

As the name suggests, this configuration determines whether or not the receipt will provide a line for the payer's signature. Card networks no longer require signature on every card present transaction, but there are a couple considerations as to why a merchant may want to collect signatures:

  • Payer signatures will help challenge any chargebacks the merchant may receive.
  • Some merchants may be accustomed to collecting signatures and may simply prefer to do so.

contactless_payments

This setting enables or disables a terminal's contactless payment (NFC chip reader) capability. Additionally, the credit_debit_preference parameter defines the credit/debit default for contactless payments when both credit and debit options are available for that card.

quick_chip

Quick chip refers to faster chip reading. For instance, imagine a grocery store checkout where the card is dipped prior to all items being scanned, and then the transaction can be completed without further payer interaction.

deferred_authorization

Deferred authorization covers the use case where a terminal is offline, and the terminal still authorizes a card. These authorizations will have a boolean offline auth property. This option allows merchants to process even in the event of an offline terminal, but also opens up the risk for declines from a valid card (for instance, when a valid card has insufficient funds).

Once an offline authorization has occurred, the terminal must go online in order to actually process the authorization. Once that's done, the payer will see the entry on their card statement, and the card can be charged using a POST /payments API request. Note that a POST /payments request prior to the online authorization will result in a 400 HTTP error.

If setting deferred_authorization to false, set the nested parameters to 0 or null as they are required parameters.
Note

It is important to keep a terminal onboarded if its last authorization was offline. If a terminal is queued up to be offboarded, build in checks prior to executing the offboarding protocol to ensure that there are no pending offline authorizations.

If a terminal with pending offline authorizations is offboarded, those authorizations will be lost and the merchant will not be able to charge those cards. Additionally, our support must intervene in order to make any further successful onboarding/offboarding calls to that terminal.

name

Set a human readable name for the physical terminal. In the Card Present SDK, this name will show up as “name”. This is also how the terminal will be identified by the connected WiFi network (further information on this in Connect SmartPOS and Terminals). Don't have access to the Card Present SDK? Find out if your platform meets the prerequisites and work with your account manager to get started.

Provide Permissions for Terminal Communication

Local Network permission is required for connecting to the terminal card readers on the network. Refer to your SDK integration guide for further information on how to integrate the permissions and for code examples in Objective C and Swift.

See an example of the terminal notification below:

Example terminal notification
Example terminal notification

Onboard a Terminal

Note that you can only have one onboarded API Terminals instance of a physical terminal, which is uniquely identified by the model and serial number.

Once your platform has determined the settings for a given terminal, you can send the onboarding API request. Your POST /terminals request may look like this:
Copy
Copied
curl -X POST \
 --url 'https://stage-api.wepay.com/terminals' \
  -H 'App-Id: {your-app-id}' \
  -H 'App-Token: {your-app-token}' \
  -H 'Api-Version: 3.0' \
  -H 'Content-Type: application/json' \
  --data-raw '{
"account_id": "{merchant's-account-id}",
"serial_number": "{terminal's-serial-number}",
"model_number": "{terminal's-model-number}",
"reference_id": "{custom-reference-id}",
"terminal_configuration": {
	"currency": "{merchant's-currency}",
	"tip": {
		"mode": "prompt_on_terminal",
		"amount_guide_type": "percentage_guide",
		"terminal_display": {
			"percentage_guide": {
				"show_amount": true,
				"percentage_low": 15,
				"percentage_medium": 20,
				"percentage_high": 25
				}
			}
		},
	"signature_required": true,
	"contactless_payments": {
		"enabled": true,
		"credit_debit_preference": "debit"
		},
	"quick_chip": {
		"enabled": true
		},
	"deferred_authorization": {
		"enabled": true,
		"international_enabled": true,
		"max_transaction_count": 20,
		"max_total_amount": 250000,
		"max_transaction_amount": 12500,
		"supported_card_entry_modes": [
			"chip", 
			"magnetic_stripe", 
			"contactless"
			]
		},
	"name": "Front Desk"
	}
}'
When a 200 HTTP response is received, the response body will include the Terminal ID and a status of either pending or active. A pending status after terminal onboarding indicates that changes are being applied. Any pending status will only last a few minutes at most, and will then transition to an active status. Here is what you might expect in the API response:
Copy
Copied
{
	"id": "eaf1ef26-ea2d-4be3-b990-ec2c410b54de",
	"resource": "terminals",
	"path": "/terminals/eaf1ef26-ea2d-4be3-b990-ec2c410b54de",
	"owner": {
		"id": "0ef0dcd6-a2c6-49c4-9051-bbbe5c6c36e2",
		"path": "/accounts/0ef0dcd6-a2c6-49c4-9051-bbbe5c6c36e2",
		"resource": "accounts"
		},
	"api_version": "3.0",
	"status": "active",
	"serial_number": "FA00332-1000138",
	"model": "verifone_p400",
	"reference_id": "abc12345",
	"last_call_home": 1549570307,
	"terminal_application_version": "1.27.311",
	"terminal_configuration": {
		"name": "Front Desk",
		"maintenance_window": {
			"start": 0,
			"duration": 1
			},
		"manual_entry_configuration": {
			"avs_prompt_enabled": true,
			"cvd_prompt_enabled": true
			},
		"address": {
			"city": "Redwood City",
			"country": "US",
			"line1": "250 Convention Way",
			"line2": "Suite 200",
			"postal_code": "94063",
			"region": "CA"
			},
		"timezone": "US/Pacific",
		"currency": "USD",
		"supported_card_brands": [
			"visa",
			"american_express",
			"discover",
			"mastercard",
			"diners_club",
			"jcb"
			],
		"credit_debit_preference": "prompt",
		"sim_card_id": "5aad45c2-d128-466a-aae3-d42fef57e2f7",
		"tip": {
			"mode": "prompt_on_terminal",
			"terminal_display": {
				"amount_guide_type": "percentage_guide",
				"percentage_guide": {
					"show_amount": false,
					"percentage_low": 15,
					"percentage_medium": 18,
					"percentage_high": 20
					}
				}
			},
		"signature_required": true,
		"contactless_payments": {
			"enabled": true,
			"credit_debit_preference": "credit"
			},
		"quick_chip": {
			"enabled": true
			},
		"deferred_authorization": {
			"enabled": true,
			"international_enabled": true,
			"max_transaction_count": 20,
			"max_total_amount": 250000,
			"max_transaction_amount": 12500,
			"supported_card_entry_modes": [
				"chip",
				"contactless"
				]
			}
		},
	"gateway_id": "AB00004D3Z"
}
The API response will also include the Terminal name in terminal_configuration.name, which is what the merchant will have access to in the terminal UI and will be referenced there as the TID. The name can also be retrieved by using the get Terminal info function in the Card Present SDK, which is also a useful, basic sanity check to ensure that your systems are communicating with the correct terminal.
Note
A merchant's Account must have the requirements outlined in the Fulfill Merchant Orders section fulfilled before the merchant can begin using a terminal. Please see the requirements outlined above, and check out our CIP/KYC Certification for more details on developing your CIP/KYC collection process.

Once updates are complete, the terminal can begin interacting with the Card Present SDK.

Note

Each terminal should only have one payment application instance to connect to the Card Present SDK.

Set the enable discovery config in your Card Present SDK to true in order to use the automatic device discovery feature (iOS: WPConfig.discoveryEnabled; Android: Config.isDiscoveryEnabled). Once any available updates have been applied, the SDK will return a list of discovered devices, which you should display in your application. Discovered devices will be designated by the readable name (configured in the terminal_configuration.name API parameter during onboarding) and serial number. Once the merchant selects the terminal from your application, the terminal's IP address will be passed to the Card Present SDK.

You can customize the number of seconds that the auto discovery feature will run before ending and delivering the list of results. To do so, set the seconds as an integer in the discovery timeout config (iOS: WPConfig.discoveryTime; Android: Config.discoveryTime). Note that the timeout config defaults to 8 seconds.

If the enable discovery config is left as false (this is the default), then the merchant will be prompted to manually enter the device's IP address, which can be found by following the Terminal User Manual.

Note
At this point, the merchant can access the gateway ID for their terminal. They can find instructions on how to do so in their terminal user manual. Initially, the gateway ID will be default to FFFFFFFF. Once the terminal's onboarding information has been downloaded onto the device, a new gateway ID will be assigned to it and should match the gateway_id found in the Terminal Onboarding record.

Once your platform has the IP address for the terminal, you can use the Card Present SDK to perform the get Terminal info function. Running this function is a good sanity check to verify that the correct merchant is associated with the freshly connected terminal.

From here, the terminal is ready to begin authorizing Card Present transactions, and you can skip ahead to Process Payments in order to continue that flow.

Plan for Other Use Cases

Outside of the onboarding and setup flow for Terminals, there are other use cases which your platform should be ready to handle:

Deactivate a Terminal

Some use cases may call for a terminal to be deactivated, but not offboarded. For instance, if a merchant reports a lost terminal, it should be deactivated, giving the merchant time to find it without risk of running fraudulent transactions.

In order to deactivate a terminal, simple send a POST /terminals/{id}/deactivate request like so:
Copy
Copied
curl -X POST \
 --url 'https://stage-api.wepay.com/terminals/{id}/deactivate' \
  -H 'App-Id: {your-app-id}' \
  -H 'App-Token: {your-app-token}' \
  -H 'Api-Version: 3.0' \
  -H 'Content-Type: application/json' \
Note
There will be a minimum latency of 10 seconds between calling POST /terminals/{id}/deactivate and failing handshakes/authorizations due to disconnection. This latency can last up to 5 minutes, but should typically not last longer than 1 minute.

To accommodate, be sure to build out validation of authorizations processed for the 5 minutes after a Terminal has been deactivated.

The API response will show ”status”: “inactive”. In order to re-activate the terminal, use the POST /terminals/{id}/activate endpoint.

Similar to the latency for deactivation, be aware that there could be a delay between activating a Terminal and successful authorizations.

Offboard a Terminal

Whenever a merchant is done processing card present transactions, your platform can offboard the terminal. A merchant might be done processing card present transactions if they are moving their business online, closing up shop, or moving to a different platform. It is up to you if your model involves merchants purchasing or renting the terminal, which will determine if your platform should expect the merchant to return the terminal during offboarding.

Whatever the case may be, send a DELETE /terminals/{id} request when a terminal is being offboarded:

Copy
Copied
curl -X DELETE \
 --url 'https://stage-api.wepay.com/terminals/{id} \
  -H 'App-Id: {your-app-id}\
  -H 'App-Token: {your-app-token}\
  -H 'Api-Version: 3.0'\
  -H 'Content-Type: application/json' \
Once this request receives a 200 response, the status will be deleted and that physical terminal cannot be used again until it is re-onboarded. If a terminal goes through onboarding again, the merchant will need to reset their terminal as outlined in the user manual.
Note

Each time a terminal is onboarded, a gateway ID will be assigned to that terminal. Do not assume that it will be a new gateway ID, as they can be recycled from an offboarded terminal.

From the merchant's perspective, the terminal's status bar will reflect that the handshake is failing once it's offboarded.

Example of a failed handshake
Example of a failed handshake

Merchants can find additional information on handshaking in the terminal user manual provided to them. Note that the status bar on the terminal may not immediately reflect the true status, so it's valuable for merchants to know how to perform a handshake manually.

If you plan on re-onboarding the terminal, follow the instructions in the Terminal User Manual in order to reset MIS settings. Once that step is taken, the hardware can be successfully re-onboarded.

Note

While offboarding a Terminal, there will be a minimum latency of 10 seconds between the API-level offboarding and the physical terminal being truly offboarded. This latency can last up to 5 minutes, but should typically last no more than 1 minute.

To accommodate, build a check for the 5 minutes after onboarding to validate authorizations prior to making a POST /payments API request.

Update a Terminal

Note

When there is a new API update which involves new options to configurations, one needs to update the terminal by calling the POST /terminals/{id} API with the updated configurations.

To provide merchants with the option of updating their customized terminal configuration, you'll collect the details being updated and then send a POST /terminals/{id} API request.

Changes in configuration will only be reflected on the physical terminal when it has performed an online update. Ways that a terminal can be updated include:

  • Automatic daily maintenance to check for and apply any available updates.
    • Default maintenance window is 2 AM - 6 AM in the terminal's timezone.
  • Merchant manually updates via terminal UI.
    • More information can be found in the terminal user manual.
  • Partner calls WePay Card Present SDK to update.
    • Use the update Terminal function.

Terminal updates, completed outside of the maintenance window, typically take 3-4 minutes to complete. If there is nothing to update on the terminal, the process will end in a few seconds.