@stackbe/sdk 0.13.0 → 0.15.0

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/dist/index.mjs CHANGED
@@ -1127,6 +1127,201 @@ var SubscriptionsClient = class {
1127
1127
  `/v1/subscriptions/${subscriptionId}/has-access`
1128
1128
  );
1129
1129
  }
1130
+ // ============================================
1131
+ // StackBE-Managed Billing Methods
1132
+ // ============================================
1133
+ /**
1134
+ * Manually charge a StackBE-managed subscription.
1135
+ *
1136
+ * This is useful for:
1137
+ * - Testing billing in development
1138
+ * - Recovering from failed automatic charges
1139
+ * - Charging ahead of schedule
1140
+ *
1141
+ * The subscription must be in `stackbe_managed` billing mode.
1142
+ *
1143
+ * @example
1144
+ * ```typescript
1145
+ * const result = await stackbe.subscriptions.charge('sub_123');
1146
+ *
1147
+ * if (result.success) {
1148
+ * console.log('Charge successful:', result.chargeId);
1149
+ * } else if (result.requiresAction) {
1150
+ * // Redirect customer to 3DS authentication
1151
+ * window.location.href = result.actionUrl;
1152
+ * } else {
1153
+ * console.log('Charge failed:', result.errorMessage);
1154
+ * }
1155
+ * ```
1156
+ */
1157
+ async charge(subscriptionId) {
1158
+ return this.http.post(
1159
+ `/v1/subscriptions/${subscriptionId}/charge`
1160
+ );
1161
+ }
1162
+ /**
1163
+ * Migrate a subscription from gateway-managed to StackBE-managed billing.
1164
+ *
1165
+ * This will:
1166
+ * 1. Extract the payment method from the gateway subscription
1167
+ * 2. Store it in StackBE's PaymentMethod table
1168
+ * 3. Set the subscription to `stackbe_managed` billing mode
1169
+ * 4. Cancel the gateway subscription at period end
1170
+ * 5. StackBE will handle renewals going forward
1171
+ *
1172
+ * Use cases:
1173
+ * - Migrate existing Stripe subscriptions to unified StackBE billing
1174
+ * - Prepare for multi-gateway support
1175
+ * - Gain more control over billing timing and retry logic
1176
+ *
1177
+ * @example
1178
+ * ```typescript
1179
+ * const result = await stackbe.subscriptions.migrateToStackbeManaged('sub_123');
1180
+ *
1181
+ * console.log('Migration complete');
1182
+ * console.log('Payment method:', result.paymentMethodId);
1183
+ * console.log('Next billing date:', result.nextBillingDate);
1184
+ * ```
1185
+ */
1186
+ async migrateToStackbeManaged(subscriptionId) {
1187
+ return this.http.post(
1188
+ `/v1/subscriptions/${subscriptionId}/migrate-to-stackbe-managed`
1189
+ );
1190
+ }
1191
+ };
1192
+
1193
+ // src/payment-methods.ts
1194
+ var PaymentMethodsClient = class {
1195
+ constructor(http) {
1196
+ this.http = http;
1197
+ }
1198
+ /**
1199
+ * Create a setup session for collecting a payment method.
1200
+ *
1201
+ * Returns a URL to redirect the customer to for secure payment method collection.
1202
+ * This is similar to Stripe Checkout but in setup mode - no charge is made.
1203
+ *
1204
+ * @example
1205
+ * ```typescript
1206
+ * const session = await stackbe.paymentMethods.createSetupSession('cust_123', {
1207
+ * successUrl: 'https://yourapp.com/payment-methods/success',
1208
+ * cancelUrl: 'https://yourapp.com/payment-methods/cancel',
1209
+ * });
1210
+ *
1211
+ * // Redirect customer to payment method collection
1212
+ * window.location.href = session.url;
1213
+ * ```
1214
+ */
1215
+ async createSetupSession(customerId, options) {
1216
+ return this.http.post(
1217
+ `/v1/apps/{appId}/customers/${customerId}/payment-methods/setup`,
1218
+ options
1219
+ );
1220
+ }
1221
+ /**
1222
+ * Attach a payment method to a customer.
1223
+ *
1224
+ * After the customer completes the setup session, call this to store
1225
+ * the payment method in StackBE for future charges.
1226
+ *
1227
+ * @example
1228
+ * ```typescript
1229
+ * // After redirect from setup session
1230
+ * const paymentMethod = await stackbe.paymentMethods.attach('cust_123', {
1231
+ * gatewayPaymentMethodId: 'pm_1234...', // From setup session completion
1232
+ * setAsDefault: true,
1233
+ * });
1234
+ *
1235
+ * console.log(`Added ${paymentMethod.brand} ending in ${paymentMethod.last4}`);
1236
+ * ```
1237
+ */
1238
+ async attach(customerId, options) {
1239
+ return this.http.post(
1240
+ `/v1/apps/{appId}/customers/${customerId}/payment-methods`,
1241
+ options
1242
+ );
1243
+ }
1244
+ /**
1245
+ * List all payment methods for a customer.
1246
+ *
1247
+ * @example
1248
+ * ```typescript
1249
+ * const paymentMethods = await stackbe.paymentMethods.list('cust_123');
1250
+ *
1251
+ * for (const pm of paymentMethods) {
1252
+ * console.log(`${pm.brand} **** ${pm.last4} ${pm.isDefault ? '(default)' : ''}`);
1253
+ * }
1254
+ * ```
1255
+ */
1256
+ async list(customerId, options) {
1257
+ const params = {};
1258
+ if (options?.status) params.status = options.status;
1259
+ return this.http.get(
1260
+ `/v1/apps/{appId}/customers/${customerId}/payment-methods`,
1261
+ params
1262
+ );
1263
+ }
1264
+ /**
1265
+ * Get a specific payment method.
1266
+ *
1267
+ * @example
1268
+ * ```typescript
1269
+ * const pm = await stackbe.paymentMethods.get('cust_123', 'pm_123');
1270
+ * console.log(`Expires: ${pm.expiryMonth}/${pm.expiryYear}`);
1271
+ * ```
1272
+ */
1273
+ async get(customerId, paymentMethodId) {
1274
+ return this.http.get(
1275
+ `/v1/apps/{appId}/customers/${customerId}/payment-methods/${paymentMethodId}`
1276
+ );
1277
+ }
1278
+ /**
1279
+ * Set a payment method as the default for a customer.
1280
+ *
1281
+ * The default payment method is used for subscription renewals.
1282
+ *
1283
+ * @example
1284
+ * ```typescript
1285
+ * await stackbe.paymentMethods.setDefault('cust_123', 'pm_456');
1286
+ * console.log('Default payment method updated');
1287
+ * ```
1288
+ */
1289
+ async setDefault(customerId, paymentMethodId) {
1290
+ return this.http.post(
1291
+ `/v1/apps/{appId}/customers/${customerId}/payment-methods/${paymentMethodId}/default`
1292
+ );
1293
+ }
1294
+ /**
1295
+ * Remove a payment method.
1296
+ *
1297
+ * Cannot remove a payment method that is being used by an active subscription.
1298
+ *
1299
+ * @example
1300
+ * ```typescript
1301
+ * await stackbe.paymentMethods.remove('cust_123', 'pm_old');
1302
+ * console.log('Payment method removed');
1303
+ * ```
1304
+ */
1305
+ async remove(customerId, paymentMethodId) {
1306
+ return this.http.delete(
1307
+ `/v1/apps/{appId}/customers/${customerId}/payment-methods/${paymentMethodId}`
1308
+ );
1309
+ }
1310
+ /**
1311
+ * Get the default payment method for a customer.
1312
+ *
1313
+ * @example
1314
+ * ```typescript
1315
+ * const defaultPM = await stackbe.paymentMethods.getDefault('cust_123');
1316
+ * if (defaultPM) {
1317
+ * console.log(`Default: ${defaultPM.brand} **** ${defaultPM.last4}`);
1318
+ * }
1319
+ * ```
1320
+ */
1321
+ async getDefault(customerId) {
1322
+ const paymentMethods = await this.list(customerId, { status: "active" });
1323
+ return paymentMethods.find((pm) => pm.isDefault) || null;
1324
+ }
1130
1325
  };
