Skip to content

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.

Request

The SecciRequest specifies the payment method, shopping basket, currency, and delivery method.

FieldDescription
currencyThree-letter uppercase currency code, such as EUR.
delivery.methodPDF to return the document, or EMAIL to send it to the buyer.
delivery.actionDOWNLOAD or PRINT. Required for PDF delivery.
delivery.emailBuyer's email address. Required for EMAIL delivery.
delivery.countryCode, delivery.languageOptional country and language settings for the document.
paymentMethod.paymentOptionPayment option, such as OPEN_INVOICE or PAY_NOW.
paymentMethod.transferTypeTransfer type, such as BANK_TRANSFER or SEPA_DIRECT_DEBIT.
shopBasketsAt 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());
}

Deliver the SECCI by email

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.

Reuse a basket from an authorization request

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.

Handle the response

The SDK returns a SecciOutcome based on the selected delivery method.

Outcome KindDescription
DOCUMENTPDF delivery. Contains the SECCI PDF bytes and an attestation token.
EMAILEDEmail 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.

Authorize the payment with the attestation token

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.

Client-side validation

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.

Exceptions

The following exceptions may be thrown when generating a SECCI:

ExceptionHTTP Status Code
RatepaySdkValidationException(local checks)
RatepayAuthException401/403
RatepayValidationException400
RatepayLegalException451
RatepayNetworkException5xx/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.

Next steps

  • Authorize a transaction using the SECCI attestation token.