/** * Create Payment Intent for Order * Creates a Stripe PaymentIntent with automatic transfer to connected account * * POST: { * BusinessID: int, * OrderID: int, * Amount: number (in dollars), * Tip: number (optional, in dollars), * CustomerEmail: string (optional) * } * * Returns: { OK: true, CLIENT_SECRET: string, PAYMENT_INTENT_ID: string } */ response = { "OK": false }; try { requestData = deserializeJSON(toString(getHttpRequestData().content)); businessID = val(requestData.BusinessID ?: 0); orderID = val(requestData.OrderID ?: 0); amount = val(requestData.Amount ?: 0); tip = val(requestData.Tip ?: 0); customerEmail = requestData.CustomerEmail ?: ""; if (businessID == 0) { response["ERROR"] = "BusinessID is required"; writeOutput(serializeJSON(response)); abort; } if (orderID == 0) { response["ERROR"] = "OrderID is required"; writeOutput(serializeJSON(response)); abort; } if (amount <= 0) { response["ERROR"] = "Invalid amount"; writeOutput(serializeJSON(response)); abort; } stripeSecretKey = application.stripeSecretKey ?: ""; if (stripeSecretKey == "") { response["ERROR"] = "Stripe is not configured"; writeOutput(serializeJSON(response)); abort; } // Get business Stripe account qBusiness = queryExecute(" SELECT BusinessStripeAccountID, BusinessStripeOnboardingComplete, BusinessName FROM Businesses WHERE BusinessID = :businessID ", { businessID: businessID }); if (qBusiness.recordCount == 0) { response["ERROR"] = "Business not found"; writeOutput(serializeJSON(response)); abort; } if (!qBusiness.BusinessStripeOnboardingComplete || qBusiness.BusinessStripeAccountID == "") { response["ERROR"] = "Business has not completed Stripe setup"; writeOutput(serializeJSON(response)); abort; } // Calculate amounts in cents totalAmount = round((amount + tip) * 100); tipAmount = round(tip * 100); // Platform fee: 2.5% of subtotal (not tip) - adjust as needed platformFeePercent = 0.025; platformFee = round(amount * 100 * platformFeePercent); // Amount that goes to the business (total minus platform fee) transferAmount = totalAmount - platformFee; // Create PaymentIntent with automatic transfer httpService = new http(); httpService.setMethod("POST"); httpService.setUrl("https://api.stripe.com/v1/payment_intents"); httpService.setUsername(stripeSecretKey); httpService.setPassword(""); // Required parameters httpService.addParam(type="formfield", name="amount", value=totalAmount); httpService.addParam(type="formfield", name="currency", value="usd"); httpService.addParam(type="formfield", name="automatic_payment_methods[enabled]", value="true"); // Transfer to connected account httpService.addParam(type="formfield", name="transfer_data[destination]", value=qBusiness.BusinessStripeAccountID); httpService.addParam(type="formfield", name="transfer_data[amount]", value=transferAmount); // Metadata for tracking httpService.addParam(type="formfield", name="metadata[order_id]", value=orderID); httpService.addParam(type="formfield", name="metadata[business_id]", value=businessID); httpService.addParam(type="formfield", name="metadata[tip_amount]", value=tipAmount); httpService.addParam(type="formfield", name="metadata[platform_fee]", value=platformFee); // Description httpService.addParam(type="formfield", name="description", value="Order ###orderID# at #qBusiness.BusinessName#"); // Receipt email if provided if (customerEmail != "") { httpService.addParam(type="formfield", name="receipt_email", value=customerEmail); } result = httpService.send().getPrefix(); piData = deserializeJSON(result.fileContent); if (structKeyExists(piData, "error")) { response["ERROR"] = piData.error.message; writeOutput(serializeJSON(response)); abort; } // Save payment intent to order queryExecute(" UPDATE Orders SET OrderStripePaymentIntentID = :paymentIntentID, OrderTipAmount = :tipAmount, OrderPlatformFee = :platformFee WHERE OrderID = :orderID ", { paymentIntentID: piData.id, tipAmount: tip, platformFee: platformFee / 100, orderID: orderID }); response["OK"] = true; response["CLIENT_SECRET"] = piData.client_secret; response["PAYMENT_INTENT_ID"] = piData.id; response["AMOUNT"] = totalAmount; response["PLATFORM_FEE"] = platformFee; response["TRANSFER_AMOUNT"] = transferAmount; } catch (any e) { response["ERROR"] = e.message; } writeOutput(serializeJSON(response));