@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.mjs
CHANGED
|
@@ -1596,12 +1596,347 @@ export function useSettlrPayment(onSuccess: (sig: string) => void) {
|
|
|
1596
1596
|
return { startPayment };
|
|
1597
1597
|
}
|
|
1598
1598
|
`;
|
|
1599
|
+
|
|
1600
|
+
// src/subscriptions.ts
|
|
1601
|
+
var SubscriptionClient = class {
|
|
1602
|
+
constructor(config) {
|
|
1603
|
+
if (!config.apiKey) {
|
|
1604
|
+
throw new Error(
|
|
1605
|
+
"API key is required. Get one at https://settlr.dev/dashboard"
|
|
1606
|
+
);
|
|
1607
|
+
}
|
|
1608
|
+
this.apiKey = config.apiKey;
|
|
1609
|
+
this.baseUrl = (config.baseUrl || "https://settlr.dev").replace(/\/$/, "");
|
|
1610
|
+
this.merchantId = config.merchantId;
|
|
1611
|
+
this.merchantWallet = config.merchantWallet;
|
|
1612
|
+
}
|
|
1613
|
+
async fetch(path, options = {}) {
|
|
1614
|
+
const url = `${this.baseUrl}${path}`;
|
|
1615
|
+
const res = await fetch(url, {
|
|
1616
|
+
...options,
|
|
1617
|
+
headers: {
|
|
1618
|
+
"Content-Type": "application/json",
|
|
1619
|
+
"X-API-Key": this.apiKey,
|
|
1620
|
+
...options.headers
|
|
1621
|
+
}
|
|
1622
|
+
});
|
|
1623
|
+
const data = await res.json();
|
|
1624
|
+
if (!res.ok) {
|
|
1625
|
+
throw new Error(
|
|
1626
|
+
data.error || `API error: ${res.status}`
|
|
1627
|
+
);
|
|
1628
|
+
}
|
|
1629
|
+
return data;
|
|
1630
|
+
}
|
|
1631
|
+
/**
|
|
1632
|
+
* Resolve merchant ID from API key
|
|
1633
|
+
*/
|
|
1634
|
+
async ensureMerchantId() {
|
|
1635
|
+
if (this.merchantId) return this.merchantId;
|
|
1636
|
+
const data = await this.fetch("/api/sdk/validate", {
|
|
1637
|
+
method: "POST",
|
|
1638
|
+
body: JSON.stringify({})
|
|
1639
|
+
});
|
|
1640
|
+
this.merchantId = data.merchantId;
|
|
1641
|
+
if (data.merchantWallet && !this.merchantWallet) {
|
|
1642
|
+
this.merchantWallet = data.merchantWallet;
|
|
1643
|
+
}
|
|
1644
|
+
return this.merchantId;
|
|
1645
|
+
}
|
|
1646
|
+
// ═══════════════════════════════════════
|
|
1647
|
+
// PLANS
|
|
1648
|
+
// ═══════════════════════════════════════
|
|
1649
|
+
/**
|
|
1650
|
+
* Create a subscription plan
|
|
1651
|
+
*/
|
|
1652
|
+
async createPlan(options) {
|
|
1653
|
+
const merchantId = await this.ensureMerchantId();
|
|
1654
|
+
const data = await this.fetch(
|
|
1655
|
+
"/api/subscriptions/plans",
|
|
1656
|
+
{
|
|
1657
|
+
method: "POST",
|
|
1658
|
+
body: JSON.stringify({
|
|
1659
|
+
merchantId,
|
|
1660
|
+
name: options.name,
|
|
1661
|
+
description: options.description,
|
|
1662
|
+
amount: options.amount,
|
|
1663
|
+
interval: options.interval,
|
|
1664
|
+
intervalCount: options.intervalCount || 1,
|
|
1665
|
+
trialDays: options.trialDays || 0,
|
|
1666
|
+
features: options.features || []
|
|
1667
|
+
})
|
|
1668
|
+
}
|
|
1669
|
+
);
|
|
1670
|
+
return data.plan;
|
|
1671
|
+
}
|
|
1672
|
+
/**
|
|
1673
|
+
* List all plans for the merchant
|
|
1674
|
+
*/
|
|
1675
|
+
async listPlans() {
|
|
1676
|
+
const merchantId = await this.ensureMerchantId();
|
|
1677
|
+
const data = await this.fetch(
|
|
1678
|
+
`/api/subscriptions/plans?merchantId=${merchantId}`
|
|
1679
|
+
);
|
|
1680
|
+
return data.plans;
|
|
1681
|
+
}
|
|
1682
|
+
/**
|
|
1683
|
+
* Update a plan
|
|
1684
|
+
*/
|
|
1685
|
+
async updatePlan(planId, options) {
|
|
1686
|
+
const data = await this.fetch(
|
|
1687
|
+
`/api/subscriptions/plans/${planId}`,
|
|
1688
|
+
{
|
|
1689
|
+
method: "PUT",
|
|
1690
|
+
body: JSON.stringify(options)
|
|
1691
|
+
}
|
|
1692
|
+
);
|
|
1693
|
+
return data.plan;
|
|
1694
|
+
}
|
|
1695
|
+
/**
|
|
1696
|
+
* Deactivate a plan (stops new subscriptions)
|
|
1697
|
+
*/
|
|
1698
|
+
async deactivatePlan(planId) {
|
|
1699
|
+
await this.updatePlan(planId, { active: false });
|
|
1700
|
+
}
|
|
1701
|
+
// ═══════════════════════════════════════
|
|
1702
|
+
// SUBSCRIPTIONS
|
|
1703
|
+
// ═══════════════════════════════════════
|
|
1704
|
+
/**
|
|
1705
|
+
* Subscribe a customer to a plan
|
|
1706
|
+
*/
|
|
1707
|
+
async subscribe(options) {
|
|
1708
|
+
const data = await this.fetch("/api/subscriptions", {
|
|
1709
|
+
method: "POST",
|
|
1710
|
+
body: JSON.stringify({
|
|
1711
|
+
action: "subscribe",
|
|
1712
|
+
planId: options.planId,
|
|
1713
|
+
customerWallet: options.customerWallet,
|
|
1714
|
+
merchantWallet: options.merchantWallet || this.merchantWallet,
|
|
1715
|
+
customerEmail: options.customerEmail,
|
|
1716
|
+
metadata: options.metadata
|
|
1717
|
+
})
|
|
1718
|
+
});
|
|
1719
|
+
return data;
|
|
1720
|
+
}
|
|
1721
|
+
/**
|
|
1722
|
+
* List subscriptions
|
|
1723
|
+
*/
|
|
1724
|
+
async listSubscriptions(options) {
|
|
1725
|
+
const merchantId = await this.ensureMerchantId();
|
|
1726
|
+
const params = new URLSearchParams({ merchantId });
|
|
1727
|
+
if (options?.status) params.set("status", options.status);
|
|
1728
|
+
if (options?.customerWallet)
|
|
1729
|
+
params.set("customer", options.customerWallet);
|
|
1730
|
+
if (options?.planId) params.set("planId", options.planId);
|
|
1731
|
+
const data = await this.fetch(
|
|
1732
|
+
`/api/subscriptions?${params.toString()}`
|
|
1733
|
+
);
|
|
1734
|
+
return data.subscriptions;
|
|
1735
|
+
}
|
|
1736
|
+
/**
|
|
1737
|
+
* Get subscription details including payment history
|
|
1738
|
+
*/
|
|
1739
|
+
async getSubscription(subscriptionId) {
|
|
1740
|
+
const data = await this.fetch(`/api/subscriptions/${subscriptionId}`);
|
|
1741
|
+
return {
|
|
1742
|
+
...data.subscription,
|
|
1743
|
+
payments: data.payments
|
|
1744
|
+
};
|
|
1745
|
+
}
|
|
1746
|
+
/**
|
|
1747
|
+
* Cancel a subscription
|
|
1748
|
+
* @param immediately - If true, cancels now. If false (default), cancels at end of billing period.
|
|
1749
|
+
*/
|
|
1750
|
+
async cancel(subscriptionId, immediately = false) {
|
|
1751
|
+
return this.fetch("/api/subscriptions", {
|
|
1752
|
+
method: "POST",
|
|
1753
|
+
body: JSON.stringify({
|
|
1754
|
+
action: "cancel",
|
|
1755
|
+
subscriptionId,
|
|
1756
|
+
immediately
|
|
1757
|
+
})
|
|
1758
|
+
});
|
|
1759
|
+
}
|
|
1760
|
+
/**
|
|
1761
|
+
* Pause a subscription (stops billing, preserves subscription)
|
|
1762
|
+
*/
|
|
1763
|
+
async pause(subscriptionId) {
|
|
1764
|
+
return this.fetch("/api/subscriptions", {
|
|
1765
|
+
method: "POST",
|
|
1766
|
+
body: JSON.stringify({
|
|
1767
|
+
action: "pause",
|
|
1768
|
+
subscriptionId
|
|
1769
|
+
})
|
|
1770
|
+
});
|
|
1771
|
+
}
|
|
1772
|
+
/**
|
|
1773
|
+
* Resume a paused subscription
|
|
1774
|
+
*/
|
|
1775
|
+
async resume(subscriptionId) {
|
|
1776
|
+
return this.fetch("/api/subscriptions", {
|
|
1777
|
+
method: "POST",
|
|
1778
|
+
body: JSON.stringify({
|
|
1779
|
+
action: "resume",
|
|
1780
|
+
subscriptionId
|
|
1781
|
+
})
|
|
1782
|
+
});
|
|
1783
|
+
}
|
|
1784
|
+
/**
|
|
1785
|
+
* Manually charge a subscription (useful for metered billing)
|
|
1786
|
+
*/
|
|
1787
|
+
async charge(subscriptionId) {
|
|
1788
|
+
return this.fetch("/api/subscriptions", {
|
|
1789
|
+
method: "POST",
|
|
1790
|
+
body: JSON.stringify({
|
|
1791
|
+
action: "charge",
|
|
1792
|
+
subscriptionId
|
|
1793
|
+
})
|
|
1794
|
+
});
|
|
1795
|
+
}
|
|
1796
|
+
};
|
|
1797
|
+
function createSubscriptionClient(config) {
|
|
1798
|
+
return new SubscriptionClient(config);
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
// src/payouts.ts
|
|
1802
|
+
var PayoutClient = class {
|
|
1803
|
+
constructor(config) {
|
|
1804
|
+
if (!config.apiKey) {
|
|
1805
|
+
throw new Error(
|
|
1806
|
+
"API key is required. Get one at https://settlr.dev/dashboard"
|
|
1807
|
+
);
|
|
1808
|
+
}
|
|
1809
|
+
this.apiKey = config.apiKey;
|
|
1810
|
+
this.baseUrl = (config.baseUrl || "https://settlr.dev").replace(/\/$/, "");
|
|
1811
|
+
}
|
|
1812
|
+
async fetch(path, options = {}) {
|
|
1813
|
+
const url = `${this.baseUrl}${path}`;
|
|
1814
|
+
const res = await fetch(url, {
|
|
1815
|
+
...options,
|
|
1816
|
+
headers: {
|
|
1817
|
+
"Content-Type": "application/json",
|
|
1818
|
+
"X-API-Key": this.apiKey,
|
|
1819
|
+
...options.headers
|
|
1820
|
+
}
|
|
1821
|
+
});
|
|
1822
|
+
const data = await res.json();
|
|
1823
|
+
if (!res.ok) {
|
|
1824
|
+
throw new Error(
|
|
1825
|
+
data.error || `Payout API error: ${res.status}`
|
|
1826
|
+
);
|
|
1827
|
+
}
|
|
1828
|
+
return data;
|
|
1829
|
+
}
|
|
1830
|
+
// -----------------------------------------------------------------------
|
|
1831
|
+
// Create a single payout
|
|
1832
|
+
// -----------------------------------------------------------------------
|
|
1833
|
+
/**
|
|
1834
|
+
* Send a payout to a recipient by email.
|
|
1835
|
+
* They'll receive an email with a claim link — no wallet or bank details needed.
|
|
1836
|
+
*
|
|
1837
|
+
* @example
|
|
1838
|
+
* ```typescript
|
|
1839
|
+
* const payout = await payouts.create({
|
|
1840
|
+
* email: 'alice@example.com',
|
|
1841
|
+
* amount: 250.00,
|
|
1842
|
+
* memo: 'March data labeling — 500 tasks',
|
|
1843
|
+
* });
|
|
1844
|
+
* console.log(payout.id); // "po_abc123"
|
|
1845
|
+
* console.log(payout.status); // "sent"
|
|
1846
|
+
* console.log(payout.claimUrl); // "https://settlr.dev/claim/..."
|
|
1847
|
+
* ```
|
|
1848
|
+
*/
|
|
1849
|
+
async create(options) {
|
|
1850
|
+
if (!options.email || !options.email.includes("@")) {
|
|
1851
|
+
throw new Error("Valid email address is required");
|
|
1852
|
+
}
|
|
1853
|
+
if (!options.amount || options.amount <= 0) {
|
|
1854
|
+
throw new Error("Amount must be a positive number");
|
|
1855
|
+
}
|
|
1856
|
+
return this.fetch("/api/payouts", {
|
|
1857
|
+
method: "POST",
|
|
1858
|
+
body: JSON.stringify({
|
|
1859
|
+
email: options.email,
|
|
1860
|
+
amount: options.amount,
|
|
1861
|
+
currency: options.currency || "USDC",
|
|
1862
|
+
memo: options.memo,
|
|
1863
|
+
metadata: options.metadata
|
|
1864
|
+
})
|
|
1865
|
+
});
|
|
1866
|
+
}
|
|
1867
|
+
// -----------------------------------------------------------------------
|
|
1868
|
+
// Create batch payouts
|
|
1869
|
+
// -----------------------------------------------------------------------
|
|
1870
|
+
/**
|
|
1871
|
+
* Send multiple payouts at once. Each recipient gets their own email.
|
|
1872
|
+
*
|
|
1873
|
+
* @example
|
|
1874
|
+
* ```typescript
|
|
1875
|
+
* const batch = await payouts.createBatch([
|
|
1876
|
+
* { email: 'alice@example.com', amount: 250.00, memo: 'March' },
|
|
1877
|
+
* { email: 'bob@example.com', amount: 180.00, memo: 'March' },
|
|
1878
|
+
* ]);
|
|
1879
|
+
* console.log(batch.id); // "batch_xyz"
|
|
1880
|
+
* console.log(batch.total); // 430.00
|
|
1881
|
+
* ```
|
|
1882
|
+
*/
|
|
1883
|
+
async createBatch(payoutsList) {
|
|
1884
|
+
if (!Array.isArray(payoutsList) || payoutsList.length === 0) {
|
|
1885
|
+
throw new Error("Payouts list must be a non-empty array");
|
|
1886
|
+
}
|
|
1887
|
+
return this.fetch("/api/payouts/batch", {
|
|
1888
|
+
method: "POST",
|
|
1889
|
+
body: JSON.stringify({ payouts: payoutsList })
|
|
1890
|
+
});
|
|
1891
|
+
}
|
|
1892
|
+
// -----------------------------------------------------------------------
|
|
1893
|
+
// Get a single payout
|
|
1894
|
+
// -----------------------------------------------------------------------
|
|
1895
|
+
/**
|
|
1896
|
+
* Get a payout by ID.
|
|
1897
|
+
*
|
|
1898
|
+
* @example
|
|
1899
|
+
* ```typescript
|
|
1900
|
+
* const payout = await payouts.get('po_abc123');
|
|
1901
|
+
* console.log(payout.status); // "claimed"
|
|
1902
|
+
* console.log(payout.claimedAt); // "2024-03-15T14:30:00Z"
|
|
1903
|
+
* ```
|
|
1904
|
+
*/
|
|
1905
|
+
async get(id) {
|
|
1906
|
+
if (!id) throw new Error("Payout ID is required");
|
|
1907
|
+
return this.fetch(`/api/payouts/${encodeURIComponent(id)}`);
|
|
1908
|
+
}
|
|
1909
|
+
// -----------------------------------------------------------------------
|
|
1910
|
+
// List payouts
|
|
1911
|
+
// -----------------------------------------------------------------------
|
|
1912
|
+
/**
|
|
1913
|
+
* List payouts for the authenticated merchant.
|
|
1914
|
+
*
|
|
1915
|
+
* @example
|
|
1916
|
+
* ```typescript
|
|
1917
|
+
* const result = await payouts.list({ status: 'claimed', limit: 50 });
|
|
1918
|
+
* result.data.forEach(p => console.log(p.email, p.amount, p.status));
|
|
1919
|
+
* ```
|
|
1920
|
+
*/
|
|
1921
|
+
async list(options) {
|
|
1922
|
+
const params = new URLSearchParams();
|
|
1923
|
+
if (options?.status) params.set("status", options.status);
|
|
1924
|
+
if (options?.limit) params.set("limit", options.limit.toString());
|
|
1925
|
+
if (options?.offset) params.set("offset", options.offset.toString());
|
|
1926
|
+
const qs = params.toString();
|
|
1927
|
+
return this.fetch(`/api/payouts${qs ? `?${qs}` : ""}`);
|
|
1928
|
+
}
|
|
1929
|
+
};
|
|
1930
|
+
function createPayoutClient(config) {
|
|
1931
|
+
return new PayoutClient(config);
|
|
1932
|
+
}
|
|
1599
1933
|
export {
|
|
1600
1934
|
BuyButton,
|
|
1601
1935
|
CheckoutWidget,
|
|
1602
1936
|
INCO_LIGHTNING_PROGRAM_ID,
|
|
1603
1937
|
OneClickClient,
|
|
1604
1938
|
PaymentModal,
|
|
1939
|
+
PayoutClient,
|
|
1605
1940
|
PrivacyFeatures,
|
|
1606
1941
|
REACT_NATIVE_EXAMPLE,
|
|
1607
1942
|
REST_API,
|
|
@@ -1611,6 +1946,7 @@ export {
|
|
|
1611
1946
|
SUPPORTED_TOKENS,
|
|
1612
1947
|
Settlr,
|
|
1613
1948
|
SettlrProvider,
|
|
1949
|
+
SubscriptionClient,
|
|
1614
1950
|
UNITY_EXAMPLE,
|
|
1615
1951
|
USDC_MINT_DEVNET,
|
|
1616
1952
|
USDC_MINT_MAINNET,
|
|
@@ -1619,6 +1955,8 @@ export {
|
|
|
1619
1955
|
buildAllowanceRemainingAccounts,
|
|
1620
1956
|
buildPrivateReceiptAccounts,
|
|
1621
1957
|
createOneClickClient,
|
|
1958
|
+
createPayoutClient,
|
|
1959
|
+
createSubscriptionClient,
|
|
1622
1960
|
createWebhookHandler,
|
|
1623
1961
|
encryptAmount,
|
|
1624
1962
|
findAllowancePda,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@settlr/sdk",
|
|
3
|
-
"version": "0.6.
|
|
4
|
-
"description": "Settlr SDK
|
|
3
|
+
"version": "0.6.8",
|
|
4
|
+
"description": "Settlr SDK — Global payout infrastructure. Pay anyone, anywhere, with just their email. One API call sends USDC, recipient claims with any Solana wallet. Batch payouts, webhooks, hosted claim page.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -26,38 +26,30 @@
|
|
|
26
26
|
},
|
|
27
27
|
"keywords": [
|
|
28
28
|
"settlr",
|
|
29
|
-
"
|
|
30
|
-
"
|
|
29
|
+
"payout-api",
|
|
30
|
+
"payout-infrastructure",
|
|
31
|
+
"global-payouts",
|
|
32
|
+
"pay-by-email",
|
|
33
|
+
"usdc-payouts",
|
|
34
|
+
"batch-payouts",
|
|
31
35
|
"solana",
|
|
32
36
|
"solana-payments",
|
|
33
37
|
"usdc",
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"checkout",
|
|
43
|
-
"gaming-payments",
|
|
44
|
-
"game-monetization",
|
|
45
|
-
"in-app-purchases",
|
|
46
|
-
"react",
|
|
38
|
+
"stablecoin-payouts",
|
|
39
|
+
"cross-border-payments",
|
|
40
|
+
"international-payouts",
|
|
41
|
+
"contractor-payments",
|
|
42
|
+
"creator-payouts",
|
|
43
|
+
"data-labeling-payouts",
|
|
44
|
+
"freelancer-payments",
|
|
45
|
+
"crypto-payouts",
|
|
47
46
|
"typescript",
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"private-receipts",
|
|
55
|
-
"privacy-cash",
|
|
56
|
-
"zk-payments",
|
|
57
|
-
"range-security",
|
|
58
|
-
"compliance",
|
|
59
|
-
"sanctions-screening",
|
|
60
|
-
"one-click-payments"
|
|
47
|
+
"react",
|
|
48
|
+
"checkout-sdk",
|
|
49
|
+
"payment-gateway",
|
|
50
|
+
"webhooks",
|
|
51
|
+
"gasless",
|
|
52
|
+
"web3"
|
|
61
53
|
],
|
|
62
54
|
"author": "Settlr <hello@settlr.dev> (https://settlr.dev)",
|
|
63
55
|
"license": "MIT",
|