@settlr/sdk 0.6.6 → 0.6.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +194 -537
- package/dist/index.d.mts +430 -2
- package/dist/index.d.ts +430 -2
- package/dist/index.js +342 -0
- package/dist/index.mjs +338 -0
- package/package.json +22 -30
package/dist/index.js
CHANGED
|
@@ -35,6 +35,7 @@ __export(index_exports, {
|
|
|
35
35
|
INCO_LIGHTNING_PROGRAM_ID: () => INCO_LIGHTNING_PROGRAM_ID,
|
|
36
36
|
OneClickClient: () => OneClickClient,
|
|
37
37
|
PaymentModal: () => PaymentModal,
|
|
38
|
+
PayoutClient: () => PayoutClient,
|
|
38
39
|
PrivacyFeatures: () => PrivacyFeatures,
|
|
39
40
|
REACT_NATIVE_EXAMPLE: () => REACT_NATIVE_EXAMPLE,
|
|
40
41
|
REST_API: () => REST_API,
|
|
@@ -44,6 +45,7 @@ __export(index_exports, {
|
|
|
44
45
|
SUPPORTED_TOKENS: () => SUPPORTED_TOKENS,
|
|
45
46
|
Settlr: () => Settlr,
|
|
46
47
|
SettlrProvider: () => SettlrProvider,
|
|
48
|
+
SubscriptionClient: () => SubscriptionClient,
|
|
47
49
|
UNITY_EXAMPLE: () => UNITY_EXAMPLE,
|
|
48
50
|
USDC_MINT_DEVNET: () => USDC_MINT_DEVNET,
|
|
49
51
|
USDC_MINT_MAINNET: () => USDC_MINT_MAINNET,
|
|
@@ -52,6 +54,8 @@ __export(index_exports, {
|
|
|
52
54
|
buildAllowanceRemainingAccounts: () => buildAllowanceRemainingAccounts,
|
|
53
55
|
buildPrivateReceiptAccounts: () => buildPrivateReceiptAccounts,
|
|
54
56
|
createOneClickClient: () => createOneClickClient,
|
|
57
|
+
createPayoutClient: () => createPayoutClient,
|
|
58
|
+
createSubscriptionClient: () => createSubscriptionClient,
|
|
55
59
|
createWebhookHandler: () => createWebhookHandler,
|
|
56
60
|
encryptAmount: () => encryptAmount,
|
|
57
61
|
findAllowancePda: () => findAllowancePda,
|
|
@@ -1650,6 +1654,340 @@ export function useSettlrPayment(onSuccess: (sig: string) => void) {
|
|
|
1650
1654
|
return { startPayment };
|
|
1651
1655
|
}
|
|
1652
1656
|
`;
|
|
1657
|
+
|
|
1658
|
+
// src/subscriptions.ts
|
|
1659
|
+
var SubscriptionClient = class {
|
|
1660
|
+
constructor(config) {
|
|
1661
|
+
if (!config.apiKey) {
|
|
1662
|
+
throw new Error(
|
|
1663
|
+
"API key is required. Get one at https://settlr.dev/dashboard"
|
|
1664
|
+
);
|
|
1665
|
+
}
|
|
1666
|
+
this.apiKey = config.apiKey;
|
|
1667
|
+
this.baseUrl = (config.baseUrl || "https://settlr.dev").replace(/\/$/, "");
|
|
1668
|
+
this.merchantId = config.merchantId;
|
|
1669
|
+
this.merchantWallet = config.merchantWallet;
|
|
1670
|
+
}
|
|
1671
|
+
async fetch(path, options = {}) {
|
|
1672
|
+
const url = `${this.baseUrl}${path}`;
|
|
1673
|
+
const res = await fetch(url, {
|
|
1674
|
+
...options,
|
|
1675
|
+
headers: {
|
|
1676
|
+
"Content-Type": "application/json",
|
|
1677
|
+
"X-API-Key": this.apiKey,
|
|
1678
|
+
...options.headers
|
|
1679
|
+
}
|
|
1680
|
+
});
|
|
1681
|
+
const data = await res.json();
|
|
1682
|
+
if (!res.ok) {
|
|
1683
|
+
throw new Error(
|
|
1684
|
+
data.error || `API error: ${res.status}`
|
|
1685
|
+
);
|
|
1686
|
+
}
|
|
1687
|
+
return data;
|
|
1688
|
+
}
|
|
1689
|
+
/**
|
|
1690
|
+
* Resolve merchant ID from API key
|
|
1691
|
+
*/
|
|
1692
|
+
async ensureMerchantId() {
|
|
1693
|
+
if (this.merchantId) return this.merchantId;
|
|
1694
|
+
const data = await this.fetch("/api/sdk/validate", {
|
|
1695
|
+
method: "POST",
|
|
1696
|
+
body: JSON.stringify({})
|
|
1697
|
+
});
|
|
1698
|
+
this.merchantId = data.merchantId;
|
|
1699
|
+
if (data.merchantWallet && !this.merchantWallet) {
|
|
1700
|
+
this.merchantWallet = data.merchantWallet;
|
|
1701
|
+
}
|
|
1702
|
+
return this.merchantId;
|
|
1703
|
+
}
|
|
1704
|
+
// ═══════════════════════════════════════
|
|
1705
|
+
// PLANS
|
|
1706
|
+
// ═══════════════════════════════════════
|
|
1707
|
+
/**
|
|
1708
|
+
* Create a subscription plan
|
|
1709
|
+
*/
|
|
1710
|
+
async createPlan(options) {
|
|
1711
|
+
const merchantId = await this.ensureMerchantId();
|
|
1712
|
+
const data = await this.fetch(
|
|
1713
|
+
"/api/subscriptions/plans",
|
|
1714
|
+
{
|
|
1715
|
+
method: "POST",
|
|
1716
|
+
body: JSON.stringify({
|
|
1717
|
+
merchantId,
|
|
1718
|
+
name: options.name,
|
|
1719
|
+
description: options.description,
|
|
1720
|
+
amount: options.amount,
|
|
1721
|
+
interval: options.interval,
|
|
1722
|
+
intervalCount: options.intervalCount || 1,
|
|
1723
|
+
trialDays: options.trialDays || 0,
|
|
1724
|
+
features: options.features || []
|
|
1725
|
+
})
|
|
1726
|
+
}
|
|
1727
|
+
);
|
|
1728
|
+
return data.plan;
|
|
1729
|
+
}
|
|
1730
|
+
/**
|
|
1731
|
+
* List all plans for the merchant
|
|
1732
|
+
*/
|
|
1733
|
+
async listPlans() {
|
|
1734
|
+
const merchantId = await this.ensureMerchantId();
|
|
1735
|
+
const data = await this.fetch(
|
|
1736
|
+
`/api/subscriptions/plans?merchantId=${merchantId}`
|
|
1737
|
+
);
|
|
1738
|
+
return data.plans;
|
|
1739
|
+
}
|
|
1740
|
+
/**
|
|
1741
|
+
* Update a plan
|
|
1742
|
+
*/
|
|
1743
|
+
async updatePlan(planId, options) {
|
|
1744
|
+
const data = await this.fetch(
|
|
1745
|
+
`/api/subscriptions/plans/${planId}`,
|
|
1746
|
+
{
|
|
1747
|
+
method: "PUT",
|
|
1748
|
+
body: JSON.stringify(options)
|
|
1749
|
+
}
|
|
1750
|
+
);
|
|
1751
|
+
return data.plan;
|
|
1752
|
+
}
|
|
1753
|
+
/**
|
|
1754
|
+
* Deactivate a plan (stops new subscriptions)
|
|
1755
|
+
*/
|
|
1756
|
+
async deactivatePlan(planId) {
|
|
1757
|
+
await this.updatePlan(planId, { active: false });
|
|
1758
|
+
}
|
|
1759
|
+
// ═══════════════════════════════════════
|
|
1760
|
+
// SUBSCRIPTIONS
|
|
1761
|
+
// ═══════════════════════════════════════
|
|
1762
|
+
/**
|
|
1763
|
+
* Subscribe a customer to a plan
|
|
1764
|
+
*/
|
|
1765
|
+
async subscribe(options) {
|
|
1766
|
+
const data = await this.fetch("/api/subscriptions", {
|
|
1767
|
+
method: "POST",
|
|
1768
|
+
body: JSON.stringify({
|
|
1769
|
+
action: "subscribe",
|
|
1770
|
+
planId: options.planId,
|
|
1771
|
+
customerWallet: options.customerWallet,
|
|
1772
|
+
merchantWallet: options.merchantWallet || this.merchantWallet,
|
|
1773
|
+
customerEmail: options.customerEmail,
|
|
1774
|
+
metadata: options.metadata
|
|
1775
|
+
})
|
|
1776
|
+
});
|
|
1777
|
+
return data;
|
|
1778
|
+
}
|
|
1779
|
+
/**
|
|
1780
|
+
* List subscriptions
|
|
1781
|
+
*/
|
|
1782
|
+
async listSubscriptions(options) {
|
|
1783
|
+
const merchantId = await this.ensureMerchantId();
|
|
1784
|
+
const params = new URLSearchParams({ merchantId });
|
|
1785
|
+
if (options?.status) params.set("status", options.status);
|
|
1786
|
+
if (options?.customerWallet)
|
|
1787
|
+
params.set("customer", options.customerWallet);
|
|
1788
|
+
if (options?.planId) params.set("planId", options.planId);
|
|
1789
|
+
const data = await this.fetch(
|
|
1790
|
+
`/api/subscriptions?${params.toString()}`
|
|
1791
|
+
);
|
|
1792
|
+
return data.subscriptions;
|
|
1793
|
+
}
|
|
1794
|
+
/**
|
|
1795
|
+
* Get subscription details including payment history
|
|
1796
|
+
*/
|
|
1797
|
+
async getSubscription(subscriptionId) {
|
|
1798
|
+
const data = await this.fetch(`/api/subscriptions/${subscriptionId}`);
|
|
1799
|
+
return {
|
|
1800
|
+
...data.subscription,
|
|
1801
|
+
payments: data.payments
|
|
1802
|
+
};
|
|
1803
|
+
}
|
|
1804
|
+
/**
|
|
1805
|
+
* Cancel a subscription
|
|
1806
|
+
* @param immediately - If true, cancels now. If false (default), cancels at end of billing period.
|
|
1807
|
+
*/
|
|
1808
|
+
async cancel(subscriptionId, immediately = false) {
|
|
1809
|
+
return this.fetch("/api/subscriptions", {
|
|
1810
|
+
method: "POST",
|
|
1811
|
+
body: JSON.stringify({
|
|
1812
|
+
action: "cancel",
|
|
1813
|
+
subscriptionId,
|
|
1814
|
+
immediately
|
|
1815
|
+
})
|
|
1816
|
+
});
|
|
1817
|
+
}
|
|
1818
|
+
/**
|
|
1819
|
+
* Pause a subscription (stops billing, preserves subscription)
|
|
1820
|
+
*/
|
|
1821
|
+
async pause(subscriptionId) {
|
|
1822
|
+
return this.fetch("/api/subscriptions", {
|
|
1823
|
+
method: "POST",
|
|
1824
|
+
body: JSON.stringify({
|
|
1825
|
+
action: "pause",
|
|
1826
|
+
subscriptionId
|
|
1827
|
+
})
|
|
1828
|
+
});
|
|
1829
|
+
}
|
|
1830
|
+
/**
|
|
1831
|
+
* Resume a paused subscription
|
|
1832
|
+
*/
|
|
1833
|
+
async resume(subscriptionId) {
|
|
1834
|
+
return this.fetch("/api/subscriptions", {
|
|
1835
|
+
method: "POST",
|
|
1836
|
+
body: JSON.stringify({
|
|
1837
|
+
action: "resume",
|
|
1838
|
+
subscriptionId
|
|
1839
|
+
})
|
|
1840
|
+
});
|
|
1841
|
+
}
|
|
1842
|
+
/**
|
|
1843
|
+
* Manually charge a subscription (useful for metered billing)
|
|
1844
|
+
*/
|
|
1845
|
+
async charge(subscriptionId) {
|
|
1846
|
+
return this.fetch("/api/subscriptions", {
|
|
1847
|
+
method: "POST",
|
|
1848
|
+
body: JSON.stringify({
|
|
1849
|
+
action: "charge",
|
|
1850
|
+
subscriptionId
|
|
1851
|
+
})
|
|
1852
|
+
});
|
|
1853
|
+
}
|
|
1854
|
+
};
|
|
1855
|
+
function createSubscriptionClient(config) {
|
|
1856
|
+
return new SubscriptionClient(config);
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
// src/payouts.ts
|
|
1860
|
+
var PayoutClient = class {
|
|
1861
|
+
constructor(config) {
|
|
1862
|
+
if (!config.apiKey) {
|
|
1863
|
+
throw new Error(
|
|
1864
|
+
"API key is required. Get one at https://settlr.dev/dashboard"
|
|
1865
|
+
);
|
|
1866
|
+
}
|
|
1867
|
+
this.apiKey = config.apiKey;
|
|
1868
|
+
this.baseUrl = (config.baseUrl || "https://settlr.dev").replace(/\/$/, "");
|
|
1869
|
+
}
|
|
1870
|
+
async fetch(path, options = {}) {
|
|
1871
|
+
const url = `${this.baseUrl}${path}`;
|
|
1872
|
+
const res = await fetch(url, {
|
|
1873
|
+
...options,
|
|
1874
|
+
headers: {
|
|
1875
|
+
"Content-Type": "application/json",
|
|
1876
|
+
"X-API-Key": this.apiKey,
|
|
1877
|
+
...options.headers
|
|
1878
|
+
}
|
|
1879
|
+
});
|
|
1880
|
+
const data = await res.json();
|
|
1881
|
+
if (!res.ok) {
|
|
1882
|
+
throw new Error(
|
|
1883
|
+
data.error || `Payout API error: ${res.status}`
|
|
1884
|
+
);
|
|
1885
|
+
}
|
|
1886
|
+
return data;
|
|
1887
|
+
}
|
|
1888
|
+
// -----------------------------------------------------------------------
|
|
1889
|
+
// Create a single payout
|
|
1890
|
+
// -----------------------------------------------------------------------
|
|
1891
|
+
/**
|
|
1892
|
+
* Send a payout to a recipient by email.
|
|
1893
|
+
* They'll receive an email with a claim link — no wallet or bank details needed.
|
|
1894
|
+
*
|
|
1895
|
+
* @example
|
|
1896
|
+
* ```typescript
|
|
1897
|
+
* const payout = await payouts.create({
|
|
1898
|
+
* email: 'alice@example.com',
|
|
1899
|
+
* amount: 250.00,
|
|
1900
|
+
* memo: 'March data labeling — 500 tasks',
|
|
1901
|
+
* });
|
|
1902
|
+
* console.log(payout.id); // "po_abc123"
|
|
1903
|
+
* console.log(payout.status); // "sent"
|
|
1904
|
+
* console.log(payout.claimUrl); // "https://settlr.dev/claim/..."
|
|
1905
|
+
* ```
|
|
1906
|
+
*/
|
|
1907
|
+
async create(options) {
|
|
1908
|
+
if (!options.email || !options.email.includes("@")) {
|
|
1909
|
+
throw new Error("Valid email address is required");
|
|
1910
|
+
}
|
|
1911
|
+
if (!options.amount || options.amount <= 0) {
|
|
1912
|
+
throw new Error("Amount must be a positive number");
|
|
1913
|
+
}
|
|
1914
|
+
return this.fetch("/api/payouts", {
|
|
1915
|
+
method: "POST",
|
|
1916
|
+
body: JSON.stringify({
|
|
1917
|
+
email: options.email,
|
|
1918
|
+
amount: options.amount,
|
|
1919
|
+
currency: options.currency || "USDC",
|
|
1920
|
+
memo: options.memo,
|
|
1921
|
+
metadata: options.metadata
|
|
1922
|
+
})
|
|
1923
|
+
});
|
|
1924
|
+
}
|
|
1925
|
+
// -----------------------------------------------------------------------
|
|
1926
|
+
// Create batch payouts
|
|
1927
|
+
// -----------------------------------------------------------------------
|
|
1928
|
+
/**
|
|
1929
|
+
* Send multiple payouts at once. Each recipient gets their own email.
|
|
1930
|
+
*
|
|
1931
|
+
* @example
|
|
1932
|
+
* ```typescript
|
|
1933
|
+
* const batch = await payouts.createBatch([
|
|
1934
|
+
* { email: 'alice@example.com', amount: 250.00, memo: 'March' },
|
|
1935
|
+
* { email: 'bob@example.com', amount: 180.00, memo: 'March' },
|
|
1936
|
+
* ]);
|
|
1937
|
+
* console.log(batch.id); // "batch_xyz"
|
|
1938
|
+
* console.log(batch.total); // 430.00
|
|
1939
|
+
* ```
|
|
1940
|
+
*/
|
|
1941
|
+
async createBatch(payoutsList) {
|
|
1942
|
+
if (!Array.isArray(payoutsList) || payoutsList.length === 0) {
|
|
1943
|
+
throw new Error("Payouts list must be a non-empty array");
|
|
1944
|
+
}
|
|
1945
|
+
return this.fetch("/api/payouts/batch", {
|
|
1946
|
+
method: "POST",
|
|
1947
|
+
body: JSON.stringify({ payouts: payoutsList })
|
|
1948
|
+
});
|
|
1949
|
+
}
|
|
1950
|
+
// -----------------------------------------------------------------------
|
|
1951
|
+
// Get a single payout
|
|
1952
|
+
// -----------------------------------------------------------------------
|
|
1953
|
+
/**
|
|
1954
|
+
* Get a payout by ID.
|
|
1955
|
+
*
|
|
1956
|
+
* @example
|
|
1957
|
+
* ```typescript
|
|
1958
|
+
* const payout = await payouts.get('po_abc123');
|
|
1959
|
+
* console.log(payout.status); // "claimed"
|
|
1960
|
+
* console.log(payout.claimedAt); // "2024-03-15T14:30:00Z"
|
|
1961
|
+
* ```
|
|
1962
|
+
*/
|
|
1963
|
+
async get(id) {
|
|
1964
|
+
if (!id) throw new Error("Payout ID is required");
|
|
1965
|
+
return this.fetch(`/api/payouts/${encodeURIComponent(id)}`);
|
|
1966
|
+
}
|
|
1967
|
+
// -----------------------------------------------------------------------
|
|
1968
|
+
// List payouts
|
|
1969
|
+
// -----------------------------------------------------------------------
|
|
1970
|
+
/**
|
|
1971
|
+
* List payouts for the authenticated merchant.
|
|
1972
|
+
*
|
|
1973
|
+
* @example
|
|
1974
|
+
* ```typescript
|
|
1975
|
+
* const result = await payouts.list({ status: 'claimed', limit: 50 });
|
|
1976
|
+
* result.data.forEach(p => console.log(p.email, p.amount, p.status));
|
|
1977
|
+
* ```
|
|
1978
|
+
*/
|
|
1979
|
+
async list(options) {
|
|
1980
|
+
const params = new URLSearchParams();
|
|
1981
|
+
if (options?.status) params.set("status", options.status);
|
|
1982
|
+
if (options?.limit) params.set("limit", options.limit.toString());
|
|
1983
|
+
if (options?.offset) params.set("offset", options.offset.toString());
|
|
1984
|
+
const qs = params.toString();
|
|
1985
|
+
return this.fetch(`/api/payouts${qs ? `?${qs}` : ""}`);
|
|
1986
|
+
}
|
|
1987
|
+
};
|
|
1988
|
+
function createPayoutClient(config) {
|
|
1989
|
+
return new PayoutClient(config);
|
|
1990
|
+
}
|
|
1653
1991
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1654
1992
|
0 && (module.exports = {
|
|
1655
1993
|
BuyButton,
|
|
@@ -1657,6 +1995,7 @@ export function useSettlrPayment(onSuccess: (sig: string) => void) {
|
|
|
1657
1995
|
INCO_LIGHTNING_PROGRAM_ID,
|
|
1658
1996
|
OneClickClient,
|
|
1659
1997
|
PaymentModal,
|
|
1998
|
+
PayoutClient,
|
|
1660
1999
|
PrivacyFeatures,
|
|
1661
2000
|
REACT_NATIVE_EXAMPLE,
|
|
1662
2001
|
REST_API,
|
|
@@ -1666,6 +2005,7 @@ export function useSettlrPayment(onSuccess: (sig: string) => void) {
|
|
|
1666
2005
|
SUPPORTED_TOKENS,
|
|
1667
2006
|
Settlr,
|
|
1668
2007
|
SettlrProvider,
|
|
2008
|
+
SubscriptionClient,
|
|
1669
2009
|
UNITY_EXAMPLE,
|
|
1670
2010
|
USDC_MINT_DEVNET,
|
|
1671
2011
|
USDC_MINT_MAINNET,
|
|
@@ -1674,6 +2014,8 @@ export function useSettlrPayment(onSuccess: (sig: string) => void) {
|
|
|
1674
2014
|
buildAllowanceRemainingAccounts,
|
|
1675
2015
|
buildPrivateReceiptAccounts,
|
|
1676
2016
|
createOneClickClient,
|
|
2017
|
+
createPayoutClient,
|
|
2018
|
+
createSubscriptionClient,
|
|
1677
2019
|
createWebhookHandler,
|
|
1678
2020
|
encryptAmount,
|
|
1679
2021
|
findAllowancePda,
|