@stacksjs/payments 0.75.422 → 0.75.423

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/payment.d.ts CHANGED
@@ -94,9 +94,21 @@ export declare function createCoupon(options: {
94
94
  }): Promise<Stripe.Coupon>;
95
95
  export declare function createPromoCode(couponId: string, code: string, options?: Partial<Stripe.PromotionCodeCreateParams>): Promise<Stripe.PromotionCode>;
96
96
  export declare function validatePromoCode(code: string): Promise<Stripe.PromotionCode | null>;
97
+ /**
98
+ * Decimal places in a provider `amount` for `currency`. With Stripe, the
99
+ * default driver, that is Stripe's own table: none for its zero-decimal
100
+ * currencies and two for everything else, ISK and UGX included, though ISO
101
+ * gives those no minor unit and MGA two. Another driver uses the ISO 4217
102
+ * exponent `Intl` carries.
103
+ */
104
+ export declare function minorUnitExponent(currency: string, driver?: string): number;
97
105
  /**
98
106
  * Format amount for display.
99
107
  *
108
+ * `amount` is in the currency's minor unit, as every provider amount is, and
109
+ * is scaled by {@link minorUnitExponent}. It used to be divided by 100 for
110
+ * every currency, so 1000 JPY showed as ¥10.
111
+ *
100
112
  * Currency defaults to the project's configured payment currency
101
113
  * (`config.payment.currency` / `STRIPE_CURRENCY`), falling back to USD only
102
114
  * when nothing else is set. Locale follows the same pattern via
@@ -104,11 +116,12 @@ export declare function validatePromoCode(code: string): Promise<Stripe.Promotio
104
116
  */
105
117
  export declare function formatAmount(amount: number, currency?: string): string;
106
118
  /**
107
- * Convert dollars to cents
119
+ * Convert dollars to cents: for two-decimal currencies only. A JPY amount
120
+ * is already in its minor unit; see {@link minorUnitExponent}.
108
121
  */
109
122
  export declare function toCents(dollars: number): number;
110
123
  /**
111
- * Convert cents to dollars
124
+ * Convert cents to dollars: for two-decimal currencies only (see {@link toCents}).
112
125
  */
113
126
  export declare function toDollars(cents: number): number;
