Migrating from v1
v1 keeps working. v2 lives under /v2/* as a separate surface, so you migrate one integration at a
time and roll back by pointing the base URL back at /v1.
Side by side
| v1 | v2 | |
|---|---|---|
| Base URL | https://api.sdb.lbpay.com.br/v1 | https://api.sdb.lbpay.com.br/v2 |
| Credential | client_id + client_secret | client_id + your public key |
| Token request | form with the secret | client_assertion (JWT) + DPoP proof |
| Token lifetime | 2 hours | 60 seconds |
| Auth header | Authorization: Bearer <token> | Authorization: DPoP <token> |
| Extra header | DPoP: <fresh proof per request> | |
| Source IP | not checked | checked against the credential's list |
What changes in your code
Three things, and nothing else:
- The token function. Instead of posting a secret, sign two short JWTs. The private key is loaded once at startup; everything else is the same HTTP call.
- A proof per request. One function that takes method, URL and body, and returns a header.
- Renewal. Every 35 to 45 seconds instead of every two hours, with singleflight so concurrent calls do not each trigger a renewal.
Your business calls (paths, payloads, responses) do not change shape because of authentication.
Suggested order
Start with a read_only credential and a single GET route. It exercises the whole mechanism (token,
proof, clock, IP list) with no money involved. Only then move the write routes.
Common mistakes on the first day
- Renewing the token per request. It works, and it wastes a round trip on every call. Cache it.
htuwith the query. It goes inqh, never inhtu.- Hashing a re-serialized body. Hash the exact bytes you send.
- Forgetting
bhon GET. It is the hash of the empty string, not an absent field. - Container clock. A drift over 60 seconds fails every proof; it is the most common cause of "works locally, fails in production".
- Not knowing your exit addresses. The IP list is required, so it helps to check, before the migration, which addresses your integration actually leaves from. Usually the NAT gateway, the proxy or the cluster egress, rather than the address of the machine running the code.