mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 13:20:31 +00:00
feat: wip Stripe connect integration
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { GetSaleInvoice } from '../Sales/Invoices/GetSaleInvoice';
|
||||
import { CreatePaymentReceived } from '../Sales/PaymentReceived/CreatePaymentReceived';
|
||||
|
||||
@Service()
|
||||
export class CreatePaymentReceiveStripePayment {
|
||||
@Inject()
|
||||
private getSaleInvoiceService: GetSaleInvoice;
|
||||
|
||||
@Inject()
|
||||
private createPaymentReceivedService: CreatePaymentReceived;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} tenantId
|
||||
* @param {number} saleInvoiceId
|
||||
* @param {number} paidAmount
|
||||
*/
|
||||
async createPaymentReceived(
|
||||
tenantId: number,
|
||||
saleInvoiceId: number,
|
||||
paidAmount: number
|
||||
) {
|
||||
const invoice = await this.getSaleInvoiceService.getSaleInvoice(
|
||||
tenantId,
|
||||
saleInvoiceId
|
||||
);
|
||||
await this.createPaymentReceivedService.createPaymentReceived(tenantId, {
|
||||
customerId: invoice.customerId,
|
||||
paymentDate: new Date(),
|
||||
amount: paidAmount,
|
||||
depositAccountId: 1002,
|
||||
statement: '',
|
||||
entries: [{ invoiceId: saleInvoiceId, paymentAmount: paidAmount }],
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import HasTenancyService from '../Tenancy/TenancyService';
|
||||
import { StripePaymentService } from './StripePaymentService';
|
||||
import { Knex } from 'knex';
|
||||
|
||||
@Service()
|
||||
export class DeleteStripePaymentLinkInvoice {
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
@Inject()
|
||||
private stripePayment: StripePaymentService;
|
||||
|
||||
/**
|
||||
* Deletes the Stripe payment link associates to the given sale invoice.
|
||||
* @param {number} tenantId
|
||||
* @param {number} invoiceId
|
||||
*/
|
||||
async deletePaymentLink(
|
||||
tenantId: number,
|
||||
invoiceId: number,
|
||||
trx?: Knex.Transaction
|
||||
): Promise<void> {
|
||||
const { SaleInvoice } = this.tenancy.models(tenantId);
|
||||
const invoice = await SaleInvoice.query().findById(invoiceId);
|
||||
|
||||
const stripeAcocunt = { stripeAccount: 'acct_1Px3dSPjeOqFxnPw' };
|
||||
|
||||
if (invoice.stripePlinkId) {
|
||||
await this.stripePayment.stripe.paymentLinks.update(
|
||||
invoice.stripePlinkId,
|
||||
{ active: false },
|
||||
stripeAcocunt
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import { ISaleInvoice } from '@/interfaces';
|
||||
import { StripePaymentService } from './StripePaymentService';
|
||||
import { Inject, Service } from 'typedi';
|
||||
import HasTenancyService from '../Tenancy/TenancyService';
|
||||
import { STRIPE_PAYMENT_LINK_REDIRECT } from './constants';
|
||||
|
||||
@Service()
|
||||
export class SaleInvoiceStripePaymentLink {
|
||||
@Inject()
|
||||
private stripePayment: StripePaymentService;
|
||||
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
/**
|
||||
* Creates a Stripe payment link for the given sale invoice.
|
||||
* @param {number} tenantId
|
||||
* @param {ISaleInvoice} saleInvoice
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
async createPaymentLink(tenantId: number, saleInvoice: ISaleInvoice) {
|
||||
const { SaleInvoice } = this.tenancy.models(tenantId);
|
||||
const saleInvoiceId = saleInvoice.id;
|
||||
|
||||
try {
|
||||
const stripeAcocunt = { stripeAccount: 'acct_1Px3dSPjeOqFxnPw' };
|
||||
const price = await this.stripePayment.stripe.prices.create(
|
||||
{
|
||||
unit_amount: saleInvoice.total * 100,
|
||||
currency: 'usd',
|
||||
product_data: {
|
||||
name: saleInvoice.invoiceNo,
|
||||
},
|
||||
},
|
||||
stripeAcocunt
|
||||
);
|
||||
const paymentLinkInfo = {
|
||||
line_items: [{ price: price.id, quantity: 1 }],
|
||||
after_completion: {
|
||||
type: 'redirect',
|
||||
redirect: {
|
||||
url: STRIPE_PAYMENT_LINK_REDIRECT,
|
||||
},
|
||||
},
|
||||
metadata: { saleInvoiceId, tenantId, resource: 'SaleInvoice' },
|
||||
};
|
||||
const paymentLink = await this.stripePayment.stripe.paymentLinks.create(
|
||||
paymentLinkInfo,
|
||||
stripeAcocunt
|
||||
);
|
||||
await SaleInvoice.query().findById(saleInvoiceId).patch({
|
||||
stripePlinkId: paymentLink.id,
|
||||
});
|
||||
return paymentLink.id;
|
||||
} catch (error) {
|
||||
console.error('Error creating payment link:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import config from '@/config';
|
||||
|
||||
@Service()
|
||||
export class StripePaymentService {
|
||||
private stripe;
|
||||
public stripe;
|
||||
|
||||
constructor() {
|
||||
this.stripe = new stripe(config.stripePayment.secretKey, {
|
||||
@@ -12,7 +12,12 @@ export class StripePaymentService {
|
||||
});
|
||||
}
|
||||
|
||||
public async createAccountSession(accountId: string) {
|
||||
/**
|
||||
*
|
||||
* @param {number} accountId
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
public async createAccountSession(accountId: string): Promise<string> {
|
||||
try {
|
||||
const accountSession = await this.stripe.accountSessions.create({
|
||||
account: accountId,
|
||||
@@ -28,7 +33,7 @@ export class StripePaymentService {
|
||||
}
|
||||
}
|
||||
|
||||
public async createAccount() {
|
||||
public async createAccount(): Promise<string> {
|
||||
try {
|
||||
const account = await this.stripe.accounts.create({});
|
||||
|
||||
|
||||
1
packages/server/src/services/StripePayment/constants.ts
Normal file
1
packages/server/src/services/StripePayment/constants.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const STRIPE_PAYMENT_LINK_REDIRECT = 'https://your_redirect_url.com';
|
||||
@@ -0,0 +1,66 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
||||
import {
|
||||
ISaleInvoiceCreatedPayload,
|
||||
ISaleInvoiceDeletedPayload,
|
||||
} from '@/interfaces';
|
||||
import { SaleInvoiceStripePaymentLink } from '../SaleInvoiceStripePaymentLink';
|
||||
import { runAfterTransaction } from '@/services/UnitOfWork/TransactionsHooks';
|
||||
import events from '@/subscribers/events';
|
||||
import { DeleteStripePaymentLinkInvoice } from '../DeleteStripePaymentLinkInvoice';
|
||||
|
||||
@Service()
|
||||
export class CreatePaymentLinkOnInvoiceCreated extends EventSubscriber {
|
||||
@Inject()
|
||||
private invoiceStripePaymentLink: SaleInvoiceStripePaymentLink;
|
||||
|
||||
@Inject()
|
||||
private deleteStripePaymentLinkInvoice: DeleteStripePaymentLinkInvoice;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.saleInvoice.onCreated,
|
||||
this.handleUpdateTransactionsOnItemCreated
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleInvoice.onDeleted,
|
||||
this.handleDeletePaymentLinkOnInvoiceDeleted
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the Plaid item transactions
|
||||
* @param {IPlaidItemCreatedEventPayload} payload - Event payload.
|
||||
*/
|
||||
private handleUpdateTransactionsOnItemCreated = async ({
|
||||
saleInvoice,
|
||||
saleInvoiceId,
|
||||
tenantId,
|
||||
trx,
|
||||
}: ISaleInvoiceCreatedPayload) => {
|
||||
runAfterTransaction(trx, async () => {
|
||||
await this.invoiceStripePaymentLink.createPaymentLink(
|
||||
tenantId,
|
||||
saleInvoice
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes the Stripe payment link once the associated invoice deleted.
|
||||
* @param {ISaleInvoiceDeletedPayload}
|
||||
*/
|
||||
private handleDeletePaymentLinkOnInvoiceDeleted = async ({
|
||||
saleInvoiceId,
|
||||
tenantId,
|
||||
}: ISaleInvoiceDeletedPayload) => {
|
||||
await this.deleteStripePaymentLinkInvoice.deletePaymentLink(
|
||||
tenantId,
|
||||
saleInvoiceId
|
||||
);
|
||||
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user