diff --git a/api/stripe/createPaymentIntent.cfm b/api/stripe/createPaymentIntent.cfm index 3be2d44..4fc9ccb 100644 --- a/api/stripe/createPaymentIntent.cfm +++ b/api/stripe/createPaymentIntent.cfm @@ -83,45 +83,6 @@ try { WHERE o.ID = :orderID ", { orderID: orderID }, { datasource: "payfrit" }); - // Check if order already has a PaymentIntent - retrieve and reuse if still valid - existingPiId = qOrder.StripePaymentIntentID ?: ""; - if (qOrder.recordCount > 0 && len(trim(existingPiId)) > 0) { - // Retrieve existing PaymentIntent from Stripe - piRetrieve = new http(); - piRetrieve.setMethod("GET"); - piRetrieve.setUrl("https://api.stripe.com/v1/payment_intents/#existingPiId#"); - piRetrieve.setUsername(stripeSecretKey); - piRetrieve.setPassword(""); - piResult = piRetrieve.send().getPrefix(); - existingPi = deserializeJSON(piResult.fileContent); - - if (!structKeyExists(existingPi, "error")) { - piStatus = existingPi.status ?: ""; - // Reusable states: can still complete payment - if (listFindNoCase("requires_payment_method,requires_confirmation,requires_action", piStatus)) { - // Return existing PaymentIntent - user can retry with same one - response["OK"] = true; - response["CLIENT_SECRET"] = existingPi.client_secret; - response["PAYMENT_INTENT_ID"] = existingPi.id; - response["PUBLISHABLE_KEY"] = application.stripePublishableKey ?: "pk_test_sPBNzSyJ9HcEPJGC7dSo8NqN"; - response["REUSED"] = true; - writeOutput(serializeJSON(response)); - abort; - } else if (piStatus == "succeeded") { - // Already paid - don't create another - response["OK"] = false; - response["ERROR"] = "already_paid"; - response["MESSAGE"] = "This order has already been paid."; - writeOutput(serializeJSON(response)); - abort; - } - // Other terminal states (canceled, etc.) - clear and create new - } - // PaymentIntent not found or terminal - clear it from order - queryExecute("UPDATE Orders SET StripePaymentIntentID = NULL WHERE ID = :orderID", - { orderID: orderID }, { datasource: "payfrit" }); - } - deliveryFee = 0; if (qOrder.recordCount > 0 && qOrder.OrderTypeID == 3) { deliveryFee = val(qOrder.DeliveryFee); @@ -169,6 +130,59 @@ try { totalAmountCents = round(totalCustomerPays * 100); totalPlatformFeeCents = round((payfritCustomerFee + payfritBusinessFee) * 100); + // ============================================================ + // CHECK FOR EXISTING PAYMENTINTENT - REUSE OR UPDATE IF VALID + // ============================================================ + existingPiId = qOrder.StripePaymentIntentID ?: ""; + if (qOrder.recordCount > 0 && len(trim(existingPiId)) > 0) { + // Retrieve existing PaymentIntent from Stripe + piRetrieve = new http(); + piRetrieve.setMethod("GET"); + piRetrieve.setUrl("https://api.stripe.com/v1/payment_intents/#existingPiId#"); + piRetrieve.setUsername(stripeSecretKey); + piRetrieve.setPassword(""); + piResult = piRetrieve.send().getPrefix(); + existingPi = deserializeJSON(piResult.fileContent); + + if (!structKeyExists(existingPi, "error")) { + piStatus = existingPi.status ?: ""; + // Reusable states: can still complete payment + if (listFindNoCase("requires_payment_method,requires_confirmation,requires_action", piStatus)) { + // Check if amount changed (cart modified) + if (existingPi.amount != totalAmountCents) { + // Update the PaymentIntent with new amount + piUpdate = new http(); + piUpdate.setMethod("POST"); + piUpdate.setUrl("https://api.stripe.com/v1/payment_intents/#existingPiId#"); + piUpdate.setUsername(stripeSecretKey); + piUpdate.setPassword(""); + piUpdate.addParam(type="formfield", name="amount", value=totalAmountCents); + piUpdateResult = piUpdate.send().getPrefix(); + existingPi = deserializeJSON(piUpdateResult.fileContent); + } + // Return existing PaymentIntent + response["OK"] = true; + response["CLIENT_SECRET"] = existingPi.client_secret; + response["PAYMENT_INTENT_ID"] = existingPi.id; + response["PUBLISHABLE_KEY"] = application.stripePublishableKey ?: "pk_test_sPBNzSyJ9HcEPJGC7dSo8NqN"; + response["REUSED"] = true; + writeOutput(serializeJSON(response)); + abort; + } else if (piStatus == "succeeded") { + // Already paid - don't create another + response["OK"] = false; + response["ERROR"] = "already_paid"; + response["MESSAGE"] = "This order has already been paid."; + writeOutput(serializeJSON(response)); + abort; + } + // Other terminal states (canceled, etc.) - clear and create new + } + // PaymentIntent not found or terminal - clear it from order + queryExecute("UPDATE Orders SET StripePaymentIntentID = NULL WHERE ID = :orderID", + { orderID: orderID }, { datasource: "payfrit" }); + } + // ============================================================ // STRIPE CUSTOMER (for saving payment methods) // ============================================================