CREDIT_CARD and DEBIT_CARD transactions with the Rinne Core API.
Rinne officially supports both 3DS strategies for card payments: session-first and transaction-first.
Transaction endpoints (self vs merchant)
| Context | Create transaction | Authenticate pending transaction |
|---|---|---|
| Self (company) | POST /v1/transactions | POST /v1/transactions/{id}/authenticate |
| Organization on behalf of merchant | POST /v1/merchants/{merchantId}/transactions | POST /v1/merchants/{merchantId}/transactions/{id}/authenticate |
Prerequisites
- Active affiliation for card payments.
ECOMMERCEcapture enabled for online transactions.- One unique
request_idper payment attempt. - Encrypted card values from RinneJS secure components.
Required transaction shape
Payment provider configured for the affiliation.
Idempotency key for creation.
Amount in cents.
Use
ECOMMERCE for card-not-present checkout.CREDIT_CARD or DEBIT_CARD.Card payload for card transactions.
Card data rules
- Send exactly one of
card_data.numberorcard_data.network_token. - Send
expiry_month(MM) andexpiry_year(YYYY). - For authenticated/tokenized flows, provide cryptogram directly or via
three_d_secure_session_idinjection. - For wallet tokenized flows, include
wallet_type(APPLE_PAYorGOOGLE_PAY).
3DS challenge strategy flags
TransactionCreateRequest supports two optional card-only flags:
When
true, card transaction creation always goes directly to AWAITING_3DS. Provider authorization is deferred until /authenticate is called with an authenticated 3DS session.When
true, any path that would require a challenge (risk-triggered or soft-decline-triggered) is refused immediately (REFUSED) instead of transitioning to AWAITING_3DS.Why these flags are useful
| Flag | Immediate status behavior | What your backend still handles | What this avoids |
|---|---|---|---|
require_3ds | Always creates card transactions in AWAITING_3DS | Create 3DS session, complete challenge when required, and call /authenticate | Implementing a second session-first architecture only to enforce 3DS policy |
refuse_on_challenge | Returns REFUSED with status_reason=CHALLENGE_NOT_ALLOWED when challenge would be required | Handle refusal/retry paths only | Implementing challenge UX and pending AWAITING_3DS operational queues for that scope |
require_3ds, organizations that already run transaction-first can enforce 3DS for all or selected transactions without adding a separate session-first policy path.
The transaction enters AWAITING_3DS immediately, which is the status you already handle in this flow.
With refuse_on_challenge, challenge-triggered flows do not enter AWAITING_3DS; they stop immediately as REFUSED, so your operation fails fast and carries no challenge-handling workload.
refuse_on_challenge changes only challenge-triggered paths. Transactions that do not require challenge continue normal provider processing.CHALLENGE_NOT_ALLOWED status reason
When refuse_on_challenge is true and a challenge would be required (risk-triggered or soft-decline-triggered), transaction response uses:
status = REFUSEDstatus_reason = CHALLENGE_NOT_ALLOWED
Policy granularity
Because these flags are part of each transaction request, you can apply policies with fine control:- Per merchant (choose behavior by
merchantIdin your backend routing). - Per payment flow (for example, mobile app vs web checkout).
- Per transaction segment (risk tier, issuer group, customer cohort, high-value purchases).
Example: standard card transaction
cURL
Example: force transaction-first 3DS
cURL
Example response
Example: fail fast when challenge is not allowed
cURL
Example response
Card transaction lifecycle highlights
| Status | Meaning | Typical next action |
|---|---|---|
PROCESSING | Authorization in progress | Wait for webhook/result fetch |
AWAITING_3DS | 3DS authentication required | Complete 3DS and call /authenticate |
AUTHORIZED | Authorized but not captured | Follow capture policy |
APPROVED | Payment accepted | Fulfill order |
REFUSED | Payment declined | Retry with new attempt/payment method |
Retry and idempotency
- Generate one
request_idper attempt. - Reuse same
request_idonly for safe retries of the same attempt. - Use a new
request_idfor a new customer attempt.
Integration with RinneJS
- Use Card Element for encrypted card capture.
- Use Guide: Card + 3DS Checkout for frontend 3DS orchestration.
- Use 3D Secure authentication for backend 3DS API contracts.
Your card integration is production-ready when you correctly handle
PROCESSING, AWAITING_3DS, APPROVED, REFUSED, and the CHALLENGE_NOT_ALLOWED status reason.
