@@ -14,6 +14,7 @@ import {
1414 PriceConfigError ,
1515 OrderStateInvalidError ,
1616} from '@/lib/services/errors' ;
17+ import { readStripePaymentIntentParams } from '@/lib/services/orders/payment-intent' ;
1718
1819import {
1920 createOrderWithItems ,
@@ -157,7 +158,11 @@ export async function POST(request: NextRequest) {
157158 logWarn ( 'Failed to parse cart payload' , {
158159 reason : error instanceof Error ? error . message : String ( error ) ,
159160 } ) ;
160- return errorResponse ( 'INVALID_PAYLOAD' , 'Unable to process cart data.' , 400 ) ;
161+ return errorResponse (
162+ 'INVALID_PAYLOAD' ,
163+ 'Unable to process cart data.' ,
164+ 400
165+ ) ;
161166 }
162167
163168 const idempotencyKey = getIdempotencyKey ( request ) ;
@@ -232,18 +237,29 @@ export async function POST(request: NextRequest) {
232237 locale,
233238 } ) ;
234239
235- const { order, totalCents } = result ;
240+ const { order } = result ;
236241
237242 const paymentsEnabled = isPaymentsEnabled ( ) ;
238243
239244 if ( ! paymentsEnabled ) {
240- if ( order . paymentProvider === 'none' && order . paymentStatus === 'failed' ) {
241- return errorResponse ( 'CHECKOUT_FAILED' , 'Order could not be completed.' , 409 , {
242- orderId : order . id ,
243- } ) ;
245+ if (
246+ order . paymentProvider === 'none' &&
247+ order . paymentStatus === 'failed'
248+ ) {
249+ return errorResponse (
250+ 'CHECKOUT_FAILED' ,
251+ 'Order could not be completed.' ,
252+ 409 ,
253+ {
254+ orderId : order . id ,
255+ }
256+ ) ;
244257 }
245258
246- if ( order . paymentProvider === 'stripe' && order . paymentStatus !== 'paid' ) {
259+ if (
260+ order . paymentProvider === 'stripe' &&
261+ order . paymentStatus !== 'paid'
262+ ) {
247263 return errorResponse (
248264 'PAYMENTS_DISABLED' ,
249265 'Payments are disabled. This order requires payment and cannot be processed.' ,
@@ -253,9 +269,16 @@ export async function POST(request: NextRequest) {
253269 }
254270
255271 if ( order . paymentProvider === 'none' ) {
256- if ( ! [ 'paid' , 'failed' ] . includes ( order . paymentStatus ) || order . paymentIntentId ) {
272+ if (
273+ ! [ 'paid' , 'failed' ] . includes ( order . paymentStatus ) ||
274+ order . paymentIntentId
275+ ) {
257276 logError (
258- `Payments disabled but order is not paid/none. orderId=${ order . id } provider=${ order . paymentProvider } status=${ order . paymentStatus } intent=${ order . paymentIntentId ?? 'null' } ` ,
277+ `Payments disabled but order is not paid/none. orderId=${
278+ order . id
279+ } provider=${ order . paymentProvider } status=${
280+ order . paymentStatus
281+ } intent=${ order . paymentIntentId ?? 'null' } `,
259282 new Error ( 'ORDER_STATE_INVALID' )
260283 ) ;
261284 return errorResponse (
@@ -267,7 +290,8 @@ export async function POST(request: NextRequest) {
267290 }
268291 }
269292
270- const stripePaymentFlow = paymentsEnabled && order . paymentProvider === 'stripe' ;
293+ const stripePaymentFlow =
294+ paymentsEnabled && order . paymentProvider === 'stripe' ;
271295
272296 // =========================
273297 // Existing order path
@@ -276,7 +300,9 @@ export async function POST(request: NextRequest) {
276300 // Existing order already has PI: retrieve client_secret
277301 if ( stripePaymentFlow && order . paymentIntentId ) {
278302 try {
279- const paymentIntent = await retrievePaymentIntent ( order . paymentIntentId ) ;
303+ const paymentIntent = await retrievePaymentIntent (
304+ order . paymentIntentId
305+ ) ;
280306 return buildCheckoutResponse ( {
281307 order : {
282308 id : order . id ,
@@ -292,7 +318,11 @@ export async function POST(request: NextRequest) {
292318 } ) ;
293319 } catch ( error ) {
294320 logError ( 'Checkout payment intent retrieval failed' , error ) ;
295- return errorResponse ( 'STRIPE_ERROR' , 'Unable to initiate payment.' , 502 ) ;
321+ return errorResponse (
322+ 'STRIPE_ERROR' ,
323+ 'Unable to initiate payment.' ,
324+ 502
325+ ) ;
296326 }
297327 }
298328
@@ -301,15 +331,21 @@ export async function POST(request: NextRequest) {
301331 let paymentIntent : { paymentIntentId : string ; clientSecret : string } ;
302332
303333 try {
334+ const snapshot = await readStripePaymentIntentParams ( order . id ) ;
335+
304336 paymentIntent = await createPaymentIntent ( {
305- amount : totalCents ,
306- currency : order . currency ,
337+ amount : snapshot . amountMinor ,
338+ currency : snapshot . currency ,
307339 orderId : order . id ,
308340 idempotencyKey,
309341 } ) ;
310342 } catch ( error ) {
311343 logError ( 'Checkout payment intent creation failed' , error ) ;
312- return errorResponse ( 'STRIPE_ERROR' , 'Unable to initiate payment.' , 502 ) ;
344+ return errorResponse (
345+ 'STRIPE_ERROR' ,
346+ 'Unable to initiate payment.' ,
347+ 502
348+ ) ;
313349 }
314350
315351 try {
@@ -351,7 +387,11 @@ export async function POST(request: NextRequest) {
351387 } ) ;
352388 }
353389
354- return errorResponse ( 'INTERNAL_ERROR' , 'Unable to process checkout.' , 500 ) ;
390+ return errorResponse (
391+ 'INTERNAL_ERROR' ,
392+ 'Unable to process checkout.' ,
393+ 500
394+ ) ;
355395 }
356396 }
357397
@@ -394,9 +434,11 @@ export async function POST(request: NextRequest) {
394434 let paymentIntent : { paymentIntentId : string ; clientSecret : string } ;
395435
396436 try {
437+ const snapshot = await readStripePaymentIntentParams ( order . id ) ;
438+
397439 paymentIntent = await createPaymentIntent ( {
398- amount : totalCents ,
399- currency : order . currency ,
440+ amount : snapshot . amountMinor ,
441+ currency : snapshot . currency ,
400442 orderId : order . id ,
401443 idempotencyKey,
402444 } ) ;
@@ -406,7 +448,10 @@ export async function POST(request: NextRequest) {
406448 try {
407449 await restockOrder ( order . id , { reason : 'failed' } ) ;
408450 } catch ( restockError ) {
409- logError ( 'Restoring stock after payment intent failure failed' , restockError ) ;
451+ logError (
452+ 'Restoring stock after payment intent failure failed' ,
453+ restockError
454+ ) ;
410455 }
411456
412457 return errorResponse ( 'STRIPE_ERROR' , 'Unable to initiate payment.' , 502 ) ;
@@ -450,7 +495,10 @@ export async function POST(request: NextRequest) {
450495 try {
451496 await restockOrder ( order . id , { reason : 'failed' } ) ;
452497 } catch ( restockError ) {
453- logError ( 'Restoring stock after payment intent attach failure failed' , restockError ) ;
498+ logError (
499+ 'Restoring stock after payment intent attach failure failed' ,
500+ restockError
501+ ) ;
454502 }
455503
456504 if ( error instanceof OrderStateInvalidError ) {
@@ -460,7 +508,11 @@ export async function POST(request: NextRequest) {
460508 } ) ;
461509 }
462510
463- return errorResponse ( 'INTERNAL_ERROR' , 'Unable to process checkout.' , 500 ) ;
511+ return errorResponse (
512+ 'INTERNAL_ERROR' ,
513+ 'Unable to process checkout.' ,
514+ 500
515+ ) ;
464516 }
465517 } catch ( error ) {
466518 if ( isExpectedBusinessError ( error ) ) {
@@ -473,7 +525,11 @@ export async function POST(request: NextRequest) {
473525 }
474526
475527 if ( error instanceof InvalidPayloadError ) {
476- return errorResponse ( error . code , error . message || 'Invalid checkout payload' , 400 ) ;
528+ return errorResponse (
529+ error . code ,
530+ error . message || 'Invalid checkout payload' ,
531+ 400
532+ ) ;
477533 }
478534
479535 if ( error instanceof InvalidVariantError ) {
@@ -524,4 +580,4 @@ export async function POST(request: NextRequest) {
524580
525581 return errorResponse ( 'INTERNAL_ERROR' , 'Unable to process checkout.' , 500 ) ;
526582 }
527- }
583+ }
0 commit comments