From 1504f77d04de02c438a40a669e94844890b2e65f Mon Sep 17 00:00:00 2001 From: tahseen-ccprotocol Date: Fri, 20 Feb 2026 16:36:15 +0600 Subject: [PATCH 1/5] feat: added sync API in customer service --- packages/api/src/services/customerService.ts | 23 ++++++++++++++++++++ packages/api/src/types/customer.ts | 16 ++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/packages/api/src/services/customerService.ts b/packages/api/src/services/customerService.ts index 4a0f71d..65696c6 100644 --- a/packages/api/src/services/customerService.ts +++ b/packages/api/src/services/customerService.ts @@ -13,6 +13,8 @@ export interface CustomerService { id: string, customer: Customer.Request, ): Promise>; + + sync(id: string, sync: Customer.Sync): Promise>; } export const createCustomerService = (client: OakClient): CustomerService => ({ @@ -91,4 +93,25 @@ export const createCustomerService = (client: OakClient): CustomerService => ({ }, ); }, + + async sync( + id: string, + sync: Customer.Sync, + ): Promise> { + const token = await client.getAccessToken(); + if (!token.ok) { + return err(token.error); + } + + return httpClient.post( + `${client.config.baseUrl}/api/v1/customers/${id}/sync`, + sync, + { + headers: { + Authorization: `Bearer ${token.value}`, + }, + retryOptions: client.retryOptions, + }, + ); + }, }); diff --git a/packages/api/src/types/customer.ts b/packages/api/src/types/customer.ts index 7fc2a00..f9d7e03 100644 --- a/packages/api/src/types/customer.ts +++ b/packages/api/src/types/customer.ts @@ -53,6 +53,22 @@ export namespace Customer { account_type?: string | null; } + export interface Sync { + // provider is an array of providers to sync the customer with and length must be 1 + providers: + | "stripe" + | "bridge" + | "pagar_me" + | "brla" + | "avenia" + | "mercado_pago"[]; + + // fields is an array of fields to sync the customer + fields: "shipping" | "email" | "first_name" | "last_name"[]; + } + + export type SyncResponse = ApiResponse; + export interface Request extends Partial {} export type Response = ApiResponse; From c86a0b8c9b215a41c3cd0f5e97544851280c1ac5 Mon Sep 17 00:00:00 2001 From: tahseen-ccprotocol Date: Fri, 20 Feb 2026 22:34:21 +0600 Subject: [PATCH 2/5] feat: integrated sync and balance api in customer service --- packages/api/src/services/customerService.ts | 27 +++++++++++++++++ packages/api/src/types/customer.ts | 31 ++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/packages/api/src/services/customerService.ts b/packages/api/src/services/customerService.ts index 65696c6..a549408 100644 --- a/packages/api/src/services/customerService.ts +++ b/packages/api/src/services/customerService.ts @@ -15,6 +15,11 @@ export interface CustomerService { ): Promise>; sync(id: string, sync: Customer.Sync): Promise>; + + balance( + customer_id: string, + filter: Customer.BalanceFilter, + ): Promise>; } export const createCustomerService = (client: OakClient): CustomerService => ({ @@ -114,4 +119,26 @@ export const createCustomerService = (client: OakClient): CustomerService => ({ }, ); }, + + async balance( + customer_id: string, + filter: Customer.BalanceFilter, + ): Promise> { + const token = await client.getAccessToken(); + if (!token.ok) { + return err(token.error); + } + + const queryString = buildQueryString(filter); + + return httpClient.get( + `${client.config.baseUrl}/api/v1/customers/${customer_id}/balance${queryString}`, + { + headers: { + Authorization: `Bearer ${token.value}`, + }, + retryOptions: client.retryOptions, + }, + ); + }, }); diff --git a/packages/api/src/types/customer.ts b/packages/api/src/types/customer.ts index f9d7e03..12baeec 100644 --- a/packages/api/src/types/customer.ts +++ b/packages/api/src/types/customer.ts @@ -88,4 +88,35 @@ export namespace Customer { document_type?: string; country_code?: string; } + export interface BalanceFilter { + provider: string; + role: string; + } + + export interface BalanceResponse + extends ApiResponse<{ + as_of: string; + filters: { + customer_id: string; + provider?: string; + role?: string; + }; + + balances: { + account_id: string; + provider: string; + customer: { + id: string; + role: string; + }; + as_of: string; + totals: { + currency: string; + amount: number; + pending: number; + reserved: number; + instant_payouts: number; + }[]; + }[]; + }> {} } From 44cee69fefee780d0fc3ed3613fb668a51dc254e Mon Sep 17 00:00:00 2001 From: tahseen-ccprotocol Date: Fri, 20 Feb 2026 22:43:03 +0600 Subject: [PATCH 3/5] added change set --- .changeset/seven-hornets-shout.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/seven-hornets-shout.md diff --git a/.changeset/seven-hornets-shout.md b/.changeset/seven-hornets-shout.md new file mode 100644 index 0000000..2fc0fb2 --- /dev/null +++ b/.changeset/seven-hornets-shout.md @@ -0,0 +1,5 @@ +--- +"@oaknetwork/api": minor +--- + +added sync and balance API From 5ce3d18bf0f2762d926d3736e25d91c8794d8872 Mon Sep 17 00:00:00 2001 From: tahseen-ccprotocol Date: Sat, 21 Feb 2026 02:44:07 +0600 Subject: [PATCH 4/5] refactor: clean type safety --- packages/api/src/types/customer.ts | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/api/src/types/customer.ts b/packages/api/src/types/customer.ts index 12baeec..6cdb73b 100644 --- a/packages/api/src/types/customer.ts +++ b/packages/api/src/types/customer.ts @@ -53,18 +53,19 @@ export namespace Customer { account_type?: string | null; } - export interface Sync { - // provider is an array of providers to sync the customer with and length must be 1 - providers: - | "stripe" - | "bridge" - | "pagar_me" - | "brla" - | "avenia" - | "mercado_pago"[]; + type Provider = + | "stripe" + | "bridge" + | "pagar_me" + | "brla" + | "avenia" + | "mercado_pago"; + + type SyncField = "shipping" | "email" | "first_name" | "last_name"; - // fields is an array of fields to sync the customer - fields: "shipping" | "email" | "first_name" | "last_name"[]; + export interface Sync { + providers: [Provider]; // exactly 1 + fields: SyncField[]; } export type SyncResponse = ApiResponse; From da8727b8f58074d3b2543e0be3d217409811023e Mon Sep 17 00:00:00 2001 From: tahseen-ccprotocol Date: Sat, 21 Feb 2026 02:47:13 +0600 Subject: [PATCH 5/5] test: added test coverage --- packages/api/__tests__/unit/services.test.ts | 33 ++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/packages/api/__tests__/unit/services.test.ts b/packages/api/__tests__/unit/services.test.ts index 261e167..99f6415 100644 --- a/packages/api/__tests__/unit/services.test.ts +++ b/packages/api/__tests__/unit/services.test.ts @@ -200,6 +200,27 @@ describe("Crowdsplit services (Unit)", () => { authConfig, ], }); + await expectSuccess({ + client, + call: () => + service.sync("cust-1", { providers: ["stripe"], fields: ["shipping"] }), + httpMethod: "post", + expectedArgs: [ + `${SANDBOX_URL}/api/v1/customers/cust-1/sync`, + { providers: ["stripe"], fields: ["shipping"] }, + authConfig, + ], + }); + await expectSuccess({ + client, + call: () => + service.balance("cust-1", { provider: "stripe", role: "customer" }), + httpMethod: "get", + expectedArgs: [ + `${SANDBOX_URL}/api/v1/customers/cust-1/balance?provider=stripe&role=customer`, + authConfig, + ], + }); await expectFailure({ call: () => service.update("cust-1", { email: "new@example.com" }), httpMethod: "put", @@ -216,6 +237,18 @@ describe("Crowdsplit services (Unit)", () => { await expectTokenFailure(() => tokenErrorService.update("cust-1", { email: "t@t.com" }), ); + await expectTokenFailure(() => + tokenErrorService.sync("cust-1", { + providers: ["stripe"], + fields: ["shipping"], + }), + ); + await expectTokenFailure(() => + tokenErrorService.balance("cust-1", { + provider: "stripe", + role: "customer", + }), + ); }); it("payment service methods", async () => {