Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Current SDK methods in `client.ts` (PluggyClient):
| Items | `createItem()`, `fetchItem()`, `updateItem()`, `deleteItem()` | /items |
| Item MFA | `updateItemMFA()` | POST /items/{id}/mfa |
| Item Resources | `fetchItemResources()` | GET /items/{id}/resources |
| SCR (opt-in) | `fetchItemScr()` | GET /items/{id}/scr |
| Accounts | `fetchAccounts()`, `fetchAccount()` | /accounts |
| Account Statements | `fetchAccountStatements()` | GET /accounts/{id}/statements |
| Transactions | `fetchTransactionsCursor()` (single page) + `fetchAllTransactions()` (full sweep) for the v2 cursor endpoint; `fetchTransactions()` page-based is `@deprecated`; `fetchTransaction()` by id | GET /v2/transactions, GET /transactions/{id} |
Expand All @@ -79,6 +80,9 @@ Current SDK methods in `client.ts` (PluggyClient):
| Identity | `fetchIdentity()`, `fetchIdentityByItemId()` | /identity |
| Credit Card Bills | `fetchCreditCardBills()`, `fetchCreditCardBill()` | /bills |
| Categories | `fetchCategories()`, `fetchCategory()` | /categories |
| Category Rules | `fetchCategoryRules()`, `createCategoryRule()`, `deleteCategoryRule()` | /categories/rules |
| Merchants | `fetchMerchants()` | GET /merchants |
| Boleto Management (beta) | `createBoletoConnection()`, `createBoletoConnectionFromItem()`, `createBoleto()`, `fetchBoleto()`, `cancelBoleto()` | /boleto-connections, /boletos |
| Webhooks | Full CRUD | /webhooks |
| Connect Token | `createConnectToken()` | POST /connect_token |

Expand All @@ -87,15 +91,15 @@ Current SDK methods in `paymentsClient.ts` (PluggyPaymentsClient):
| Resource | SDK Methods |
|----------|-------------|
| Payment Recipients | `createPaymentRecipient()`, `fetchPaymentRecipient()`, `fetchPaymentRecipients()`, `updatePaymentRecipient()`, `deletePaymentRecipient()` |
| Payment Requests | `createPaymentRequest()`, `fetchPaymentRequest()`, `fetchPaymentRequests()`, `deletePaymentRequest()` |
| Payment Requests | `createPaymentRequest()`, `createPixQrPaymentRequest()`, `fetchPaymentRequest()`, `fetchPaymentRequests()`, `deletePaymentRequest()` |
| Payment Intents | `createPaymentIntent()`, `fetchPaymentIntent()`, `fetchPaymentIntents()` |
| Payment Customers | Full CRUD |
| Payment Institutions | `fetchPaymentInstitution()`, `fetchPaymentInstitutions()` |
| Bulk Payments | Full CRUD |
| Smart Accounts | `createSmartAccount()`, `fetchSmartAccount()`, `fetchSmartAccountBalance()`, `fetchSmartAccounts()` |
| Automatic PIX | Multiple methods for PIX automático |
| Scheduled Payments | Multiple methods |
| Smart Transfers | Multiple methods |
| Smart Transfers | Multiple methods, incl. `fetchSmartTransferPreauthorizationPayments()` |

### 3. Type Definition Patterns

