Consumer loan application and origination flow.
Application Flow
1. (Optional) Get anonymous offer to show preliminary rate
2. Create application → triggers credit scoring
3. (Optional) Link account snapshot for final credit check
4. (Optional) Upload purchase contract for financed goods
5. Review offers → download SECCI pre-contract PDF (required by law)
6. (Optional) Subsidize an offer to reduce interest rate
7. Retrieve final contract PDF → present to customer for e-signing
8. PUT consumer_loan → creates loan and initiates payoutLegal Requirements
Per EU Consumer Credit Directive, the SECCI pre-contract document must
be shown to the customer before they sign. Always call get_secci/3
and present it before proceeding to contract signing.
Webhook
Monitor CONSUMER_LOAN_APPLICATION for status transitions:
OFFERED— offers available for reviewACCOUNT_SNAPSHOT_REQUIRED— snapshot needed for final scoringREJECTED— application declinedLOAN_CREATED— loan issued, payout initiated
Summary
Functions
Creates a consumer loan application for a person.
Creates the loan and initiates payout.
Returns a non-binding loan offer based on self-declared financial info.
Retrieves a consumer loan application.
Downloads the final loan contract PDF for e-signing.
Downloads the SECCI pre-contract PDF for a loan offer.
Returns representative 2/3 interest rates per loan term (regulatory disclosure).
Links an account snapshot to the application for final credit scoring.
Skips the account snapshot step in the application.
Subsidizes a loan offer to reduce the interest rate.
Uploads a purchase contract for a financed good (e.g. hire-purchase).
Functions
@spec create_application(String.t(), map(), keyword()) :: {:ok, map()} | {:error, Solaris.Error.t()}
Creates a consumer loan application for a person.
Triggers credit scoring. Monitor CONSUMER_LOAN_APPLICATION webhook
for status transitions.
Required fields
:amount— loan amount in cents:currency— e.g."EUR":term_months— loan term in months:purpose— loan purpose code
Examples
{:ok, application} = Solaris.Lending.ConsumerLoans.create_application("cper_123", %{
amount: 10_000_00,
currency: "EUR",
term_months: 36,
purpose: "CONSUMER_GOODS"
})
@spec create_loan(String.t(), String.t(), map(), keyword()) :: {:ok, map()} | {:error, Solaris.Error.t()}
Creates the loan and initiates payout.
This is the final step — after the customer has reviewed the SECCI
and signed the contract. Sets application status to loan_created.
Examples
{:ok, loan} = Solaris.Lending.ConsumerLoans.create_loan(
"cper_123",
"capp_456",
%{offer_id: "coffer_789", signing_id: "csign_012"}
)
@spec get_anonymous_offer( map(), keyword() ) :: {:ok, map()} | {:error, Solaris.Error.t()}
Returns a non-binding loan offer based on self-declared financial info.
No person record required — useful for pre-qualification UX.
Examples
{:ok, offer} = Solaris.Lending.ConsumerLoans.get_anonymous_offer(%{
amount: 5_000_00,
currency: "EUR",
term_months: 24,
monthly_income_cents: 300_000,
employment_status: "EMPLOYEE"
})
@spec get_application(String.t(), String.t(), keyword()) :: {:ok, map()} | {:error, Solaris.Error.t()}
Retrieves a consumer loan application.
@spec get_contract(String.t(), String.t(), String.t(), keyword()) :: {:ok, binary()} | {:error, Solaris.Error.t()}
Downloads the final loan contract PDF for e-signing.
Only available after SECCI has been presented.
@spec get_secci(String.t(), String.t(), String.t(), keyword()) :: {:ok, binary()} | {:error, Solaris.Error.t()}
Downloads the SECCI pre-contract PDF for a loan offer.
Required by EU Consumer Credit Directive — must be shown to the customer before they sign the loan contract.
Examples
{:ok, pdf_binary} = Solaris.Lending.ConsumerLoans.get_secci(
"cper_123",
"capp_456",
"coffer_789"
)
File.write!("secci.pdf", pdf_binary)
@spec get_two_thirds_rates(keyword()) :: {:ok, map()} | {:error, Solaris.Error.t()}
Returns representative 2/3 interest rates per loan term (regulatory disclosure).
Examples
{:ok, rates} = Solaris.Lending.ConsumerLoans.get_two_thirds_rates()
@spec link_account_snapshot(String.t(), String.t(), String.t(), keyword()) :: {:ok, map()} | {:error, Solaris.Error.t()}
Links an account snapshot to the application for final credit scoring.
snapshot_id comes from Solaris.Lending.AccountSnapshots.
@spec skip_account_snapshot(String.t(), String.t(), keyword()) :: {:ok, map()} | {:error, Solaris.Error.t()}
Skips the account snapshot step in the application.
Use when the customer declines to share account data.
@spec subsidize_offer(String.t(), String.t(), String.t(), map(), keyword()) :: {:ok, map()} | {:error, Solaris.Error.t()}
Subsidizes a loan offer to reduce the interest rate.
Partners can subsidize offers to make them more attractive, taking on part of the interest cost.
@spec upload_purchase_contract(String.t(), String.t(), binary(), keyword()) :: {:ok, map()} | {:error, Solaris.Error.t()}
Uploads a purchase contract for a financed good (e.g. hire-purchase).