This directory contains example code and tutorials for using the Exact Online Client.
Note: This client is read-only and designed for fetching data from Exact Online. It does not support creating, updating, or deleting data in Exact Online.
See oauth2-example.md for a step-by-step guide on setting up OAuth2 authentication.
See api-client-example.md for examples of fetching accounts, subscriptions, and transactions.
See webhook-example.md for setting up and handling webhooks.
@RestController
@RequiredArgsConstructor
public class AccountController {
private final ExactOnlineApiClient apiClient;
@GetMapping("/accounts")
public ResponseEntity<List<ExactOnlineAccountDto>> getAllAccounts() {
List<ExactOnlineAccountDto> accounts = apiClient.fetchAllAccounts().block();
return ResponseEntity.ok(accounts);
}
}@RestController
@RequiredArgsConstructor
public class WebhookController {
private final ExactOnlineWebhookService webhookService;
@PostMapping("/subscribe")
public ResponseEntity<String> subscribe() {
UUID subscriptionId = webhookService.subscribeToWebhook(
"https://your-app.com/webhook",
"Accounts"
).block();
return ResponseEntity.ok("Subscribed with ID: " + subscriptionId);
}
}@RestController
@RequiredArgsConstructor
public class WebhookHandlerController {
private final ExactOnlineWebhookRouter webhookRouter;
@PostMapping("/webhook")
public ResponseEntity<Void> handleWebhook(
@RequestBody WebhookNotificationDto notification) {
webhookRouter.routeNotification(notification);
return ResponseEntity.ok().build();
}
}# application.yml
exact-online:
oauth2:
client-id: ${EXACT_ONLINE_CLIENT_ID}
client-secret: ${EXACT_ONLINE_CLIENT_SECRET}
division-id: ${EXACT_ONLINE_DIVISION_ID}
redirect-uri: ${EXACT_ONLINE_REDIRECT_URI:http://localhost:8080/callback}See the root docker-compose.yml for a complete example with all services.
@Component
public class CustomAccountHandler implements WebhookTopicHandler {
@Override
public String getTopic() {
return "Accounts";
}
@Override
public void handleNotification(JsonNode data, String key) {
// Your custom logic here
log.info("Account updated: {}", key);
}
}@Service
@RequiredArgsConstructor
@ConditionalOnProperty(name = "exact-online.events.enabled", havingValue = "true")
public class CustomEventService {
private final AmqpTemplate amqpTemplate;
public void publishCustomEvent(MyEvent event) {
amqpTemplate.convertAndSend(
"exact-online-events",
"custom.routing.key",
event
);
}
}- Check the test files in
src/test/javafor more usage examples - Review the controller implementations in
src/main/java/io/exactonline/client/controller/ - See the service layer for business logic examples