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: 12 additions & 0 deletions .changeset/warm-pandas-dance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@blindpay/node": minor
---

Add support for Colombia (COP) and Argentina (ARS) payins

- Added PSE payment method support for Colombia payins
- Added Transfers instruction support for Argentina payins
- Improved type definitions for Payin, PayinPaymentMethod, and related types
- Added new tracking fields for PSE and Transfers instructions
- Removed deprecated `export`, `get`, and `list` methods from payin quotes resource

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@blindpay/node",
"version": "3.0.0",
"version": "3.1.0",
"description": "Official Node.js SDK for Blindpay API - Global payments infrastructure",
"keywords": [
"blindpay",
Expand Down
203 changes: 69 additions & 134 deletions src/resources/payins/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import type {
AccountClass,
AchCopDocument,
BlindpayApiResponse,
Currency,
Network,
PaginationMetadata,
PaginationParams,
PayerRules,
PayinPaymentMethod,
PayinTrackingComplete,
PayinTrackingPartnerFee,
PayinTrackingPayment,
Expand All @@ -12,87 +17,86 @@ import type {
} from "../../../types";
import type { InternalApiClient } from "../../internal/api-client";

export type BlindpayBankDetails = {
routing_number: string;
account_number: string;
account_type: string;
swift_bic_code?: string | null;
ach?: {
routing_number: string;
account_number: string;
} | null;
wire?: {
routing_number: string;
account_number: string;
} | null;
rtp?: {
routing_number: string;
account_number: string;
} | null;
beneficiary: {
name: string;
address_line_1: string;
address_line_2: string;
};
};

export type Payin = {
receiver_id: string;
id: string;
pix_code?: string;
memo_code?: string;
clabe?: string;
receiver_id: string;
pix_code?: string | null;
memo_code?: string | null;
clabe?: string | null;
status: TransactionStatus;
payin_quote_id: string;
instance_id: string;
tracking_transaction?: PayinTrackingTransaction;
tracking_payment?: PayinTrackingPayment;
tracking_complete?: PayinTrackingComplete;
tracking_transaction: PayinTrackingTransaction;
tracking_payment: PayinTrackingPayment;
tracking_complete: PayinTrackingComplete;
tracking_partner_fee?: PayinTrackingPartnerFee;
created_at: string;
updated_at: string;
image_url?: string;
first_name?: string;
last_name?: string;
legal_name?: string;
type: string;
payment_method: string;
image_url?: string | null | undefined;
first_name?: string | null | undefined;
last_name?: string | null | undefined;
legal_name?: string | null | undefined;
type: AccountClass;
payment_method: PayinPaymentMethod;
sender_amount: number;
receiver_amount: number;
token: StablecoinToken;
partner_fee_amount: number;
total_fee_amount: number;
partner_fee_amount?: number | null;
total_fee_amount?: number | null;
commercial_quotation: number;
blindpay_quotation: number;
currency: string;
billing_fee: number;
currency: Extract<Currency, "BRL" | "USD" | "MXN" | "COP" | "ARS">;
billing_fee?: number | null;
is_otc?: boolean | null;
payer_rules?: PayerRules | null;
name: string;
address: string;
address?: string | null;
network: Network;
blindpay_bank_details: {
routing_number: string;
account_number: string;
account_type: string;
swift_bic_code: string;
ach: {
routing_number: string;
account_number: string;
};
wire: {
routing_number: string;
account_number: string;
};
rtp: {
routing_number: string;
account_number: string;
};
beneficiary: {
name: string;
address_line_1: string;
address_line_2: string;
};
receiving_bank: {
name: string;
address_line_1: string;
address_line_2: string;
};
};
blindpay_bank_details?: BlindpayBankDetails | null;
pse_payment_link?: string | null;
pse_full_name?: string | null;
pse_tax_id?: string | null;
pse_document_type?: Extract<AchCopDocument, "CC" | "NIT"> | null;
};

export type ListPayinsInput = PaginationParams & {
status?: TransactionStatus;
receiver_id?: string;
};

export type ListPayinsResponse = {
data: Payin[];
pagination: PaginationMetadata;
};
export type ListPayinsResponse =
| {
data: Payin[];
pagination: PaginationMetadata;
}
| Payin[];

export type CreatePayinInput = {
quote_id: string;
sender_address: string;
receiver_address: string;
amount: number;
token: StablecoinToken;
network: Network;
description?: string | null;
};

export type GetPayinInput = string;
Expand All @@ -101,74 +105,7 @@ export type GetPayinResponse = Payin;

export type GetPayinTrackInput = string;

export type GetPayinTrackResponse = {
receiver_id: string;
id: string;
pix_code: string;
memo_code: string;
clabe: string;
status: string;
payin_quote_id: string;
instance_id: string;
tracking_transaction: PayinTrackingTransaction;
tracking_payment: PayinTrackingPayment;
tracking_complete: PayinTrackingComplete;
tracking_partner_fee: PayinTrackingPartnerFee;
created_at: string;
updated_at: string;
image_url: string;
first_name: string;
last_name: string;
legal_name: string;
type: string;
payment_method: string;
sender_amount: number;
receiver_amount: number;
token: StablecoinToken;
partner_fee_amount: number;
total_fee_amount: number;
commercial_quotation: number;
blindpay_quotation: number;
currency: string;
billing_fee: number;
name: string;
address: string;
network: Network;
blindpay_bank_details: {
routing_number: string;
account_number: string;
account_type: string;
swift_bic_code: string;
ach: {
routing_number: string;
account_number: string;
};
wire: {
routing_number: string;
account_number: string;
};
rtp: {
routing_number: string;
account_number: string;
};
beneficiary: {
name: string;
address_line_1: string;
address_line_2: string;
};
receiving_bank: {
name: string;
address_line_1: string;
address_line_2: string;
};
};
};

export type ExportPayinsInput = Pick<PaginationParams, "limit" | "offset"> & {
status: TransactionStatus;
};

export type ExportPayinsResponse = Payin[];
export type GetPayinTrackResponse = Payin;

export type CreateEvmPayinInput = string;

Expand All @@ -183,10 +120,14 @@ export type CreateEvmPayinResponse = Pick<
| "tracking_payment"
| "tracking_transaction"
| "tracking_partner_fee"
| "blindpay_bank_details"
| "receiver_id"
| "receiver_amount"
>;
> & {
blindpay_bank_details: BlindpayBankDetails;
receiver_id?: string | null;
receiver_amount?: number | null;
payment_method?: PayinPaymentMethod | null;
billing_fee?: number | null;
sender_amount?: number | null;
};

export function createPayinsResource(instanceId: string, client: InternalApiClient) {
return {
Expand All @@ -200,12 +141,6 @@ export function createPayinsResource(instanceId: string, client: InternalApiClie
getTrack(payinId: GetPayinTrackInput): Promise<BlindpayApiResponse<GetPayinTrackResponse>> {
return client.get(`/e/payins/${payinId}`);
},
export({
...params
}: ExportPayinsInput): Promise<BlindpayApiResponse<ExportPayinsResponse>> {
const queryParams = params ? `?${new URLSearchParams(params)}` : "";
return client.get(`/instances/${instanceId}/export/payins${queryParams}`);
},
createEvm(
payin_quote_id: CreateEvmPayinInput
): Promise<BlindpayApiResponse<CreateEvmPayinResponse>> {
Expand Down
101 changes: 1 addition & 100 deletions src/resources/payins/payins-quotes.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { afterEach, describe, expect, it } from "vitest";
import { BlindPay } from "../../client";
import type {
CreatePayinQuoteResponse,
GetPayinFxRateResponse,
GetPayinQuoteResponse,
ListPayinQuotesResponse,
} from "./quotes";
import type { CreatePayinQuoteResponse, GetPayinFxRateResponse } from "./quotes";

describe("Payin quotes", () => {
afterEach(() => fetchMock.resetMocks());
Expand Down Expand Up @@ -72,98 +67,4 @@ describe("Payin quotes", () => {
expect(data).toEqual(mockedFxRate);
});
});

describe("Get payin quote", () => {
it("should get a payin quote", async () => {
const mockedPayinQuote: GetPayinQuoteResponse = {
id: "qu_000000000000",
payment_method: "pix",
token: "USDC",
request_amount: 1000,
cover_fees: true,
currency_type: "sender",
expires_at: 1712958191,
currency: "BRL",
commercial_quotation: 495,
blindpay_quotation: 505,
receiver_amount: 1010,
sender_amount: 5240,
partner_fee_amount: 150,
flat_fee: 50,
total_fee_amount: 1.53,
payer_rules: {
pix_allowed_tax_ids: ["149.476.037-68"],
},
blockchain_wallet_id: "bw_000000000000",
instance_id: "in_000000000000",
partner_fee_id: "pf_000000000000",
billing_fee: 100,
created_at: "2021-01-01T00:00:00Z",
updated_at: "2021-01-01T00:00:00Z",
};

fetchMock.mockResponseOnce(JSON.stringify(mockedPayinQuote), {
headers: { "Content-Type": "application/json" },
});

const { data, error } = await blindpay.payins.quotes.get("qu_000000000000");

expect(error).toBeNull();
expect(data).toEqual(mockedPayinQuote);
});
});

describe("List payin quotes", () => {
it("should get a payin quote", async () => {
const mockedPayinQuote: ListPayinQuotesResponse = {
data: [
{
id: "qu_000000000000",
payment_method: "pix",
token: "USDC",
request_amount: 1000,
cover_fees: true,
currency_type: "sender",
expires_at: 1712958191,
currency: "BRL",
commercial_quotation: 495,
blindpay_quotation: 505,
receiver_amount: 1010,
sender_amount: 5240,
partner_fee_amount: 150,
flat_fee: 50,
total_fee_amount: 1.53,
payer_rules: {
pix_allowed_tax_ids: ["149.476.037-68"],
},
blockchain_wallet_id: "bw_000000000000",
instance_id: "in_000000000000",
partner_fee_id: "pf_000000000000",
billing_fee: 100,
created_at: "2021-01-01T00:00:00Z",
updated_at: "2021-01-01T00:00:00Z",
},
],
pagination: {
has_more: true,
next_page: "qu_123",
prev_page: "qu_123",
},
};

fetchMock.mockResponseOnce(JSON.stringify(mockedPayinQuote), {
headers: { "Content-Type": "application/json" },
});

const { data, error } = await blindpay.payins.quotes.list({
blockchain_wallet_id: "bw_000000000000",
payment_method: "pix",
token: "USDC",
receiver_id: "re_000000000000",
});

expect(error).toBeNull();
expect(data).toEqual(mockedPayinQuote);
});
});
});
Loading