31 lines
1 KiB
TypeScript
31 lines
1 KiB
TypeScript
import Stripe from 'stripe';
|
|
import { PaymentClient } from '../portal';
|
|
|
|
/**
|
|
* Stripe-backed reloads: creates a PaymentIntent and returns its client
|
|
* secret. The balance is credited only after the payment confirms (webhook
|
|
* step); until then creditedCents is 0 and the intent is pending.
|
|
*/
|
|
export function stripePaymentClient(secretKey: string): PaymentClient {
|
|
const stripe = new Stripe(secretKey);
|
|
return {
|
|
reload: async (customer, amountCents) => {
|
|
const intent = await stripe.paymentIntents.create({
|
|
amount: amountCents,
|
|
currency: 'usd',
|
|
automatic_payment_methods: { enabled: true },
|
|
metadata: { customerId: customer.id },
|
|
});
|
|
return {
|
|
mode: 'stripe',
|
|
creditedCents: 0,
|
|
clientSecret: intent.client_secret ?? undefined,
|
|
};
|
|
},
|
|
};
|
|
}
|
|
|
|
/** True when the key looks usable (not empty / not the setup placeholder). */
|
|
export function hasRealStripeKey(key: string | undefined): key is string {
|
|
return typeof key === 'string' && key.startsWith('sk_');
|
|
}
|