Concepts
Fundamental concepts for integrating with the Owem Pay API.
Security Architecture
The API employs three independent layers of protection. All are mandatory.
Layer 1 -- API Key + Secret
Each integrator receives a pair of credentials (client_id and client_secret). The secret is never stored in plain text -- we only store the hash. When a request arrives, the submitted secret is compared against the stored hash. If it does not match, the request is rejected immediately, before reaching business logic.
Layer 2 -- Per-Request HMAC-SHA512 Signature
In addition to the API Key, each transactional request (POST) must include an HMAC-SHA512 signature in the hmac header.
The process works as follows:
- The integrator serializes the request body as JSON
- Generates the HMAC-SHA512 hash using the
client_secretas the key - Sends the hash in hexadecimal format in the
hmacheader
On our side, we recalculate the hash using the same method and compare it with the received value. If any byte of the content is altered in transit (e.g., in a man-in-the-middle attack), the signature will not match and the request is rejected with a 401 error. This comparison is performed using constant-time comparison, which prevents timing attacks that attempt to discover the signature byte by byte.
Layer 3 -- Mandatory IP Whitelist
Each API Key can only be used from previously authorized IPs. Even if someone gains access to the credentials, they will not be able to use the API from another IP. Requests from unauthorized IPs receive 403 Forbidden.
Additional Protections
| Protection | Description |
|---|---|
| Rate Limiting | 60,000 requests/minute per IP. Unauthenticated endpoints: 5 req/min |
| Cloud Armor (WAF) | Web application firewall protecting the GKE cluster |
| Mandatory HTTPS | TLS 1.2 or higher on all connections |
| HSTS | HTTP Strict Transport Security enabled |
Full details: Authentication | HMAC-SHA512
Why HMAC and not mTLS?
mTLS (mutual TLS) adds authentication via X.509 certificate at the connection level. It is a valid layer, but in our scenario per-request HMAC provides equivalent or more suitable protection:
| Aspect | mTLS | HMAC-SHA512 |
|---|---|---|
| What it validates | The connection (TLS channel) | Each individual request |
| Payload integrity | No -- if the connection is trusted, requests pass through | Yes -- any change to the body causes the request to be rejected |
| Operational management | Complex: issuance, rotation, revocation, CRL/OCSP | Simple: generate new pair, update, invalidate previous |
| Common incidents | Expired or mismanaged certificates | Rare -- key is a string with no complex lifecycle |
TLS already ensures transport encryption. HMAC serves as an additional layer, ensuring payload integrity and authenticity -- something that mTLS alone does not cover.
Monetary Values
The Owem Pay API uses two different units depending on the direction:
| Direction | Unit | Scale | Example R$ 30.00 |
|---|---|---|---|
| Request sent (request body) | centavos | BRL x 100 | 3000 |
| Response received (response body) | base units | BRL x 10,000 | 300000 |
Quick Conversion
- To send: multiply the BRL value by 100. R$ 30.00 =
3000 - To read responses: divide by 10,000.
300000/ 10,000 = R$ 30.00 - Never use floating point -- always integers
Reference Table
| BRL Value | Request (centavos) | Response (base units) |
|---|---|---|
| R$ 1.00 | 100 | 10000 |
| R$ 30.00 | 3000 | 300000 |
| R$ 150.50 | 15050 | 1505000 |
| R$ 1,000.00 | 100000 | 10000000 |
Attention
The value 3000 in the request (R$ 30.00) becomes 300000 in the response. They are the same BRL value, represented in different units. If you divide the response by 100 instead of 10,000, you will get R$ 3,000.00 instead of R$ 30.00.
External ID
The external_id field is an optional identifier that you define in your system to track transactions. It is accepted in cash-in and cash-out endpoints and returned in all associated responses and webhooks.
| Attribute | Value |
|---|---|
| Required | No |
| Maximum length | 128 characters |
| Allowed characters | Alphanumeric, ., _, :, - |
| Regex | ^[a-zA-Z0-9._:\-]+$ |
| Example | "order-9876", "invoice-4521", "ref:2026-03-07:001" |
In addition to being returned in responses, you can query a transaction by external_id:
GET /api/external/transactions/ref/{external_id}Tracking
Use the external_id to correlate Owem Pay transactions with orders, invoices, or records in your system. Duplicate values are not rejected, but we recommend uniqueness to simplify reconciliation.
Idempotency
Write requests (POST) accept the Idempotency-Key header to prevent duplicate processing. If the same key is sent in a second identical request within 24 hours, the API returns the original cached response instead of processing again.
Idempotency-Key: unique-request-id-123| Attribute | Value |
|---|---|
| Header | Idempotency-Key |
| Maximum length | 256 characters |
| Cache TTL | 24 hours |
| Applies to | POST only (cash-in, cash-out, refund, webhooks, CPF) |
| Replay response | Header X-Idempotent-Replay: true |
Important
The idempotency key considers method + path + key. Two requests to different endpoints with the same key are treated as distinct operations.
Transaction Status
Cash In (Receipts)
| Status | Description |
|---|---|
active | QR Code generated, awaiting payment |
pending | Payment detected, processing |
completed | Payment confirmed and credited to the account |
failed | Payment failed |
cancelled | QR Code expired (24h) or cancelled |
Cash Out (Transfers)
| Status | Description |
|---|---|
pending_approval | Awaiting approval (create + approve flow) |
processing | Sent to SPI, awaiting settlement |
completed | Successfully settled |
failed | Rejected by SPI or processing error |
refunded | Returned (fully or partially) |
End-to-End ID (E2E ID)
Unique identifier of a PIX transaction within the Central Bank ecosystem. Standard format:
E{ISPB}{YYYYMMDDHHMM}{sequential}Example: E37839059202603071530000001
| Component | Value | Description |
|---|---|---|
E | Fixed prefix | Identifies as E2E ID |
37839059 | Owem Pay ISPB | 8 digits |
202603071530 | UTC date and time | YYYYMMDDHHMM (12 digits) |
000001 | Sequential | 6 digits |
The E2E ID is automatically generated by Owem Pay and returned in the response of each PIX operation. Use it to track transactions between institutions.
PIX Key Types
| Type | Format | Example | Individual Limit | Business Limit |
|---|---|---|---|---|
cpf | 11 digits | 12345678901 | 1 | -- |
cnpj | 14 digits | 12345678000190 | -- | 1 |
email | Valid email | contato@empresa.com.br | 5 | 20 |
phone | +55 + area code + number | +5511999998888 | 5 | 20 |
evp | UUID v4 (random key) | a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d | 5 | 20 |
Response Pattern
All API responses follow the pattern:
Success
{
"worked": true,
...
}Error
{
"worked": false,
"detail": "Error description"
}The worked field indicates whether the operation succeeded (true) or failed (false). In case of error, the detail field describes the reason.