Java SDK — OpenTelemetry
Both dev.paylera:paylera-sdk and
dev.paylera:paylera-spring-boot-starter emit OpenTelemetry spans
when an OTel SDK is on the host process classpath. With no SDK
present the calls are zero-cost no-ops — the API-only dep keeps the
abstraction free.
Tracer names
The protocol contract pins three tracer names so spans can be filtered by source:
| Tracer name | Where it’s used |
|---|---|
Paylera.Sdk | Typed client (PayleraClient) — one client-kind span per API call. |
Paylera.Relay | Spring starter’s relay controller — one server-kind span per relay route. |
Paylera.Webhook | Spring starter’s webhook receiver — one server-kind span per delivery. |
Span names are Paylera.<Op> (typed client), Paylera.Relay.<Op>
(relay), and Paylera.Webhook.<event> (webhook). The <Op> value
matches the OpenAPI operationId, so traces line up with the spec.
Span attributes
Every span carries at least:
| Attribute | Value |
|---|---|
paylera.endpoint | API path, e.g. /v1/check or /api/paylera/me. |
paylera.api_mode | "live" / "test" / "custom" (typed client only). |
Webhook spans add paylera.problem.type when a handler throws.
Typed client
opentelemetry-api is an optional dependency on paylera-sdk. Pass a
Tracer to the builder and the SDK emits one client-kind span per
public operation:
import dev.paylera.sdk.PayleraClient;import io.opentelemetry.api.GlobalOpenTelemetry;
var client = PayleraClient.builder() .apiToken(System.getenv("PAYLERA_API_TOKEN")) .tracer(GlobalOpenTelemetry.getTracer("Paylera.Sdk")) .build();Skip the tracer(...) call to opt out at zero cost — internally the
SDK uses a no-op tracer when none is supplied.
The span hierarchy:
your.app.span├── Paylera.Check (client kind)│ ├── http.client (OkHttp instrumentation)│ └── (server-side Paylera spans, when sampled)└── ...If your app has OkHttp HTTP-client instrumentation registered, you’ll
see an http.client child span per Paylera call — the SDK’s
client-span captures the operation context, the HTTP span captures
wire details.
Spring Boot starter
The starter declares opentelemetry-api as
<optional>true</optional> so merchant builds that already pin a
different OTel version aren’t surprised by transitive resolution.
To wire spans:
-
Add the OpenTelemetry SDK to your host app’s POM. For example:
<dependency><groupId>io.opentelemetry</groupId><artifactId>opentelemetry-api</artifactId></dependency><dependency><groupId>io.opentelemetry</groupId><artifactId>opentelemetry-sdk</artifactId></dependency>Or use the Spring Boot OpenTelemetry starter:
<dependency><groupId>io.opentelemetry.instrumentation</groupId><artifactId>opentelemetry-spring-boot-starter</artifactId></dependency> -
Configure an exporter — OTLP to your collector, Zipkin, Jaeger, etc. The Paylera starter is transport-agnostic; whatever OTel SDK is registered as the global instance picks up the spans.
That’s it. The autoconfig registers two Tracer beans
(payleraRelayTracer, payleraWebhookTracer) via
GlobalOpenTelemetry.getTracer(...). With no SDK installed those
return no-op tracers — span emission is silently free.
To wire a custom tracer (different exporter, different sampler):
@Bean(name = "payleraRelayTracer")Tracer payleraRelayTracer(OpenTelemetry openTelemetry) { return openTelemetry.getTracer("MyApp.PayleraRelay");}@ConditionalOnMissingBean(name = "payleraRelayTracer") in the
autoconfig backs off to your bean. The same pattern works for
payleraWebhookTracer.
Cross-tier trace propagation
The relay forwards inbound traceparent / tracestate headers to
Paylera, and Paylera echoes them on the response. End-to-end a
single trace spans:
React SDK fetch span└── Spring Boot starter Paylera.Relay.Check span └── Paylera Java client Paylera.Check span └── http.client span └── (Paylera server-side spans, when sampled)The React SDK populates traceparent from the global OTel context if
@paylera/react’s provider sees an active span; without one, the
client passes through whatever the upstream sent.
Sampling
The SDK does not configure a sampler — that’s the host app’s job. For
a high-volume check workload, consider:
- Ratio sampling (e.g. 10% of
Paylera.Checkspans). - Tail-based sampling at the collector — keep 100% of error traces, 10% of OK traces.
- A custom sampler that always keeps spans with
paylera.problem.typeset.
Disabling
To turn off Paylera spans without uninstalling the OTel SDK, configure a sampler that drops everything from the Paylera tracers, or override the bean with a no-op tracer:
@Bean(name = "payleraRelayTracer")Tracer payleraRelayTracer() { return io.opentelemetry.api.trace.TracerProvider.noop().get("paylera");}See also
- Spring Boot starter — autoconfig overview.
- Direct client — wiring tracers without Spring.
- Relay protocol § Observability — the cross-language tracer-name contract.