From f5999d347b48cf8a384c7089cfc157b9668f0837 Mon Sep 17 00:00:00 2001 From: Juan Cernadas Date: Thu, 21 May 2026 15:45:58 -0300 Subject: [PATCH 1/2] feat(identity): add PF/PJ identity fields exposed by Pluggy API 0.24 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirror the Identity additions on the API side (pluggy-api PR #1659 / @pluggyai/commons 6.39.0). All new fields are optional — existing consumers keep working unchanged. IdentityResponse gains: - socialName, sex, maritalStatus, nationality, otherDocuments, passport (PF, from the Open Finance natural-person registrations endpoint) - incorporationDate, parties, businessOtherDocuments (PJ, from the business registrations endpoint) - companiesCnpj (shared) PhoneNumber gains countryCallingCode, areaCode, extension, additionalInfo. Address gains district, ibgeTownCode, countryCode, geographicCoordinates. New supporting types: - Sex enum - MaritalStatus + MaritalStatusCode enum - Nationality + OtherNationality + NationalityDocument - OtherDocument + OtherDocumentType enum - Passport - BusinessParty + BusinessPartyType / PersonType / DocumentType enums - BusinessOtherDocument - GeographicCoordinates Each enum follows the project's existing pattern (Gson @SerializedName + Lombok @AllArgsConstructor / @Getter); each value class uses @Data + @Builder for consistency with Address, IdentityResponse, etc. Note: the Java SDK has historically not exposed `qualifications` or `financialRelationships`, so the new sub-fields under those (economicActivities, informedRevenue, portabilitiesReceived, etc.) are out of scope for this change and can land in a follow-up that introduces the missing parent types. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../ai/pluggy/client/response/Address.java | 8 ++++ .../response/BusinessOtherDocument.java | 21 ++++++++++ .../pluggy/client/response/BusinessParty.java | 38 +++++++++++++++++++ .../response/BusinessPartyDocumentType.java | 20 ++++++++++ .../response/BusinessPartyPersonType.java | 16 ++++++++ .../client/response/BusinessPartyType.java | 16 ++++++++ .../response/GeographicCoordinates.java | 17 +++++++++ .../client/response/IdentityResponse.java | 23 +++++++++++ .../pluggy/client/response/MaritalStatus.java | 13 +++++++ .../client/response/MaritalStatusCode.java | 26 +++++++++++++ .../pluggy/client/response/Nationality.java | 14 +++++++ .../client/response/NationalityDocument.java | 18 +++++++++ .../pluggy/client/response/OtherDocument.java | 20 ++++++++++ .../client/response/OtherDocumentType.java | 22 +++++++++++ .../client/response/OtherNationality.java | 15 ++++++++ .../ai/pluggy/client/response/Passport.java | 17 +++++++++ .../pluggy/client/response/PhoneNumber.java | 8 ++++ .../java/ai/pluggy/client/response/Sex.java | 18 +++++++++ 18 files changed, 330 insertions(+) create mode 100644 src/main/java/ai/pluggy/client/response/BusinessOtherDocument.java create mode 100644 src/main/java/ai/pluggy/client/response/BusinessParty.java create mode 100644 src/main/java/ai/pluggy/client/response/BusinessPartyDocumentType.java create mode 100644 src/main/java/ai/pluggy/client/response/BusinessPartyPersonType.java create mode 100644 src/main/java/ai/pluggy/client/response/BusinessPartyType.java create mode 100644 src/main/java/ai/pluggy/client/response/GeographicCoordinates.java create mode 100644 src/main/java/ai/pluggy/client/response/MaritalStatus.java create mode 100644 src/main/java/ai/pluggy/client/response/MaritalStatusCode.java create mode 100644 src/main/java/ai/pluggy/client/response/Nationality.java create mode 100644 src/main/java/ai/pluggy/client/response/NationalityDocument.java create mode 100644 src/main/java/ai/pluggy/client/response/OtherDocument.java create mode 100644 src/main/java/ai/pluggy/client/response/OtherDocumentType.java create mode 100644 src/main/java/ai/pluggy/client/response/OtherNationality.java create mode 100644 src/main/java/ai/pluggy/client/response/Passport.java create mode 100644 src/main/java/ai/pluggy/client/response/Sex.java diff --git a/src/main/java/ai/pluggy/client/response/Address.java b/src/main/java/ai/pluggy/client/response/Address.java index 962c998..cd0322d 100644 --- a/src/main/java/ai/pluggy/client/response/Address.java +++ b/src/main/java/ai/pluggy/client/response/Address.java @@ -14,4 +14,12 @@ public class Address { String postalCode; String primaryAddress; AddressType type; + /** District / neighborhood (bairro). */ + String district; + /** IBGE municipality code (7 digits). The first two digits identify the Federation Unit. */ + String ibgeTownCode; + /** Country code in alpha3 ISO-3166 format (e.g. 'BRA'). */ + String countryCode; + /** Geographic coordinates of the address. */ + GeographicCoordinates geographicCoordinates; } diff --git a/src/main/java/ai/pluggy/client/response/BusinessOtherDocument.java b/src/main/java/ai/pluggy/client/response/BusinessOtherDocument.java new file mode 100644 index 0000000..e1ee7d0 --- /dev/null +++ b/src/main/java/ai/pluggy/client/response/BusinessOtherDocument.java @@ -0,0 +1,21 @@ +package ai.pluggy.client.response; + +import java.util.Date; + +import lombok.Builder; +import lombok.Data; + +/** + * Additional document for businesses headquartered abroad and not required to register a CNPJ. + */ +@Data +@Builder +public class BusinessOtherDocument { + + /** Type of the document (e.g. 'EIN'). */ + String type; + String number; + /** Issuing country in alpha3 ISO-3166 format. */ + String country; + Date expirationDate; +} diff --git a/src/main/java/ai/pluggy/client/response/BusinessParty.java b/src/main/java/ai/pluggy/client/response/BusinessParty.java new file mode 100644 index 0000000..2654497 --- /dev/null +++ b/src/main/java/ai/pluggy/client/response/BusinessParty.java @@ -0,0 +1,38 @@ +package ai.pluggy.client.response; + +import java.util.Date; + +import lombok.Builder; +import lombok.Data; + +/** + * Partner or administrator of a business. + * + * Partners with less than 25% shareholding may be omitted by the institution. + */ +@Data +@Builder +public class BusinessParty { + + BusinessPartyType type; + BusinessPartyPersonType personType; + BusinessPartyDocumentType documentType; + String documentNumber; + /** Issuing country of the document, alpha3 ISO-3166. */ + String documentCountry; + Date documentExpirationDate; + Date documentIssueDate; + String documentAdditionalInfo; + /** Civil name. Required when personType is NATURAL_PERSON. */ + String civilName; + String socialName; + /** Company name. Required when personType is LEGAL_ENTITY. */ + String companyName; + String tradeName; + Date startDate; + /** + * Shareholding fraction between 0 and 1 (e.g. 0.51 represents 51%, 1 represents 100%). + * Required when type is PARTNER and the shareholding is 25% or higher. + */ + Double shareholding; +} diff --git a/src/main/java/ai/pluggy/client/response/BusinessPartyDocumentType.java b/src/main/java/ai/pluggy/client/response/BusinessPartyDocumentType.java new file mode 100644 index 0000000..40bdc1e --- /dev/null +++ b/src/main/java/ai/pluggy/client/response/BusinessPartyDocumentType.java @@ -0,0 +1,20 @@ +package ai.pluggy.client.response; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +public enum BusinessPartyDocumentType { + @SerializedName("CPF") + CPF("CPF"), + @SerializedName("CNPJ") + CNPJ("CNPJ"), + @SerializedName("PASSPORT") + PASSPORT("PASSPORT"), + @SerializedName("OTHER_TRAVEL_DOCUMENT") + OTHER_TRAVEL_DOCUMENT("OTHER_TRAVEL_DOCUMENT"); + + @Getter + private String value; +} diff --git a/src/main/java/ai/pluggy/client/response/BusinessPartyPersonType.java b/src/main/java/ai/pluggy/client/response/BusinessPartyPersonType.java new file mode 100644 index 0000000..d358173 --- /dev/null +++ b/src/main/java/ai/pluggy/client/response/BusinessPartyPersonType.java @@ -0,0 +1,16 @@ +package ai.pluggy.client.response; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +public enum BusinessPartyPersonType { + @SerializedName("NATURAL_PERSON") + NATURAL_PERSON("NATURAL_PERSON"), + @SerializedName("LEGAL_ENTITY") + LEGAL_ENTITY("LEGAL_ENTITY"); + + @Getter + private String value; +} diff --git a/src/main/java/ai/pluggy/client/response/BusinessPartyType.java b/src/main/java/ai/pluggy/client/response/BusinessPartyType.java new file mode 100644 index 0000000..f8bb473 --- /dev/null +++ b/src/main/java/ai/pluggy/client/response/BusinessPartyType.java @@ -0,0 +1,16 @@ +package ai.pluggy.client.response; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +public enum BusinessPartyType { + @SerializedName("PARTNER") + PARTNER("PARTNER"), + @SerializedName("ADMINISTRATOR") + ADMINISTRATOR("ADMINISTRATOR"); + + @Getter + private String value; +} diff --git a/src/main/java/ai/pluggy/client/response/GeographicCoordinates.java b/src/main/java/ai/pluggy/client/response/GeographicCoordinates.java new file mode 100644 index 0000000..8b16286 --- /dev/null +++ b/src/main/java/ai/pluggy/client/response/GeographicCoordinates.java @@ -0,0 +1,17 @@ +package ai.pluggy.client.response; + +import lombok.Builder; +import lombok.Data; + +/** + * Geographic coordinates in decimal degrees, WGS84 reference system. + */ +@Data +@Builder +public class GeographicCoordinates { + + /** Between -90 and 90. */ + Double latitude; + /** Between -180 and 180. */ + Double longitude; +} diff --git a/src/main/java/ai/pluggy/client/response/IdentityResponse.java b/src/main/java/ai/pluggy/client/response/IdentityResponse.java index d27b5fb..2b8d475 100644 --- a/src/main/java/ai/pluggy/client/response/IdentityResponse.java +++ b/src/main/java/ai/pluggy/client/response/IdentityResponse.java @@ -28,4 +28,27 @@ public class IdentityResponse { Date createdAt; Date updatedAt; String companyName; + /** Social name of the natural person (PF-only). */ + String socialName; + /** Sex of the natural person (PF-only). */ + Sex sex; + /** Marital status of the natural person (PF-only). */ + MaritalStatus maritalStatus; + /** Nationality of the natural person (PF-only). */ + Nationality nationality; + /** Other identification documents the natural person holds (PF-only). */ + List otherDocuments; + /** Passport metadata for the natural person (PF-only). */ + Passport passport; + /** Date the business was incorporated (PJ-only). */ + Date incorporationDate; + /** Partners and administrators of the business (PJ-only). */ + List parties; + /** + * Additional documents for businesses headquartered abroad and not required to register a CNPJ + * (PJ-only). + */ + List businessOtherDocuments; + /** CNPJs of the financial institutions responsible for the customer cadastro. */ + List companiesCnpj; } diff --git a/src/main/java/ai/pluggy/client/response/MaritalStatus.java b/src/main/java/ai/pluggy/client/response/MaritalStatus.java new file mode 100644 index 0000000..e0e5377 --- /dev/null +++ b/src/main/java/ai/pluggy/client/response/MaritalStatus.java @@ -0,0 +1,13 @@ +package ai.pluggy.client.response; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class MaritalStatus { + + MaritalStatusCode code; + /** Free-text complement. Populated when code is OTHER. */ + String additionalInfo; +} diff --git a/src/main/java/ai/pluggy/client/response/MaritalStatusCode.java b/src/main/java/ai/pluggy/client/response/MaritalStatusCode.java new file mode 100644 index 0000000..625dfbe --- /dev/null +++ b/src/main/java/ai/pluggy/client/response/MaritalStatusCode.java @@ -0,0 +1,26 @@ +package ai.pluggy.client.response; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +public enum MaritalStatusCode { + @SerializedName("SINGLE") + SINGLE("SINGLE"), + @SerializedName("MARRIED") + MARRIED("MARRIED"), + @SerializedName("WIDOWED") + WIDOWED("WIDOWED"), + @SerializedName("JUDICIALLY_SEPARATED") + JUDICIALLY_SEPARATED("JUDICIALLY_SEPARATED"), + @SerializedName("DIVORCED") + DIVORCED("DIVORCED"), + @SerializedName("STABLE_UNION") + STABLE_UNION("STABLE_UNION"), + @SerializedName("OTHER") + OTHER("OTHER"); + + @Getter + private String value; +} diff --git a/src/main/java/ai/pluggy/client/response/Nationality.java b/src/main/java/ai/pluggy/client/response/Nationality.java new file mode 100644 index 0000000..aa8c8fd --- /dev/null +++ b/src/main/java/ai/pluggy/client/response/Nationality.java @@ -0,0 +1,14 @@ +package ai.pluggy.client.response; + +import java.util.List; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class Nationality { + + Boolean hasBrazilianNationality; + List otherNationalities; +} diff --git a/src/main/java/ai/pluggy/client/response/NationalityDocument.java b/src/main/java/ai/pluggy/client/response/NationalityDocument.java new file mode 100644 index 0000000..74c716e --- /dev/null +++ b/src/main/java/ai/pluggy/client/response/NationalityDocument.java @@ -0,0 +1,18 @@ +package ai.pluggy.client.response; + +import java.util.Date; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class NationalityDocument { + + String type; + String number; + String country; + Date issueDate; + Date expirationDate; + String additionalInfo; +} diff --git a/src/main/java/ai/pluggy/client/response/OtherDocument.java b/src/main/java/ai/pluggy/client/response/OtherDocument.java new file mode 100644 index 0000000..c7a9138 --- /dev/null +++ b/src/main/java/ai/pluggy/client/response/OtherDocument.java @@ -0,0 +1,20 @@ +package ai.pluggy.client.response; + +import java.util.Date; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class OtherDocument { + + OtherDocumentType type; + /** Free-text complement. Populated when type is OTHER. */ + String typeAdditionalInfo; + String number; + String checkDigit; + /** Free-text complement, used to record the issuing authority (e.g. 'SSP/SP') when relevant. */ + String additionalInfo; + Date expirationDate; +} diff --git a/src/main/java/ai/pluggy/client/response/OtherDocumentType.java b/src/main/java/ai/pluggy/client/response/OtherDocumentType.java new file mode 100644 index 0000000..9ce4ace --- /dev/null +++ b/src/main/java/ai/pluggy/client/response/OtherDocumentType.java @@ -0,0 +1,22 @@ +package ai.pluggy.client.response; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +public enum OtherDocumentType { + @SerializedName("CNH") + CNH("CNH"), + @SerializedName("RG") + RG("RG"), + @SerializedName("NIF") + NIF("NIF"), + @SerializedName("RNE") + RNE("RNE"), + @SerializedName("OTHER") + OTHER("OTHER"); + + @Getter + private String value; +} diff --git a/src/main/java/ai/pluggy/client/response/OtherNationality.java b/src/main/java/ai/pluggy/client/response/OtherNationality.java new file mode 100644 index 0000000..09acb6e --- /dev/null +++ b/src/main/java/ai/pluggy/client/response/OtherNationality.java @@ -0,0 +1,15 @@ +package ai.pluggy.client.response; + +import java.util.List; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class OtherNationality { + + /** Country code in alpha3 ISO-3166 format. */ + String countryCode; + List documents; +} diff --git a/src/main/java/ai/pluggy/client/response/Passport.java b/src/main/java/ai/pluggy/client/response/Passport.java new file mode 100644 index 0000000..a8b43d7 --- /dev/null +++ b/src/main/java/ai/pluggy/client/response/Passport.java @@ -0,0 +1,17 @@ +package ai.pluggy.client.response; + +import java.util.Date; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class Passport { + + String number; + /** Issuing country in alpha3 ISO-3166 format. */ + String country; + Date issueDate; + Date expirationDate; +} diff --git a/src/main/java/ai/pluggy/client/response/PhoneNumber.java b/src/main/java/ai/pluggy/client/response/PhoneNumber.java index 93ab7ff..0ffec68 100644 --- a/src/main/java/ai/pluggy/client/response/PhoneNumber.java +++ b/src/main/java/ai/pluggy/client/response/PhoneNumber.java @@ -7,4 +7,12 @@ public class PhoneNumber { PhoneNumberType type; String value; + /** International dialing code (DDI). Populated when different from '55'. */ + String countryCallingCode; + /** Area code (DDD) of the phone. */ + String areaCode; + /** Extension number, when part of the phone identification. */ + String extension; + /** Additional info related to the source phone type. */ + String additionalInfo; } diff --git a/src/main/java/ai/pluggy/client/response/Sex.java b/src/main/java/ai/pluggy/client/response/Sex.java new file mode 100644 index 0000000..2927462 --- /dev/null +++ b/src/main/java/ai/pluggy/client/response/Sex.java @@ -0,0 +1,18 @@ +package ai.pluggy.client.response; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +public enum Sex { + @SerializedName("FEMALE") + FEMALE("FEMALE"), + @SerializedName("MALE") + MALE("MALE"), + @SerializedName("OTHER") + OTHER("OTHER"); + + @Getter + private String value; +} From 5bbdbd98e195dcd4ad245bc380f02a810e509411 Mon Sep 17 00:00:00 2001 From: Juan Cernadas Date: Thu, 21 May 2026 15:58:42 -0300 Subject: [PATCH 2/2] chore(release): bump pom.xml to 1.9.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v1.8.5 is already tagged. The release workflow reads project.version from pom.xml and skips when the corresponding tag exists, so a bump is required for this PR's additions to ship. Minor bump (1.8.5 → 1.9.0): the PR adds new optional fields and new public classes/enums but doesn't change any existing field's semantics, so the change is strictly additive / backward-compatible. Co-Authored-By: Claude Opus 4.7 (1M context) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e4fec33..08525d7 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ ai.pluggy pluggy-java - 1.8.5 + 1.9.0 jar