using legacy stripe versions
This commit is contained in:
4
bun.lock
4
bun.lock
@@ -85,7 +85,7 @@
|
||||
"react": "^18.2.0",
|
||||
"recaseai": "^0.0.37",
|
||||
"resend": "^4.1.1",
|
||||
"stripe": "18.4.0",
|
||||
"stripe": "^18.4.0",
|
||||
"svix": "^1.45.1",
|
||||
"tsc-alias": "^1.8.16",
|
||||
"ws": "^8.18.0",
|
||||
@@ -3025,8 +3025,6 @@
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"@types/bun/bun-types": ["bun-types@1.2.20", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-pxTnQYOrKvdOwyiyd/7sMt9yFOenN004Y6O4lCcCUoKVej48FS5cvTw9geRaEcB9TsDZaJKAxPTVvi8tFsVuXA=="],
|
||||
|
||||
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
||||
|
||||
"accepts/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
|
||||
|
||||
@@ -16,6 +16,7 @@ fi
|
||||
# 'tests/attach/addOn/*.ts'
|
||||
|
||||
$MOCHA_CMD \
|
||||
'tests/attach/checkout/*.ts' \
|
||||
'tests/attach/entities/*.ts' \
|
||||
'tests/attach/free/*.ts'\
|
||||
'tests/attach/checkout/*.ts'
|
||||
# \
|
||||
# 'tests/attach/entities/*.ts' \
|
||||
# 'tests/attach/free/*.ts'\
|
||||
|
||||
2
server/src/external/autumn/autumnCli.ts
vendored
2
server/src/external/autumn/autumnCli.ts
vendored
@@ -340,7 +340,7 @@ export class AutumnInt {
|
||||
|
||||
rewards = {
|
||||
create: async (reward: any) => {
|
||||
const data = await this.post(`/rewards`, reward);
|
||||
const data = await this.post(`/rewards?legacyStripe=true`, reward);
|
||||
return data;
|
||||
},
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ export const deleteCouponFromCus = async ({
|
||||
|
||||
try {
|
||||
let stripeCus = (await stripeCli.customers.retrieve(
|
||||
stripeCusId,
|
||||
stripeCusId
|
||||
)) as Stripe.Customer;
|
||||
if (stripeCus.discount?.id === discountId) {
|
||||
await stripeCli.customers.deleteDiscount(stripeCusId, discountId);
|
||||
|
||||
@@ -9,8 +9,10 @@ import {
|
||||
Product,
|
||||
UsagePriceConfig,
|
||||
RewardType,
|
||||
AppEnv,
|
||||
} from "@autumn/shared";
|
||||
import { Stripe } from "stripe";
|
||||
import { createStripeCli } from "../utils.js";
|
||||
|
||||
const couponToStripeDuration = (coupon: Reward) => {
|
||||
let discountConfig = coupon.discount_config;
|
||||
@@ -62,19 +64,27 @@ const couponToStripeValue = ({
|
||||
|
||||
export const createStripeCoupon = async ({
|
||||
reward,
|
||||
stripeCli,
|
||||
org,
|
||||
env,
|
||||
prices,
|
||||
logger,
|
||||
legacyVersion,
|
||||
}: {
|
||||
reward: Reward;
|
||||
stripeCli: Stripe;
|
||||
org: Organization;
|
||||
env: AppEnv;
|
||||
prices: (Price & { product: Product })[];
|
||||
logger: any;
|
||||
legacyVersion?: boolean;
|
||||
}) => {
|
||||
let discountConfig = reward.discount_config;
|
||||
|
||||
const stripeCli = createStripeCli({
|
||||
org,
|
||||
env,
|
||||
legacyVersion,
|
||||
});
|
||||
|
||||
try {
|
||||
await stripeCli.coupons.del(reward.id);
|
||||
} catch (error) {}
|
||||
|
||||
10
server/src/external/stripe/utils.ts
vendored
10
server/src/external/stripe/utils.ts
vendored
@@ -16,9 +16,13 @@ import Stripe from "stripe";
|
||||
export const createStripeCli = ({
|
||||
org,
|
||||
env,
|
||||
// apiVersion,
|
||||
legacyVersion,
|
||||
}: {
|
||||
org: Organization;
|
||||
env: AppEnv;
|
||||
// apiVersion?: string;
|
||||
legacyVersion?: boolean;
|
||||
}) => {
|
||||
let encrypted =
|
||||
env == AppEnv.Sandbox
|
||||
@@ -34,7 +38,11 @@ export const createStripeCli = ({
|
||||
}
|
||||
|
||||
let decrypted = decryptData(encrypted);
|
||||
return new Stripe(decrypted);
|
||||
return new Stripe(decrypted, {
|
||||
apiVersion: legacyVersion
|
||||
? ("2025-02-24.acacia" as any)
|
||||
: "2025-07-30.basil",
|
||||
});
|
||||
};
|
||||
|
||||
export const calculateMetered1Price = ({
|
||||
|
||||
@@ -18,6 +18,7 @@ import { Decimal } from "decimal.js";
|
||||
import { generateId } from "@/utils/genUtils.js";
|
||||
import { addMonths } from "date-fns";
|
||||
import { getStripeNow } from "@/utils/scriptUtils/testClockUtils.js";
|
||||
import { invoiceToSubId } from "../stripeInvoiceUtils.js";
|
||||
|
||||
export const handleInvoicePaidDiscount = async ({
|
||||
db,
|
||||
@@ -39,7 +40,7 @@ export const handleInvoicePaidDiscount = async ({
|
||||
}
|
||||
|
||||
let stripeCus = await stripeCli.customers.retrieve(
|
||||
expandedInvoice.customer as string,
|
||||
expandedInvoice.customer as string
|
||||
);
|
||||
|
||||
try {
|
||||
@@ -86,7 +87,7 @@ export const handleInvoicePaidDiscount = async ({
|
||||
const curAmount = discount.coupon.amount_off;
|
||||
|
||||
const amountUsed = totalDiscountAmounts?.find(
|
||||
(item) => item.discount === discount.id,
|
||||
(item) => item.discount === discount.id
|
||||
)?.amount;
|
||||
|
||||
const newAmount = new Decimal(curAmount!).sub(amountUsed!).toNumber();
|
||||
@@ -103,16 +104,17 @@ export const handleInvoicePaidDiscount = async ({
|
||||
});
|
||||
|
||||
let expired = curExpiresAt && curExpiresAt < now;
|
||||
const subId = invoiceToSubId({ invoice: expandedInvoice });
|
||||
|
||||
if (discountFinished || expired) {
|
||||
logger.info(
|
||||
`Coupon ${couponId}, stripeCus: ${stripeCus.id}: credits used up or expired. discountFinished: ${discountFinished}, expired: ${expired}`,
|
||||
`Coupon ${couponId}, stripeCus: ${stripeCus.id}: credits used up or expired. discountFinished: ${discountFinished}, expired: ${expired}`
|
||||
);
|
||||
|
||||
if (expandedInvoice.subscription) {
|
||||
if (subId) {
|
||||
await deleteCouponFromCus({
|
||||
stripeCli,
|
||||
stripeSubId: expandedInvoice.subscription as string,
|
||||
stripeSubId: subId,
|
||||
stripeCusId: expandedInvoice.customer as string,
|
||||
discountId: discount.id,
|
||||
logger,
|
||||
@@ -123,7 +125,7 @@ export const handleInvoicePaidDiscount = async ({
|
||||
}
|
||||
|
||||
logger.info(
|
||||
`Coupon ${couponId}, stripeCus: ${stripeCus.id}, updating amount from ${curAmount} to ${newAmount}`,
|
||||
`Coupon ${couponId}, stripeCus: ${stripeCus.id}, updating amount from ${curAmount} to ${newAmount}`
|
||||
);
|
||||
|
||||
// Set expiry date
|
||||
@@ -147,18 +149,30 @@ export const handleInvoicePaidDiscount = async ({
|
||||
},
|
||||
});
|
||||
|
||||
await stripeCli.customers.update(expandedInvoice.customer as string, {
|
||||
coupon: newCoupon.id,
|
||||
const legacyStripeCli = createStripeCli({
|
||||
org,
|
||||
env,
|
||||
legacyVersion: true,
|
||||
});
|
||||
|
||||
await legacyStripeCli.rawRequest(
|
||||
"POST",
|
||||
`/v1/customers/${expandedInvoice.customer}/discounts`,
|
||||
{
|
||||
coupon: newCoupon.id,
|
||||
}
|
||||
);
|
||||
|
||||
await stripeCli.coupons.del(newCoupon.id);
|
||||
|
||||
await deleteCouponFromSub({
|
||||
stripeCli,
|
||||
stripeSubId: expandedInvoice.subscription as string,
|
||||
discountId: discount.id,
|
||||
logger,
|
||||
});
|
||||
if (subId) {
|
||||
await deleteCouponFromSub({
|
||||
stripeCli,
|
||||
stripeSubId: subId,
|
||||
discountId: discount.id,
|
||||
logger,
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error("invoice.paid: error updating coupon");
|
||||
|
||||
@@ -8,7 +8,6 @@ import { OrgService } from "@/internal/orgs/OrgService.js";
|
||||
import { createStripeCoupon } from "@/external/stripe/stripeCouponUtils/stripeCouponUtils.js";
|
||||
import { RewardService } from "@/internal/rewards/RewardService.js";
|
||||
import { PriceService } from "@/internal/products/prices/PriceService.js";
|
||||
import { createStripePriceIFNotExist } from "@/external/stripe/createStripePrice/createStripePrice.js";
|
||||
import { EntitlementService } from "@/internal/products/entitlements/EntitlementService.js";
|
||||
import {
|
||||
constructReward,
|
||||
@@ -54,30 +53,6 @@ rewardRouter.post("", async (req: any, res: any) => {
|
||||
}),
|
||||
]);
|
||||
|
||||
// Initialize prices
|
||||
|
||||
// if (!discountConfig!.apply_to_all) {
|
||||
// // Create stripe prices if not exists
|
||||
|
||||
// const batchSize = 5;
|
||||
|
||||
// // for (let i = 0; i < prices.length; i += batchSize) {
|
||||
// // const batch = prices.slice(i, i + batchSize);
|
||||
// // const batchPriceCreate = batch.map((price) =>
|
||||
// // createStripePriceIFNotExist({
|
||||
// // stripeCli,
|
||||
// // price,
|
||||
// // entitlements,
|
||||
// // org,
|
||||
// // logger,
|
||||
// // db,
|
||||
// // product: price.product,
|
||||
// // })
|
||||
// // );
|
||||
// // await Promise.all(batchPriceCreate);
|
||||
// // }
|
||||
// }
|
||||
|
||||
await initRewardStripePrices({
|
||||
db,
|
||||
prices,
|
||||
@@ -88,10 +63,11 @@ rewardRouter.post("", async (req: any, res: any) => {
|
||||
|
||||
await createStripeCoupon({
|
||||
reward: newReward,
|
||||
stripeCli,
|
||||
org,
|
||||
env,
|
||||
prices,
|
||||
logger,
|
||||
legacyVersion: req.query.legacyStripe === "true",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -206,10 +182,11 @@ rewardRouter.post("/:internalId", async (req: any, res: any) => {
|
||||
if (rewardCat == RewardCategory.Discount) {
|
||||
await createStripeCoupon({
|
||||
reward: rewardBody,
|
||||
stripeCli,
|
||||
org,
|
||||
env,
|
||||
prices,
|
||||
logger,
|
||||
legacyVersion: req.query.legacyStripe === "true",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,24 +1,14 @@
|
||||
import { freeTrialToStripeTimestamp } from "@/internal/products/free-trials/freeTrialUtils.js";
|
||||
import RecaseError from "@/utils/errorUtils.js";
|
||||
import {
|
||||
Customer,
|
||||
FreeTrial,
|
||||
Organization,
|
||||
ErrCode,
|
||||
BillingInterval,
|
||||
Reward,
|
||||
IntervalConfig,
|
||||
} from "@autumn/shared";
|
||||
import { ErrCode, Reward, IntervalConfig } from "@autumn/shared";
|
||||
import Stripe from "stripe";
|
||||
import { getCusPaymentMethod } from "@/external/stripe/stripeCusUtils.js";
|
||||
import { SubService } from "@/internal/subscriptions/SubService.js";
|
||||
import { formatUnixToDateTime, generateId } from "@/utils/genUtils.js";
|
||||
import { ItemSet } from "@/utils/models/ItemSet.js";
|
||||
import { generateId } from "@/utils/genUtils.js";
|
||||
import { DrizzleCli } from "@/db/initDrizzle.js";
|
||||
import { getAlignedIntervalUnix } from "@/internal/products/prices/billingIntervalUtils.js";
|
||||
import { getEarliestPeriodEnd } from "@/external/stripe/stripeSubUtils/convertSubUtils.js";
|
||||
import { AttachParams } from "@/internal/customers/cusProducts/AttachParams.js";
|
||||
import { getSmallestInterval } from "@/internal/products/prices/priceUtils/priceIntervalUtils.js";
|
||||
|
||||
// Get payment method
|
||||
|
||||
@@ -122,6 +112,15 @@ export const createStripeSub2 = async ({
|
||||
// coupon: reward ? reward.id : undefined,
|
||||
discounts: reward ? [{ coupon: reward.id }] : undefined,
|
||||
expand: ["latest_invoice"],
|
||||
|
||||
trial_settings:
|
||||
freeTrial && !freeTrial.card_required
|
||||
? {
|
||||
end_behavior: {
|
||||
missing_payment_method: "cancel",
|
||||
},
|
||||
}
|
||||
: undefined,
|
||||
});
|
||||
|
||||
// console.log("Latest invoice:", subscription.latest_invoice);
|
||||
|
||||
@@ -135,7 +135,7 @@ export const updateStripeSub = async ({
|
||||
let { replaceables } = await createAndFilterContUseItems({
|
||||
attachParams,
|
||||
curMainProduct: curMainProduct!,
|
||||
stripeSubs,
|
||||
sub: curSub,
|
||||
interval,
|
||||
intervalCount,
|
||||
logger,
|
||||
|
||||
@@ -12,7 +12,6 @@ import { createStripeCli } from "@/external/stripe/utils.js";
|
||||
import { handleDeleteCustomer } from "./handlers/cusDeleteHandlers.js";
|
||||
import { handleUpdateBalances } from "./handlers/handleUpdateBalances.js";
|
||||
import { handleUpdateEntitlement } from "./handlers/handleUpdateEntitlement.js";
|
||||
import { handleCusProductExpired } from "./handlers/handleCusProductExpired.js";
|
||||
import { handleAddCouponToCus } from "./handlers/handleAddCouponToCus.js";
|
||||
import { handlePostCustomerRequest } from "./handlers/handlePostCustomer.js";
|
||||
import { entityRouter } from "../api/entities/entityRouter.js";
|
||||
|
||||
@@ -44,7 +44,12 @@ export const handleAddCouponToCus = async (req: any, res: any) => {
|
||||
});
|
||||
}
|
||||
|
||||
const stripeCli = createStripeCli({ org, env });
|
||||
const stripeCli = createStripeCli({
|
||||
org,
|
||||
env,
|
||||
// apiVersion: "2025-02-24.acacia",
|
||||
legacyVersion: true,
|
||||
});
|
||||
|
||||
await createStripeCusIfNotExists({
|
||||
db,
|
||||
@@ -55,9 +60,22 @@ export const handleAddCouponToCus = async (req: any, res: any) => {
|
||||
});
|
||||
|
||||
// Attach coupon to customer
|
||||
await stripeCli.customers.update(customer.processor.id, {
|
||||
coupon: coupon.id,
|
||||
});
|
||||
// curl https://api.stripe.com/v1/customers/cus_123456/discounts \
|
||||
// -u sk_test_your_key: \
|
||||
// -d coupon=COUPON_ID
|
||||
|
||||
await stripeCli.rawRequest(
|
||||
"POST",
|
||||
`/v1/customers/${customer.processor.id}`,
|
||||
{
|
||||
coupon: coupon.id,
|
||||
}
|
||||
);
|
||||
// await stripeCli.customers.update(customer.processor.id, {
|
||||
// coupon: coupon.id,
|
||||
|
||||
// discounts: [{ coupon: coupon.id }],
|
||||
// });
|
||||
|
||||
res.status(200).json({ customer, coupon });
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AutumnInt } from "@/external/autumn/autumnCli.js";
|
||||
import { initCustomer } from "@/utils/scriptUtils/initCustomer.js";
|
||||
import { APIVersion, AppEnv, Organization } from "@autumn/shared";
|
||||
import { AppEnv, Organization } from "@autumn/shared";
|
||||
import chalk from "chalk";
|
||||
import Stripe from "stripe";
|
||||
import { DrizzleCli } from "@/db/initDrizzle.js";
|
||||
@@ -16,7 +16,6 @@ import { TestFeature } from "tests/setup/v2Features.js";
|
||||
import { completeCheckoutForm } from "tests/utils/stripeUtils.js";
|
||||
import { timeout } from "@/utils/genUtils.js";
|
||||
import { expectProductAttached } from "tests/utils/expectUtils/expectProductAttached.js";
|
||||
import { expectFeaturesCorrect } from "tests/utils/expectUtils/expectFeaturesCorrect.js";
|
||||
import { expect } from "chai";
|
||||
import { getBasePrice } from "tests/utils/testProductUtils/testProductUtils.js";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user