mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-04-05 00:23:10 +00:00
go: upi payment
This commit is contained in:
@@ -239,10 +239,11 @@ export namespace Billing {
|
||||
z.object({
|
||||
successUrl: z.string(),
|
||||
cancelUrl: z.string(),
|
||||
method: z.enum(["alipay", "upi"]).optional(),
|
||||
}),
|
||||
async (input) => {
|
||||
const user = Actor.assert("user")
|
||||
const { successUrl, cancelUrl } = input
|
||||
const { successUrl, cancelUrl, method } = input
|
||||
|
||||
const email = await User.getAuthEmail(user.properties.userID)
|
||||
const billing = await Billing.get()
|
||||
@@ -250,38 +251,102 @@ export namespace Billing {
|
||||
if (billing.subscriptionID) throw new Error("Already subscribed to Black")
|
||||
if (billing.liteSubscriptionID) throw new Error("Already subscribed to Lite")
|
||||
|
||||
const session = await Billing.stripe().checkout.sessions.create({
|
||||
mode: "subscription",
|
||||
billing_address_collection: "required",
|
||||
line_items: [{ price: LiteData.priceID(), quantity: 1 }],
|
||||
discounts: [{ coupon: LiteData.firstMonth50Coupon() }],
|
||||
...(billing.customerID
|
||||
? {
|
||||
customer: billing.customerID,
|
||||
customer_update: {
|
||||
name: "auto",
|
||||
address: "auto",
|
||||
},
|
||||
const createSession = () =>
|
||||
Billing.stripe().checkout.sessions.create({
|
||||
mode: "subscription",
|
||||
discounts: [{ coupon: LiteData.firstMonth50Coupon() }],
|
||||
...(billing.customerID
|
||||
? {
|
||||
customer: billing.customerID,
|
||||
customer_update: {
|
||||
name: "auto",
|
||||
address: "auto",
|
||||
},
|
||||
}
|
||||
: {
|
||||
customer_email: email!,
|
||||
}),
|
||||
...(() => {
|
||||
if (method === "alipay") {
|
||||
return {
|
||||
line_items: [{ price: LiteData.priceID(), quantity: 1 }],
|
||||
payment_method_types: ["alipay"],
|
||||
adaptive_pricing: {
|
||||
enabled: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
: {
|
||||
customer_email: email!,
|
||||
}),
|
||||
currency: "usd",
|
||||
tax_id_collection: {
|
||||
enabled: true,
|
||||
},
|
||||
success_url: successUrl,
|
||||
cancel_url: cancelUrl,
|
||||
subscription_data: {
|
||||
metadata: {
|
||||
workspaceID: Actor.workspace(),
|
||||
userID: user.properties.userID,
|
||||
type: "lite",
|
||||
if (method === "upi") {
|
||||
return {
|
||||
line_items: [
|
||||
{
|
||||
price_data: {
|
||||
currency: "inr",
|
||||
product: LiteData.productID(),
|
||||
recurring: {
|
||||
interval: "month",
|
||||
interval_count: 1,
|
||||
},
|
||||
unit_amount: LiteData.priceInr(),
|
||||
},
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
payment_method_types: ["upi"] as any,
|
||||
adaptive_pricing: {
|
||||
enabled: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
return {
|
||||
line_items: [{ price: LiteData.priceID(), quantity: 1 }],
|
||||
billing_address_collection: "required",
|
||||
}
|
||||
})(),
|
||||
tax_id_collection: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
success_url: successUrl,
|
||||
cancel_url: cancelUrl,
|
||||
subscription_data: {
|
||||
metadata: {
|
||||
workspaceID: Actor.workspace(),
|
||||
userID: user.properties.userID,
|
||||
type: "lite",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return session.url
|
||||
try {
|
||||
const session = await createSession()
|
||||
return session.url
|
||||
} catch (e: any) {
|
||||
if (
|
||||
e.type !== "StripeInvalidRequestError" ||
|
||||
!e.message.includes("You cannot combine currencies on a single customer")
|
||||
)
|
||||
throw e
|
||||
|
||||
// get pending payment intent
|
||||
const intents = await Billing.stripe().paymentIntents.search({
|
||||
query: `-status:'canceled' AND -status:'processing' AND -status:'succeeded' AND customer:'${billing.customerID}'`,
|
||||
})
|
||||
if (intents.data.length === 0) throw e
|
||||
|
||||
for (const intent of intents.data) {
|
||||
// get checkout session
|
||||
const sessions = await Billing.stripe().checkout.sessions.list({
|
||||
customer: billing.customerID!,
|
||||
payment_intent: intent.id,
|
||||
})
|
||||
|
||||
// delete pending payment intent
|
||||
await Billing.stripe().checkout.sessions.expire(sessions.data[0].id)
|
||||
}
|
||||
|
||||
const session = await createSession()
|
||||
return session.url
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ export namespace LiteData {
|
||||
|
||||
export const productID = fn(z.void(), () => Resource.ZEN_LITE_PRICE.product)
|
||||
export const priceID = fn(z.void(), () => Resource.ZEN_LITE_PRICE.price)
|
||||
export const priceInr = fn(z.void(), () => Resource.ZEN_LITE_PRICE.priceInr)
|
||||
export const firstMonth50Coupon = fn(z.void(), () => Resource.ZEN_LITE_PRICE.firstMonth50Coupon)
|
||||
export const planName = fn(z.void(), () => "lite")
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ export const PaymentTable = mysqlTable(
|
||||
enrichment: json("enrichment").$type<
|
||||
| {
|
||||
type: "subscription" | "lite"
|
||||
currency?: "inr"
|
||||
couponID?: string
|
||||
}
|
||||
| {
|
||||
|
||||
Reference in New Issue
Block a user