diff --git a/apps/web/src/lib/payment.ts b/apps/web/src/lib/payment.ts index dca4b05..6d33d00 100644 --- a/apps/web/src/lib/payment.ts +++ b/apps/web/src/lib/payment.ts @@ -87,26 +87,31 @@ export async function capturePayment( throw new Error("Cannot capture without a COMPLETED claim"); } - let capturedIntent; - try { - if (!stripe) throw new Error("Stripe is not initialized"); - // Perform real Stripe capture - capturedIntent = await stripe.paymentIntents.capture(task.stripe_payment_intent_id, undefined, { - idempotencyKey - }); - } catch (error: any) { - // Record failed capture - await tx.ledgerEntry.create({ - data: { - task_id: taskId, - phase: "CAPTURE", - idempotency_key: idempotencyKey, - stripe_object_id: task.stripe_payment_intent_id, - response_status: "FAILED", - http_status: error.statusCode || 500, - }, - }); - throw error; + let capturedIntentId = task.stripe_payment_intent_id; + if (task.stripe_payment_intent_id === "promo_free_bounty_intent") { + // Skip real Stripe capture for promo tasks + } else { + try { + if (!stripe) throw new Error("Stripe is not initialized"); + // Perform real Stripe capture + const capturedIntent = await stripe.paymentIntents.capture(task.stripe_payment_intent_id, undefined, { + idempotencyKey + }); + capturedIntentId = capturedIntent.id; + } catch (error: any) { + // Record failed capture + await tx.ledgerEntry.create({ + data: { + task_id: taskId, + phase: "CAPTURE", + idempotency_key: idempotencyKey, + stripe_object_id: task.stripe_payment_intent_id, + response_status: "FAILED", + http_status: error.statusCode || 500, + }, + }); + throw error; + } } return await tx.ledgerEntry.create({ @@ -114,7 +119,7 @@ export async function capturePayment( task_id: taskId, phase: "CAPTURE", idempotency_key: idempotencyKey, - stripe_object_id: capturedIntent.id, + stripe_object_id: capturedIntentId, response_status: "SUCCESS", http_status: 200, }, @@ -148,24 +153,29 @@ export async function releasePayment( }); } - let canceledIntent; - try { - if (!stripe) throw new Error("Stripe is not initialized"); - canceledIntent = await stripe.paymentIntents.cancel(task.stripe_payment_intent_id, undefined, { - idempotencyKey - }); - } catch (error: any) { - await tx.ledgerEntry.create({ - data: { - task_id: taskId, - phase: "RELEASE", - idempotency_key: idempotencyKey, - stripe_object_id: task.stripe_payment_intent_id, - response_status: "FAILED", - http_status: error.statusCode || 500, - }, - }); - throw error; + let canceledIntentId = task.stripe_payment_intent_id; + if (task.stripe_payment_intent_id === "promo_free_bounty_intent") { + // Skip real Stripe cancel for promo tasks + } else { + try { + if (!stripe) throw new Error("Stripe is not initialized"); + const canceledIntent = await stripe.paymentIntents.cancel(task.stripe_payment_intent_id, undefined, { + idempotencyKey + }); + canceledIntentId = canceledIntent.id; + } catch (error: any) { + await tx.ledgerEntry.create({ + data: { + task_id: taskId, + phase: "RELEASE", + idempotency_key: idempotencyKey, + stripe_object_id: task.stripe_payment_intent_id, + response_status: "FAILED", + http_status: error.statusCode || 500, + }, + }); + throw error; + } } return await tx.ledgerEntry.create({ @@ -173,7 +183,7 @@ export async function releasePayment( task_id: taskId, phase: "RELEASE", idempotency_key: idempotencyKey, - stripe_object_id: canceledIntent.id, + stripe_object_id: canceledIntentId, response_status: "SUCCESS", http_status: 200, },