@stacksjs/payments 0.72.103 → 0.73.1
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/billable/subscription.d.ts +1 -1
- package/dist/billable/webhook.d.ts +5 -0
- package/dist/connect/account.d.ts +42 -0
- package/dist/connect/account.js +1 -0
- package/dist/connect/charge.d.ts +17 -0
- package/dist/connect/charge.js +1 -0
- package/dist/connect/index.d.ts +44 -0
- package/dist/connect/index.js +1 -0
- package/dist/connect/payout.d.ts +17 -0
- package/dist/connect/payout.js +1 -0
- package/dist/connect/transfer.d.ts +25 -0
- package/dist/connect/transfer.js +1 -0
- package/dist/connect/webhook.d.ts +49 -0
- package/dist/connect/webhook.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/dist/payment.d.ts +2 -0
- package/dist/payment.js +1 -1
- package/package.json +3 -3
|
@@ -13,7 +13,7 @@ export declare const manageSubscription: SubscriptionManager;
|
|
|
13
13
|
export declare interface SubscriptionManager {
|
|
14
14
|
create: (user: UserModel, type: string, lookupKey: string, params: Partial<Stripe.SubscriptionCreateParams>) => Promise<Stripe.Response<Stripe.Subscription>>
|
|
15
15
|
update: (user: UserModel, type: string, lookupKey: string, params: Partial<Stripe.SubscriptionUpdateParams>) => Promise<Stripe.Response<Stripe.Subscription>>
|
|
16
|
-
cancel: (subscriptionId: string, params?: Partial<Stripe.
|
|
16
|
+
cancel: (subscriptionId: string, params?: Partial<Stripe.SubscriptionCancelParams>) => Promise<Stripe.Response<Stripe.Subscription>>
|
|
17
17
|
retrieve: (user: UserModel, subscriptionId: string) => Promise<Stripe.Response<Stripe.Subscription>>
|
|
18
18
|
isValid: (user: UserModel, type: string) => Promise<boolean>
|
|
19
19
|
isIncomplete: (user: UserModel, type: string) => Promise<boolean>
|
|
@@ -169,5 +169,10 @@ export type WebhookEventType = | 'payment_intent.succeeded'
|
|
|
169
169
|
| 'payment_method.detached'
|
|
170
170
|
| 'setup_intent.succeeded'
|
|
171
171
|
| 'setup_intent.setup_failed'
|
|
172
|
+
| 'account.updated'
|
|
173
|
+
| 'account.application.deauthorized'
|
|
174
|
+
| 'payout.created'
|
|
175
|
+
| 'payout.paid'
|
|
176
|
+
| 'payout.failed'
|
|
172
177
|
| string;
|
|
173
178
|
export type WebhookHandler = (_event: Stripe.Event) => Promise<void> | void;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { UserModel } from '@stacksjs/orm';
|
|
2
|
+
import type Stripe from 'stripe';
|
|
3
|
+
/**
|
|
4
|
+
* Connected-account ids are `acct_...`. Checking the shape here turns a
|
|
5
|
+
* confusing Stripe 404 (which reads as "no such account" even when the caller
|
|
6
|
+
* passed a customer id, a user id, or an empty string) into a local error that
|
|
7
|
+
* names the argument.
|
|
8
|
+
*/
|
|
9
|
+
export declare function requireAccountId(accountId: string, caller: string): void;
|
|
10
|
+
export declare const manageConnectedAccount: ManageConnectedAccount;
|
|
11
|
+
/**
|
|
12
|
+
* A connected account's readiness, reduced to the questions a marketplace
|
|
13
|
+
* actually asks.
|
|
14
|
+
*
|
|
15
|
+
* Stripe answers "can this merchant be paid yet" across three booleans and two
|
|
16
|
+
* nested requirement arrays, and every caller that reaches for the raw account
|
|
17
|
+
* ends up re-deriving the same digest. Onboarding is not finished when the
|
|
18
|
+
* merchant returns from the onboarding link - it is finished when
|
|
19
|
+
* `chargesEnabled` turns true, which can lag by minutes or need more documents.
|
|
20
|
+
*/
|
|
21
|
+
export declare interface ConnectAccountStatus {
|
|
22
|
+
chargesEnabled: boolean
|
|
23
|
+
payoutsEnabled: boolean
|
|
24
|
+
detailsSubmitted: boolean
|
|
25
|
+
currentlyDue: string[]
|
|
26
|
+
pastDue: string[]
|
|
27
|
+
disabledReason: string | null
|
|
28
|
+
raw: Stripe.Account
|
|
29
|
+
}
|
|
30
|
+
export declare interface ManageConnectedAccount {
|
|
31
|
+
createConnectedAccount: (user: UserModel, params?: Partial<Stripe.AccountCreateParams>) => Promise<Stripe.Response<Stripe.Account>>
|
|
32
|
+
createTestConnectedAccount: (user: UserModel, params?: Partial<Stripe.AccountCreateParams>) => Promise<Stripe.Response<Stripe.Account>>
|
|
33
|
+
accountOnboardingLink: (accountId: string, options: OnboardingLinkOptions) => Promise<Stripe.Response<Stripe.AccountLink>>
|
|
34
|
+
accountStatus: (accountId: string) => Promise<ConnectAccountStatus>
|
|
35
|
+
retrieveConnectedAccount: (accountId: string) => Promise<Stripe.Response<Stripe.Account>>
|
|
36
|
+
}
|
|
37
|
+
export declare interface OnboardingLinkOptions {
|
|
38
|
+
refreshUrl: string
|
|
39
|
+
returnUrl: string
|
|
40
|
+
type?: Stripe.AccountLinkCreateParams.Type
|
|
41
|
+
collect?: Stripe.AccountLinkCreateParams.CollectionOptions.Fields
|
|
42
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{stripe}from"../drivers/stripe";import{stacksIdempotencyKey}from"../idempotency";export const manageConnectedAccount=(()=>{async function createConnectedAccount(user,params={}){const merged={...{type:"express",email:user.email??void 0,metadata:{stacks_user_id:String(user.id)}},...params};return await stripe.accounts.create(merged,{idempotencyKey:stacksIdempotencyKey("connect.account.create",user.id)})}async function createTestConnectedAccount(user,params={}){const merged={...{type:"express",email:user.email??void 0,business_type:"individual",capabilities:{card_payments:{requested:!0},transfers:{requested:!0}},business_profile:{url:"https://example.com",mcc:"5812"},metadata:{stacks_user_id:String(user.id),stacks_test_account:"true"}},...params};return await stripe.accounts.create(merged,{idempotencyKey:stacksIdempotencyKey("connect.account.create_test",user.id)})}async function accountOnboardingLink(accountId,options){requireAccountId(accountId,"accountOnboardingLink");if(!options?.refreshUrl||!options?.returnUrl)throw Error("[payments/connect] accountOnboardingLink requires refreshUrl and returnUrl");return await stripe.accountLinks.create({account:accountId,refresh_url:options.refreshUrl,return_url:options.returnUrl,type:options.type??"account_onboarding",...options.collect?{collection_options:{fields:options.collect}}:{}})}async function retrieveConnectedAccount(accountId){requireAccountId(accountId,"retrieveConnectedAccount");return await stripe.accounts.retrieve(accountId)}async function accountStatus(accountId){const account=await retrieveConnectedAccount(accountId),requirements=account.requirements;return{chargesEnabled:account.charges_enabled===!0,payoutsEnabled:account.payouts_enabled===!0,detailsSubmitted:account.details_submitted===!0,currentlyDue:requirements?.currently_due??[],pastDue:requirements?.past_due??[],disabledReason:requirements?.disabled_reason??null,raw:account}}return{createConnectedAccount,createTestConnectedAccount,accountOnboardingLink,accountStatus,retrieveConnectedAccount}})();export function requireAccountId(accountId,caller){if(!accountId||typeof accountId!=="string")throw Error(`[payments/connect] ${caller} requires a connected account id`);if(!accountId.startsWith("acct_"))throw Error(`[payments/connect] ${caller} expects a connected account id (acct_...), got "${accountId}"`)}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { UserModel } from '@stacksjs/orm';
|
|
2
|
+
import type Stripe from 'stripe';
|
|
3
|
+
export declare const manageDestinationCharge: ManageDestinationCharge;
|
|
4
|
+
export declare interface DestinationChargeOptions extends Partial<Stripe.PaymentIntentCreateParams> {
|
|
5
|
+
applicationFeeAmount?: number
|
|
6
|
+
platformFeePercent?: number
|
|
7
|
+
transferGroup?: string
|
|
8
|
+
}
|
|
9
|
+
export declare interface ManageDestinationCharge {
|
|
10
|
+
destinationCharge: (
|
|
11
|
+
user: UserModel,
|
|
12
|
+
amount: number,
|
|
13
|
+
destinationAccountId: string,
|
|
14
|
+
options?: DestinationChargeOptions,
|
|
15
|
+
) => Promise<Stripe.Response<Stripe.PaymentIntent>>
|
|
16
|
+
applicationFeeFor: (amount: number, options?: { applicationFeeAmount?: number, platformFeePercent?: number }) => number | undefined
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{config}from"@stacksjs/config";import{stripe}from"../drivers/stripe";import{freshIdempotencyKey}from"../idempotency";import{requireAccountId}from"./account";function defaultCurrency(){const cfg=config||{};return(cfg.payment?.currency||cfg.billing?.currency||process.env.STRIPE_CURRENCY||"usd").toLowerCase()}function configuredFeePercent(){return(config||{}).payment?.connect?.platformFeePercent}export const manageDestinationCharge=(()=>{function applicationFeeFor(amount,options={}){if(options.applicationFeeAmount!=null){if(!Number.isFinite(options.applicationFeeAmount)||options.applicationFeeAmount<0)throw Error("[payments/connect] applicationFeeAmount must be a non-negative number of minor units");if(options.applicationFeeAmount>amount)throw Error(`[payments/connect] applicationFeeAmount ${options.applicationFeeAmount} exceeds the charge amount ${amount}`);return Math.floor(options.applicationFeeAmount)}const percent=options.platformFeePercent??configuredFeePercent();if(percent==null)return;if(!Number.isFinite(percent)||percent<0||percent>100)throw Error(`[payments/connect] platformFeePercent must be between 0 and 100, got ${percent}`);return Math.floor(amount*percent/100)}async function destinationCharge(user,amount,destinationAccountId,options={}){requireAccountId(destinationAccountId,"destinationCharge");if(!Number.isFinite(amount)||amount<=0)throw Error("[payments/connect] destinationCharge requires a positive amount in minor units");const{applicationFeeAmount,platformFeePercent,transferGroup,...intentParams}=options,fee=applicationFeeFor(amount,{applicationFeeAmount,platformFeePercent}),params={amount,currency:defaultCurrency(),transfer_data:{destination:destinationAccountId},...fee!=null&&fee>0?{application_fee_amount:fee}:{},...transferGroup?{transfer_group:transferGroup}:{},...intentParams};if(!params.customer&&user.hasStripeId())params.customer=user.stripe_id??void 0;return await stripe.paymentIntents.create(params,{idempotencyKey:freshIdempotencyKey("connect.destination_charge",user.id,amount)})}return{destinationCharge,applicationFeeFor}})();
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grouped Connect surface, reached as `Payment.connect.*`.
|
|
3
|
+
*/
|
|
4
|
+
export declare const connect: {
|
|
5
|
+
createAccount: unknown;
|
|
6
|
+
createTestAccount: unknown;
|
|
7
|
+
onboardingLink: unknown;
|
|
8
|
+
accountStatus: unknown;
|
|
9
|
+
retrieveAccount: unknown;
|
|
10
|
+
destinationCharge: unknown;
|
|
11
|
+
applicationFeeFor: unknown;
|
|
12
|
+
createTransfer: unknown;
|
|
13
|
+
reverseTransfer: unknown;
|
|
14
|
+
listTransfers: unknown;
|
|
15
|
+
retrieveTransfer: unknown;
|
|
16
|
+
listPayouts: unknown;
|
|
17
|
+
retrievePayout: unknown;
|
|
18
|
+
accountBalance: unknown;
|
|
19
|
+
onAccount: unknown;
|
|
20
|
+
onPayout: unknown;
|
|
21
|
+
getAccount: unknown;
|
|
22
|
+
getPayout: unknown;
|
|
23
|
+
getConnectedAccountId: unknown;
|
|
24
|
+
account: unknown;
|
|
25
|
+
charge: unknown;
|
|
26
|
+
transfer: unknown;
|
|
27
|
+
payout: unknown
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Stripe Connect
|
|
31
|
+
*
|
|
32
|
+
* Marketplace payments: onboard merchants as connected accounts, charge the
|
|
33
|
+
* customer on the platform while settling to the merchant, move money between
|
|
34
|
+
* the two, and follow what Stripe pays out.
|
|
35
|
+
*
|
|
36
|
+
* Everything here is additive - an app that charges for itself never touches
|
|
37
|
+
* it, and the `stripe` client stays lazily resolved, so importing
|
|
38
|
+
* `@stacksjs/payments` still costs nothing when Stripe is not installed.
|
|
39
|
+
*/
|
|
40
|
+
export * from './account';
|
|
41
|
+
export * from './charge';
|
|
42
|
+
export * from './payout';
|
|
43
|
+
export * from './transfer';
|
|
44
|
+
export * from './webhook';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"./account";export*from"./charge";export*from"./payout";export*from"./transfer";export*from"./webhook";import{manageConnectedAccount}from"./account";import{manageDestinationCharge}from"./charge";import{managePayout}from"./payout";import{manageTransfer}from"./transfer";import{manageConnectWebhook}from"./webhook";export const connect={createAccount:manageConnectedAccount.createConnectedAccount,createTestAccount:manageConnectedAccount.createTestConnectedAccount,onboardingLink:manageConnectedAccount.accountOnboardingLink,accountStatus:manageConnectedAccount.accountStatus,retrieveAccount:manageConnectedAccount.retrieveConnectedAccount,destinationCharge:manageDestinationCharge.destinationCharge,applicationFeeFor:manageDestinationCharge.applicationFeeFor,createTransfer:manageTransfer.createTransfer,reverseTransfer:manageTransfer.reverseTransfer,listTransfers:manageTransfer.listTransfers,retrieveTransfer:manageTransfer.retrieveTransfer,listPayouts:managePayout.listPayouts,retrievePayout:managePayout.retrievePayout,accountBalance:managePayout.accountBalance,onAccount:manageConnectWebhook.onAccount,onPayout:manageConnectWebhook.onPayout,getAccount:manageConnectWebhook.getAccount,getPayout:manageConnectWebhook.getPayout,getConnectedAccountId:manageConnectWebhook.getConnectedAccountId,account:manageConnectedAccount,charge:manageDestinationCharge,transfer:manageTransfer,payout:managePayout};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type Stripe from 'stripe';
|
|
2
|
+
/**
|
|
3
|
+
* Payouts as the connected account sees them: bank transfers out of the
|
|
4
|
+
* merchant's Stripe balance.
|
|
5
|
+
*
|
|
6
|
+
* Every call is made *as* the connected account (`stripeAccount`), not as the
|
|
7
|
+
* platform. Listing payouts on the platform account instead returns the
|
|
8
|
+
* platform's own bank transfers, which is a quietly wrong answer rather than an
|
|
9
|
+
* error - a merchant statement page would render the platform's payouts and
|
|
10
|
+
* nobody would notice until reconciliation.
|
|
11
|
+
*/
|
|
12
|
+
export declare const managePayout: ManagePayout;
|
|
13
|
+
export declare interface ManagePayout {
|
|
14
|
+
listPayouts: (accountId: string, params?: Stripe.PayoutListParams) => Promise<Stripe.Response<Stripe.ApiList<Stripe.Payout>>>
|
|
15
|
+
retrievePayout: (accountId: string, payoutId: string) => Promise<Stripe.Response<Stripe.Payout>>
|
|
16
|
+
accountBalance: (accountId: string) => Promise<Stripe.Response<Stripe.Balance>>
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{stripe}from"../drivers/stripe";import{requireAccountId}from"./account";export const managePayout=(()=>{async function listPayouts(accountId,params={}){requireAccountId(accountId,"listPayouts");return await stripe.payouts.list(params,{stripeAccount:accountId})}async function retrievePayout(accountId,payoutId){requireAccountId(accountId,"retrievePayout");if(!payoutId||typeof payoutId!=="string")throw Error("[payments/connect] retrievePayout requires a payout id");return await stripe.payouts.retrieve(payoutId,{},{stripeAccount:accountId})}async function accountBalance(accountId){requireAccountId(accountId,"accountBalance");return await stripe.balance.retrieve({},{stripeAccount:accountId})}return{listPayouts,retrievePayout,accountBalance}})();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type Stripe from 'stripe';
|
|
2
|
+
/**
|
|
3
|
+
* Separate transfers, for money movement that is not tied to a single charge at
|
|
4
|
+
* the moment the customer pays.
|
|
5
|
+
*
|
|
6
|
+
* `destinationCharge` covers the common marketplace case. This is the other
|
|
7
|
+
* one: paying a courier their accumulated earnings, settling a merchant weekly
|
|
8
|
+
* rather than per order, or splitting one charge across several recipients.
|
|
9
|
+
*/
|
|
10
|
+
export declare const manageTransfer: ManageTransfer;
|
|
11
|
+
export declare interface CreateTransferOptions {
|
|
12
|
+
amount: number
|
|
13
|
+
destination: string
|
|
14
|
+
currency?: string
|
|
15
|
+
transferGroup?: string
|
|
16
|
+
sourceTransaction?: string
|
|
17
|
+
description?: string
|
|
18
|
+
metadata?: Stripe.MetadataParam
|
|
19
|
+
}
|
|
20
|
+
export declare interface ManageTransfer {
|
|
21
|
+
createTransfer: (options: CreateTransferOptions) => Promise<Stripe.Response<Stripe.Transfer>>
|
|
22
|
+
reverseTransfer: (transferId: string, amount?: number) => Promise<Stripe.Response<Stripe.TransferReversal>>
|
|
23
|
+
listTransfers: (params?: Stripe.TransferListParams) => Promise<Stripe.Response<Stripe.ApiList<Stripe.Transfer>>>
|
|
24
|
+
retrieveTransfer: (transferId: string) => Promise<Stripe.Response<Stripe.Transfer>>
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{config}from"@stacksjs/config";import{stripe}from"../drivers/stripe";import{freshIdempotencyKey}from"../idempotency";import{requireAccountId}from"./account";function defaultCurrency(){const cfg=config||{};return(cfg.payment?.currency||cfg.billing?.currency||process.env.STRIPE_CURRENCY||"usd").toLowerCase()}export const manageTransfer=(()=>{async function createTransfer(options){requireAccountId(options?.destination,"createTransfer");if(!Number.isFinite(options.amount)||options.amount<=0)throw Error("[payments/connect] createTransfer requires a positive amount in minor units");const params={amount:Math.floor(options.amount),currency:(options.currency??defaultCurrency()).toLowerCase(),destination:options.destination,...options.transferGroup?{transfer_group:options.transferGroup}:{},...options.sourceTransaction?{source_transaction:options.sourceTransaction}:{},...options.description?{description:options.description}:{},...options.metadata?{metadata:options.metadata}:{}};return await stripe.transfers.create(params,{idempotencyKey:freshIdempotencyKey("connect.transfer.create",options.destination,options.amount)})}async function reverseTransfer(transferId,amount){if(!transferId||typeof transferId!=="string")throw Error("[payments/connect] reverseTransfer requires a transfer id");if(amount!=null&&(!Number.isFinite(amount)||amount<=0))throw Error("[payments/connect] reverseTransfer amount must be a positive number of minor units");const params=amount==null?{}:{amount:Math.floor(amount)};return await stripe.transfers.createReversal(transferId,params,{idempotencyKey:`stacks:connect.transfer.reverse:${transferId}:${amount??"full"}:v1`})}async function listTransfers(params={}){return await stripe.transfers.list(params)}async function retrieveTransfer(transferId){if(!transferId||typeof transferId!=="string")throw Error("[payments/connect] retrieveTransfer requires a transfer id");return await stripe.transfers.retrieve(transferId)}return{createTransfer,reverseTransfer,listTransfers,retrieveTransfer}})();
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { WebhookHandler } from '../billable/webhook';
|
|
2
|
+
import type Stripe from 'stripe';
|
|
3
|
+
/**
|
|
4
|
+
* Connect webhooks arrive on their own endpoint, with their own signing secret
|
|
5
|
+
* (`config.payment.connect.webhookSecret`), and every event carries
|
|
6
|
+
* `event.account` naming the connected account it is about. Verifying them
|
|
7
|
+
* against the account webhook secret fails every signature, and reading them
|
|
8
|
+
* without `event.account` loses the only field that says whose money moved.
|
|
9
|
+
*
|
|
10
|
+
* Dispatch reuses the account-webhook registry, so `processWebhook` handles
|
|
11
|
+
* both endpoints - only the secret differs at the route.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Account lifecycle. `updated` is the one that matters: it fires when a
|
|
15
|
+
* merchant finishes onboarding, when Stripe needs more documents, and when an
|
|
16
|
+
* account is restricted. Treat it as "re-read `accountStatus` and store it"
|
|
17
|
+
* rather than trying to diff the payload.
|
|
18
|
+
*/
|
|
19
|
+
export declare function onAccount(handlers: {
|
|
20
|
+
updated?: WebhookHandler
|
|
21
|
+
deauthorized?: WebhookHandler
|
|
22
|
+
}): void;
|
|
23
|
+
/**
|
|
24
|
+
* Payout lifecycle for connected accounts. `failed` is the one worth alerting
|
|
25
|
+
* on - a merchant whose bank details are wrong keeps accruing balance while
|
|
26
|
+
* believing they are being paid.
|
|
27
|
+
*/
|
|
28
|
+
export declare function onPayout(handlers: {
|
|
29
|
+
created?: WebhookHandler
|
|
30
|
+
paid?: WebhookHandler
|
|
31
|
+
failed?: WebhookHandler
|
|
32
|
+
}): void;
|
|
33
|
+
/**
|
|
34
|
+
* The connected account an event is about, or null when it is a plain
|
|
35
|
+
* platform-account event.
|
|
36
|
+
*
|
|
37
|
+
* Every Connect handler needs this to know which merchant to update, and it is
|
|
38
|
+
* easy to miss because it sits on the event rather than in `data.object`.
|
|
39
|
+
*/
|
|
40
|
+
export declare function getConnectedAccountId(event: Stripe.Event): string | null;
|
|
41
|
+
export declare function getAccount(event: Stripe.Event): Stripe.Account | null;
|
|
42
|
+
export declare function getPayout(event: Stripe.Event): Stripe.Payout | null;
|
|
43
|
+
export declare const manageConnectWebhook: {
|
|
44
|
+
onAccount: typeof onAccount;
|
|
45
|
+
onPayout: typeof onPayout;
|
|
46
|
+
getAccount: typeof getAccount;
|
|
47
|
+
getPayout: typeof getPayout;
|
|
48
|
+
getConnectedAccountId: typeof getConnectedAccountId
|
|
49
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{onWebhookEvent}from"../billable/webhook";export function onAccount(handlers){if(handlers.updated)onWebhookEvent("account.updated",handlers.updated);if(handlers.deauthorized)onWebhookEvent("account.application.deauthorized",handlers.deauthorized)}export function onPayout(handlers){if(handlers.created)onWebhookEvent("payout.created",handlers.created);if(handlers.paid)onWebhookEvent("payout.paid",handlers.paid);if(handlers.failed)onWebhookEvent("payout.failed",handlers.failed)}export function getConnectedAccountId(event){const account=event.account;return typeof account==="string"&&account.length>0?account:null}export function getAccount(event){if(event.type.startsWith("account.")&&!event.type.startsWith("account.application."))return event.data.object;return null}export function getPayout(event){if(event.type.startsWith("payout."))return event.data.object;return null}export const manageConnectWebhook={onAccount,onPayout,getAccount,getPayout,getConnectedAccountId};
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export * from './payment';
|
|
|
8
8
|
export { default as Payment } from './payment';
|
|
9
9
|
// Billable modules
|
|
10
10
|
export * from './billable/index';
|
|
11
|
+
// Stripe Connect (marketplaces)
|
|
12
|
+
export * from './connect/index';
|
|
11
13
|
// Stripe driver and SDK
|
|
12
14
|
export * from './drivers/stripe';
|
|
13
15
|
// Idempotency-key helpers — passed to every Stripe create/update so
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./payment";export{default as Payment}from"./payment";export*from"./billable";export*from"./drivers/stripe";export{freshIdempotencyKey,stacksIdempotencyKey}from"./idempotency";
|
|
1
|
+
export*from"./payment";export{default as Payment}from"./payment";export*from"./billable";export*from"./connect";export*from"./drivers/stripe";export{freshIdempotencyKey,stacksIdempotencyKey}from"./idempotency";
|
package/dist/payment.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { connect } from './connect/index';
|
|
1
2
|
import { onCharge, onCheckout, onInvoice, onPaymentIntent, onSubscription, processWebhook } from './billable/webhook';
|
|
2
3
|
import { stripe } from './drivers/stripe';
|
|
3
4
|
import type { UserModel } from '@stacksjs/orm';
|
|
@@ -172,6 +173,7 @@ export declare const Payment: {
|
|
|
172
173
|
onCheckout: typeof onCheckout;
|
|
173
174
|
onCharge: typeof onCharge;
|
|
174
175
|
processWebhook: typeof processWebhook;
|
|
176
|
+
connect: typeof connect;
|
|
175
177
|
stripe: typeof stripe;
|
|
176
178
|
customer: unknown;
|
|
177
179
|
subscription: unknown;
|
package/dist/payment.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{stripe}from"./drivers/stripe";import{manageCharge}from"./billable/charge";import{manageCheckout}from"./billable/checkout";import{manageCustomer}from"./billable/customer";import{manageInvoice}from"./billable/invoice";import{managePaymentMethod}from"./billable/payment-method";import{managePrice}from"./billable/price";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";export async function charge(user,amount,paymentMethod,options={}){return manageCharge.charge(user,amount,paymentMethod,options)}export async function createPayment(user,amount,options={}){return manageCharge.createPayment(user,amount,options)}export async function refund(paymentIntentId,amount,options={}){return manageCharge.refund(paymentIntentId,{amount,...options})}export async function checkout(user,lineItems,options={}){return manageCheckout.create(user,{line_items:lineItems,mode:"payment",...options})}export async function subscriptionCheckout(user,priceId,options={}){return manageCheckout.create(user,{line_items:[{price:priceId,quantity:1}],mode:"subscription",...options})}export async function subscribe(user,lookupKey,options={}){return manageSubscription.create(user,"default",lookupKey,options)}export async function cancelSubscription(subscriptionId,immediately=!1){return manageSubscription.cancel(subscriptionId,{prorate:!immediately,invoice_now:immediately})}export async function hasActiveSubscription(user,type="default"){return manageSubscription.isValid(user,type)}export async function changeSubscription(user,newLookupKey,type="default"){return manageSubscription.update(user,type,newLookupKey,{})}export async function getOrCreateCustomer(user,options={}){return manageCustomer.createOrGetStripeUser(user,options)}export async function updateCustomer(user,options){return manageCustomer.updateStripeCustomer(user,options)}export async function deleteCustomer(user){return manageCustomer.deleteStripeUser(user)}export async function addPaymentMethod(user,paymentMethodId){return managePaymentMethod.addPaymentMethod(user,paymentMethodId)}export async function setDefaultPaymentMethod(user,paymentMethodId){return managePaymentMethod.setUserDefaultPayment(user,paymentMethodId)}export async function removePaymentMethod(user,paymentMethodId){return managePaymentMethod.deletePaymentMethod(user,paymentMethodId)}export async function createSetupIntent(user,options={}){return manageSetupIntent.create(user,options)}export async function getInvoices(user){return manageInvoice.list(user)}export async function createInvoice(customerId,options={}){return stripe.invoices.create({customer:customerId,...options})}export async function payInvoice(invoiceId){return stripe.invoices.pay(invoiceId)}export async function createProduct(name,price,options={}){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){return managePrice.retrieveByLookupKey(lookupKey)}export async function listProducts(options={}){return manageProduct.list(options)}export async function createCoupon(options){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={}){return manageCoupon.createPromotionCode({promotion:{type:"coupon",coupon:couponId},code,...options})}export async function validatePromoCode(code){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 const Payment={charge,createPayment,refund,checkout,subscriptionCheckout,subscribe,cancelSubscription,hasActiveSubscription,changeSubscription,getOrCreateCustomer,updateCustomer,deleteCustomer,addPaymentMethod,setDefaultPaymentMethod,removePaymentMethod,createSetupIntent,getInvoices,createInvoice,payInvoice,createProduct,getPrice,listProducts,createCoupon,createPromoCode,validatePromoCode,formatAmount,toCents,toDollars,webhook:manageWebhook,onPaymentIntent,onSubscription,onInvoice,onCheckout,onCharge,processWebhook,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{manageCharge}from"./billable/charge";import{manageCheckout}from"./billable/checkout";import{manageCustomer}from"./billable/customer";import{manageInvoice}from"./billable/invoice";import{managePaymentMethod}from"./billable/payment-method";import{managePrice}from"./billable/price";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";export async function charge(user,amount,paymentMethod,options={}){return manageCharge.charge(user,amount,paymentMethod,options)}export async function createPayment(user,amount,options={}){return manageCharge.createPayment(user,amount,options)}export async function refund(paymentIntentId,amount,options={}){return manageCharge.refund(paymentIntentId,{amount,...options})}export async function checkout(user,lineItems,options={}){return manageCheckout.create(user,{line_items:lineItems,mode:"payment",...options})}export async function subscriptionCheckout(user,priceId,options={}){return manageCheckout.create(user,{line_items:[{price:priceId,quantity:1}],mode:"subscription",...options})}export async function subscribe(user,lookupKey,options={}){return manageSubscription.create(user,"default",lookupKey,options)}export async function cancelSubscription(subscriptionId,immediately=!1){return manageSubscription.cancel(subscriptionId,{prorate:!immediately,invoice_now:immediately})}export async function hasActiveSubscription(user,type="default"){return manageSubscription.isValid(user,type)}export async function changeSubscription(user,newLookupKey,type="default"){return manageSubscription.update(user,type,newLookupKey,{})}export async function getOrCreateCustomer(user,options={}){return manageCustomer.createOrGetStripeUser(user,options)}export async function updateCustomer(user,options){return manageCustomer.updateStripeCustomer(user,options)}export async function deleteCustomer(user){return manageCustomer.deleteStripeUser(user)}export async function addPaymentMethod(user,paymentMethodId){return managePaymentMethod.addPaymentMethod(user,paymentMethodId)}export async function setDefaultPaymentMethod(user,paymentMethodId){return managePaymentMethod.setUserDefaultPayment(user,paymentMethodId)}export async function removePaymentMethod(user,paymentMethodId){return managePaymentMethod.deletePaymentMethod(user,paymentMethodId)}export async function createSetupIntent(user,options={}){return manageSetupIntent.create(user,options)}export async function getInvoices(user){return manageInvoice.list(user)}export async function createInvoice(customerId,options={}){return stripe.invoices.create({customer:customerId,...options})}export async function payInvoice(invoiceId){return stripe.invoices.pay(invoiceId)}export async function createProduct(name,price,options={}){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){return managePrice.retrieveByLookupKey(lookupKey)}export async function listProducts(options={}){return manageProduct.list(options)}export async function createCoupon(options){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={}){return manageCoupon.createPromotionCode({promotion:{type:"coupon",coupon:couponId},code,...options})}export async function validatePromoCode(code){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 const Payment={charge,createPayment,refund,checkout,subscriptionCheckout,subscribe,cancelSubscription,hasActiveSubscription,changeSubscription,getOrCreateCustomer,updateCustomer,deleteCustomer,addPaymentMethod,setDefaultPaymentMethod,removePaymentMethod,createSetupIntent,getInvoices,createInvoice,payInvoice,createProduct,getPrice,listProducts,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;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/payments",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.73.1",
|
|
6
6
|
"description": "The Stacks payments package. Currently supporting Stripe.",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -72,9 +72,9 @@
|
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
-
"@stacksjs/config": "0.
|
|
75
|
+
"@stacksjs/config": "0.73.1",
|
|
76
76
|
"better-dx": "^0.2.24",
|
|
77
|
-
"@stacksjs/utils": "0.
|
|
77
|
+
"@stacksjs/utils": "0.73.1",
|
|
78
78
|
"@stripe/stripe-js": "^9.10.0",
|
|
79
79
|
"stripe": "22.3.2"
|
|
80
80
|
}
|