Local communication between PDV, service/SDK and PINPad
Integrate TEF.
Your in-person operation
powered by IOPAY
Power up your connected face-to-face sales by finishing TEF! Bring the power of management control of Iopay technology to your operation
A well-defined two-tiered integration
TEF in-person capture takes place locally between Your Applicationthe Zoop component and the PINPad The payment transaction, however, remains integrated into IOPAY. This preserves a single layer for account, transaction management, terminal activation, events and webhooks
Use Zoop Desktop SDK or Zoop Desktop Server to local TEF capture. Continue using IOPAY APIs + webhooks for the remainder of the operational and transactional cycle
Credentiation, Account, Terminal Activation, Transaction and Webhooks
Keep your APIs and IOPAY webhooks and add local TEF capture
Who does what in integration
The separation below prevents the use of the Zoop component for local capture from being confused with an exchange of the main integration of the operation
| Part of the | Responsibility in the project |
|---|---|
| Your Application | Integrate TEF capture with Zoop Desktop SDK or Desktop Server and maintain integration with IOPAY APIs and webhooks |
| IOPAY | Establishment accreditation, account, portal terminal activation, webhooks and transaction flow |
| SDK / Server Zoop | TEF location capture call and communication between your Application and PINPad |
| PINPad / terminal | Physical device responsible for interacting with the card and the carrier during capture. |
For this integration model, whenever the Zoop activation stream requests that a token be confirmed on the — dashboard — , the operational link must be completed on portal IOPAY → Payment terminals → Adding terminal.
SDK Embedded or Desktop Server
There are two documented ways to implement the local layer Both preserve the same IOPAY architecture for account, activation and events
Library Embedded in Your Application Indicates when the PDV can directly consume the plugin and control local communication with the terminal
Local service in the background Your Application talks to him via WebSocket, usually on
ws://localhost:1337.
From the empty project to the first payment in five steps
Prepare the design and the terminal
Confirm with IOPAY the terminal and test environment. Configure Zoop's Maven repository, select the artifact corresponding to your platform — JVM, Android or KMP — , and add the auxiliary dependencies indicated in the official documentation Use the agreed version for the project
implementation(
"br.zoop.pos.plugin:zoop-pos-plugin-desktop-jvm:X.Y.Z"
)
Downloading packages may require a GitHub user and a PAT with reading permission This access is for the development/distribution of the artifact only and is separate from the authentication of the terminal
Start without payment credentials
On the first activation, boot Zoop without the credentials block and connect the DesktopPlugin. In JVM, also report application data when required by the SDK version; block
application doesn't apply to Android
Zoop.initialize(context)
val desktopPlugin = DesktopPlugin(
Zoop.constructorParameters()
)
Zoop.plug(desktopPlugin)
Run the token and link to the IOPAY portal
Create the activation request with
createDashboardActivationRequestBuilder()treat the tokenCallback and send the request with: Zoop.post(). Show the token to the operator and use it on the IOPAY em portal
Payment terminals → Adding terminal. Then wait for the confirmation returned by the SDK
val activationRequest =
ZoopFoundationPlugin
.createDashboardActivationRequestBuilder()
.tokenCallback(/* receber e exibir o token */)
.confirmCallback(/* persistir dados confirmados */)
.build()
Zoop.post(activationRequest)
Continue activation and authenticate automatically
No , not confirmCallbacksave the data returned by activation In the next initialization, reuse
marketplace, seller and
accessKey. Activation is done once per device as long as this data remains valid and available
{
"marketplace": "<retornado-na-ativacao>",
"seller": "<retornado-na-ativacao>",
"accessKey": "<retornado-na-ativacao>"
}
Make the first payment
Before you sell, confirm the presence of the transaction key on the PINPad Then create a sale with
DesktopPlugin.createPaymentRequestBuilder()Inform the value in cents, modality and installments applicable and deal with messages, success, failure and end of flow.
Your Application does not need to request or pre-enter payment keys to activate each terminal The technical data used in the following initializations are obtained in the activation flow and persisted by the application itself.
Zoop Desktop SDK integrated directly into PDV
In this approach, the capture component is within Your Application The plugin converses locally with PINPad while the operation remains linked to IOPAY infrastructure
Initiation after activation
After that marketplace, seller and
accessKey if they have been recovered and persisted, use those values in runtime to restart the SDK They must not be manually typed by the operator
Zoop.initialize(context) {
credentials {
marketplace = storedMarketplace
seller = storedSeller
accessKey = storedAccessKey
}
}
val desktopPlugin = DesktopPlugin(
Zoop.constructorParameters()
)
Zoop.plug(desktopPlugin)
State of integration
Initializes without credentials, generates tokens and waits for link through the IOPAY portal
Your App store marketplace, seller and accessKey securely
Saved data is reused without re-typing by the operator
The token is born in the SDK and the link is completed in IOPAY
Activation associates the device with the correct account This step must occur before the first transaction and must be tested also after you restart your application
Your Application requests activation of the Zoop component and receives a temporary token
The token is reported in Payment Terminals → Add Terminal
SDK returns the data that Your Application needs to persist for future initializations
Save the returned data in a secure manner. Evit marketplace, seller and accessKey on user screens, application logs, open telemetry or debug dumps
Consult the transaction key before charging
The Zoop transaction key needs to be in the PINPad for card payments to be executed If you are absent, tap IOPAY to coordinate the correction with the equipment supplier
Do not treat the absence of the key as a software-only error in the PDV The terminal needs to be regulated before the transaction
Example of card charge
val paymentRequest = DesktopPlugin
.createPaymentRequestBuilder()
.amount(1000) // R$ 10,00 — valor em centavos
.option(Option.CREDIT)
.installments(2)
.referenceId("pedido-84217")
.callback(/* tratar sucesso e falha */)
.build()
Zoop.post(paymentRequest)
Treat also the flow intermediate messages to show the operator instructions such as approaching, inserting or reading the card Local feedback allows PDV to keep track of what's happening at the terminal
What persists of the result
Relate the local transaction to the order and operation accompanied by IOPAY.
Preserve NSU and authorization code returned for reconciliation and support
Save the proof data made available by the SDK version in use.
The callback onComplete indicates that the flow has ended, even when there was a failure Consider the approved payment only from the corresponding successful return and correlate the result with the IOPAY transaction.
Alternative via local WebSocket
Zoop Desktop Server runs as a local service and exposes a WebSocket to Your Application Your scope continues to be TEF capture Accreditation, account, webhooks and transactional flow remain on IOPAY platforms
Install and start the service
Get the installer in official Zoop releases In the Windows and Linux installations described in the guide, prepare Java/JDK 17, valid with
java -version and keep the server running on the PINPad-connected station
java -version
Connect your app
When Your Application and Desktop Server are on the same machine, connect to the local address below Treat socket opening, messages, errors and closing
ws://localhost:1337
const socket = new WebSocket('ws://localhost:1337');
socket.onopen = () => {
console.log('Desktop Server conectado');
};
socket.onmessage = (event) => {
const message = JSON.parse(event.data);
handleZoopMessage(message);
};
socket.onerror = (error) => {
handleSocketError(error);
};
socket.onclose = () => {
handleSocketClosed();
};
Start the activation
Send it in . {"type":"activation"}. When the server responds with status
tokenPresent the field
token and complete the link on the IOPAY portal Save Status
success.
{
"type": "activation"
}
In Success, Persist marketplace,
seller and accessKey for upcoming initializations
Start with the recovered data
Send the message initialize using exactly the values stored after activation. The field devicePort is optional; when omitted, the server can automatically detect the PINPad. Wait a minute . status: success
before allowing transactions
{
"type": "initialize",
"marketplace": "<valor recebido na ativacao>",
"seller": "<valor recebido na ativacao>",
"accessKey": "<valor recebido na ativacao>"
}
Implement the catch in the VPD
Use the JSON schemes documented by Desktop Server for local capture commands and handle all returns Local response serves to conduct the PINPad experience; transactional management and webhooks continue through IOPAY
<valor recebido na ativacao> represents the data persisted by your Application These are not information that the operator has to enter at each start.
Your Application continues receiving events from IOPAY.
Adding TEF does not change the asynchronous integration agreement: Your Application continues to receive webhooks from IOPAY for each event and transaction according to the contracted integration SDK/Server Local Return complements the PDV experience; it does not eliminate the IOPAY event layer
Transactions, operational updates and integration events
Keep your webhook endpoint and correlate events with request, terminal and local transaction
Recommended correlation model
Use your own identifier to link payment to your application request when available
Save the identifiers returned by the terminal's local flow
Update the status of the operation with the events received by the IOPAY integration
The TEF component is local, but Your Application does not need to abandon the existing flow of IOPAY APIs and webhooks Continue validating the webhooks of each event and transaction during homologation
Exercise faults before approval
Don't just validate the approval scenario The pilot must consider communication failures, expired token, interruption during capture, restart application and cancellations
When applicable to local flow, use the commands documented by the SDK to interrupt/cancel an ongoing operation
Server has its own cancellation and status message streams Treat Start, Selection, Success, Failure and End according to the documentation of the version used
Cancelement also applies to the IOPAY transaction flow. Before repeating a charge after failure to communicate, confirm the actual status of the transaction to avoid duplication
Activation data must remain outside the interface and logs
marketplace, seller and accessKey are part of the technical startup of the device Your Application must protect and use them automatically after activation
Use a local mechanism appropriate to the platform and restrict access to processes that actually need the data
Do not enter accessKey or equivalent data in logs, traces, error messages or analytics
Activation is technical The operator should not need to copy credentials to sell
Checklist before releasing the pilot
Accreditation, account and transactional flow continue through IOPAY platforms, with webhooks validated for integration events and transactions
Confirm the link in Payment Terminals → Add Terminal and restart Your Application to validate the use of the saved data
Show SDK messages, successfully differentiate simple flow termination and preserve transactionId, NSU, authorization code and proofs/receipt data
This communication failure test, token expiration, capture interruption and cancellations in IOPAY flow and local layer where applicable.
Confirm the presence of the transaction key before the first sale If it is absent, tap IOPAY to coordinate the correction with the supplier
Activation data stored securely and absent from screens, logs and improper telemetry
Official documentation for implementation
Use the guides below as a technical reference for the version of the component installed in the project Parameters, compatibility, versions and protocols may evolve; always validate official documentation during implementation
The flow has been structured from the IOPAY technical guide for TEF integration and the public references of Zoop. Use the approved version for the project and confirm full parameters in the official guides at the time of implementation
Ready to approve the first terminal?
Manage the token through the SDK or Desktop Server, link the terminal to the IOPAY portal and validate the full flow — local capture, transaction and webhooks — before proceeding to production

