Apertura del portafoglio
Come seguire questo capitolo
Dati richiesti: userId, token CLIENT, ID delle risposte al questionario, proposta scelta e dati del cliente.
Passaggi e risultato atteso: Salva il questionario e i dati mancanti prima di inviare il contratto PDF. Conserva orderId e portfolioId. Il successo della richiesta registra un ordine, ma non significa che il portafoglio sia già investito.
Alternative e operazioni successive: Questo percorso richiede un contratto; il servizio di generazione PDF è opzionale. Puoi produrre il contratto con la tua soluzione.
Codice sorgente dei DTO: AccountHoldingInstitutionOutputModel, CivilStatusOutputModel, CountryOutputModel, GenderOutputModel, LanguageOutputModel, NationalityOutputModel, PensionSituationOutputModel, PortfolioOrderOutputModel, TaxLiabilityOutputModel
Le variabili assegnate in un blocco precedente vengono riutilizzate nei successivi. I dati inseriti dal cliente provengono dalla tua interfaccia. Conserva identificativi e valori di riferimento nel contesto del cliente; non ricreare il contesto a ogni passaggio.
Salvataggio del profilo di rischio
Operazione: Salva le risposte al questionario.
Da conservare / risultato atteso: Prosegui dopo una risposta positiva, mantenendo lo stesso contesto del cliente e della proposta.
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var payload = JsonConvert.SerializeObject(new
{
BusinessLineId = businessLineVorsorge.Id,
UserId = userId,
Responses = responseIds.Select(id => new { ResponseId = id }).ToArray()
});
(await httpClient.PostAsync("api/v1/user-risk-categorizations", new StringContent(payload, Encoding.UTF8, "application/json"))).EnsureSuccessStatusCode();
JsonObject payload = new JsonObject();
payload.addProperty("BusinessLineId", businessLineId);
payload.addProperty("UserId", userId);
payload.add("Responses", new Gson().toJsonTree(responseIds.stream().map(id -> Map.of("ResponseId", id)).toList()));
HttpRequest request = HttpRequest.newBuilder()
.uri(Settings.wmsUri("user-risk-categorizations"))
.timeout(Duration.ofMinutes(1))
.header("Authorization", "Bearer " + accessToken)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload.toString())).build();
var response = httpClient.send(request, BodyHandlers.ofString());
Api.requireSuccess(response);
Completamento dei dati del cliente
Operazione: Completa le informazioni richieste prima dell’apertura del portafoglio.
Da conservare / risultato atteso: Prosegui dopo l’aggiornamento riuscito; conserva userId e la proposta selezionata.
var nationality = await httpClient.GetFromJsonAsync<NationalityOutputModel>("api/v1/nationalities/code/CH");
var country = await httpClient.GetFromJsonAsync<CountryOutputModel>("api/v1/countries/code/CH");
var pensionSituation = await httpClient.GetFromJsonAsync<PensionSituationOutputModel>("api/v1/pension-situations/code/PENSION-FUND");
var taxLiability = await httpClient.GetFromJsonAsync<TaxLiabilityOutputModel>("api/v1/tax-liabilities/code/CH");
var civilStatus = await httpClient.GetFromJsonAsync<CivilStatusOutputModel>("api/v1/civil-statuses/code/MARRIAGE");
// clientBirthDate and civilStatusDate are collected from the client.
payload = JsonConvert.SerializeObject(new
{
Name = clientName,
Surname = clientSurname,
Email = clientEmail,
PhoneNumberPrefix = phoneNumberPrefix,
PhoneNumberNumber = phoneNumberNumber,
BirthDate = clientBirthDate,
CivilStatusId = civilStatus.Id,
CivilStatusDate = civilStatusDate,
GenderId = gender.Id,
LanguageId = language.Id,
Nationality1Id = nationality.Id,
DeliverTaxStatement = true,
TaxLiabilityId = taxLiability.Id,
PensionSituationId = pensionSituation.Id
});
using var clientUpdateContent = new MultipartFormDataContent();
clientUpdateContent.Add(new StringContent(payload, Encoding.UTF8, "application/json"), "jsonPayload");
(await httpClient.PutAsync($"api/v1/users/user-id/{userId}", clientUpdateContent)).EnsureSuccessStatusCode();
payload = JsonConvert.SerializeObject(new
{
Street = "Neugasse",
StreetNr = "1",
City = "Baar",
CountryId = country.Id,
Zip = "6340"
});
(await httpClient.PutAsync($"api/v1/users/update-address/user-id/{userId}", new StringContent(payload, Encoding.UTF8, "application/json"))).EnsureSuccessStatusCode();
// Saving missing client data
HttpRequest languageRequest = HttpRequest.newBuilder()
.timeout(Duration.ofMinutes(1))
.uri(Settings.wmsUri("languages/code/DE"))
.header("Accept-Language", "de-DE")
.header("Authorization", "Bearer " + Settings.GUEST_TOKEN)
.header("Content-Type", "application/json")
.build();
response = httpClient.send(languageRequest, BodyHandlers.ofString());
Api.requireSuccess(response);
LanguageOutputModel languageObj = new Gson().fromJson(response.body(), LanguageOutputModel.class);
var languageId = languageObj.Id;
HttpRequest nationalityRequest = HttpRequest.newBuilder()
.timeout(Duration.ofMinutes(1))
.uri(Settings.wmsUri("nationalities/code/CH"))
.header("Accept-Language", "de-DE")
.header("Authorization", "Bearer " + Settings.GUEST_TOKEN)
.header("Content-Type", "application/json")
.build();
response = httpClient.send(nationalityRequest, BodyHandlers.ofString());
Api.requireSuccess(response);
NationalityOutputModel nationalityObj = new Gson().fromJson(response.body(), NationalityOutputModel.class);
var nationalityId = nationalityObj.Id;
HttpRequest countryRequest = HttpRequest.newBuilder()
.timeout(Duration.ofMinutes(1))
.uri(Settings.wmsUri("countries/code/CH"))
.header("Accept-Language", "de-DE")
.header("Authorization", "Bearer " + Settings.GUEST_TOKEN)
.header("Content-Type", "application/json")
.build();
response = httpClient.send(countryRequest, BodyHandlers.ofString());
Api.requireSuccess(response);
CountryOutputModel countryObj = new Gson().fromJson(response.body(), CountryOutputModel.class);
var countryId = countryObj.Id;
HttpRequest pensionRequest = HttpRequest.newBuilder()
.timeout(Duration.ofMinutes(1))
.uri(Settings.wmsUri("pension-situations/code/PENSION-FUND"))
.header("Accept-Language", "de-DE")
.header("Authorization", "Bearer " + Settings.GUEST_TOKEN)
.header("Content-Type", "application/json")
.build();
response = httpClient.send(pensionRequest, BodyHandlers.ofString());
Api.requireSuccess(response);
PensionSituationOutputModel pensionObj = new Gson().fromJson(response.body(), PensionSituationOutputModel.class);
var pensionId = pensionObj.Id;
HttpRequest taxLiabilityRequest = HttpRequest.newBuilder()
.timeout(Duration.ofMinutes(1))
.uri(Settings.wmsUri("tax-liabilities/code/CH"))
.header("Accept-Language", "de-DE")
.header("Authorization", "Bearer " + Settings.GUEST_TOKEN)
.header("Content-Type", "application/json")
.build();
response = httpClient.send(taxLiabilityRequest, BodyHandlers.ofString());
Api.requireSuccess(response);
TaxLiabilityOutputModel taxLiabilityObj = new Gson().fromJson(response.body(), TaxLiabilityOutputModel.class);
var taxLiabilityId = taxLiabilityObj.Id;
HttpRequest civilStatusRequest = HttpRequest.newBuilder()
.timeout(Duration.ofMinutes(1))
.uri(Settings.wmsUri("civil-statuses/code/MARRIAGE"))
.header("Accept-Language", "de-DE")
.header("Authorization", "Bearer " + Settings.GUEST_TOKEN)
.header("Content-Type", "application/json")
.build();
response = httpClient.send(civilStatusRequest, BodyHandlers.ofString());
Api.requireSuccess(response);
CivilStatusOutputModel civilStatusObj = new Gson().fromJson(response.body(), CivilStatusOutputModel.class);
var civilStatusId = civilStatusObj.Id;
HttpRequest genderRequest = HttpRequest.newBuilder()
.timeout(Duration.ofMinutes(1))
.uri(Settings.wmsUri("genders/code/MALE"))
.header("Accept-Language", "de-DE")
.header("Authorization", "Bearer " + Settings.GUEST_TOKEN)
.header("Content-Type", "application/json")
.build();
response = httpClient.send(genderRequest, BodyHandlers.ofString());
Api.requireSuccess(response);
GenderOutputModel genderObj = new Gson().fromJson(response.body(), GenderOutputModel.class);
var genderId = genderObj.Id;
JsonObject updatePayload = new JsonObject();
updatePayload.addProperty("CivilStatusId", civilStatusId);
updatePayload.addProperty("CivilStatusDate", civilStatusDate);
updatePayload.addProperty("BirthDate", clientBirthDate);
updatePayload.addProperty("GenderId", genderId);
updatePayload.addProperty("LanguageId", languageId);
updatePayload.addProperty("Nationality1Id", nationalityId);
updatePayload.addProperty("DeliverTaxStatement", true);
updatePayload.addProperty("TaxLiabilityId", taxLiabilityId);
updatePayload.addProperty("PensionSituationId", pensionId);
MultiPartBodyPublisher multipartBody = new MultiPartBodyPublisher()
.addPart("jsonPayload", updatePayload.toString());
HttpRequest updateRequest = HttpRequest.newBuilder()
.timeout(Duration.ofMinutes(1))
.uri(Settings.wmsUri("users/user-id/" + userId))
.header("Accept-Language", "de-DE")
.header("Authorization", "Bearer " + accessToken)
.header("Content-Type", "multipart/form-data; boundary=" + multipartBody.getBoundary())
.PUT(multipartBody.build())
.build();
response = httpClient.send(updateRequest, BodyHandlers.ofString());
Api.requireSuccess(response);
JsonObject updateAddressPayload = new JsonObject();
updateAddressPayload.addProperty("Street", "Neugasse");
updateAddressPayload.addProperty("StreetNr", "1");
updateAddressPayload.addProperty("City", "Baar");
updateAddressPayload.addProperty("CountryId", countryId);
updateAddressPayload.addProperty("Zip", "6340");
HttpRequest updateAddressRequest = HttpRequest.newBuilder()
.timeout(Duration.ofMinutes(1))
.uri(Settings.wmsUri("users/update-address/user-id/" + userId))
.header("Accept-Language", "de-DE")
.header("Authorization", "Bearer " + accessToken)
.header("Content-Type", "application/json")
.PUT(HttpRequest.BodyPublishers.ofString(updateAddressPayload.toString()))
.build();
response = httpClient.send(updateAddressRequest, BodyHandlers.ofString());
Api.requireSuccess(response);
Preparazione del contratto
L’endpoint PDF mostrato è opzionale. Se hai già un contratto completo, usalo e passa a Invio dell’ordine.
Operazione: Prepara un contratto PDF con la tua soluzione o con il servizio PDF opzionale.
Da conservare / risultato atteso: C#: pdfContractAsByteArray. Java: contractPath punta al PDF generato.
// Optional PDF service: use its configured origin and authorized token.
// contractPath points to the current template approved for this product.
// formFields maps template field names to actual client/portfolio values.
using var pdfClient = new HttpClient
{
BaseAddress = new Uri(pdfServiceBaseUrl.TrimEnd('/') + "/")
};
pdfClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", pdfServiceToken);
var payload = new
{
PlaceHolderValues = formFields.Select(x => new { Name = x.Key, Value = x.Value }).ToList()
};
var template = await File.ReadAllBytesAsync(contractPath);
using var content = GuideHttp.CreateMultipartContent(payload, template, "attachments");
using var response = await pdfClient.PostAsync("api/v1/pdf-service/fill-pdf-with-data", content);
response.EnsureSuccessStatusCode();
var pdfContractAsByteArray = await response.Content.ReadAsByteArrayAsync();
// Optional PDF service: formFields contains actual values for its template fields.
JsonArray fields = new JsonArray();
for (Map.Entry<String, String> entry : formFields.entrySet()) {
JsonObject field = new JsonObject();
field.addProperty("Name", entry.getKey());
field.addProperty("Value", entry.getValue());
fields.add(field);
}
JsonObject payload = new JsonObject();
payload.add("PlaceHolderValues", fields);
byte[] template = Files.readAllBytes(contractPath);
MultiPartBodyPublisher body = new MultiPartBodyPublisher()
.addPart("jsonPayload", payload.toString())
.addPart("attachments", () -> new ByteArrayInputStream(template), "Contract.pdf", "application/pdf");
URI pdfUri = URI.create(pdfServiceBaseUrl.replaceAll("/+$", "") + "/api/v1/pdf-service/fill-pdf-with-data");
HttpRequest request = HttpRequest.newBuilder().uri(pdfUri)
.timeout(Duration.ofMinutes(1))
.header("Authorization", "Bearer " + pdfServiceToken)
.header("Content-Type", "multipart/form-data; boundary=" + body.getBoundary())
.POST(body.build()).build();
var response = httpClient.send(request, BodyHandlers.ofByteArray());
Api.requireSuccess(response);
var pdfAsByteArray = response.body();
// Preserve the filled PDF separately from the input template.
var completedContractPath = Files.createTempFile("wms-contract-", ".pdf");
Files.write(completedContractPath, pdfAsByteArray);
contractPath = completedContractPath;
Invio dell’ordine
Operazione: Invia l’ordine di apertura.
Da conservare / risultato atteso: Conserva orderId e portfolioId, quindi verifica lo stato dell’ordine.
var accountHoldingInstitution = await httpClient.GetFromJsonAsync<AccountHoldingInstitutionOutputModel>("api/v1/account-holding-institutions/code/LIENHARDT");
var orderPayload = new
{
AccountHoldingInstitutionCode = accountHoldingInstitution.Code,
UserId = userId,
InvestmentCategoryId = investmentCategory3A.Id,
ProposalId = proposalSelectedByUser.Id,
ReasonToChangeProposalResponsesIds = selectedReasonIds
};
using var content = GuideHttp.CreateMultipartContent(orderPayload, pdfContractAsByteArray);
using var response = await httpClient.PostAsync("api/v1/user-portfolio-orders/creation", content);
response.EnsureSuccessStatusCode();
var order = JsonConvert.DeserializeObject<PortfolioOrderOutputModel>(await response.Content.ReadAsStringAsync());
var orderId = order.Id;
var portfolioId = order.PortfolioId;
// Submitting the order
HttpRequest accountHoldingInstitutionRequest = HttpRequest.newBuilder()
.timeout(Duration.ofMinutes(1))
.uri(Settings.wmsUri("account-holding-institutions/code/LIENHARDT"))
.header("Accept-Language", "de-DE")
.header("Authorization", "Bearer " + Settings.GUEST_TOKEN)
.header("Content-Type", "application/json")
.build();
response = httpClient.send(accountHoldingInstitutionRequest, BodyHandlers.ofString());
Api.requireSuccess(response);
AccountHoldingInstitutionOutputModel accountHoldingInstitutionObj = new Gson().fromJson(response.body(), AccountHoldingInstitutionOutputModel.class);
JsonObject orderPayload = new JsonObject();
orderPayload.addProperty("AccountHoldingInstitutionCode", accountHoldingInstitutionObj.Code);
orderPayload.addProperty("UserId", userId);
orderPayload.addProperty("InvestmentCategoryId", investmentCategoryId);
orderPayload.addProperty("ProposalId", proposalId);
orderPayload.add("ReasonToChangeProposalResponsesIds", new Gson().toJsonTree(selectedReasonIds));
InputStream contractStream = new ByteArrayInputStream(pdfAsByteArray);
MultiPartBodyPublisher multipartOrderBody = new MultiPartBodyPublisher()
.addPart("jsonPayload", orderPayload.toString())
.addPart("userContracts", () -> contractStream, "Contract.pdf", "application/pdf");
HttpRequest createPortfolioRequest = HttpRequest.newBuilder()
.timeout(Duration.ofMinutes(1))
.uri(Settings.wmsUri("user-portfolio-orders/creation"))
.header("Accept-Language", "de-DE")
.header("Authorization", "Bearer " + accessToken)
.header("Content-Type", "multipart/form-data; boundary=" + multipartOrderBody.getBoundary())
.POST(multipartOrderBody.build())
.build();
response = httpClient.send(createPortfolioRequest, BodyHandlers.ofString());
Api.requireSuccess(response);
PortfolioOrderOutputModel orderObj = new Gson().fromJson(response.body(), PortfolioOrderOutputModel.class);
var orderId = orderObj.Id;
var portfolioId = orderObj.PortfolioId;
Monitoraggio dello stato dell’ordine
Operazione: Leggi l’ordine registrato e risolvi OrderStatusId tramite l’elenco degli stati.
Da conservare / risultato atteso: Usa lo stato restituito per attendere o mostrare un risultato. Gli ID numerici non hanno un significato universale in questa guida.
var currentOrder = await httpClient.GetFromJsonAsync<PortfolioOrderOutputModel>($"api/v1/user-portfolio-orders/order-id/{orderId}");
HttpRequest request = HttpRequest.newBuilder()
.uri(Settings.wmsUri("user-portfolio-orders/order-id/" + orderId))
.header("Authorization", "Bearer " + accessToken).GET().build();
var response = httpClient.send(request, BodyHandlers.ofString());
Api.requireSuccess(response);
PortfolioOrderOutputModel currentOrder = new Gson().fromJson(response.body(), PortfolioOrderOutputModel.class);
Riconoscere il risultato
Estratto illustrativo della risposta di un ordine. Gli ID sono esempi; risolvi lo stato reale tramite l’elenco di riferimento. Il successo HTTP conferma la ricezione, gli stati successivi indicano l’elaborazione.
{"id":456,"portfolioId":789,"orderStatusId":1}Il catalogo DTO contiene le altre proprietà della risposta. Gestisci una richiesta non riuscita prima di proseguire; consulta Gestione degli errori.