Expand Down Expand Up @@ -226,5 +230,5 @@ Type-only gap fixes from comparing `src/types/` against the OpenAPI spec (`oas3.
- **CreditCardBills**: `payments` (new `CreditCardBillPayment` type + `valueType`/`paymentMode` enums)
- Re-exported `creditCardBills` types from `src/types/index.ts` (were public via `fetchCreditCardBill()` return type but not importable)

### Not Implemented (Intentional)
- Boleto Management: Beta feature, not added to SDK (the `Connector.supportsBoletoManagement` flag is exposed as read-only metadata, but no boleto endpoints/types are implemented)
### Boleto Management (beta)
Boleto endpoints (`/boleto-connections`, `/boletos`) are implemented on `PluggyClient` and marked BETA in their JSDoc, since the API still flags them as beta.
2 changes: 1 addition & 1 deletion src/baseApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ export class BaseApi {
json: body,
})

if (statusCode !== 200) {
if (statusCode < 200 || statusCode >= 300) {
return Promise.reject(body)
}

Expand Down
119 changes: 119 additions & 0 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ import {
PageFilters,
InvestmentsFilters,
AccountStatement,
ScrFilters,
ScrResponse,
MerchantsResponse,
ClientCategoryRule,
CreateClientCategoryRule,
BoletoConnection,
CreateBoletoConnection,
CreateBoletoConnectionFromItem,
CreateBoleto,
IssuedBoleto,
} from './types'
import { CreditCardBills } from './types/creditCardBills'
import { ValidationResult } from './types/validation'
Expand Down Expand Up @@ -155,6 +165,24 @@ export class PluggyClient extends BaseApi {
return await this.createGetRequest(`items/${itemId}/resources`, options)
}

/**
* Fetch the SCR (Bacen's Sistema de Informações de Crédito) for the document behind an Item.
*
* Opt-in: requires the SCR feature to be enabled for your team (ask Pluggy support); otherwise
* 403 SCR_FEATURE_NOT_ENABLED. Only available for Open Finance items with a known CPF/CNPJ
* (otherwise 422 SCR_ITEM_NOT_SUPPORTED).
*
* The response is Bacen's own payload, forwarded unchanged. Base dates are months (YYYYMM) and
* Bacen consolidates each one with a few months of delay: when `from` and `to` are omitted the
* last 4 available base dates are consulted, ending 2 months before the current one.
* @param itemId The Item id
* @param {ScrFilters} options - optional `from` / `to` base dates, as YYYYMM
* @returns {ScrResponse} the SCR data for the Item's document
*/
async fetchItemScr(itemId: string, options: ScrFilters = {}): Promise<ScrResponse> {
return await this.createGetRequest(`items/${itemId}/scr`, { ...options })
}

/**
* Fetch accounts from an Item
* @param itemId The Item id
Expand Down Expand Up @@ -434,6 +462,97 @@ export class PluggyClient extends BaseApi {
return await this.createGetRequest(`categories/${id}`)
}

/**
* Fetch the category rules of your client
* @returns {PageResponse<ClientCategoryRule>} paged response of category rules
*/
async fetchCategoryRules(): Promise<PageResponse<ClientCategoryRule>> {
return await this.createGetRequest('categories/rules')
}

/**
* Create a category rule: transactions matching the description are assigned the given category
* @param rule - the rule to create
* @returns {ClientCategoryRule} the created category rule
*/
async createCategoryRule(rule: CreateClientCategoryRule): Promise<ClientCategoryRule> {
return await this.createPostRequest('categories/rules', null, rule)
}

/**
* Delete a category rule. Clients can only delete their own rules.
* @param id - the category rule id
*/
async deleteCategoryRule(id: string): Promise<void> {
await this.createDeleteRequest(`categories/rules/${id}`)
}

/**
* Fetch merchant information for a list of CNPJs
* @param cnpjs - list of CNPJs to look up (sent as a comma-separated list)
* @returns {MerchantsResponse} found merchants, valid CNPJs that were not found, and invalid CNPJs
*/
async fetchMerchants(cnpjs: string[]): Promise<MerchantsResponse> {
return await this.createGetRequest('merchants', { cnpjs: cnpjs.join(',') })
}

/**
* BETA: Boleto Management is in beta and may change.
*
* Create a boleto connection from the institution's credentials
* @param payload - the connector id (with `supportsBoletoManagement`) and its credentials
* @returns {BoletoConnection} the created boleto connection
*/
async createBoletoConnection(payload: CreateBoletoConnection): Promise<BoletoConnection> {
return await this.createPostRequest('boleto-connections', null, payload)
}

/**
* BETA: Boleto Management is in beta and may change.
*
* Create a boleto connection from an existing Item
* @param payload - the Item id
* @returns {BoletoConnection} the created boleto connection
*/
async createBoletoConnectionFromItem(
payload: CreateBoletoConnectionFromItem
): Promise<BoletoConnection> {
return await this.createPostRequest('boleto-connections/from-item', null, payload)
}

/**
* BETA: Boleto Management is in beta and may change.
*
* Issue a boleto through a boleto connection
* @param payload - the boleto connection id and the boleto data
* @returns {IssuedBoleto} the issued boleto
*/
async createBoleto(payload: CreateBoleto): Promise<IssuedBoleto> {
return await this.createPostRequest('boletos', null, payload)
}

/**
* BETA: Boleto Management is in beta and may change.
*
* Fetch a single issued boleto
* @param id - the boleto id
* @returns {IssuedBoleto} the issued boleto
*/
async fetchBoleto(id: string): Promise<IssuedBoleto> {
return await this.createGetRequest(`boletos/${id}`)
}

/**
* BETA: Boleto Management is in beta and may change.
*
* Cancel an issued boleto
* @param id - the boleto id
* @returns {IssuedBoleto} the cancelled boleto
*/
async cancelBoleto(id: string): Promise<IssuedBoleto> {
return await this.createPostRequest(`boletos/${id}/cancel`)
}

/**
* Fetch a single webhook
* @returns {Webhook} a webhook object
Expand Down
26 changes: 26 additions & 0 deletions src/paymentsClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import {
SmartTransferPayment,
CreateSmartTransferPayment,
SmartTransferPreauthorizationsFilters,
SmartTransferPreauthorizationPaymentsFilters,
CreatePixQrPaymentRequest,
} from './types'

/**
Expand All @@ -51,6 +53,15 @@ export class PluggyPaymentsClient extends BaseApi {
return await this.createPostRequest(`payments/requests`, null, paymentRequest)
}

/**
* Creates a payment request from a PIX QR code
* @param payload CreatePixQrPaymentRequest with the PIX QR code
* @returns {PaymentRequest} PaymentRequest object
*/
async createPixQrPaymentRequest(payload: CreatePixQrPaymentRequest): Promise<PaymentRequest> {
return await this.createPostRequest('payments/requests/pix-qr', null, payload)
}

/**
* Fetch a single payment request
* @returns {PaymentRequest} PaymentRequest object
Expand Down Expand Up @@ -447,6 +458,21 @@ export class PluggyPaymentsClient extends BaseApi {
return await this.createGetRequest(`smart-transfers/preauthorizations/${id}`)
}

/**
* Fetch the payments of a smart transfer preauthorization, ordered by date descending
* @param id ID of the smart transfer preauthorization
* @param options SmartTransferPreauthorizationPaymentsFilters with from, to, page and pageSize
* @returns {PageResponse<SmartTransferPayment>} paged response of smart transfer payments
*/
async fetchSmartTransferPreauthorizationPayments(
id: string,
options: SmartTransferPreauthorizationPaymentsFilters = {}
): Promise<PageResponse<SmartTransferPayment>> {
return await this.createGetRequest(`smart-transfers/preauthorizations/${id}/payments`, {
...options,
})
}

/**
* Creates a smart transfer payment
* @param payload CreateSmartTransferPayment
Expand Down
7 changes: 7 additions & 0 deletions src/types/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,11 @@ export type CreditData = {
holderType: 'MAIN' | 'ADDITIONAL' | null
/** Detailed credit limit information, broken down by credit line. Only returned for Open Finance connectors */
disaggregatedCreditLimits?: DisaggregatedCreditLimit[]
/** Additional credit cards associated with the main one */
additionalCards?: AdditionalCard[] | null
}

export type AdditionalCard = {
/** Number of the additional credit card */
number: string
}
142 changes: 142 additions & 0 deletions src/types/boleto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
export type CreateBoletoConnection = {
/** Connector identifier. The connector must have `supportsBoletoManagement` set to true */
connectorId: number
/** Credentials required for the connection (for Inter: clientId, clientSecret, certificate and privateKey) */
credentials: Record<string, string>
}

export type CreateBoletoConnectionFromItem = {
/** Item ID */
itemId: string
}

export type BoletoConnection = {
/** Primary identifier */
id: string
/** Primary identifier of the connector associated with this connection */
connectorId: number
/** Date when the connection was created */
createdAt: Date
/** Date when the connection was last updated */
updatedAt: Date
}

export const BOLETO_FINE_TYPES = ['PERCENTAGE', 'FIXED'] as const
export type BoletoFineType = typeof BOLETO_FINE_TYPES[number]

export const BOLETO_INTEREST_TYPES = ['PERCENTAGE'] as const
export type BoletoInterestType = typeof BOLETO_INTEREST_TYPES[number]

export type BoletoFine = {
/** Fine value */
value: number
/** Type of fine calculation */
type: BoletoFineType
}

export type BoletoInterest = {
/** Interest value */
value: number
/** Type of interest calculation */
type: BoletoInterestType
}

export type CreateBoletoPayer = {
/** Payer tax number (CPF/CNPJ) */
taxNumber: string
/** Payer name */
name: string
/** Payer street address */
addressStreet?: string
/** Payer city */
addressCity?: string
/** Payer state */
addressState: string
/** Payer ZIP code */
addressZipCode: string
}

export type CreateBoleto = {
/** Primary identifier of the boleto connection */
boletoConnectionId: string
boleto: {
/** Your identifier for this boleto (max 10 characters) */
seuNumero: string
/** Boleto amount (minimum 2.5) */
amount: number
/** Due date for the boleto (ISO date-time). Must be today or in the future */
dueDate: string
payer: CreateBoletoPayer
/** Fine information for late payment */
fine?: BoletoFine
/** Interest information for late payment */
interest?: BoletoInterest
}
}

export const BOLETO_STATUSES = ['OPEN', 'PAID', 'OVERDUE', 'CANCELLED', 'PROTESTED'] as const
/**
* @typedef BoletoStatus
* - OPEN: issued and awaiting payment
* - PAID: paid (see `paidAt`, `amountPaid`, `paymentOrigin`)
* - OVERDUE: the due date has passed and the boleto has not been paid
* - CANCELLED: canceled by the issuer
* - PROTESTED: sent to a protesto/credit-bureau process
*/
export type BoletoStatus = typeof BOLETO_STATUSES[number]

export const BOLETO_PAYMENT_ORIGINS = ['PIX', 'BOLETO'] as const
export type BoletoPaymentOrigin = typeof BOLETO_PAYMENT_ORIGINS[number]

export type IssuedBoletoPayer = CreateBoletoPayer & {
/** Type of person (individual or business) */
personType?: string
/** Payer address number */
addressNumber?: string
/** Additional address information */
addressComplement?: string
/** Payer neighborhood */
addressNeighborhood?: string
/** Payer email */
email?: string
/** Payer area code */
ddd?: string
/** Payer phone number */
phoneNumber?: string
}

export type IssuedBoleto = {
/** Primary identifier */
id: string
/** Boleto amount */
amount: number
/** Current status of the boleto */
status: BoletoStatus
/** Your identifier for this boleto */
seuNumero: string
/** Due date of the boleto */
dueDate: Date
payer: IssuedBoletoPayer
/** PIX QR code for payment */
pixQr?: string
/** Boleto digitable line */
digitableLine: string
/** Bank's internal identifier for the boleto */
nossoNumero?: string
/** Boleto barcode */
barcode: string
/** ID of the boleto connection used to create this boleto */
boletoConnectionId: string
/** Date when the boleto was created */
createdAt: Date
/** Amount that was paid for this boleto */
amountPaid?: number | null
/** Origin of the payment when the boleto is paid */
paymentOrigin?: BoletoPaymentOrigin | null
/** Fine information for late payment */
fine?: BoletoFine | null
/** Interest information for late payment */
interest?: BoletoInterest
/** Date when the boleto was paid */
paidAt?: Date
}
Loading
Loading