1131
1326
 
1132
1327
  // src/auth.ts
@@ -2022,37 +2217,18 @@ var AffiliatesClient = class {
2022
2217
  /**
2023
2218
  * Get the current customer's affiliate info.
2024
2219
  * Requires customer session token.
2025
- *
2026
- * @example
2027
- * ```typescript
2028
- * const affiliate = await stackbe.affiliates.get();
2029
- *
2030
- * if (affiliate.enrolled) {
2031
- * console.log(`Your referral code: ${affiliate.code}`);
2032
- * console.log(`Earnings: $${(affiliate.totalEarned! / 100).toFixed(2)}`);
2033
- * } else {
2034
- * console.log('Not enrolled in affiliate program');
2035
- * }
2036
- * ```
2037
2220
  */
2038
2221
  async get() {
2039
2222
  return this.http.get("/v1/affiliate");
2040
2223
  }
2041
2224
  /**
2042
- * Enroll the current customer as an affiliate.
2225
+ * Enroll the current customer as an affiliate/partner.
2043
2226
  * Requires customer session token.
2044
2227
  *
2045
2228
  * @example
2046
2229
  * ```typescript
2047
- * // Enroll with auto-generated code
2048
- * const affiliate = await stackbe.affiliates.enroll();
2230
+ * const affiliate = await stackbe.affiliates.enroll({ type: 'referral' });
2049
2231
  * console.log(`Your referral code: ${affiliate.code}`);
2050
- *
2051
- * // Enroll with custom code
2052
- * const affiliate = await stackbe.affiliates.enroll({
2053
- * code: 'MYCODE',
2054
- * payoutEmail: 'payouts@example.com',
2055
- * });
2056
2232
  * ```
2057
2233
  */
2058
2234
  async enroll(options = {}) {
@@ -2061,18 +2237,6 @@ var AffiliatesClient = class {
2061
2237
  /**
2062
2238
  * Get affiliate statistics.
2063
2239
  * Requires customer session token.
2064
- *
2065
- * @example
2066
- * ```typescript
2067
- * const stats = await stackbe.affiliates.getStats();
2068
- *
2069
- * if (stats.enrolled) {
2070
- * console.log(`Total earned: $${(stats.totalEarned / 100).toFixed(2)}`);
2071
- * console.log(`Pending: $${(stats.pendingBalance / 100).toFixed(2)}`);
2072
- * console.log(`Referrals: ${stats.totalReferrals}`);
2073
- * console.log(`Conversions: ${stats.totalConversions}`);
2074
- * }
2075
- * ```
2076
2240
  */
2077
2241
  async getStats() {
2078
2242
  return this.http.get("/v1/affiliate/stats");
@@ -2080,34 +2244,13 @@ var AffiliatesClient = class {
2080
2244
  /**
2081
2245
  * Get affiliate commission history.
2082
2246
  * Requires customer session token.
2083
- *
2084
- * @example
2085
- * ```typescript
2086
- * const { commissions, total } = await stackbe.affiliates.getCommissions();
2087
- *
2088
- * commissions.forEach((c) => {
2089
- * console.log(`$${(c.amount / 100).toFixed(2)} - ${c.status}`);
2090
- * });
2091
- * ```
2092
2247
  */
2093
2248
  async getCommissions() {
2094
2249
  return this.http.get("/v1/affiliate/commissions");
2095
2250
  }
2096
2251
  /**
2097
2252
  * Track a referral click (store token for attribution).
2098
- * Call this when a user lands on your site with a referral code.
2099
2253
  * Requires API key.
2100
- *
2101
- * @example
2102
- * ```typescript
2103
- * // In your landing page handler
2104
- * const refCode = req.query.ref;
2105
- * if (refCode) {
2106
- * const { token, expiresInDays } = await stackbe.affiliates.trackReferral(refCode);
2107
- * // Store token in cookie for attribution on signup
2108
- * res.cookie('ref_token', token, { maxAge: expiresInDays * 24 * 60 * 60 * 1000 });
2109
- * }
2110
- * ```
2111
2254
  */
2112
2255
  async trackReferral(code, referralUrl) {
2113
2256
  return this.http.post("/v1/affiliate/track", {
@@ -2115,6 +2258,44 @@ var AffiliatesClient = class {
2115
2258
  referralUrl
2116
2259
  });
2117
2260
  }
2261
+ /**
2262
+ * Get the full partner dashboard with stats, earnings by source, deals, and coupons.
2263
+ * Requires customer session token.
2264
+ *
2265
+ * @example
2266
+ * ```typescript
2267
+ * const dashboard = await stackbe.affiliates.getDashboard();
2268
+ * console.log(`Link earnings: $${dashboard.earningsBySource.link}`);
2269
+ * console.log(`Coupon earnings: $${dashboard.earningsBySource.coupon}`);
2270
+ * console.log(`Deal earnings: $${dashboard.earningsBySource.deal}`);
2271
+ * ```
2272
+ */
2273
+ async getDashboard() {
2274
+ return this.http.get("/v1/affiliate/dashboard");
2275
+ }
2276
+ /**
2277
+ * Register a deal (lead attribution).
2278
+ * Requires customer session token and active partner enrollment.
2279
+ *
2280
+ * @example
2281
+ * ```typescript
2282
+ * const deal = await stackbe.affiliates.registerDeal({
2283
+ * leadEmail: 'prospect@company.com',
2284
+ * leadName: 'John Smith',
2285
+ * notes: 'Met at conference, interested in Pro plan',
2286
+ * });
2287
+ * ```
2288
+ */
2289
+ async registerDeal(options) {
2290
+ return this.http.post("/v1/affiliate/deals", options);
2291
+ }
2292
+ /**
2293
+ * List the current partner's deal registrations.
2294
+ * Requires customer session token.
2295
+ */
2296
+ async listDeals() {
2297
+ return this.http.get("/v1/affiliate/deals");
2298
+ }
2118
2299
  };
2119
2300
 
2120
2301
  // src/early-access.ts
@@ -2525,6 +2706,7 @@ var StackBE = class {
2525
2706
  this.customers = new CustomersClient(this.http, config.appId);
2526
2707
  this.checkout = new CheckoutClient(this.http, config.appId);
2527
2708
  this.subscriptions = new SubscriptionsClient(this.http);
2709
+ this.paymentMethods = new PaymentMethodsClient(this.http);
2528
2710
  this.auth = new AuthClient(this.http, config.appId, {
2529
2711
  sessionCacheTTL: config.sessionCacheTTL,
2530
2712
  devCallbackUrl: config.devCallbackUrl
@@ -2679,6 +2861,7 @@ export {
2679
2861
  EntitlementsClient,
2680
2862
  FeatureRequestsClient,
2681
2863
  OrganizationsClient,
2864
+ PaymentMethodsClient,
2682
2865
  PlansClient,
2683
2866
  ProductsClient,
2684
2867
  StackBE,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackbe/sdk",
3
- "version": "0.13.0",
3
+ "version": "0.15.0",
4
4
  "description": "Official JavaScript/TypeScript SDK for StackBE - the billing backend for your side project",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",