Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions apps/api/src/donations/donations.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -400,12 +400,19 @@ export class DonationsService {
}
}

async getDonationByPaymentIntent(id: string): Promise<{ id: string } | null> {
async getDonationByPaymentIntent(id: string): Promise<{
id: string
targetVault: { campaign: Campaign } | null
} | null> {
return await this.prisma.donation.findFirst({
where: { payment: { extPaymentIntentId: id } },
select: { id: true },
select: {
id: true,
targetVault: { include: { campaign: true } },
},
})
}

async getAffiliateDonationById(donationId: string, affiliateCode: string) {
try {
const donation = await this.prisma.payment.findFirstOrThrow({
Expand Down
14 changes: 9 additions & 5 deletions apps/api/src/stripe/events/stripe-payment.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -449,12 +449,14 @@ describe('StripePaymentService', () => {
secret: stripeSecret,
})

const campaignService = app.get<CampaignService>(CampaignService)
const vaultService = app.get<VaultService>(VaultService)

const mockedCampaignById = jest
.spyOn(campaignService, 'getCampaignById')
.mockImplementation(() => Promise.resolve(mockedCampaign))
const mockedGetDonationByPaymentIntent = jest
.spyOn(donationService, 'getDonationByPaymentIntent')
.mockResolvedValue({
id: 'test-donation-id',
targetVault: { campaign: mockedCampaign },
})

const paymentData = getPaymentDataFromCharge(
mockChargeEventSucceeded.data.object as Stripe.Charge,
Expand Down Expand Up @@ -491,7 +493,9 @@ describe('StripePaymentService', () => {
.send(payloadString)
.expect(201)
.then(() => {
expect(mockedCampaignById).toHaveBeenCalledWith(campaignId) //campaignId from the Stripe Event
expect(mockedGetDonationByPaymentIntent).toHaveBeenCalledWith(
'pi_3MmYVtKApGjVGa9t1BtdkBrz',
)
expect(mockedUpdateDonationPayment).toHaveBeenCalled()
expect(prismaMock.payment.findUnique).toHaveBeenCalled()
expect(prismaMock.payment.create).not.toHaveBeenCalled()
Expand Down
14 changes: 8 additions & 6 deletions apps/api/src/stripe/events/stripe-payment.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
import { PaymentStatus, CampaignState } from '@prisma/client'
import { EmailService } from '../../email/email.service'
import { RefundDonationEmailDto } from '../../email/template.interface'
import { PrismaService } from '../../prisma/prisma.service'
import { StripeService } from '../stripe.service'
import { DonationsService } from '../../donations/donations.service'

Expand Down Expand Up @@ -162,17 +161,20 @@ export class StripePaymentService {
chargePaymentIntent.metadata as StripeMetadata,
)

const metadata: StripeMetadata = chargePaymentIntent.metadata as StripeMetadata
const paymentIntentId = chargePaymentIntent.payment_intent as string

if (!metadata.campaignId) {
Logger.debug('[ handleRefundCreated ] No campaignId in metadata ' + chargePaymentIntent.id)
const donation = await this.donationService.getDonationByPaymentIntent(paymentIntentId)
const campaign = donation?.targetVault?.campaign

if (!campaign) {
Logger.warn(
'[ handleRefundCreated ] No donation/campaign found for payment intent ' + paymentIntentId,
)
return
}

const billingData = getPaymentDataFromCharge(chargePaymentIntent)

const campaign = await this.campaignService.getCampaignById(metadata.campaignId)

await this.donationService.updateDonationPayment(campaign, billingData, PaymentStatus.refund)

if (billingData.billingEmail !== undefined) {
Expand Down
Loading