payout retry lambda
This commit is contained in:
152
lambdas/payoutRetryProcessor/queries.js
Normal file
152
lambdas/payoutRetryProcessor/queries.js
Normal file
@@ -0,0 +1,152 @@
|
||||
const { db } = require("../shared");
|
||||
|
||||
/**
|
||||
* Get all failed payouts with eligible owners (Stripe enabled).
|
||||
* Matches the query from backend PayoutService.retryFailedPayouts()
|
||||
* @returns {Promise<Array>} Array of failed payouts with owner and item details
|
||||
*/
|
||||
async function getFailedPayoutsWithOwners() {
|
||||
const result = await db.query(
|
||||
`SELECT
|
||||
r.id,
|
||||
r."itemId",
|
||||
r."renterId",
|
||||
r."ownerId",
|
||||
r."startDateTime",
|
||||
r."endDateTime",
|
||||
r."totalAmount",
|
||||
r."payoutAmount",
|
||||
r."platformFee",
|
||||
r."paymentStatus",
|
||||
r."payoutStatus",
|
||||
r.status,
|
||||
r."stripeTransferId",
|
||||
r."createdAt",
|
||||
r."updatedAt",
|
||||
-- Owner fields
|
||||
owner.id AS "owner_id",
|
||||
owner.email AS "owner_email",
|
||||
owner."firstName" AS "owner_firstName",
|
||||
owner."lastName" AS "owner_lastName",
|
||||
owner."stripeConnectedAccountId" AS "owner_stripeConnectedAccountId",
|
||||
owner."stripePayoutsEnabled" AS "owner_stripePayoutsEnabled",
|
||||
-- Item fields
|
||||
item.id AS "item_id",
|
||||
item.name AS "item_name"
|
||||
FROM "Rentals" r
|
||||
INNER JOIN "Users" owner ON r."ownerId" = owner.id
|
||||
INNER JOIN "Items" item ON r."itemId" = item.id
|
||||
WHERE r.status = 'completed'
|
||||
AND r."paymentStatus" = 'paid'
|
||||
AND r."payoutStatus" = 'failed'
|
||||
AND owner."stripeConnectedAccountId" IS NOT NULL
|
||||
AND owner."stripePayoutsEnabled" = true`
|
||||
);
|
||||
|
||||
// Transform flat results into nested structure
|
||||
return result.rows.map((row) => ({
|
||||
id: row.id,
|
||||
itemId: row.itemId,
|
||||
renterId: row.renterId,
|
||||
ownerId: row.ownerId,
|
||||
startDateTime: row.startDateTime,
|
||||
endDateTime: row.endDateTime,
|
||||
totalAmount: parseFloat(row.totalAmount),
|
||||
payoutAmount: parseFloat(row.payoutAmount),
|
||||
platformFee: parseFloat(row.platformFee),
|
||||
paymentStatus: row.paymentStatus,
|
||||
payoutStatus: row.payoutStatus,
|
||||
status: row.status,
|
||||
stripeTransferId: row.stripeTransferId,
|
||||
createdAt: row.createdAt,
|
||||
updatedAt: row.updatedAt,
|
||||
owner: {
|
||||
id: row.owner_id,
|
||||
email: row.owner_email,
|
||||
firstName: row.owner_firstName,
|
||||
lastName: row.owner_lastName,
|
||||
stripeConnectedAccountId: row.owner_stripeConnectedAccountId,
|
||||
stripePayoutsEnabled: row.owner_stripePayoutsEnabled,
|
||||
},
|
||||
item: {
|
||||
id: row.item_id,
|
||||
name: row.item_name,
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update rental payout status to pending (before retry attempt).
|
||||
* @param {string} rentalId - UUID of the rental
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function resetPayoutToPending(rentalId) {
|
||||
await db.query(
|
||||
`UPDATE "Rentals"
|
||||
SET "payoutStatus" = 'pending',
|
||||
"updatedAt" = NOW()
|
||||
WHERE id = $1`,
|
||||
[rentalId]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update rental with successful payout information.
|
||||
* @param {string} rentalId - UUID of the rental
|
||||
* @param {string} stripeTransferId - Stripe transfer ID
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function updatePayoutSuccess(rentalId, stripeTransferId) {
|
||||
await db.query(
|
||||
`UPDATE "Rentals"
|
||||
SET "payoutStatus" = 'completed',
|
||||
"payoutProcessedAt" = NOW(),
|
||||
"stripeTransferId" = $2,
|
||||
"updatedAt" = NOW()
|
||||
WHERE id = $1`,
|
||||
[rentalId, stripeTransferId]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update rental payout status to failed.
|
||||
* @param {string} rentalId - UUID of the rental
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function updatePayoutFailed(rentalId) {
|
||||
await db.query(
|
||||
`UPDATE "Rentals"
|
||||
SET "payoutStatus" = 'failed',
|
||||
"updatedAt" = NOW()
|
||||
WHERE id = $1`,
|
||||
[rentalId]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear Stripe connection for a disconnected account.
|
||||
* Called when we detect an account is no longer connected.
|
||||
* @param {string} stripeConnectedAccountId - The disconnected account ID
|
||||
* @returns {Promise<Object|null>} The affected user or null
|
||||
*/
|
||||
async function clearDisconnectedAccount(stripeConnectedAccountId) {
|
||||
const result = await db.query(
|
||||
`UPDATE "Users"
|
||||
SET "stripeConnectedAccountId" = NULL,
|
||||
"stripePayoutsEnabled" = false,
|
||||
"updatedAt" = NOW()
|
||||
WHERE "stripeConnectedAccountId" = $1
|
||||
RETURNING id, email, "firstName", "lastName"`,
|
||||
[stripeConnectedAccountId]
|
||||
);
|
||||
|
||||
return result.rows[0] || null;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getFailedPayoutsWithOwners,
|
||||
resetPayoutToPending,
|
||||
updatePayoutSuccess,
|
||||
updatePayoutFailed,
|
||||
clearDisconnectedAccount,
|
||||
};
|
||||
Reference in New Issue
Block a user