For transactions subject to the EU Consumer Credit Directive II (CCD2), buyers must receive Standard European Consumer Credit Information (SECCI) before payment authorization.
Use generateSecci() to generate and deliver the document. The method returns an attestation token that must be included in the subsequent authorization request.
For details on CCD2 requirements and the buyer experience, see CCD2 with Payment API 2.0.
The SecciRequest specifies the payment method, shopping basket, currency, and delivery method.
| Field | Description |
|---|---|
currency | Three-letter uppercase currency code, such as EUR. |
delivery.method | PDF to return the document, or EMAIL to send it to the buyer. |
delivery.action | DOWNLOAD or PRINT. Required for PDF delivery. |
delivery.email | Buyer's email address. Required for EMAIL delivery. |
delivery.countryCode, delivery.language | Optional country and language settings for the document. |
paymentMethod.paymentOption | Payment option, such as OPEN_INVOICE or PAY_NOW. |
paymentMethod.transferType | Transfer type, such as BANK_TRANSFER or SEPA_DIRECT_DEBIT. |
shopBaskets | At least one basket containing partnerShopId, grossAmount, and at least one item or special item. |
The following example generates a SECCI document for an Open Invoice payment and returns the PDF for delivery to the buyer.
import com.ratepay.sdk.SecciOutcome;
import com.ratepay.sdk.model.api.secci.*;
import java.math.BigDecimal;
import java.util.List;
SecciRequest request = new SecciRequest(
"EUR",
new SecciDelivery(
SecciDeliveryMethod.PDF,
SecciDeliveryAction.DOWNLOAD,
"DE", // countryCode
null, // email
"de" // language
),
new SecciPaymentMethod(SecciPaymentMethodOption.OPEN_INVOICE, null), // paymentOption, transferType
List.of(
new SecciShopBasket(
new BigDecimal("249.00"), // grossAmount
"SHOP-001", // partnerShopId
List.of(
new SecciItem(new BigDecimal("249.00"),
"Ergonomic Office Chair",
new BigDecimal("1"),
new BigDecimal("19")) // grossUnitPrice, name, quantity, taxRate
),
null // specialItems
)
)
);
SecciOutcome outcome = client.generateSecci(request, null);
if (outcome.isDocument()) {
var document = (SecciOutcome.Document) outcome;
byte[] pdf = document.getPdf(); // show or print this to the buyer
String attestationToken = document.getAttestationToken();
} else {
var emailed = (SecciOutcome.Emailed) outcome;
System.out.println("SECCI sent, id " + emailed.getSecciId());
}To send the document directly to the buyer, set delivery.method to EMAIL and provide the buyer's email address.
SecciDelivery delivery = new SecciDelivery(
SecciDeliveryMethod.EMAIL,
null, // action, not used for email
"DE", // countryCode
"buyer@example.com", // email
"de" // language
);For email delivery, the SDK returns SecciOutcome.Emailed with a secciId rather than PDF content. The attestationToken is available for both delivery methods.
If you have already constructed an AuthorizationRequest, you can pass its shopBaskets directly to the generateSecci() overload instead of constructing the basket again.
SecciOutcome outcome = client.generateSecci(request, authorizationRequest.getShopBaskets(), null);The SDK converts the supplied Payment API baskets into the SECCI request format, replacing any shopBaskets already present in the SecciRequest.
Other fields, such as currency and paymentMethod, remain unchanged.
The SDK returns a SecciOutcome based on the selected delivery method.
| Outcome Kind | Description |
|---|---|
DOCUMENT | PDF delivery. Contains the SECCI PDF bytes and an attestation token. |
EMAILED | Email delivery. Contains the SECCI ID and an attestation token. No PDF is returned. |
Both outcomes include an attestationToken, corresponding to the API's X-Attestation-Token response header.
SECCI generation failures throw exceptions rather than returning a decline outcome.
After providing the SECCI to the buyer, pass the returned attestation token to the authorize() method.
AuthorizeOutcome authorization = client.authorize(authorizationRequest, outcome.getAttestationToken(), null);The SDK adds the token to complianceDetails.attestationToken in the authorization request.
The authorization must use the same basket and payment method as the SECCI. If these details change, generate and provide a new SECCI before authorizing the payment.
The attestation token is valid for seven days. If it expires before authorization, repeat the SECCI process.
For details, see Authorizing a payment.
Before sending the request, the SDK validates the required fields and throws RatepaySdkValidationException if validation fails.
The checks include:
- Delivery: A valid delivery method, action for PDF delivery, and a correctly formatted email address for email delivery.
- Payment method: A supported payment option; UNKNOWN values are rejected.
- Currency: Three uppercase letters.
- Shopping baskets: At least one basket with a non-empty partnerShopId, a positive grossAmount, and the required item information.
- Item details: Valid names, quantities, amounts, and tax rates.
The following exceptions may be thrown when generating a SECCI:
| Exception | HTTP Status Code |
|---|---|
RatepaySdkValidationException | (local checks) |
RatepayAuthException | 401/403 |
RatepayValidationException | 400 |
RatepayLegalException | 451 |
RatepayNetworkException | 5xx/transport |
The SDK supports idempotent requests. You can supply an idempotencyKey or let the SDK generate one automatically.
For more information, see Exception hierarchy and Idempotency and retries.
- Authorize a transaction using the SECCI attestation token.