114
127
  /**
@@ -156,6 +169,7 @@ export declare const Payment: {
156
169
  createPromoCode: typeof createPromoCode;
157
170
  validatePromoCode: typeof validatePromoCode;
158
171
  formatAmount: typeof formatAmount;
172
+ minorUnitExponent: typeof minorUnitExponent;
159
173
  toCents: typeof toCents;
160
174
  toDollars: typeof toDollars;
161
175
  webhook: typeof manageWebhook;
package/dist/payment.js CHANGED
@@ -1 +1 @@
1
- import{stripe}from"./drivers/stripe";import{manageCustomer}from"./billable/customer";import{manageInvoice}from"./billable/invoice";import{managePaymentMethod}from"./billable/payment-method";import{managePrice}from"./billable/price";import{manageBillingPortal}from"./billable/portal";import{manageCoupon,managePriceExtended,manageProduct}from"./billable/product";import{manageSubscription}from"./billable/subscription";import{manageSetupIntent}from"./billable/intent";import{manageWebhook,onCharge,onCheckout,onInvoice,onPaymentIntent,onSubscription,processWebhook}from"./billable/webhook";import{connect}from"./connect";import{assertStripeDriver,paymentDriver}from"./driver";export async function charge(payer,amount,paymentMethod,options={}){return paymentDriver().charge(payer,amount,paymentMethod,options)}export async function createPayment(payer,amount,options={}){return paymentDriver().createPayment(payer,amount,options)}export async function refund(paymentId,options={}){return paymentDriver().refund(paymentId,options)}export async function checkout(payer,request){return paymentDriver().checkout(payer,request)}export async function subscriptionCheckout(payer,price,options){const{quantity=1,...request}=options;return paymentDriver().checkout(payer,{...request,mode:"subscription",lines:[{price,quantity}]})}export async function subscribe(payer,price,options={}){return paymentDriver().subscribe(payer,price,options)}export async function cancelSubscription(subscriptionId,options={}){return paymentDriver().cancelSubscription(subscriptionId,options)}export async function subscriptions(payer){return paymentDriver().subscriptions(payer)}export async function hasActiveSubscription(user,type="default"){return manageSubscription.isValid(user,type)}export async function changeSubscription(user,newLookupKey,type="default"){assertStripeDriver("changeSubscription");return manageSubscription.update(user,type,newLookupKey,{})}export async function getOrCreateCustomer(payer){return paymentDriver().customer(payer)}export async function updateCustomer(user,options){assertStripeDriver("updateCustomer");return manageCustomer.updateStripeCustomer(user,options)}export async function deleteCustomer(user){assertStripeDriver("deleteCustomer");return manageCustomer.deleteStripeUser(user)}export async function paymentMethods(payer){return paymentDriver().paymentMethods(payer)}export async function removePaymentMethod(payer,paymentMethodId){return paymentDriver().removePaymentMethod(payer,paymentMethodId)}export async function addPaymentMethod(user,paymentMethodId){assertStripeDriver("addPaymentMethod");return managePaymentMethod.addPaymentMethod(user,paymentMethodId)}export async function setDefaultPaymentMethod(user,paymentMethodId){assertStripeDriver("setDefaultPaymentMethod");return managePaymentMethod.setUserDefaultPayment(user,paymentMethodId)}export async function createSetupIntent(user,options={}){assertStripeDriver("createSetupIntent");return manageSetupIntent.create(user,options)}export async function getInvoices(user){assertStripeDriver("getInvoices");return manageInvoice.list(user)}export async function createInvoice(customerId,options={}){assertStripeDriver("createInvoice");return stripe.invoices.create({customer:customerId,...options})}export async function payInvoice(invoiceId){assertStripeDriver("payInvoice");return stripe.invoices.pay(invoiceId)}export async function createProduct(name,price,options={}){assertStripeDriver("createProduct");const{currency="usd",interval,description,metadata}=options,priceParams={unit_amount:price,currency};if(interval)priceParams.recurring={interval};return manageProduct.createWithPrice({name,description,metadata},priceParams)}export async function getPrice(lookupKey){assertStripeDriver("getPrice");return managePrice.retrieveByLookupKey(lookupKey)}export async function listProducts(options={}){assertStripeDriver("listProducts");return manageProduct.list(options)}export async function createCoupon(options){assertStripeDriver("createCoupon");const params={duration:options.duration||"once"};if(options.percentOff)params.percent_off=options.percentOff;else if(options.amountOff){params.amount_off=options.amountOff;params.currency=options.currency||"usd"}if(options.name)params.name=options.name;if(options.durationInMonths)params.duration_in_months=options.durationInMonths;if(options.maxRedemptions)params.max_redemptions=options.maxRedemptions;return manageCoupon.create(params)}export async function createPromoCode(couponId,code,options={}){assertStripeDriver("createPromoCode");return manageCoupon.createPromotionCode({promotion:{type:"coupon",coupon:couponId},code,...options})}export async function validatePromoCode(code){assertStripeDriver("validatePromoCode");return manageCoupon.retrievePromotionCode(code)}export function formatAmount(amount,currency){const cfg=globalThis.config||{},ccy=(currency||cfg.payment?.currency||cfg.billing?.currency||process.env.STRIPE_CURRENCY||"usd").toLowerCase(),locale=cfg.app?.locale||"en-US";return new Intl.NumberFormat(locale,{style:"currency",currency:ccy.toUpperCase()}).format(amount/100)}export function toCents(dollars){return Math.round(dollars*100)}export function toDollars(cents){return cents/100}export async function billingPortal(customer,options={}){assertStripeDriver("billingPortal");const customerId=typeof customer==="string"?customer:customer.stripe_id;if(!customerId)throw Error("billingPortal needs a Stripe customer: this user has no stripe_id yet.");return manageBillingPortal.createSession(customerId,options)}export const Payment={driver:paymentDriver,charge,createPayment,refund,checkout,subscriptionCheckout,subscribe,cancelSubscription,subscriptions,hasActiveSubscription,changeSubscription,getOrCreateCustomer,updateCustomer,deleteCustomer,paymentMethods,addPaymentMethod,setDefaultPaymentMethod,removePaymentMethod,createSetupIntent,getInvoices,createInvoice,payInvoice,createProduct,getPrice,listProducts,billingPortal,createCoupon,createPromoCode,validatePromoCode,formatAmount,toCents,toDollars,webhook:manageWebhook,onPaymentIntent,onSubscription,onInvoice,onCheckout,onCharge,processWebhook,connect,stripe,customer:manageCustomer,subscription:manageSubscription,invoice:manageInvoice,paymentMethod:managePaymentMethod,product:manageProduct,price:managePriceExtended,coupon:manageCoupon};export default Payment;
1
+ import{stripe}from"./drivers/stripe";import{manageCustomer}from"./billable/customer";import{manageInvoice}from"./billable/invoice";import{managePaymentMethod}from"./billable/payment-method";import{managePrice}from"./billable/price";import{manageBillingPortal}from"./billable/portal";import{manageCoupon,managePriceExtended,manageProduct}from"./billable/product";import{manageSubscription}from"./billable/subscription";import{manageSetupIntent}from"./billable/intent";import{manageWebhook,onCharge,onCheckout,onInvoice,onPaymentIntent,onSubscription,processWebhook}from"./billable/webhook";import{connect}from"./connect";import{assertStripeDriver,configuredPaymentDriver,paymentDriver}from"./driver";export async function charge(payer,amount,paymentMethod,options={}){return paymentDriver().charge(payer,amount,paymentMethod,options)}export async function createPayment(payer,amount,options={}){return paymentDriver().createPayment(payer,amount,options)}export async function refund(paymentId,options={}){return paymentDriver().refund(paymentId,options)}export async function checkout(payer,request){return paymentDriver().checkout(payer,request)}export async function subscriptionCheckout(payer,price,options){const{quantity=1,...request}=options;return paymentDriver().checkout(payer,{...request,mode:"subscription",lines:[{price,quantity}]})}export async function subscribe(payer,price,options={}){return paymentDriver().subscribe(payer,price,options)}export async function cancelSubscription(subscriptionId,options={}){return paymentDriver().cancelSubscription(subscriptionId,options)}export async function subscriptions(payer){return paymentDriver().subscriptions(payer)}export async function hasActiveSubscription(user,type="default"){return manageSubscription.isValid(user,type)}export async function changeSubscription(user,newLookupKey,type="default"){assertStripeDriver("changeSubscription");return manageSubscription.update(user,type,newLookupKey,{})}export async function getOrCreateCustomer(payer){return paymentDriver().customer(payer)}export async function updateCustomer(user,options){assertStripeDriver("updateCustomer");return manageCustomer.updateStripeCustomer(user,options)}export async function deleteCustomer(user){assertStripeDriver("deleteCustomer");return manageCustomer.deleteStripeUser(user)}export async function paymentMethods(payer){return paymentDriver().paymentMethods(payer)}export async function removePaymentMethod(payer,paymentMethodId){return paymentDriver().removePaymentMethod(payer,paymentMethodId)}export async function addPaymentMethod(user,paymentMethodId){assertStripeDriver("addPaymentMethod");return managePaymentMethod.addPaymentMethod(user,paymentMethodId)}export async function setDefaultPaymentMethod(user,paymentMethodId){assertStripeDriver("setDefaultPaymentMethod");return managePaymentMethod.setUserDefaultPayment(user,paymentMethodId)}export async function createSetupIntent(user,options={}){assertStripeDriver("createSetupIntent");return manageSetupIntent.create(user,options)}export async function getInvoices(user){assertStripeDriver("getInvoices");return manageInvoice.list(user)}export async function createInvoice(customerId,options={}){assertStripeDriver("createInvoice");return stripe.invoices.create({customer:customerId,...options})}export async function payInvoice(invoiceId){assertStripeDriver("payInvoice");return stripe.invoices.pay(invoiceId)}export async function createProduct(name,price,options={}){assertStripeDriver("createProduct");const{currency="usd",interval,description,metadata}=options,priceParams={unit_amount:price,currency};if(interval)priceParams.recurring={interval};return manageProduct.createWithPrice({name,description,metadata},priceParams)}export async function getPrice(lookupKey){assertStripeDriver("getPrice");return managePrice.retrieveByLookupKey(lookupKey)}export async function listProducts(options={}){assertStripeDriver("listProducts");return manageProduct.list(options)}export async function createCoupon(options){assertStripeDriver("createCoupon");const params={duration:options.duration||"once"};if(options.percentOff)params.percent_off=options.percentOff;else if(options.amountOff){params.amount_off=options.amountOff;params.currency=options.currency||"usd"}if(options.name)params.name=options.name;if(options.durationInMonths)params.duration_in_months=options.durationInMonths;if(options.maxRedemptions)params.max_redemptions=options.maxRedemptions;return manageCoupon.create(params)}export async function createPromoCode(couponId,code,options={}){assertStripeDriver("createPromoCode");return manageCoupon.createPromotionCode({promotion:{type:"coupon",coupon:couponId},code,...options})}export async function validatePromoCode(code){assertStripeDriver("validatePromoCode");return manageCoupon.retrievePromotionCode(code)}const STRIPE_ZERO_DECIMAL=new Set(["bif","clp","djf","gnf","jpy","kmf","krw","mga","pyg","rwf","vnd","vuv","xaf","xof","xpf"]);export function minorUnitExponent(currency,driver=configuredPaymentDriver()){const code=currency.trim().toLowerCase();if(driver==="stripe")return STRIPE_ZERO_DECIMAL.has(code)?0:2;try{return new Intl.NumberFormat("en",{style:"currency",currency:code.toUpperCase()}).resolvedOptions().maximumFractionDigits??2}catch{return 2}}export function formatAmount(amount,currency){const cfg=globalThis.config||{},ccy=(currency||cfg.payment?.currency||cfg.billing?.currency||process.env.STRIPE_CURRENCY||"usd").toLowerCase(),locale=cfg.app?.locale||"en-US";return new Intl.NumberFormat(locale,{style:"currency",currency:ccy.toUpperCase()}).format(amount/10**minorUnitExponent(ccy))}export function toCents(dollars){return Math.round(dollars*100)}export function toDollars(cents){return cents/100}export async function billingPortal(customer,options={}){assertStripeDriver("billingPortal");const customerId=typeof customer==="string"?customer:customer.stripe_id;if(!customerId)throw Error("billingPortal needs a Stripe customer: this user has no stripe_id yet.");return manageBillingPortal.createSession(customerId,options)}export const Payment={driver:paymentDriver,charge,createPayment,refund,checkout,subscriptionCheckout,subscribe,cancelSubscription,subscriptions,hasActiveSubscription,changeSubscription,getOrCreateCustomer,updateCustomer,deleteCustomer,paymentMethods,addPaymentMethod,setDefaultPaymentMethod,removePaymentMethod,createSetupIntent,getInvoices,createInvoice,payInvoice,createProduct,getPrice,listProducts,billingPortal,createCoupon,createPromoCode,validatePromoCode,formatAmount,minorUnitExponent,toCents,toDollars,webhook:manageWebhook,onPaymentIntent,onSubscription,onInvoice,onCheckout,onCharge,processWebhook,connect,stripe,customer:manageCustomer,subscription:manageSubscription,invoice:manageInvoice,paymentMethod:managePaymentMethod,product:manageProduct,price:managePriceExtended,coupon:manageCoupon};export default Payment;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/payments",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.75.422",
5
+ "version": "0.75.423",
6
6
  "description": "The Stacks payments package. Currently supporting Stripe.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -60,12 +60,12 @@
60
60
  "prepublishOnly": "bun run build"
61
61
  },
62
62
  "dependencies": {
63
- "@stacksjs/config": "0.75.422",
64
- "@stacksjs/database": "0.75.422",
65
- "@stacksjs/error-handling": "0.75.422",
66
- "@stacksjs/logging": "0.75.422",
67
- "@stacksjs/orm": "0.75.422",
68
- "@stacksjs/types": "0.75.422"
63
+ "@stacksjs/config": "0.75.423",
64
+ "@stacksjs/database": "0.75.423",
65
+ "@stacksjs/error-handling": "0.75.423",
66
+ "@stacksjs/logging": "0.75.423",
67
+ "@stacksjs/orm": "0.75.423",
68
+ "@stacksjs/types": "0.75.423"
69
69
  },
70
70
  "peerDependencies": {
71
71
  "@stripe/stripe-js": "^10.0.0",
@@ -80,7 +80,7 @@
80
80
  }
81
81
  },
82
82
  "devDependencies": {
83
- "@stacksjs/utils": "0.75.422",
83
+ "@stacksjs/utils": "0.75.423",
84
84
  "@stripe/stripe-js": "^10.0.0",
85
85
  "better-dx": "^0.2.24",
86
86
  "stripe": "23.0.0"