From 60d27d6fc2a7c6829e22717a99ff7a9e76d06b08 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 19 Sep 2026 17:17:02 +0000 Subject: [PATCH 1/2] feat: add partner settings methods Co-authored-by: myles.foster --- lib/Gateway.ts | 3 ++ lib/PartnerGateway.ts | 75 ++++++++++++++++++++++++++++++++++++++++ test/unit/partnerSpec.ts | 58 +++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 lib/PartnerGateway.ts create mode 100644 test/unit/partnerSpec.ts diff --git a/lib/Gateway.ts b/lib/Gateway.ts index 7aa59e8..00e5a3f 100644 --- a/lib/Gateway.ts +++ b/lib/Gateway.ts @@ -10,6 +10,7 @@ import { Client } from "./Client"; import { InvoiceLineGateway } from "./InvoiceLineGateway"; import { InvoicePaymentGateway } from "./InvoicePaymentGateway"; import { VerificationGateway } from "./VerificationGateway"; +import { PartnerGateway } from "./PartnerGateway"; export class Gateway { config: Configuration; @@ -25,6 +26,7 @@ export class Gateway { invoicePayment: InvoicePaymentGateway; verification: VerificationGateway; trust: VerificationGateway; + partner: PartnerGateway; /** * This should be called by the connect() method to setup a client gateway @@ -45,5 +47,6 @@ export class Gateway { this.invoicePayment = new InvoicePaymentGateway(this); this.verification = new VerificationGateway(this); this.trust = this.verification; + this.partner = new PartnerGateway(this); } } diff --git a/lib/PartnerGateway.ts b/lib/PartnerGateway.ts new file mode 100644 index 0000000..faaa79a --- /dev/null +++ b/lib/PartnerGateway.ts @@ -0,0 +1,75 @@ +import { Configuration } from "./Configuration"; +import { Gateway } from "./Gateway"; + +export class PartnerGateway { + gateway: Gateway; + config: Configuration; + + constructor(gateway: Gateway) { + this.gateway = gateway; + this.config = gateway.config; + } + + async getFees() { + return this.gateway.client.get("/v1/fees"); + } + + async updateFees(body: { [key: string]: any }) { + return this.gateway.client.patch("/v1/fees", body); + } + + async listPayoutMethods() { + return this.gateway.client.get("/v1/payout-methods"); + } + + async getPayoutMethod(payoutMethod: string) { + return this.gateway.client.get(`/v1/payout-methods/${encodeURIComponent(payoutMethod)}`); + } + + async updatePayoutMethod(payoutMethod: string, body: { [key: string]: any }) { + return this.gateway.client.patch( + `/v1/payout-methods/${encodeURIComponent(payoutMethod)}`, + body, + ); + } + + async getProcessingSettings() { + return this.gateway.client.get("/v1/processing-settings"); + } + + async updateProcessingSettings(body: { [key: string]: any }) { + return this.gateway.client.patch("/v1/processing-settings", body); + } + + async getWhiteLabelDnsRecords() { + return this.gateway.client.get("/v1/white-label/dns-records"); + } + + async verifyWhiteLabelDnsRecords() { + return this.gateway.client.post("/v1/white-label/dns-records/verify", {}); + } + + async deleteWhiteLabelEmail() { + return this.gateway.client.remove("/v1/white-label/email"); + } + + async updateWhiteLabelIcon(body: { [key: string]: any }) { + return this.gateway.client.patch("/v1/white-label/icon", body); + } + + async getWhiteLabelSettings() { + return this.gateway.client.get("/v1/white-label"); + } + + async updateWhiteLabelSettings(body: { [key: string]: any }) { + return this.gateway.client.patch("/v1/white-label", body); + } + + async getWidgetConfiguration() { + return this.gateway.client.get("/v1/iframe/config"); + } + + async updateWidgetConfiguration(body: { [key: string]: any } = {}) { + return this.gateway.client.post("/v1/iframe/config", body); + } +} diff --git a/test/unit/partnerSpec.ts b/test/unit/partnerSpec.ts new file mode 100644 index 0000000..ab5dca8 --- /dev/null +++ b/test/unit/partnerSpec.ts @@ -0,0 +1,58 @@ +import { Configuration, Gateway } from "../../lib"; + +import * as assert from "assert"; +import * as sinon from "sinon"; + +describe("Partner", () => { + let sandbox: sinon.SinonSandbox; + let gateway: Gateway; + + beforeEach(() => { + sandbox = sinon.createSandbox(); + gateway = new Gateway(new Configuration({ key: "access-code", secret: "secret-code" })); + }); + + afterEach(() => { + sandbox.restore(); + }); + + it("calls each partner endpoint through a dedicated method", async () => { + const get = sandbox.stub(gateway.client, "get").resolves({ ok: true }); + const patch = sandbox.stub(gateway.client, "patch").resolves({ ok: true }); + const post = sandbox.stub(gateway.client, "post").resolves({ ok: true }); + const remove = sandbox.stub(gateway.client, "remove").resolves({ ok: true }); + const body = { enabled: true }; + + await gateway.partner.getFees(); + await gateway.partner.updateFees(body); + await gateway.partner.listPayoutMethods(); + await gateway.partner.getPayoutMethod("bank-transfer"); + await gateway.partner.updatePayoutMethod("bank-transfer", body); + await gateway.partner.getProcessingSettings(); + await gateway.partner.updateProcessingSettings(body); + await gateway.partner.getWhiteLabelDnsRecords(); + await gateway.partner.verifyWhiteLabelDnsRecords(); + await gateway.partner.deleteWhiteLabelEmail(); + await gateway.partner.updateWhiteLabelIcon(body); + await gateway.partner.getWhiteLabelSettings(); + await gateway.partner.updateWhiteLabelSettings(body); + await gateway.partner.getWidgetConfiguration(); + await gateway.partner.updateWidgetConfiguration(body); + + assert(get.calledWithExactly("/v1/fees")); + assert(get.calledWithExactly("/v1/payout-methods")); + assert(get.calledWithExactly("/v1/payout-methods/bank-transfer")); + assert(get.calledWithExactly("/v1/processing-settings")); + assert(get.calledWithExactly("/v1/white-label/dns-records")); + assert(get.calledWithExactly("/v1/white-label")); + assert(get.calledWithExactly("/v1/iframe/config")); + assert(patch.calledWithExactly("/v1/fees", body)); + assert(patch.calledWithExactly("/v1/payout-methods/bank-transfer", body)); + assert(patch.calledWithExactly("/v1/processing-settings", body)); + assert(patch.calledWithExactly("/v1/white-label/icon", body)); + assert(patch.calledWithExactly("/v1/white-label", body)); + assert(post.calledWithExactly("/v1/white-label/dns-records/verify", {})); + assert(post.calledWithExactly("/v1/iframe/config", body)); + assert(remove.calledWithExactly("/v1/white-label/email")); + }); +}); From a9748486ac685914bff1c2faaf34a2fd0b4c4edf Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 19 Sep 2026 17:20:10 +0000 Subject: [PATCH 2/2] feat: filter partner fees by currency Co-authored-by: myles.foster --- lib/PartnerGateway.ts | 7 +++++-- test/unit/partnerSpec.ts | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/PartnerGateway.ts b/lib/PartnerGateway.ts index faaa79a..4174f44 100644 --- a/lib/PartnerGateway.ts +++ b/lib/PartnerGateway.ts @@ -10,8 +10,11 @@ export class PartnerGateway { this.config = gateway.config; } - async getFees() { - return this.gateway.client.get("/v1/fees"); + async getFees(currency?: string) { + const endpoint = currency + ? `/v1/fees?currency=${encodeURIComponent(currency)}` + : "/v1/fees"; + return this.gateway.client.get(endpoint); } async updateFees(body: { [key: string]: any }) { diff --git a/test/unit/partnerSpec.ts b/test/unit/partnerSpec.ts index ab5dca8..04de4cd 100644 --- a/test/unit/partnerSpec.ts +++ b/test/unit/partnerSpec.ts @@ -24,6 +24,7 @@ describe("Partner", () => { const body = { enabled: true }; await gateway.partner.getFees(); + await gateway.partner.getFees("USD"); await gateway.partner.updateFees(body); await gateway.partner.listPayoutMethods(); await gateway.partner.getPayoutMethod("bank-transfer"); @@ -40,6 +41,7 @@ describe("Partner", () => { await gateway.partner.updateWidgetConfiguration(body); assert(get.calledWithExactly("/v1/fees")); + assert(get.calledWithExactly("/v1/fees?currency=USD")); assert(get.calledWithExactly("/v1/payout-methods")); assert(get.calledWithExactly("/v1/payout-methods/bank-transfer")); assert(get.calledWithExactly("/v1/processing-settings"));