General Requirements
Everything cross-cutting that every integration must know — the core principles, the configuration and credentials LoyaltyPlant provisions, security, operating constraints, and a glossary — regardless of whether you build with the SDK or the raw API. The build guides (SDK / API) reference this page.
Read after the Overview. This is a two-party setup — you build and host the service; LoyaltyPlant provisions the credentials and configuration that make it live. You cannot self-configure these values; LoyaltyPlant sets them for you.
1. Core principles
These five ideas run through the whole API. Each is detailed in Payment Flows.
- Capabilities-driven. You declare a set of capabilities at
GET /v1/capabilities. LoyaltyPlant will never call an operation whose capability you didn't declare. Declare only what you have actually implemented and tested. - Business outcome lives in HTTP 200. A business result — approved, declined, pending
— is always returned as
HTTP 200with astatusfield. HTTP4xx/5xxare reserved for infrastructure errors (bad request, auth failure, your service is down). A declined card is not an HTTP error. - Idempotent. Every mutating call carries an
Idempotency-Key. The same key must always produce the same result — LoyaltyPlant retries on transient failures and must never double-charge. - Synchronous when possible, asynchronous when needed. If a payment needs 3-D Secure or a
redirect, you return
PENDINGwith aredirectUrl, then report the final result with the asynchronous callback. - Reconcilable. If an outcome is ever ambiguous (timeout, lost callback), LoyaltyPlant can
ask your PSP for the truth via
POST /v1/inquire-status.
2. What you provide to LoyaltyPlant
| You provide | Notes |
|---|---|
| Your service base URL | Public HTTPS endpoint LoyaltyPlant will call (e.g. https://payments.your-domain.example). LoyaltyPlant appends /v1/.... |
Supported apiVersion | The version segment of the contract you implement (currently v1). |
| Declared capabilities | Must match what GET /v1/capabilities returns. |
| Egress IPs (optional) | Source IPs your service calls LoyaltyPlant from, if you want them allow-listed. |
Required settings keys | Any PSP-specific config (beyond currency) you need LoyaltyPlant to pass on each request — e.g. merchantId, processing IDs. |
| Operational contacts | On-call / incident contacts and your maintenance windows. |
3. What LoyaltyPlant provisions for you
LoyaltyPlant configures the following and shares the secrets with you over a secure channel:
| LoyaltyPlant provides | What it's for |
|---|---|
integrationId | Your integration's identifier; appears in the result-callback URL /gate/integration/{integrationId}/result. |
| Outbound token | Bearer token LoyaltyPlant sends you on every request. You validate it (see §4). |
| Inbound token | Bearer token you send LoyaltyPlant on the result callback. |
settings map | The per-client/outlet key/values (e.g. merchantId) provisioned by LoyaltyPlant at onboarding and delivered on each operation (currency always present, plus any keys you requested). You receive it; you don't define it. |
| Callback host | The payments-service host you POST results to. |
| Limits | Rate, concurrency, and timeout limits LoyaltyPlant enforces in front of your service (see §7). |
Internally, LoyaltyPlant stores these in its own configuration system — that's not your concern. From your side, they simply arrive during onboarding; treat the tokens as secrets.
4. Token directionality (read this twice)
There are two tokens and they travel in opposite directions. Mixing them up is the most common integration mistake.
| Outbound token | Inbound token | |
|---|---|---|
| Direction | LoyaltyPlant → you | You → LoyaltyPlant |
| Where it appears | Authorization on incoming /v1/* requests | Authorization on POST /gate/integration/{id}/result |
| Your job | Validate it (constant-time); reject others with 401 | Send it on the callback |
| If wrong | You accept unauthenticated traffic (security hole) | LoyaltyPlant returns 401 and the payment never resumes |
Store both as secrets (vault / secret manager), never in source control or logs. Rotate via LoyaltyPlant; support overlapping old+new during rotation so there's no downtime.
5. Security
- TLS with a valid certificate on your service; reject plaintext.
- Validate the outbound token on every
/v1/*request, using a constant-time comparison; reject mismatches with401(see §4). - Protect the inbound token (your callback credential) like any secret; never log it.
- Verify PSP webhook signatures before acting on a PSP notification — never trust an unverified payload (it drives the result callback).
- Durable idempotency store, keyed per integration (the
Idempotency-Keycontract is in the spec). - Consider IP allow-listing LoyaltyPlant's egress ranges (provided during onboarding).
- Never log full PANs or tokens; keep
reasonstrings free of sensitive data.
6. Environments
LoyaltyPlant provisions you separately in a sandbox/staging environment and in
production. Each environment has its own integrationId, tokens, callback host, and
limits — never reuse staging credentials in production. Point your service at your PSP's
sandbox in staging and at the live PSP in production. Complete certification in staging first.
7. Operational limits
LoyaltyPlant protects both sides with a rate limiter, a concurrency bulkhead, a circuit breaker, and request timeouts in front of your service. Typical default limits (LoyaltyPlant sets the actual values per integration during onboarding):
| Limit | Default | What it means for you |
|---|---|---|
| Request timeout | 10 s | Respond well within this; slow responses are abandoned and treated as retriable. |
| Connect timeout | 2 s | Your TLS/connection setup must be prompt. |
| Rate limit | 100 / s | Sustained request rate ceiling. |
| Max concurrency | 25 | Concurrent in-flight requests LoyaltyPlant will run against you. |
| Circuit-breaker threshold | 5 | Repeated failures trip a breaker that briefly stops traffic to protect you. |
Design for these: keep synchronous endpoints fast (push slow work to the async callback),
make operations idempotent, and keep health honest so the breaker and routing work for you.
8. Glossary
| Term | Meaning |
|---|---|
| Integration | The standalone REST service you host that implements this API. |
| integrationId | The identifier LoyaltyPlant assigns to your integration; appears in the result-callback URL (see §3). |
| PSP | Payment service provider — the gateway/acquirer behind your integration (your existing system). |
| Capability | A feature flag you declare (CAPTURE, SALE, DIRECT_REFUND, REDIRECT_FLOW, DIRECT_WEBHOOK, STATUS_POLLING, TOKENIZATION, APPLE_PAY, GOOGLE_PAY). Gates which operations LP calls. |
| Authorize | Reserve/hold funds without capturing them (first phase of a two-phase payment). |
| Capture | Settle funds previously held by an authorize. |
| Sale | Authorize and capture in a single step (single-phase payment). |
| Reverse | Void/cancel an authorization before capture (releases the hold). |
| Refund | Return funds after capture. |
| transactionReference | Your identifier for a payment at the PSP. You return it; LP stores it and uses it for follow-up operations and to match async callbacks. |
| outbound token | Bearer token LP sends you on every request; you validate it (see §4). |
| inbound token | Bearer token you send LP on the result callback (see §4). |
| Idempotency-Key | UUID on every mutating request; repeats must return the same result. |
| Redirect flow | A payment that needs the customer to complete authentication on another page (e.g. 3-D Secure) before it resolves. |
| Result callback | The POST /gate/integration/{id}/result request you send LP after an async payment resolves. |
| Status inquiry | POST /v1/inquire-status — LP asks you for the PSP's current status of a payment (reconciliation). |
SUCCESS / PENDING / DECLINED / RETRIABLE / UNKNOWN | The five operation outcomes carried in the status field. See Payment Flows. |
Next: Payment Flows →