Skip to content

Commit

Permalink
gei stripe 0.4.2 updated webhooks and checkout
Browse files Browse the repository at this point in the history
  • Loading branch information
Matnabru committed Aug 10, 2023
1 parent 6d0953c commit 1f14773
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 23 deletions.
2 changes: 1 addition & 1 deletion packages/integrations/gei-stripe/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "gei-stripe",
"version": "0.4.1",
"version": "0.4.2",
"description": "Automatically generated by graphql-editor-cli",
"main": "lib/index.js",
"scripts": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { newStripe } from '../utils/utils.js';
import { resolverFor } from '../zeus/index.js';
import { FieldResolveInput } from 'stucco-js';
import { MongoOrb } from '../db/orm.js';
import { WithId } from 'mongodb';
type item = {
price: string;
quantity?: number;
Expand All @@ -15,37 +16,47 @@ export const handler = async (input: FieldResolveInput) =>
const stripe = newStripe();
const subscriptionItems: item[] = [];
const oneTimePaymentItems: item[] = [];
const user = await MongoOrb('UserCollection').collection.findOne(
{ username },
);
const user = await MongoOrb('UserCollection').collection.findOne({ username });
if (!user) {
throw new Error('Invalid product or customer');
}
let totalAmount = 0;


await Promise.all(
products.map(async (product) => {
let price;
if (product.productId.startsWith('price_')) {
price = await stripe.prices.retrieve(product.productId);
price = await MongoOrb('StripePriceCollection').collection.findOne({ id: product.productId });
if(!price) throw new Error("Stripe price does not exist in database");
if(price.billing_scheme == "tiered"){
price = await stripe.prices.retrieve(product.productId, {
expand: ['tiers']
});
}
} else if (product.productId.startsWith('prod_')) {
const { default_price } = await stripe.products.retrieve(product.productId);
if (!default_price) {
const foundProduct = await MongoOrb('StripeProductCollection').collection.findOne({ id: product.productId });
if(!foundProduct) throw new Error("Stripe product does not exist in database ")
if (!foundProduct.default_price) {
throw new Error('Cannot find product ' + product.productId + ' default price');
}
price =
typeof default_price === 'string'
? await stripe.prices.retrieve(default_price)
: await stripe.prices.retrieve(default_price.id);
typeof foundProduct.default_price === 'string'
? await MongoOrb('StripePriceCollection').collection.findOne({ id: foundProduct.default_price })
: await MongoOrb('StripePriceCollection').collection.findOne({ id: foundProduct.default_price.id });
} else {
throw new Error('Invalid product ID: ' + product.productId);
throw new Error('Invalid ID: ' + product.productId);
}

const quantity = price.type === 'recurring' || price.recurring?.usage_type === 'metered' ? 1 : product.quantity;
if(!price){
throw new Error("Could not fetch price");
}
const quantity =
price.type === 'recurring' || price.recurring?.usage_type === 'metered' ? 1 : product.quantity;
const item = { price: price.id, ...(quantity && { quantity }) };
totalAmount += (price.unit_amount || 0) * (quantity || 0);

if (price.type === 'recurring' && price.tiers) {
totalAmount += calculateTieredPricing(price, quantity);
} else {
totalAmount += (price.unit_amount || 0) * (quantity || 0);
}
if (price.type === 'recurring') {
subscriptionItems.push(item);
} else {
Expand Down Expand Up @@ -75,7 +86,7 @@ export const handler = async (input: FieldResolveInput) =>
address: 'auto',
name: 'auto',
},
customer: user.stripeId
customer: user.stripeId,
};

if (applicationFeeAmount > 0 && applicationFee && oneTimePaymentItems.length > 0) {
Expand All @@ -85,6 +96,9 @@ export const handler = async (input: FieldResolveInput) =>
destination: applicationFee.connectAccountId,
},
};
sessionData.invoice_creation = {
enabled: true,
};
}

if (applicationFeeAmount > 0 && applicationFee && subscriptionItems.length > 0) {
Expand All @@ -102,3 +116,31 @@ export const handler = async (input: FieldResolveInput) =>
},
)(input.arguments, input.source);

function calculateTieredPricing(price: Stripe.Response<Stripe.Price> | WithId<Stripe.Price>, quantity: number) {
if (!price.tiers) return (price.unit_amount || 0) * quantity;

let totalAmount = 0;
let remainingQuantity = quantity;
let previousTierEnd = 0; // This keeps track of the last tier's "up_to" value

for (const tier of price.tiers) {
const currentTierQuantity = tier.up_to
? Math.min(tier.up_to - previousTierEnd, remainingQuantity)
: remainingQuantity;

if (tier.flat_amount !== null) {
totalAmount += tier.flat_amount * currentTierQuantity;
} else if (tier.unit_amount) {
totalAmount += tier.unit_amount * currentTierQuantity;
}

if (tier.up_to) {
previousTierEnd = tier.up_to;
remainingQuantity -= currentTierQuantity;
}

if (remainingQuantity <= 0) break;
}

return totalAmount;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const customerUpdate = async (subEvent: Stripe.Customer) => {
return await MongoOrb('StripeCustomerCollection').collection.updateOne(
{ id: subEvent.id },
{ $set: subEventWithoutId },
{ upsert: true }
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export const externalAccountInsert = async (subEvent: ExternalAccount) => {
const { id, ...subEventWithoutId } = subEvent;
return await MongoOrb('StripeExternalAccountCollection').collection.updateOne(
{ id: subEvent.id },
{ $set: subEventWithoutId }
{ $set: subEventWithoutId },
{ upsert: true }
);;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const upsertInvoice = async (invoiceEvent: Stripe.Invoice) => {
return await MongoOrb('StripeInvoiceCollection').collection.updateOne(
{ id: invoiceEvent.id },
{ $set: { ...invoiceEvent } },
{ upsert: true } // creates a new document if no documents match the filter
{ upsert: true }
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export const stripePriceInsert = async (subEvent: Stripe.Price) => {
const { id, ...subEventWithoutId } = subEvent;
return await MongoOrb('StripePriceCollection').collection.updateOne(
{ id: subEvent.id },
{ $set: subEventWithoutId }
{ $set: subEventWithoutId },
{ upsert: true }
);;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export const stripeProductInsert = async (subEvent: Stripe.Product) => {
const { id, ...subEventWithoutId } = subEvent;
return await MongoOrb('StripeProductCollection').collection.updateOne(
{ id: subEvent.id },
{ $set: subEventWithoutId }
{ $set: subEventWithoutId },
{ upsert: true }
);;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export const stripeSubscriptionInsert = async (subEvent: Stripe.Subscription) =>
const { id, ...subEventWithoutId } = subEvent;
return await MongoOrb('StripeSubscriptionCollection').collection.updateOne(
{ id: subEvent.id },
{ $set: subEventWithoutId }
{ $set: subEventWithoutId },
{ upsert: true }
);;
};

Expand Down
3 changes: 2 additions & 1 deletion packages/integrations/gei-stripe/src/utils/tax_rateEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export const taxRateUpdated = async (subEvent: Stripe.TaxRate) => {
const { id, ...subEventWithoutId } = subEvent;
return await MongoOrb('StripeTaxRateCollection').collection.updateOne(
{ id: subEvent.id },
{ $set: subEventWithoutId }
{ $set: subEventWithoutId },
{ upsert: true }
);;
};

21 changes: 21 additions & 0 deletions packages/integrations/gei-stripe/stucco.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,27 @@
"resolve": {
"name": "Mutation.setDefaultPaymentMethod.handler"
}
},
"Query.paymentIntents": {
"name": "paymentIntents",
"description": "List stripe payment intents",
"resolve": {
"name": "Query.paymentIntents.handler"
}
},
"Query.invoices": {
"name": "invoices",
"description": "List stripe invoices for specific user",
"resolve": {
"name": "Query.invoices.handler"
}
},
"Query.customer": {
"name": "customer",
"description": "Show stripe customer object with payment methods",
"resolve": {
"name": "Query.customer.handler"
}
}
},
"azureOpts": {
Expand Down

0 comments on commit 1f14773

Please sign in to comment.