mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 13:20:31 +00:00
feat: clean up the stripe payment integration
This commit is contained in:
3064
packages/server/newrelic_agent.log
Normal file
3064
packages/server/newrelic_agent.log
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,55 +0,0 @@
|
||||
import { StripePaymentService } from '@/services/StripePayment/StripePaymentService';
|
||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { CreateStripeAccountDTO } from './types';
|
||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||
import events from '@/subscribers/events';
|
||||
|
||||
@Service()
|
||||
export class CreateStripeAccountService {
|
||||
@Inject()
|
||||
private stripePaymentService: StripePaymentService;
|
||||
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
@Inject()
|
||||
private eventPublisher: EventPublisher;
|
||||
|
||||
/**
|
||||
* Creates a new Stripe account.
|
||||
* @param {number} tenantId
|
||||
* @param {CreateStripeAccountDTO} stripeAccountDTO
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
async createStripeAccount(
|
||||
tenantId: number,
|
||||
stripeAccountDTO?: CreateStripeAccountDTO
|
||||
): Promise<string> {
|
||||
const { PaymentIntegration } = this.tenancy.models(tenantId);
|
||||
const stripeAccount = await this.stripePaymentService.createAccount();
|
||||
const stripeAccountId = stripeAccount.id;
|
||||
|
||||
const parsedStripeAccountDTO = {
|
||||
...stripeAccountDTO,
|
||||
name: 'Stripe',
|
||||
};
|
||||
// Stores the details of the Stripe account.
|
||||
await PaymentIntegration.query().insert({
|
||||
name: parsedStripeAccountDTO.name,
|
||||
accountId: stripeAccountId,
|
||||
enable: false,
|
||||
service: 'Stripe',
|
||||
});
|
||||
// Triggers `onStripeIntegrationAccountCreated` event.
|
||||
await this.eventPublisher.emitAsync(
|
||||
events.stripeIntegration.onAccountCreated,
|
||||
{
|
||||
tenantId,
|
||||
stripeAccountDTO,
|
||||
stripeAccountId,
|
||||
}
|
||||
);
|
||||
return stripeAccountId;
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
import { Service, Inject } from 'typedi';
|
||||
import { CreateStripeAccountService } from './CreateStripeAccountService';
|
||||
import { CreateStripeAccountDTO } from './types';
|
||||
@Service()
|
||||
export class StripeIntegrationApplication {
|
||||
@Inject()
|
||||
private createStripeAccountService: CreateStripeAccountService;
|
||||
|
||||
/**
|
||||
* Creates a new Stripe account for the tenant.
|
||||
* @param {TenantContext} tenantContext - The tenant context.
|
||||
* @param {string} label - The label for the Stripe account.
|
||||
* @returns {Promise<string>} The ID of the created Stripe account.
|
||||
*/
|
||||
public async createStripeAccount(
|
||||
tenantId: number,
|
||||
stripeAccountDTO?: CreateStripeAccountDTO
|
||||
): Promise<string> {
|
||||
return this.createStripeAccountService.createStripeAccount(
|
||||
tenantId,
|
||||
stripeAccountDTO
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/**
|
||||
* @param { import("knex").Knex } knex
|
||||
* @returns { Promise<void> }
|
||||
*/
|
||||
exports.up = function (knex) {
|
||||
return knex.schema.table('sales_invoices', (table) => {
|
||||
table.string('stripe_plink_id').nullable();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param { import("knex").Knex } knex
|
||||
* @returns { Promise<void> }
|
||||
*/
|
||||
exports.down = function (knex) {
|
||||
return knex.schema.table('sales_invoices', (table) => {
|
||||
table.dropColumn('stripe_plink_id');
|
||||
});
|
||||
};
|
||||
@@ -117,9 +117,7 @@ import { DisconnectPlaidItemOnAccountDeleted } from '@/services/Banking/BankAcco
|
||||
import { LoopsEventsSubscriber } from '@/services/Loops/LoopsEventsSubscriber';
|
||||
import { DeleteUncategorizedTransactionsOnAccountDeleting } from '@/services/Banking/BankAccounts/events/DeleteUncategorizedTransactionsOnAccountDeleting';
|
||||
import { SeedInitialDemoAccountDataOnOrgBuild } from '@/services/OneClickDemo/events/SeedInitialDemoAccountData';
|
||||
import { TriggerInvalidateCacheOnSubscriptionChange } from '@/services/Subscription/events/TriggerInvalidateCacheOnSubscriptionChange';
|
||||
import { EventsTrackerListeners } from '@/services/EventsTracker/events/events';
|
||||
import { CreatePaymentLinkOnInvoiceCreated } from '@/services/StripePayment/events/CreatePaymentLinkOnInvoiceCreated';
|
||||
import { InvoicePaymentIntegrationSubscriber } from '@/services/Sales/Invoices/subscribers/InvoicePaymentIntegrationSubscriber';
|
||||
import { StripeWebhooksSubscriber } from '@/services/StripePayment/events/StripeWebhooksSubscriber';
|
||||
|
||||
@@ -255,7 +253,6 @@ export const susbcribers = () => {
|
||||
// Subscription
|
||||
SubscribeFreeOnSignupCommunity,
|
||||
SendVerfiyMailOnSignUp,
|
||||
TriggerInvalidateCacheOnSubscriptionChange,
|
||||
|
||||
// Attachments
|
||||
AttachmentsOnSaleInvoiceCreated,
|
||||
@@ -295,7 +292,6 @@ export const susbcribers = () => {
|
||||
SeedInitialDemoAccountDataOnOrgBuild,
|
||||
|
||||
// Stripe Payment
|
||||
CreatePaymentLinkOnInvoiceCreated,
|
||||
InvoicePaymentIntegrationSubscriber,
|
||||
StripeWebhooksSubscriber,
|
||||
|
||||
|
||||
@@ -47,8 +47,11 @@ export class CreateInvoiceCheckoutSession {
|
||||
const stripeAccountId = stripePaymentMethod?.paymentIntegration?.accountId;
|
||||
const paymentIntegrationId = stripePaymentMethod?.paymentIntegration?.id;
|
||||
|
||||
const session = await this.createCheckoutSession(invoice, stripeAccountId);
|
||||
|
||||
// Creates checkout session for the given invoice.
|
||||
const session = await this.createCheckoutSession(invoice, stripeAccountId, {
|
||||
tenantId,
|
||||
paymentLinkId: paymentLink.id,
|
||||
});
|
||||
return {
|
||||
sessionId: session.id,
|
||||
publishableKey: config.stripePayment.publishableKey,
|
||||
@@ -64,7 +67,8 @@ export class CreateInvoiceCheckoutSession {
|
||||
*/
|
||||
private createCheckoutSession(
|
||||
invoice: ISaleInvoice,
|
||||
stripeAccountId: string
|
||||
stripeAccountId: string,
|
||||
metadata?: Record<string, any>
|
||||
) {
|
||||
return this.stripePaymentService.stripe.checkout.sessions.create(
|
||||
{
|
||||
@@ -84,11 +88,13 @@ export class CreateInvoiceCheckoutSession {
|
||||
mode: 'payment',
|
||||
success_url: `${origin}/success`,
|
||||
cancel_url: `${origin}/cancel`,
|
||||
metadata: {
|
||||
saleInvoiceId: invoice.id,
|
||||
resource: 'SaleInvoice',
|
||||
...metadata,
|
||||
},
|
||||
},
|
||||
{
|
||||
stripeAccount: stripeAccountId,
|
||||
// stripeAccount: 'acct_1Q0nE7ESY7RfeebE',
|
||||
}
|
||||
{ stripeAccount: stripeAccountId }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { StripePaymentService } from '@/services/StripePayment/StripePaymentService';
|
||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { snakeCase } from 'lodash';
|
||||
import { StripePaymentService } from './StripePaymentService';
|
||||
import HasTenancyService from '../Tenancy/TenancyService';
|
||||
|
||||
interface CreateStripeAccountDTO {
|
||||
name: string;
|
||||
}
|
||||
import { CreateStripeAccountDTO } from './types';
|
||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||
import events from '@/subscribers/events';
|
||||
|
||||
@Service()
|
||||
export class CreateStripeAccountService {
|
||||
@@ -15,29 +13,43 @@ export class CreateStripeAccountService {
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
@Inject()
|
||||
private eventPublisher: EventPublisher;
|
||||
|
||||
/**
|
||||
* Creates a new Stripe account for Bigcapital.
|
||||
* @param {number} tenantId
|
||||
* @param {number} createStripeAccountDTO
|
||||
* Creates a new Stripe account.
|
||||
* @param {number} tenantId
|
||||
* @param {CreateStripeAccountDTO} stripeAccountDTO
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
async createAccount(
|
||||
async createStripeAccount(
|
||||
tenantId: number,
|
||||
createStripeAccountDTO: CreateStripeAccountDTO
|
||||
) {
|
||||
stripeAccountDTO?: CreateStripeAccountDTO
|
||||
): Promise<string> {
|
||||
const { PaymentIntegration } = this.tenancy.models(tenantId);
|
||||
const stripeAccount = await this.stripePaymentService.createAccount();
|
||||
const stripeAccountId = stripeAccount.id;
|
||||
|
||||
// Creates a new Stripe account.
|
||||
const account = await this.stripePaymentService.createAccount();
|
||||
|
||||
const slug = snakeCase(createStripeAccountDTO.name);
|
||||
|
||||
// Store the Stripe account on tenant store.
|
||||
const parsedStripeAccountDTO = {
|
||||
...stripeAccountDTO,
|
||||
name: 'Stripe',
|
||||
};
|
||||
// Stores the details of the Stripe account.
|
||||
await PaymentIntegration.query().insert({
|
||||
service: 'stripe',
|
||||
name: createStripeAccountDTO.name,
|
||||
slug,
|
||||
enable: true,
|
||||
accountId: account.id,
|
||||
name: parsedStripeAccountDTO.name,
|
||||
accountId: stripeAccountId,
|
||||
enable: false,
|
||||
service: 'Stripe',
|
||||
});
|
||||
// Triggers `onStripeIntegrationAccountCreated` event.
|
||||
await this.eventPublisher.emitAsync(
|
||||
events.stripeIntegration.onAccountCreated,
|
||||
{
|
||||
tenantId,
|
||||
stripeAccountDTO,
|
||||
stripeAccountId,
|
||||
}
|
||||
);
|
||||
return stripeAccountId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
import { Knex } from 'knex';
|
||||
import { Inject, Service } from 'typedi';
|
||||
import HasTenancyService from '../Tenancy/TenancyService';
|
||||
import { StripePaymentService } from './StripePaymentService';
|
||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||
import events from '@/subscribers/events';
|
||||
|
||||
@Service()
|
||||
export class DeleteStripePaymentLinkInvoice {
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
@Inject()
|
||||
private stripePayment: StripePaymentService;
|
||||
|
||||
@Inject()
|
||||
private eventPublisher: EventPublisher;
|
||||
|
||||
/**
|
||||
* Deletes the Stripe payment link associates to the given sale invoice.
|
||||
* @param {number} tenantId -
|
||||
* @param {number} invoiceId -
|
||||
* @param {Knex.Transaction} knex -
|
||||
*/
|
||||
async deleteInvoicePaymentLink(
|
||||
tenantId: number,
|
||||
invoiceId: number,
|
||||
trx?: Knex.Transaction
|
||||
): Promise<void> {
|
||||
const { SaleInvoice } = this.tenancy.models(tenantId);
|
||||
|
||||
const invoice = await SaleInvoice.query(trx)
|
||||
.findById(invoiceId)
|
||||
.withGraphFetched('paymentMethods.paymentIntegration')
|
||||
.throwIfNotFound();
|
||||
|
||||
// It will be only one Stripe payment method associated to the invoice.
|
||||
const stripePaymentMethod = invoice.paymentMethods?.find(
|
||||
(method) => method.paymentIntegration?.service === 'Stripe'
|
||||
);
|
||||
const stripeAccountId = stripePaymentMethod?.paymentIntegration?.accountId;
|
||||
const paymentIntegrationId = stripePaymentMethod?.paymentIntegration?.id;
|
||||
|
||||
if (invoice.stripePlinkId && stripeAccountId) {
|
||||
const stripeAcocunt = { stripeAccount: stripeAccountId };
|
||||
const stripePlinkId = invoice.stripePlinkId;
|
||||
|
||||
await this.stripePayment.stripe.paymentLinks.update(
|
||||
stripePlinkId,
|
||||
{ active: false },
|
||||
stripeAcocunt
|
||||
);
|
||||
// Triggers `onStripePaymentLinkInactivated` event.
|
||||
await this.eventPublisher.emitAsync(
|
||||
events.stripeIntegration.onPaymentLinkInactivated,
|
||||
{
|
||||
tenantId,
|
||||
saleInvoiceId: invoiceId,
|
||||
paymentIntegrationId,
|
||||
stripePlinkId,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { ISaleInvoice } from '@/interfaces';
|
||||
import { StripePaymentService } from './StripePaymentService';
|
||||
import HasTenancyService from '../Tenancy/TenancyService';
|
||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||
import { StripePaymentLinkCreatedEventPayload } from '@/interfaces/StripePayment';
|
||||
import { STRIPE_PAYMENT_LINK_REDIRECT } from './constants';
|
||||
import events from '@/subscribers/events';
|
||||
|
||||
@Service()
|
||||
export class SaleInvoiceStripePaymentLink {
|
||||
@Inject()
|
||||
private stripePayment: StripePaymentService;
|
||||
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
@Inject()
|
||||
private eventPublisher: EventPublisher;
|
||||
|
||||
/**
|
||||
* Creates a Stripe payment link for the given sale invoice.
|
||||
* @param {number} tenantId - Tenant id.
|
||||
* @param {number} stripeIntegrationId - Stripe integration id.
|
||||
* @param {ISaleInvoice} saleInvoice - Sale invoice id.
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
async createPaymentLink(
|
||||
tenantId: number,
|
||||
stripeIntegrationId: number,
|
||||
invoiceId: number
|
||||
) {
|
||||
const { SaleInvoice, PaymentIntegration } = this.tenancy.models(tenantId);
|
||||
|
||||
const stripeIntegration = await PaymentIntegration.query()
|
||||
.findById(stripeIntegrationId)
|
||||
.throwIfNotFound();
|
||||
const stripeAccountId = stripeIntegration.accountId;
|
||||
|
||||
const invoice = await SaleInvoice.query()
|
||||
.findById(invoiceId)
|
||||
.throwIfNotFound();
|
||||
|
||||
// Creates Stripe price.
|
||||
const price = await this.createStripePrice(invoice, stripeAccountId);
|
||||
|
||||
// Creates Stripe payment link.
|
||||
const paymentLink = await this.createStripePaymentLink(
|
||||
price.id,
|
||||
invoice,
|
||||
stripeAccountId,
|
||||
{ tenantId }
|
||||
);
|
||||
// Associate the payment link id to the invoice.
|
||||
await this.updateInvoiceWithPaymentLink(
|
||||
tenantId,
|
||||
invoiceId,
|
||||
paymentLink.id
|
||||
);
|
||||
// Triggers `onStripePaymentLinkCreated` event.
|
||||
await this.eventPublisher.emitAsync(
|
||||
events.stripeIntegration.onPaymentLinkCreated,
|
||||
{
|
||||
tenantId,
|
||||
stripeIntegrationId,
|
||||
saleInvoiceId: invoiceId,
|
||||
paymentLinkId: paymentLink.id,
|
||||
} as StripePaymentLinkCreatedEventPayload
|
||||
);
|
||||
return paymentLink.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Stripe price for the invoice.
|
||||
* @param {ISaleInvoice} invoice - Sale invoice.
|
||||
* @param {string} stripeAccountId - Stripe account id.
|
||||
* @returns {Promise<Stripe.Price>}
|
||||
*/
|
||||
private async createStripePrice(
|
||||
invoice: ISaleInvoice,
|
||||
stripeAccountId: string
|
||||
) {
|
||||
return this.stripePayment.stripe.prices.create(
|
||||
{
|
||||
unit_amount: invoice.total * 100,
|
||||
currency: 'usd',
|
||||
product_data: {
|
||||
name: invoice.invoiceNo,
|
||||
},
|
||||
},
|
||||
{ stripeAccount: stripeAccountId }
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Stripe payment link.
|
||||
* @param {string} priceId - Stripe price id.
|
||||
* @param {ISaleInvoice} invoice - Sale invoice.
|
||||
* @param {number} tenantId - Tenant id.
|
||||
* @param {string} stripeAccountId - Stripe account id.
|
||||
* @returns {Promise<Stripe.PaymentLink>}
|
||||
*/
|
||||
private async createStripePaymentLink(
|
||||
priceId: string,
|
||||
invoice: ISaleInvoice,
|
||||
stripeAccountId: string,
|
||||
metadata: Record<string, any> = {}
|
||||
) {
|
||||
const paymentLinkInfo = {
|
||||
line_items: [{ price: priceId, quantity: 1 }],
|
||||
after_completion: {
|
||||
type: 'redirect',
|
||||
redirect: {
|
||||
url: STRIPE_PAYMENT_LINK_REDIRECT,
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
saleInvoiceId: invoice.id,
|
||||
resource: 'SaleInvoice',
|
||||
...metadata,
|
||||
},
|
||||
};
|
||||
return this.stripePayment.stripe.paymentLinks.create(paymentLinkInfo, {
|
||||
stripeAccount: stripeAccountId,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the sale invoice with the Stripe payment link id.
|
||||
* @param {number} tenantId - Tenant id.
|
||||
* @param {number} invoiceId - Sale invoice id.
|
||||
* @param {string} paymentLinkId - Stripe payment link id.
|
||||
*/
|
||||
private async updateInvoiceWithPaymentLink(
|
||||
tenantId: number,
|
||||
invoiceId: number,
|
||||
paymentLinkId: string
|
||||
) {
|
||||
const { SaleInvoice } = this.tenancy.models(tenantId);
|
||||
|
||||
await SaleInvoice.query().findById(invoiceId).patch({
|
||||
stripePlinkId: paymentLinkId,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,13 @@
|
||||
import { Knex } from 'knex';
|
||||
import { Inject } from 'typedi';
|
||||
import { CreateStripeAccountService } from '@/api/controllers/StripeIntegration/CreateStripeAccountService';
|
||||
import { CreateStripeAccountDTO } from '@/api/controllers/StripeIntegration/types';
|
||||
import { SaleInvoiceStripePaymentLink } from './SaleInvoiceStripePaymentLink';
|
||||
import { DeleteStripePaymentLinkInvoice } from './DeleteStripePaymentLinkInvoice';
|
||||
import { CreateInvoiceCheckoutSession } from './CreateInvoiceCheckoutSession';
|
||||
import { StripeInvoiceCheckoutSessionPOJO } from '@/interfaces/StripePayment';
|
||||
import { CreateStripeAccountService } from './CreateStripeAccountService';
|
||||
import { CreateStripeAccountDTO } from './types';
|
||||
|
||||
export class StripePaymentApplication {
|
||||
@Inject()
|
||||
private createStripeAccountService: CreateStripeAccountService;
|
||||
|
||||
@Inject()
|
||||
private saleInvoiceStripePaymentLinkService: SaleInvoiceStripePaymentLink;
|
||||
|
||||
@Inject()
|
||||
private deleteStripePaymentLinkInvoice: DeleteStripePaymentLinkInvoice;
|
||||
|
||||
@Inject()
|
||||
private createSaleInvoiceCheckoutSessionService: CreateInvoiceCheckoutSession;
|
||||
|
||||
@@ -35,25 +26,6 @@ export class StripePaymentApplication {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Stripe payment link for the given sale invoice.
|
||||
* @param {number} tenantId - Tenant id.
|
||||
* @param {number} stripeIntegrationId - Stripe integration id.
|
||||
* @param {ISaleInvoice} saleInvoice - Sale invoice id.
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
public createSaleInvoicePaymentLink(
|
||||
tenantId: number,
|
||||
stripeIntegrationId: number,
|
||||
invoiceId: number
|
||||
) {
|
||||
return this.saleInvoiceStripePaymentLinkService.createPaymentLink(
|
||||
tenantId,
|
||||
stripeIntegrationId,
|
||||
invoiceId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the Stripe checkout session from the given sale invoice.
|
||||
* @param {number} tenantId
|
||||
@@ -69,22 +41,4 @@ export class StripePaymentApplication {
|
||||
paymentLinkId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the Stripe payment link associated with the given sale invoice.
|
||||
* @param {number} tenantId - Tenant id.
|
||||
* @param {number} invoiceId - Sale invoice id.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
public deleteInvoicePaymentLink(
|
||||
tenantId: number,
|
||||
invoiceId: number,
|
||||
trx?: Knex.Transaction
|
||||
): Promise<void> {
|
||||
return this.deleteStripePaymentLinkInvoice.deleteInvoicePaymentLink(
|
||||
tenantId,
|
||||
invoiceId,
|
||||
trx
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ export class StripePaymentService {
|
||||
|
||||
constructor() {
|
||||
this.stripe = new stripe(config.stripePayment.secretKey, {
|
||||
apiVersion: '2023-10-16',
|
||||
apiVersion: '2024-06-20',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
||||
import {
|
||||
PaymentIntegrationTransactionLinkDeleteEventPayload,
|
||||
PaymentIntegrationTransactionLinkEventPayload,
|
||||
} 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.paymentIntegrationLink.onPaymentIntegrationLink,
|
||||
this.handleCreatePaymentLinkOnIntegrationLink
|
||||
);
|
||||
bus.subscribe(
|
||||
events.paymentIntegrationLink.onPaymentIntegrationDeleteLink,
|
||||
this.handleDeletePaymentLinkOnIntegrationLinkDelete
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the Plaid item transactions
|
||||
* @param {IPlaidItemCreatedEventPayload} payload - Event payload.
|
||||
*/
|
||||
private handleCreatePaymentLinkOnIntegrationLink = async ({
|
||||
tenantId,
|
||||
paymentIntegrationId,
|
||||
referenceId,
|
||||
referenceType,
|
||||
trx,
|
||||
}: PaymentIntegrationTransactionLinkEventPayload) => {
|
||||
// Can't continue if the link request is not coming from the invoice transaction.
|
||||
if ('SaleInvoice' !== referenceType) {
|
||||
return;
|
||||
}
|
||||
runAfterTransaction(trx, async () => {
|
||||
await this.invoiceStripePaymentLink.createPaymentLink(
|
||||
tenantId,
|
||||
paymentIntegrationId,
|
||||
referenceId
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes the Stripe payment link once the associated invoice deleted.
|
||||
* @param {ISaleInvoiceDeletedPayload}
|
||||
*/
|
||||
private handleDeletePaymentLinkOnIntegrationLinkDelete = async ({
|
||||
oldSaleInvoiceId,
|
||||
tenantId,
|
||||
trx,
|
||||
}: PaymentIntegrationTransactionLinkDeleteEventPayload) => {
|
||||
await this.deleteStripePaymentLinkInvoice.deleteInvoicePaymentLink(
|
||||
tenantId,
|
||||
oldSaleInvoiceId,
|
||||
trx
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
.companyLogoWrap {
|
||||
height: 50px;
|
||||
width :50px;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import React, { createContext, useContext, ReactNode } from 'react';
|
||||
import {
|
||||
GetSharableLinkMetaResponse,
|
||||
useGetSharableLinkMeta,
|
||||
GetInvoicePaymentLinkResponse,
|
||||
useGetInvoicePaymentLink,
|
||||
} from '@/hooks/query/payment-link';
|
||||
import { Spinner } from '@blueprintjs/core';
|
||||
|
||||
interface PaymentPortalContextType {
|
||||
linkId: string;
|
||||
sharableLinkMeta: GetSharableLinkMetaResponse | undefined;
|
||||
sharableLinkMeta: GetInvoicePaymentLinkResponse | undefined;
|
||||
isSharableLinkMetaLoading: boolean;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ export const PaymentPortalBoot: React.FC<PaymentPortalBootProps> = ({
|
||||
children,
|
||||
}) => {
|
||||
const { data: sharableLinkMeta, isLoading: isSharableLinkMetaLoading } =
|
||||
useGetSharableLinkMeta(linkId);
|
||||
useGetInvoicePaymentLink(linkId);
|
||||
|
||||
const value = {
|
||||
linkId,
|
||||
|
||||
@@ -10,17 +10,17 @@ import {
|
||||
import useApiRequest from '../useRequest';
|
||||
import { transformToCamelCase, transfromToSnakeCase } from '@/utils';
|
||||
|
||||
// Create Payment Link
|
||||
// ------------------------------------
|
||||
interface CreatePaymentLinkValues {
|
||||
publicity: string;
|
||||
transactionType: string;
|
||||
transactionId: number | string;
|
||||
expiryDate: string;
|
||||
}
|
||||
|
||||
interface CreatePaymentLinkResponse {
|
||||
link: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new payment link.
|
||||
* @param {UseMutationOptions<CreatePaymentLinkResponse, Error, CreatePaymentLinkValues>} options
|
||||
@@ -50,7 +50,10 @@ export function useCreatePaymentLink(
|
||||
);
|
||||
}
|
||||
|
||||
export interface GetSharableLinkMetaResponse {
|
||||
|
||||
// Get Invoice Payment Link
|
||||
// -----------------------------------------
|
||||
export interface GetInvoicePaymentLinkResponse {
|
||||
dueAmount: number;
|
||||
dueAmountFormatted: string;
|
||||
dueDate: string;
|
||||
@@ -80,20 +83,19 @@ export interface GetSharableLinkMetaResponse {
|
||||
totalFormatted: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the sharable link metadata for a given link ID.
|
||||
* Fetches the sharable invoice link metadata for a given link ID.
|
||||
* @param {string} linkId - The ID of the link to fetch metadata for.
|
||||
* @param {UseQueryOptions<GetSharableLinkMetaResponse, Error>} options - Optional query options.
|
||||
* @returns {UseQueryResult<GetSharableLinkMetaResponse, Error>} The query result.
|
||||
* @param {UseQueryOptions<GetInvoicePaymentLinkResponse, Error>} options - Optional query options.
|
||||
* @returns {UseQueryResult<GetInvoicePaymentLinkResponse, Error>} The query result.
|
||||
*/
|
||||
export function useGetSharableLinkMeta(
|
||||
export function useGetInvoicePaymentLink(
|
||||
linkId: string,
|
||||
options?: UseQueryOptions<GetSharableLinkMetaResponse, Error>,
|
||||
): UseQueryResult<GetSharableLinkMetaResponse, Error> {
|
||||
options?: UseQueryOptions<GetInvoicePaymentLinkResponse, Error>,
|
||||
): UseQueryResult<GetInvoicePaymentLinkResponse, Error> {
|
||||
const apiRequest = useApiRequest();
|
||||
|
||||
return useQuery<GetSharableLinkMetaResponse, Error>(
|
||||
return useQuery<GetInvoicePaymentLinkResponse, Error>(
|
||||
['sharable-link-meta', linkId],
|
||||
() =>
|
||||
apiRequest
|
||||
|
||||
@@ -5,10 +5,13 @@ import { transformToCamelCase } from '@/utils';
|
||||
|
||||
const PaymentServicesQueryKey = 'PaymentServices';
|
||||
|
||||
export interface GetPaymentServicesResponse {
|
||||
|
||||
}
|
||||
export interface GetPaymentServicesResponse {}
|
||||
|
||||
/**
|
||||
* Retrieves the integrated payment services.
|
||||
* @param {UseQueryOptions<GetPaymentServicesResponse, Error>} options
|
||||
* @returns {UseQueryResult<GetPaymentServicesResponse, Error>}
|
||||
*/
|
||||
export const useGetPaymentServices = (
|
||||
options?: UseQueryOptions<GetPaymentServicesResponse, Error>,
|
||||
): UseQueryResult<GetPaymentServicesResponse, Error> => {
|
||||
|
||||
@@ -14,6 +14,11 @@ interface AccountSessionResponse {
|
||||
client_secret: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a new Stripe checkout session for the provided link ID.
|
||||
* @param {CreateCheckoutSessionValues} values - The values required to create a checkout session.
|
||||
* @returns {Promise<CreateCheckoutSessionResponse>} The response containing the checkout session details.
|
||||
*/
|
||||
export const useCreateStripeAccountSession = (
|
||||
options?: UseMutationOptions<
|
||||
AccountSessionResponse,
|
||||
|
||||
Reference in New Issue
Block a user