Fix normalized DB column names across all API files

Sweep of 26 API files to use prefixed column names matching the
database schema (e.g. BusinessID not ID, BusinessName not Name,
BusinessDeliveryFlatFee not DeliveryFlatFee, ServicePointName not Name).

Files fixed: auth, beacons, businesses, menu, orders, setup, stripe,
tasks, and workers endpoints.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
John Mizerek 2026-01-31 16:56:41 -08:00
parent 62c61c13cd
commit 6b66d2cef8
26 changed files with 222 additions and 227 deletions

View file

@ -37,36 +37,19 @@ try {
apiAbort({ "OK": false, "ERROR": "missing_fields", "MESSAGE": "UUID and OTP are required" }); apiAbort({ "OK": false, "ERROR": "missing_fields", "MESSAGE": "UUID and OTP are required" });
} }
// Check for magic OTP bypass (for App Store review) // Find verified user with matching UUID and OTP
isMagicOTP = structKeyExists(application, "MAGIC_OTP_ENABLED") // Magic OTP only bypasses Twilio SMS (in loginOTP.cfm), not OTP verification
&& application.MAGIC_OTP_ENABLED qUser = queryExecute("
&& structKeyExists(application, "MAGIC_OTP_CODE") SELECT ID, FirstName, LastName
&& otp == application.MAGIC_OTP_CODE; FROM Users
WHERE UUID = :uuid
// Find verified user with matching UUID and OTP (or magic OTP) AND MobileVerifyCode = :otp
if (isMagicOTP) { AND IsContactVerified = 1
qUser = queryExecute(" LIMIT 1
SELECT ID, FirstName, LastName ", {
FROM Users uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" },
WHERE UUID = :uuid otp: { value: otp, cfsqltype: "cf_sql_varchar" }
AND IsContactVerified = 1 }, { datasource: "payfrit" });
LIMIT 1
", {
uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" }
}, { datasource: "payfrit" });
} else {
qUser = queryExecute("
SELECT ID, FirstName, LastName
FROM Users
WHERE UUID = :uuid
AND MobileVerifyCode = :otp
AND IsContactVerified = 1
LIMIT 1
", {
uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" },
otp: { value: otp, cfsqltype: "cf_sql_varchar" }
}, { datasource: "payfrit" });
}
if (qUser.recordCount == 0) { if (qUser.recordCount == 0) {
// Check if UUID exists but OTP is wrong // Check if UUID exists but OTP is wrong

View file

@ -40,36 +40,19 @@ try {
apiAbort({ "OK": false, "ERROR": "missing_fields", "MESSAGE": "UUID and OTP are required" }); apiAbort({ "OK": false, "ERROR": "missing_fields", "MESSAGE": "UUID and OTP are required" });
} }
// Check for magic OTP bypass (for App Store review) // Find unverified user with matching UUID and OTP
isMagicOTP = structKeyExists(application, "MAGIC_OTP_ENABLED") // Magic OTP only bypasses Twilio SMS (in sendOTP.cfm), not OTP verification
&& application.MAGIC_OTP_ENABLED qUser = queryExecute("
&& structKeyExists(application, "MAGIC_OTP_CODE") SELECT ID, FirstName, LastName, EmailAddress, IsEmailVerified
&& otp == application.MAGIC_OTP_CODE; FROM Users
WHERE UUID = :uuid
// Find unverified user with matching UUID and OTP (or magic OTP) AND MobileVerifyCode = :otp
if (isMagicOTP) { AND IsContactVerified = 0
qUser = queryExecute(" LIMIT 1
SELECT ID, FirstName, LastName, EmailAddress, IsEmailVerified ", {
FROM Users uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" },
WHERE UUID = :uuid otp: { value: otp, cfsqltype: "cf_sql_varchar" }
AND IsContactVerified = 0 }, { datasource: "payfrit" });
LIMIT 1
", {
uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" }
}, { datasource: "payfrit" });
} else {
qUser = queryExecute("
SELECT ID, FirstName, LastName, EmailAddress, IsEmailVerified
FROM Users
WHERE UUID = :uuid
AND MobileVerifyCode = :otp
AND IsContactVerified = 0
LIMIT 1
", {
uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" },
otp: { value: otp, cfsqltype: "cf_sql_varchar" }
}, { datasource: "payfrit" });
}
if (qUser.recordCount == 0) { if (qUser.recordCount == 0) {
// Check if UUID exists but OTP is wrong // Check if UUID exists but OTP is wrong

View file

@ -50,11 +50,11 @@ beaconId = int(data.BeaconID);
SELECT SELECT
sp.BusinessID, sp.BusinessID,
sp.ID AS ServicePointID, sp.ID AS ServicePointID,
biz.Name AS BusinessName, biz.BusinessName AS BusinessName,
biz.ParentBusinessID, biz.BusinessParentBusinessID,
sp.Name AS ServicePointName sp.Name AS ServicePointName
FROM ServicePoints sp FROM ServicePoints sp
INNER JOIN Businesses biz ON biz.ID = sp.BusinessID INNER JOIN Businesses biz ON biz.BusinessID = sp.BusinessID
WHERE sp.BeaconID = <cfqueryparam cfsqltype="cf_sql_integer" value="#beaconId#"> WHERE sp.BeaconID = <cfqueryparam cfsqltype="cf_sql_integer" value="#beaconId#">
AND sp.IsActive = 1 AND sp.IsActive = 1
@ -63,18 +63,18 @@ beaconId = int(data.BeaconID);
SELECT SELECT
lt.BusinessID, lt.BusinessID,
0 AS ServicePointID, 0 AS ServicePointID,
biz.Name AS BusinessName, biz.BusinessName AS BusinessName,
biz.ParentBusinessID, biz.BusinessParentBusinessID,
'' AS ServicePointName '' AS ServicePointName
FROM lt_BeaconsID_BusinessesID lt FROM lt_BeaconsID_BusinessesID lt
INNER JOIN Businesses biz ON biz.ID = lt.BusinessID INNER JOIN Businesses biz ON biz.BusinessID = lt.BusinessID
WHERE lt.BeaconID = <cfqueryparam cfsqltype="cf_sql_integer" value="#beaconId#"> WHERE lt.BeaconID = <cfqueryparam cfsqltype="cf_sql_integer" value="#beaconId#">
AND lt.BusinessID NOT IN ( AND lt.BusinessID NOT IN (
SELECT sp2.BusinessID FROM ServicePoints sp2 SELECT sp2.BusinessID FROM ServicePoints sp2
WHERE sp2.BeaconID = <cfqueryparam cfsqltype="cf_sql_integer" value="#beaconId#"> AND sp2.IsActive = 1 WHERE sp2.BeaconID = <cfqueryparam cfsqltype="cf_sql_integer" value="#beaconId#"> AND sp2.IsActive = 1
) )
ORDER BY ParentBusinessID IS NULL DESC, BusinessName ASC ORDER BY BusinessParentBusinessID IS NULL DESC, BusinessName ASC
</cfquery> </cfquery>
<!--- Check if any assigned business is a parent (has children) ---> <!--- Check if any assigned business is a parent (has children) --->
@ -83,7 +83,7 @@ beaconId = int(data.BeaconID);
<!--- Check if this business has children ---> <!--- Check if this business has children --->
<cfquery name="qChildren" datasource="payfrit"> <cfquery name="qChildren" datasource="payfrit">
SELECT COUNT(*) as cnt FROM Businesses SELECT COUNT(*) as cnt FROM Businesses
WHERE ParentBusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#qAssignments.BusinessID#"> WHERE BusinessParentBusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#qAssignments.BusinessID#">
</cfquery> </cfquery>
<cfif qChildren.cnt GT 0> <cfif qChildren.cnt GT 0>
<cfset parentBusinessID = qAssignments.BusinessID> <cfset parentBusinessID = qAssignments.BusinessID>
@ -98,24 +98,24 @@ beaconId = int(data.BeaconID);
<cfif parentBusinessID GT 0> <cfif parentBusinessID GT 0>
<!--- Get parent business info for header image ---> <!--- Get parent business info for header image --->
<cfquery name="qParent" datasource="payfrit"> <cfquery name="qParent" datasource="payfrit">
SELECT Name, HeaderImageExtension SELECT BusinessName, BusinessHeaderImageExtension
FROM Businesses FROM Businesses
WHERE ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#parentBusinessID#"> WHERE BusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#parentBusinessID#">
</cfquery> </cfquery>
<cfquery name="qChildBusinesses" datasource="payfrit"> <cfquery name="qChildBusinesses" datasource="payfrit">
SELECT SELECT
ID, BusinessID,
Name, BusinessName,
ParentBusinessID, BusinessParentBusinessID,
HeaderImageExtension BusinessHeaderImageExtension
FROM Businesses FROM Businesses
WHERE ParentBusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#parentBusinessID#"> WHERE BusinessParentBusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#parentBusinessID#">
ORDER BY Name ASC ORDER BY Name ASC
</cfquery> </cfquery>
<cfloop query="qChildBusinesses"> <cfloop query="qChildBusinesses">
<cfset arrayAppend(businesses, { <cfset arrayAppend(businesses, {
"BusinessID" = qChildBusinesses.ID, "BusinessID" = qChildBusinesses.BusinessID,
"Name" = qChildBusinesses.Name, "Name" = qChildBusinesses.BusinessName,
"ServicePointID" = qAssignments.ServicePointID, "ServicePointID" = qAssignments.ServicePointID,
"ServicePointName" = qAssignments.ServicePointName, "ServicePointName" = qAssignments.ServicePointName,
"IsParent" = false, "IsParent" = false,
@ -156,8 +156,8 @@ beaconId = int(data.BeaconID);
<cfif parentBusinessID GT 0> <cfif parentBusinessID GT 0>
<cfset response["PARENT"] = { <cfset response["PARENT"] = {
"BusinessID" = parentBusinessID, "BusinessID" = parentBusinessID,
"Name" = qParent.Name, "Name" = qParent.BusinessName,
"HeaderImageExtension" = len(trim(qParent.HeaderImageExtension)) ? qParent.HeaderImageExtension : "" "HeaderImageExtension" = len(trim(qParent.BusinessHeaderImageExtension)) ? qParent.BusinessHeaderImageExtension : ""
}> }>
</cfif> </cfif>

View file

@ -35,17 +35,17 @@ try {
// Get business details // Get business details
q = queryExecute(" q = queryExecute("
SELECT SELECT
ID, BusinessID,
Name, BusinessName,
Phone, BusinessPhone,
StripeAccountID, BusinessStripeAccountID,
StripeOnboardingComplete, BusinessStripeOnboardingComplete,
IsHiring, BusinessIsHiring,
HeaderImageExtension, BusinessHeaderImageExtension,
TaxRate, BusinessTaxRate,
BrandColor BusinessBrandColor
FROM Businesses FROM Businesses
WHERE ID = :businessID WHERE BusinessID = :businessID
", { businessID: businessID }, { datasource: "payfrit" }); ", { businessID: businessID }, { datasource: "payfrit" });
if (q.recordCount == 0) { if (q.recordCount == 0) {
@ -54,13 +54,13 @@ try {
abort; abort;
} }
// Get address from Addresses table (either linked via BusinessID or via Businesses.AddressID) // Get address from Addresses table (either linked via AddressBusinessID or via Businesses.BusinessAddressID)
qAddr = queryExecute(" qAddr = queryExecute("
SELECT a.Line1, a.Line2, a.City, a.ZIPCode, s.Abbreviation SELECT a.AddressLine1, a.AddressLine2, a.AddressCity, a.AddressZIPCode, s.Abbreviation
FROM Addresses a FROM Addresses a
LEFT JOIN tt_States s ON s.ID = a.StateID LEFT JOIN tt_States s ON s.ID = a.AddressStateID
WHERE (a.BusinessID = :businessID OR a.ID = (SELECT AddressID FROM Businesses WHERE ID = :businessID)) WHERE (a.AddressBusinessID = :businessID OR a.AddressID = (SELECT BusinessAddressID FROM Businesses WHERE BusinessID = :businessID))
AND a.IsDeleted = 0 AND a.AddressIsDeleted = 0
LIMIT 1 LIMIT 1
", { businessID: businessID }, { datasource: "payfrit" }); ", { businessID: businessID }, { datasource: "payfrit" });
@ -70,29 +70,29 @@ try {
addressState = ""; addressState = "";
addressZip = ""; addressZip = "";
if (qAddr.recordCount > 0) { if (qAddr.recordCount > 0) {
addressLine1 = qAddr.Line1; addressLine1 = qAddr.AddressLine1;
addressCity = qAddr.City; addressCity = qAddr.AddressCity;
addressState = qAddr.Abbreviation; addressState = qAddr.Abbreviation;
addressZip = qAddr.ZIPCode; addressZip = qAddr.AddressZIPCode;
addressParts = []; addressParts = [];
if (len(qAddr.Line1)) arrayAppend(addressParts, qAddr.Line1); if (len(qAddr.AddressLine1)) arrayAppend(addressParts, qAddr.AddressLine1);
if (len(qAddr.Line2)) arrayAppend(addressParts, qAddr.Line2); if (len(qAddr.AddressLine2)) arrayAppend(addressParts, qAddr.AddressLine2);
cityStateZip = []; cityStateZip = [];
if (len(qAddr.City)) arrayAppend(cityStateZip, qAddr.City); if (len(qAddr.AddressCity)) arrayAppend(cityStateZip, qAddr.AddressCity);
if (len(qAddr.Abbreviation)) arrayAppend(cityStateZip, qAddr.Abbreviation); if (len(qAddr.Abbreviation)) arrayAppend(cityStateZip, qAddr.Abbreviation);
if (len(qAddr.ZIPCode)) arrayAppend(cityStateZip, qAddr.ZIPCode); if (len(qAddr.AddressZIPCode)) arrayAppend(cityStateZip, qAddr.AddressZIPCode);
if (arrayLen(cityStateZip) > 0) arrayAppend(addressParts, arrayToList(cityStateZip, ", ")); if (arrayLen(cityStateZip) > 0) arrayAppend(addressParts, arrayToList(cityStateZip, ", "));
addressStr = arrayToList(addressParts, ", "); addressStr = arrayToList(addressParts, ", ");
} }
// Get hours from Hours table // Get hours from Hours table
qHours = queryExecute(" qHours = queryExecute("
SELECT h.DayID, h.OpenTime, h.ClosingTime, d.Abbrev SELECT h.HoursDayID, h.HoursOpenTime, h.HoursClosingTime, d.Abbrev
FROM Hours h FROM Hours h
JOIN tt_Days d ON d.ID = h.DayID JOIN tt_Days d ON d.ID = h.HoursDayID
WHERE h.BusinessID = :businessID WHERE h.HoursBusinessID = :businessID
ORDER BY h.DayID ORDER BY h.HoursDayID
", { businessID: businessID }, { datasource: "payfrit" }); ", { businessID: businessID }, { datasource: "payfrit" });
hoursArr = []; hoursArr = [];
@ -101,13 +101,12 @@ try {
for (h in qHours) { for (h in qHours) {
arrayAppend(hoursArr, { arrayAppend(hoursArr, {
"day": h.Abbrev, "day": h.Abbrev,
"dayId": h.DayID, "dayId": h.HoursDayID,
"open": timeFormat(h.OpenTime, "h:mm tt"), "open": timeFormat(h.HoursOpenTime, "h:mm tt"),
"close": timeFormat(h.ClosingTime, "h:mm tt") "close": timeFormat(h.HoursClosingTime, "h:mm tt")
}); });
} }
// Build readable hours string (group similar days) // Build readable hours string (group similar days)
// Mon-Thu: 11am-10pm, Fri-Sat: 11am-11pm, Sun: 11am-10pm
hourGroups = {}; hourGroups = {};
for (h in hoursArr) { for (h in hoursArr) {
key = h.open & "-" & h.close; key = h.open & "-" & h.close;
@ -125,28 +124,28 @@ try {
} }
// Build business object // Build business object
taxRate = isNumeric(q.TaxRate) ? q.TaxRate : 0; taxRate = isNumeric(q.BusinessTaxRate) ? q.BusinessTaxRate : 0;
business = { business = {
"BusinessID": q.ID, "BusinessID": q.BusinessID,
"Name": q.Name, "Name": q.BusinessName,
"Address": addressStr, "Address": addressStr,
"Line1": addressLine1, "Line1": addressLine1,
"City": addressCity, "City": addressCity,
"AddressState": addressState, "AddressState": addressState,
"AddressZip": addressZip, "AddressZip": addressZip,
"Phone": q.Phone, "Phone": q.BusinessPhone,
"Hours": hoursStr, "Hours": hoursStr,
"HoursDetail": hoursArr, "HoursDetail": hoursArr,
"StripeConnected": (len(q.StripeAccountID) > 0 && q.StripeOnboardingComplete == 1), "StripeConnected": (len(q.BusinessStripeAccountID) > 0 && q.BusinessStripeOnboardingComplete == 1),
"IsHiring": q.IsHiring == 1, "IsHiring": q.BusinessIsHiring == 1,
"TaxRate": taxRate, "TaxRate": taxRate,
"TaxRatePercent": taxRate * 100, "TaxRatePercent": taxRate * 100,
"BrandColor": len(q.BrandColor) ? (left(q.BrandColor, 1) == chr(35) ? q.BrandColor : chr(35) & q.BrandColor) : "" "BrandColor": len(q.BusinessBrandColor) ? (left(q.BusinessBrandColor, 1) == chr(35) ? q.BusinessBrandColor : chr(35) & q.BusinessBrandColor) : ""
}; };
// Add header image URL if extension exists // Add header image URL if extension exists
if (len(q.HeaderImageExtension)) { if (len(q.BusinessHeaderImageExtension)) {
business["HeaderImageURL"] = "https://biz.payfrit.com/uploads/headers/" & q.ID & "." & q.HeaderImageExtension; business["HeaderImageURL"] = "https://biz.payfrit.com/uploads/headers/" & q.BusinessID & "." & q.BusinessHeaderImageExtension;
} }
response["OK"] = true; response["OK"] = true;

View file

@ -36,10 +36,10 @@ try {
q = queryExecute( q = queryExecute(
" "
SELECT SELECT
ID, BusinessID,
Name BusinessName
FROM Businesses FROM Businesses
WHERE ParentBusinessID = :parentId WHERE BusinessParentBusinessID = :parentId
ORDER BY Name ORDER BY Name
", ",
{ parentId = { value = parentBusinessId, cfsqltype = "cf_sql_integer" } }, { parentId = { value = parentBusinessId, cfsqltype = "cf_sql_integer" } },
@ -49,8 +49,8 @@ try {
rows = []; rows = [];
for (i = 1; i <= q.recordCount; i++) { for (i = 1; i <= q.recordCount; i++) {
arrayAppend(rows, { arrayAppend(rows, {
"BusinessID": q.ID[i], "BusinessID": q.BusinessID[i],
"Name": q.Name[i] "Name": q.BusinessName[i]
}); });
} }

View file

@ -43,17 +43,17 @@ try {
q = queryExecute( q = queryExecute(
" "
SELECT SELECT
b.ID, b.BusinessID,
b.Name, b.BusinessName,
a.Latitude, a.AddressLat,
a.Longitude, a.AddressLng,
a.City, a.AddressCity,
a.Line1 a.AddressLine1
FROM Businesses b FROM Businesses b
LEFT JOIN Addresses a ON b.AddressID = a.ID LEFT JOIN Addresses a ON b.BusinessAddressID = a.AddressID
WHERE (b.IsDemo = 0 OR b.IsDemo IS NULL) WHERE (b.BusinessIsDemo = 0 OR b.BusinessIsDemo IS NULL)
AND (b.IsPrivate = 0 OR b.IsPrivate IS NULL) AND (b.BusinessIsPrivate = 0 OR b.BusinessIsPrivate IS NULL)
ORDER BY b.Name ORDER BY b.BusinessName
", ",
[], [],
{ datasource = "payfrit" } { datasource = "payfrit" }
@ -63,15 +63,15 @@ try {
rows = []; rows = [];
for (i = 1; i <= q.recordCount; i++) { for (i = 1; i <= q.recordCount; i++) {
row = { row = {
"BusinessID": q.ID[i], "BusinessID": q.BusinessID[i],
"Name": q.Name[i], "Name": q.BusinessName[i],
"City": isNull(q.City[i]) ? "" : q.City[i], "City": isNull(q.AddressCity[i]) ? "" : q.AddressCity[i],
"Line1": isNull(q.Line1[i]) ? "" : q.Line1[i] "Line1": isNull(q.AddressLine1[i]) ? "" : q.AddressLine1[i]
}; };
// Calculate distance if we have both user location and business location // Calculate distance if we have both user location and business location
bizLat = isNull(q.Latitude[i]) ? 0 : val(q.Latitude[i]); bizLat = isNull(q.AddressLat[i]) ? 0 : val(q.AddressLat[i]);
bizLng = isNull(q.Longitude[i]) ? 0 : val(q.Longitude[i]); bizLng = isNull(q.AddressLng[i]) ? 0 : val(q.AddressLng[i]);
if (hasUserLocation AND bizLat != 0 AND bizLng != 0) { if (hasUserLocation AND bizLat != 0 AND bizLng != 0) {
row["DistanceMiles"] = haversineDistance(userLat, userLng, bizLat, bizLng); row["DistanceMiles"] = haversineDistance(userLat, userLng, bizLat, bizLng);

View file

@ -45,7 +45,7 @@ if (isHiring == -1) {
try { try {
queryExecute(" queryExecute("
UPDATE Businesses UPDATE Businesses
SET IsHiring = ? SET BusinessIsHiring = ?
WHERE BusinessID = ? WHERE BusinessID = ?
", [ ", [
{ value: isHiring, cfsqltype: "cf_sql_tinyint" }, { value: isHiring, cfsqltype: "cf_sql_tinyint" },

View file

@ -48,7 +48,7 @@ try {
if (len(bizName)) { if (len(bizName)) {
if (isNumeric(taxRate)) { if (isNumeric(taxRate)) {
queryExecute(" queryExecute("
UPDATE Businesses SET Name = :name, Phone = :phone, TaxRate = :taxRate UPDATE Businesses SET BusinessName = :name, BusinessPhone = :phone, BusinessTaxRate = :taxRate
WHERE BusinessID = :id WHERE BusinessID = :id
", { ", {
name: bizName, name: bizName,
@ -58,7 +58,7 @@ try {
}, { datasource: "payfrit" }); }, { datasource: "payfrit" });
} else { } else {
queryExecute(" queryExecute("
UPDATE Businesses SET Name = :name, Phone = :phone UPDATE Businesses SET BusinessName = :name, BusinessPhone = :phone
WHERE BusinessID = :id WHERE BusinessID = :id
", { ", {
name: bizName, name: bizName,
@ -90,8 +90,8 @@ try {
// Check if business has an address // Check if business has an address
qAddr = queryExecute(" qAddr = queryExecute("
SELECT ID FROM Addresses SELECT AddressID FROM Addresses
WHERE BusinessID = :bizID AND UserID = 0 AND IsDeleted = 0 WHERE AddressBusinessID = :bizID AND AddressUserID = 0 AND AddressIsDeleted = 0
LIMIT 1 LIMIT 1
", { bizID: businessId }, { datasource: "payfrit" }); ", { bizID: businessId }, { datasource: "payfrit" });
@ -99,11 +99,11 @@ try {
// Update existing address // Update existing address
queryExecute(" queryExecute("
UPDATE Addresses SET UPDATE Addresses SET
Line1 = :line1, AddressLine1 = :line1,
City = :city, AddressCity = :city,
StateID = :stateID, AddressStateID = :stateID,
ZIPCode = :zip AddressZIPCode = :zip
WHERE ID = :addrID WHERE AddressID = :addrID
", { ", {
line1: addressLine1, line1: addressLine1,
city: city, city: city,
@ -114,7 +114,7 @@ try {
} else { } else {
// Create new address // Create new address
queryExecute(" queryExecute("
INSERT INTO Addresses (Line1, City, StateID, ZIPCode, BusinessID, UserID, AddressTypeID, AddedOn) INSERT INTO Addresses (AddressLine1, AddressCity, AddressStateID, AddressZIPCode, AddressBusinessID, AddressUserID, AddressTypeID, AddressAddedOn)
VALUES (:line1, :city, :stateID, :zip, :bizID, 0, 2, NOW()) VALUES (:line1, :city, :stateID, :zip, :bizID, 0, 2, NOW())
", { ", {
line1: addressLine1, line1: addressLine1,

View file

@ -38,7 +38,7 @@ try {
// Delete all existing hours for this business // Delete all existing hours for this business
queryExecute(" queryExecute("
DELETE FROM Hours WHERE BusinessID = :bizID DELETE FROM Hours WHERE HoursBusinessID = :bizID
", { bizID: businessId }, { datasource: "payfrit" }); ", { bizID: businessId }, { datasource: "payfrit" });
// Insert new hours // Insert new hours
@ -55,7 +55,7 @@ try {
if (len(closeTime) == 5) closeTime = closeTime & ":00"; if (len(closeTime) == 5) closeTime = closeTime & ":00";
queryExecute(" queryExecute("
INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) INSERT INTO Hours (HoursBusinessID, HoursDayID, HoursOpenTime, HoursClosingTime)
VALUES (:bizID, :dayID, :openTime, :closeTime) VALUES (:bizID, :dayID, :openTime, :closeTime)
", { ", {
bizID: businessId, bizID: businessId,

View file

@ -22,14 +22,14 @@ try {
// Get counts before deletion // Get counts before deletion
qOrderLineItems = queryExecute("SELECT COUNT(*) as cnt FROM OrderLineItems", {}, { datasource: "payfrit" }); qOrderLineItems = queryExecute("SELECT COUNT(*) as cnt FROM OrderLineItems", {}, { datasource: "payfrit" });
qOrders = queryExecute("SELECT COUNT(*) as cnt FROM Orders", {}, { datasource: "payfrit" }); qOrders = queryExecute("SELECT COUNT(*) as cnt FROM Orders", {}, { datasource: "payfrit" });
qAddresses = queryExecute("SELECT COUNT(*) as cnt FROM Addresses", {}, { datasource: "payfrit" }); qAddresses = queryExecute("SELECT COUNT(*) as cnt FROM Addresses WHERE AddressTypeID != 2", {}, { datasource: "payfrit" });
qTasks = queryExecute("SELECT COUNT(*) as cnt FROM Tasks", {}, { datasource: "payfrit" }); qTasks = queryExecute("SELECT COUNT(*) as cnt FROM Tasks", {}, { datasource: "payfrit" });
// Delete in correct order (foreign key constraints) // Delete in correct order (foreign key constraints)
queryExecute("DELETE FROM Tasks", {}, { datasource: "payfrit" }); queryExecute("DELETE FROM Tasks", {}, { datasource: "payfrit" });
queryExecute("DELETE FROM OrderLineItems", {}, { datasource: "payfrit" }); queryExecute("DELETE FROM OrderLineItems", {}, { datasource: "payfrit" });
queryExecute("DELETE FROM Orders", {}, { datasource: "payfrit" }); queryExecute("DELETE FROM Orders", {}, { datasource: "payfrit" });
queryExecute("DELETE FROM Addresses", {}, { datasource: "payfrit" }); queryExecute("DELETE FROM Addresses WHERE AddressTypeID != 2", {}, { datasource: "payfrit" });
response = { response = {
"OK": true, "OK": true,

View file

@ -442,10 +442,10 @@ try {
brandColor = ""; brandColor = "";
try { try {
qBrand = queryExecute(" qBrand = queryExecute("
SELECT BrandColor FROM Businesses WHERE ID = :bizId SELECT BusinessBrandColor FROM Businesses WHERE BusinessID = :bizId
", { bizId: businessID }, { datasource: "payfrit" }); ", { bizId: businessID }, { datasource: "payfrit" });
if (qBrand.recordCount > 0 && len(trim(qBrand.BrandColor))) { if (qBrand.recordCount > 0 && len(trim(qBrand.BusinessBrandColor))) {
brandColor = left(qBrand.BrandColor, 1) == chr(35) ? qBrand.BrandColor : chr(35) & qBrand.BrandColor; brandColor = left(qBrand.BusinessBrandColor, 1) == chr(35) ? qBrand.BusinessBrandColor : chr(35) & qBrand.BusinessBrandColor;
} }
} catch (any e) { } catch (any e) {
// Column may not exist yet, ignore // Column may not exist yet, ignore

View file

@ -533,12 +533,12 @@
<cfset brandColor = ""> <cfset brandColor = "">
<cftry> <cftry>
<cfset qBrand = queryExecute( <cfset qBrand = queryExecute(
"SELECT BrandColor FROM Businesses WHERE ID = ?", "SELECT BusinessBrandColor FROM Businesses WHERE BusinessID = ?",
[ { value = BusinessID, cfsqltype = "cf_sql_integer" } ], [ { value = BusinessID, cfsqltype = "cf_sql_integer" } ],
{ datasource = "payfrit" } { datasource = "payfrit" }
)> )>
<cfif qBrand.recordCount GT 0 AND len(trim(qBrand.BrandColor))> <cfif qBrand.recordCount GT 0 AND len(trim(qBrand.BusinessBrandColor))>
<cfset brandColor = left(qBrand.BrandColor, 1) EQ chr(35) ? qBrand.BrandColor : chr(35) & qBrand.BrandColor> <cfset brandColor = left(qBrand.BusinessBrandColor, 1) EQ chr(35) ? qBrand.BusinessBrandColor : chr(35) & qBrand.BusinessBrandColor>
</cfif> </cfif>
<cfcatch> <cfcatch>
<!--- Column may not exist yet, ignore ---> <!--- Column may not exist yet, ignore --->

View file

@ -36,17 +36,17 @@ try {
o.StatusID, o.StatusID,
o.ServicePointID, o.ServicePointID,
o.AddedOn, o.AddedOn,
b.Name, b.BusinessName,
b.OrderTypes, b.BusinessOrderTypes,
sp.Name, sp.ServicePointName,
(SELECT COUNT(*) (SELECT COUNT(*)
FROM OrderLineItems oli FROM OrderLineItems oli
WHERE oli.OrderID = o.ID WHERE oli.OrderID = o.ID
AND oli.IsDeleted = 0 AND oli.IsDeleted = 0
AND oli.ParentOrderLineItemID = 0) as ItemCount AND oli.ParentOrderLineItemID = 0) as ItemCount
FROM Orders o FROM Orders o
LEFT JOIN Businesses b ON b.ID = o.BusinessID LEFT JOIN Businesses b ON b.BusinessID = o.BusinessID
LEFT JOIN ServicePoints sp ON sp.ID = o.ServicePointID LEFT JOIN ServicePoints sp ON sp.ServicePointID = o.ServicePointID
WHERE o.UserID = :userId WHERE o.UserID = :userId
AND o.StatusID = 0 AND o.StatusID = 0
ORDER BY o.ID DESC ORDER BY o.ID DESC
@ -65,7 +65,7 @@ try {
} }
// Parse business order types (e.g., "1,2,3" -> array of ints) // Parse business order types (e.g., "1,2,3" -> array of ints)
businessOrderTypes = len(trim(qCart.OrderTypes)) ? qCart.OrderTypes : "1,2,3"; businessOrderTypes = len(trim(qCart.BusinessOrderTypes)) ? qCart.BusinessOrderTypes : "1,2,3";
orderTypesArray = listToArray(businessOrderTypes, ","); orderTypesArray = listToArray(businessOrderTypes, ",");
response["OK"] = true; response["OK"] = true;
@ -74,12 +74,12 @@ try {
"OrderID": val(qCart.OrderID), "OrderID": val(qCart.OrderID),
"UUID": qCart.UUID ?: "", "UUID": qCart.UUID ?: "",
"BusinessID": val(qCart.BusinessID), "BusinessID": val(qCart.BusinessID),
"Name": len(trim(qCart.Name)) ? qCart.Name : "", "Name": len(trim(qCart.BusinessName)) ? qCart.BusinessName : "",
"OrderTypes": orderTypesArray, "OrderTypes": orderTypesArray,
"OrderTypeID": val(qCart.OrderTypeID), "OrderTypeID": val(qCart.OrderTypeID),
"OrderTypeName": orderTypeName, "OrderTypeName": orderTypeName,
"ServicePointID": val(qCart.ServicePointID), "ServicePointID": val(qCart.ServicePointID),
"Name": len(trim(qCart.Name)) ? qCart.Name : "", "ServicePointName": len(trim(qCart.ServicePointName)) ? qCart.ServicePointName : "",
"ItemCount": val(qCart.ItemCount), "ItemCount": val(qCart.ItemCount),
"AddedOn": dateTimeFormat(qCart.AddedOn, "yyyy-mm-dd HH:nn:ss") "AddedOn": dateTimeFormat(qCart.AddedOn, "yyyy-mm-dd HH:nn:ss")
}; };

View file

@ -67,12 +67,12 @@
<!--- Get business info for display in cart ---> <!--- Get business info for display in cart --->
<cfset qBusiness = queryExecute( <cfset qBusiness = queryExecute(
"SELECT DeliveryFlatFee, OrderTypes FROM Businesses WHERE ID = ? LIMIT 1", "SELECT BusinessDeliveryFlatFee, BusinessOrderTypes FROM Businesses WHERE BusinessID = ? LIMIT 1",
[ { value = qOrder.BusinessID, cfsqltype = "cf_sql_integer" } ], [ { value = qOrder.BusinessID, cfsqltype = "cf_sql_integer" } ],
{ datasource = "payfrit" } { datasource = "payfrit" }
)> )>
<cfset businessDeliveryFee = qBusiness.recordCount GT 0 ? qBusiness.DeliveryFlatFee : 0> <cfset businessDeliveryFee = qBusiness.recordCount GT 0 ? qBusiness.BusinessDeliveryFlatFee : 0>
<cfset businessOrderTypes = qBusiness.recordCount GT 0 AND len(trim(qBusiness.OrderTypes)) ? qBusiness.OrderTypes : "1,2,3"> <cfset businessOrderTypes = qBusiness.recordCount GT 0 AND len(trim(qBusiness.BusinessOrderTypes)) ? qBusiness.BusinessOrderTypes : "1,2,3">
<cfset businessOrderTypesArray = listToArray(businessOrderTypes, ",")> <cfset businessOrderTypesArray = listToArray(businessOrderTypes, ",")>
<cfset qLI = queryExecute( <cfset qLI = queryExecute(

View file

@ -62,11 +62,11 @@
<!--- Get business delivery fee for display in cart ---> <!--- Get business delivery fee for display in cart --->
<cfset var qBusiness = queryExecute( <cfset var qBusiness = queryExecute(
"SELECT DeliveryFlatFee FROM Businesses WHERE ID = ? LIMIT 1", "SELECT BusinessDeliveryFlatFee FROM Businesses WHERE BusinessID = ? LIMIT 1",
[ { value = qOrder.BusinessID, cfsqltype = "cf_sql_integer" } ], [ { value = qOrder.BusinessID, cfsqltype = "cf_sql_integer" } ],
{ datasource = "payfrit" } { datasource = "payfrit" }
)> )>
<cfset var businessDeliveryFee = qBusiness.recordCount GT 0 ? qBusiness.DeliveryFlatFee : 0> <cfset var businessDeliveryFee = qBusiness.recordCount GT 0 ? qBusiness.BusinessDeliveryFlatFee : 0>
<cfset out.Order = { <cfset out.Order = {
"OrderID": val(qOrder.ID), "OrderID": val(qOrder.ID),
@ -229,9 +229,9 @@
<!--- Create new cart order ---> <!--- Create new cart order --->
<cfset qBiz = queryExecute( <cfset qBiz = queryExecute(
" "
SELECT DeliveryMultiplier, DeliveryFlatFee SELECT BusinessDeliveryMultiplier, BusinessDeliveryFlatFee
FROM Businesses FROM Businesses
WHERE ID = ? WHERE BusinessID = ?
LIMIT 1 LIMIT 1
", ",
[ { value = BusinessID, cfsqltype = "cf_sql_integer" } ], [ { value = BusinessID, cfsqltype = "cf_sql_integer" } ],
@ -249,7 +249,7 @@
OrderTypeID: 0=undecided, 1=dine-in, 2=takeaway, 3=delivery OrderTypeID: 0=undecided, 1=dine-in, 2=takeaway, 3=delivery
Only delivery (3) should have delivery fee. Only delivery (3) should have delivery fee.
Note: For undecided orders (0), fee is set later via setOrderType.cfm ---> Note: For undecided orders (0), fee is set later via setOrderType.cfm --->
<cfset deliveryFee = (OrderTypeID EQ 3) ? qBiz.DeliveryFlatFee : 0> <cfset deliveryFee = (OrderTypeID EQ 3) ? qBiz.BusinessDeliveryFlatFee : 0>
<!--- Generate new OrderID (table is not auto-inc in SSOT) ---> <!--- Generate new OrderID (table is not auto-inc in SSOT) --->
<cfset qNext = queryExecute( <cfset qNext = queryExecute(
@ -300,7 +300,7 @@
{ value = newUUID, cfsqltype = "cf_sql_varchar" }, { value = newUUID, cfsqltype = "cf_sql_varchar" },
{ value = UserID, cfsqltype = "cf_sql_integer" }, { value = UserID, cfsqltype = "cf_sql_integer" },
{ value = BusinessID, cfsqltype = "cf_sql_integer" }, { value = BusinessID, cfsqltype = "cf_sql_integer" },
{ value = qBiz.DeliveryMultiplier, cfsqltype = "cf_sql_decimal" }, { value = qBiz.BusinessDeliveryMultiplier, cfsqltype = "cf_sql_decimal" },
{ value = OrderTypeID, cfsqltype = "cf_sql_integer" }, { value = OrderTypeID, cfsqltype = "cf_sql_integer" },
{ value = deliveryFee, cfsqltype = "cf_sql_decimal" }, { value = deliveryFee, cfsqltype = "cf_sql_decimal" },
{ value = nowDt, cfsqltype = "cf_sql_timestamp" }, { value = nowDt, cfsqltype = "cf_sql_timestamp" },

View file

@ -72,10 +72,10 @@ try {
o.OrderTypeID, o.OrderTypeID,
o.AddedOn, o.AddedOn,
o.LastEditedOn, o.LastEditedOn,
b.Name, b.BusinessName,
COALESCE(ot.Name, 'Unknown') as OrderTypeName COALESCE(ot.Name, 'Unknown') as OrderTypeName
FROM Orders o FROM Orders o
LEFT JOIN Businesses b ON b.ID = o.BusinessID LEFT JOIN Businesses b ON b.BusinessID = o.BusinessID
LEFT JOIN tt_OrderTypes ot ON ot.ID = o.OrderTypeID LEFT JOIN tt_OrderTypes ot ON ot.ID = o.OrderTypeID
WHERE o.UserID = :userId WHERE o.UserID = :userId
AND o.StatusID > 0 AND o.StatusID > 0
@ -144,7 +144,7 @@ try {
"OrderID": val(row.ID), "OrderID": val(row.ID),
"UUID": row.UUID ?: "", "UUID": row.UUID ?: "",
"BusinessID": val(row.BusinessID), "BusinessID": val(row.BusinessID),
"Name": row.Name ?: "Unknown", "Name": row.BusinessName ?: "Unknown",
"OrderTotal": round(val(total) * 100) / 100, "OrderTotal": round(val(total) * 100) / 100,
"StatusID": val(row.StatusID), "StatusID": val(row.StatusID),
"StatusName": statusText, "StatusName": statusText,

View file

@ -191,9 +191,9 @@
o.LastEditedOn, o.LastEditedOn,
o.SubmittedOn, o.SubmittedOn,
o.ServicePointID, o.ServicePointID,
COALESCE(b.DeliveryFlatFee, 0) AS BusinessDeliveryFee COALESCE(b.BusinessDeliveryFlatFee, 0) AS BusinessDeliveryFee
FROM Orders o FROM Orders o
LEFT JOIN Businesses b ON b.ID = o.BusinessID LEFT JOIN Businesses b ON b.BusinessID = o.BusinessID
WHERE o.ID = ? WHERE o.ID = ?
LIMIT 1 LIMIT 1
", ",

View file

@ -62,11 +62,11 @@
<!--- Get business delivery fee for display in cart ---> <!--- Get business delivery fee for display in cart --->
<cfset var qBusiness = queryExecute( <cfset var qBusiness = queryExecute(
"SELECT DeliveryFlatFee FROM Businesses WHERE ID = ? LIMIT 1", "SELECT BusinessDeliveryFlatFee FROM Businesses WHERE BusinessID = ? LIMIT 1",
[ { value = qOrder.BusinessID, cfsqltype = "cf_sql_integer" } ], [ { value = qOrder.BusinessID, cfsqltype = "cf_sql_integer" } ],
{ datasource = "payfrit" } { datasource = "payfrit" }
)> )>
<cfset var businessDeliveryFee = qBusiness.recordCount GT 0 ? qBusiness.DeliveryFlatFee : 0> <cfset var businessDeliveryFee = qBusiness.recordCount GT 0 ? qBusiness.BusinessDeliveryFlatFee : 0>
<cfset out.Order = { <cfset out.Order = {
"OrderID": val(qOrder.ID), "OrderID": val(qOrder.ID),
@ -201,12 +201,12 @@
<cfset deliveryFee = 0> <cfset deliveryFee = 0>
<cfif OrderTypeID EQ 3> <cfif OrderTypeID EQ 3>
<cfset qBiz = queryExecute( <cfset qBiz = queryExecute(
"SELECT DeliveryFlatFee FROM Businesses WHERE ID = ? LIMIT 1", "SELECT BusinessDeliveryFlatFee FROM Businesses WHERE BusinessID = ? LIMIT 1",
[ { value = qOrder.BusinessID, cfsqltype = "cf_sql_integer" } ], [ { value = qOrder.BusinessID, cfsqltype = "cf_sql_integer" } ],
{ datasource = "payfrit" } { datasource = "payfrit" }
)> )>
<cfif qBiz.recordCount GT 0> <cfif qBiz.recordCount GT 0>
<cfset deliveryFee = qBiz.DeliveryFlatFee> <cfset deliveryFee = qBiz.BusinessDeliveryFlatFee>
</cfif> </cfif>
</cfif> </cfif>

View file

@ -82,7 +82,7 @@ try {
} }
queryExecute(" queryExecute("
INSERT INTO Addresses (Line1, City, StateID, ZIPCode, UserID, AddressTypeID, AddedOn) INSERT INTO Addresses (AddressLine1, AddressCity, AddressStateID, AddressZIPCode, AddressUserID, AddressTypeID, AddressAddedOn)
VALUES (:line1, :city, :stateID, :zip, :userID, :typeID, NOW()) VALUES (:line1, :city, :stateID, :zip, :userID, :typeID, NOW())
", { ", {
line1: len(addressLine1) ? addressLine1 : "Address pending", line1: len(addressLine1) ? addressLine1 : "Address pending",
@ -103,7 +103,7 @@ try {
// Create new business with address link and phone // Create new business with address link and phone
queryExecute(" queryExecute("
INSERT INTO Businesses (Name, Phone, UserID, AddressID, BusinessDeliveryZipCodes, CommunityMealType, TaxRate, AddedOn) INSERT INTO Businesses (BusinessName, BusinessPhone, BusinessUserID, BusinessAddressID, BusinessDeliveryZipCodes, BusinessCommunityMealType, BusinessTaxRate, BusinessAddedOn)
VALUES (:name, :phone, :userId, :addressId, :deliveryZips, :communityMealType, :taxRate, NOW()) VALUES (:name, :phone, :userId, :addressId, :deliveryZips, :communityMealType, :taxRate, NOW())
", { ", {
name: bizName, name: bizName,
@ -121,7 +121,7 @@ try {
// Update address with business ID link // Update address with business ID link
queryExecute(" queryExecute("
UPDATE Addresses SET BusinessID = :businessID WHERE ID = :addressID UPDATE Addresses SET AddressBusinessID = :businessID WHERE AddressID = :addressID
", { ", {
businessID: businessId, businessID: businessId,
addressID: addressId addressID: addressId
@ -188,14 +188,14 @@ try {
} else { } else {
// Verify existing business exists // Verify existing business exists
qBiz = queryExecute(" qBiz = queryExecute("
SELECT ID, Name FROM Businesses WHERE ID = :id SELECT BusinessID, BusinessName FROM Businesses WHERE BusinessID = :id
", { id: businessId }, { datasource: "payfrit" }); ", { id: businessId }, { datasource: "payfrit" });
if (qBiz.recordCount == 0) { if (qBiz.recordCount == 0) {
throw(message="Business not found: " & businessId); throw(message="Business not found: " & businessId);
} }
response.steps.append("Found existing business: " & qBiz.Name); response.steps.append("Found existing business: " & qBiz.BusinessName);
} }
// Build modifier template map // Build modifier template map

View file

@ -62,9 +62,9 @@ try {
// Get business Stripe account // Get business Stripe account
qBusiness = queryExecute(" qBusiness = queryExecute("
SELECT StripeAccountID, StripeOnboardingComplete, Name SELECT BusinessStripeAccountID, BusinessStripeOnboardingComplete, BusinessName
FROM Businesses FROM Businesses
WHERE ID = :businessID WHERE BusinessID = :businessID
", { businessID: businessID }, { datasource: "payfrit" }); ", { businessID: businessID }, { datasource: "payfrit" });
if (qBusiness.recordCount == 0) { if (qBusiness.recordCount == 0) {
@ -75,18 +75,18 @@ try {
// Get order's delivery fee (if delivery order) // Get order's delivery fee (if delivery order)
qOrder = queryExecute(" qOrder = queryExecute("
SELECT DeliveryFee, OrderTypeID SELECT OrderDeliveryFee, OrderTypeID
FROM Orders FROM Orders
WHERE ID = :orderID WHERE OrderID = :orderID
", { orderID: orderID }, { datasource: "payfrit" }); ", { orderID: orderID }, { datasource: "payfrit" });
deliveryFee = 0; deliveryFee = 0;
if (qOrder.recordCount > 0 && qOrder.OrderTypeID == 3) { if (qOrder.recordCount > 0 && qOrder.OrderTypeID == 3) {
deliveryFee = val(qOrder.DeliveryFee); deliveryFee = val(qOrder.OrderDeliveryFee);
} }
// For testing, allow orders even without Stripe Connect setup // For testing, allow orders even without Stripe Connect setup
hasStripeConnect = qBusiness.StripeOnboardingComplete == 1 && len(trim(qBusiness.StripeAccountID)) > 0; hasStripeConnect = qBusiness.BusinessStripeOnboardingComplete == 1 && len(trim(qBusiness.BusinessStripeAccountID)) > 0;
// ============================================================ // ============================================================
// FEE CALCULATION // FEE CALCULATION
@ -119,12 +119,12 @@ try {
if (hasStripeConnect) { if (hasStripeConnect) {
httpService.addParam(type="formfield", name="application_fee_amount", value=totalPlatformFeeCents); httpService.addParam(type="formfield", name="application_fee_amount", value=totalPlatformFeeCents);
httpService.addParam(type="formfield", name="transfer_data[destination]", value=qBusiness.StripeAccountID); httpService.addParam(type="formfield", name="transfer_data[destination]", value=qBusiness.BusinessStripeAccountID);
} }
httpService.addParam(type="formfield", name="metadata[order_id]", value=orderID); 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[business_id]", value=businessID);
httpService.addParam(type="formfield", name="description", value="Order ###orderID# at #qBusiness.Name#"); httpService.addParam(type="formfield", name="description", value="Order ###orderID# at #qBusiness.BusinessName#");
if (customerEmail != "") { if (customerEmail != "") {
httpService.addParam(type="formfield", name="receipt_email", value=customerEmail); httpService.addParam(type="formfield", name="receipt_email", value=customerEmail);

View file

@ -32,9 +32,9 @@ try {
// Check if business already has a Stripe account // Check if business already has a Stripe account
qBusiness = queryExecute(" qBusiness = queryExecute("
SELECT StripeAccountID, Name, BusinessEmail SELECT BusinessStripeAccountID, BusinessName
FROM Businesses FROM Businesses
WHERE ID = :businessID WHERE BusinessID = :businessID
", { businessID: businessID }); ", { businessID: businessID });
if (qBusiness.recordCount == 0) { if (qBusiness.recordCount == 0) {
@ -43,7 +43,7 @@ try {
abort; abort;
} }
stripeAccountID = qBusiness.StripeAccountID; stripeAccountID = qBusiness.BusinessStripeAccountID;
// Create new connected account if none exists // Create new connected account if none exists
if (stripeAccountID == "" || isNull(stripeAccountID)) { if (stripeAccountID == "" || isNull(stripeAccountID)) {
@ -55,10 +55,9 @@ try {
httpService.setPassword(""); httpService.setPassword("");
httpService.addParam(type="formfield", name="type", value="express"); httpService.addParam(type="formfield", name="type", value="express");
httpService.addParam(type="formfield", name="country", value="US"); httpService.addParam(type="formfield", name="country", value="US");
httpService.addParam(type="formfield", name="email", value=qBusiness.BusinessEmail);
httpService.addParam(type="formfield", name="capabilities[card_payments][requested]", value="true"); httpService.addParam(type="formfield", name="capabilities[card_payments][requested]", value="true");
httpService.addParam(type="formfield", name="capabilities[transfers][requested]", value="true"); httpService.addParam(type="formfield", name="capabilities[transfers][requested]", value="true");
httpService.addParam(type="formfield", name="business_profile[name]", value=qBusiness.Name); httpService.addParam(type="formfield", name="business_profile[name]", value=qBusiness.BusinessName);
result = httpService.send().getPrefix(); result = httpService.send().getPrefix();
accountData = deserializeJSON(result.fileContent); accountData = deserializeJSON(result.fileContent);
@ -74,8 +73,8 @@ try {
// Save to database // Save to database
queryExecute(" queryExecute("
UPDATE Businesses UPDATE Businesses
SET StripeAccountID = :stripeAccountID, SET BusinessStripeAccountID = :stripeAccountID,
StripeOnboardingStarted = NOW() BusinessStripeOnboardingStarted = NOW()
WHERE BusinessID = :businessID WHERE BusinessID = :businessID
", { ", {
stripeAccountID: stripeAccountID, stripeAccountID: stripeAccountID,

View file

@ -23,9 +23,9 @@ try {
// Get business Stripe info // Get business Stripe info
qBusiness = queryExecute(" qBusiness = queryExecute("
SELECT StripeAccountID, StripeOnboardingComplete SELECT BusinessStripeAccountID, BusinessStripeOnboardingComplete
FROM Businesses FROM Businesses
WHERE ID = :businessID WHERE BusinessID = :businessID
", { businessID: businessID }); ", { businessID: businessID });
if (qBusiness.recordCount == 0) { if (qBusiness.recordCount == 0) {
@ -34,7 +34,7 @@ try {
abort; abort;
} }
stripeAccountID = qBusiness.StripeAccountID; stripeAccountID = qBusiness.BusinessStripeAccountID;
if (stripeAccountID == "" || isNull(stripeAccountID)) { if (stripeAccountID == "" || isNull(stripeAccountID)) {
response["OK"] = true; response["OK"] = true;
@ -73,10 +73,10 @@ try {
accountStatus = "active"; accountStatus = "active";
// Mark as complete in database if not already // Mark as complete in database if not already
if (!qBusiness.StripeOnboardingComplete) { if (!qBusiness.BusinessStripeOnboardingComplete) {
queryExecute(" queryExecute("
UPDATE Businesses UPDATE Businesses
SET StripeOnboardingComplete = 1 SET BusinessStripeOnboardingComplete = 1
WHERE BusinessID = :businessID WHERE BusinessID = :businessID
", { businessID: businessID }); ", { businessID: businessID });
} }
@ -96,8 +96,8 @@ try {
} else { } else {
// No Stripe key, just return what we have in DB // No Stripe key, just return what we have in DB
response["OK"] = true; response["OK"] = true;
response["CONNECTED"] = qBusiness.StripeOnboardingComplete == 1; response["CONNECTED"] = qBusiness.BusinessStripeOnboardingComplete == 1;
response["ACCOUNT_STATUS"] = qBusiness.StripeOnboardingComplete == 1 ? "active" : "unknown"; response["ACCOUNT_STATUS"] = qBusiness.BusinessStripeOnboardingComplete == 1 ? "active" : "unknown";
response["STRIPE_ACCOUNT_ID"] = stripeAccountID; response["STRIPE_ACCOUNT_ID"] = stripeAccountID;
} }

View file

@ -22,15 +22,43 @@ try {
// Webhook secret (set in Stripe dashboard) // Webhook secret (set in Stripe dashboard)
webhookSecret = application.stripeWebhookSecret ?: ""; webhookSecret = application.stripeWebhookSecret ?: "";
// For now, skip signature verification in development // Verify webhook signature (Stripe HMAC-SHA256)
// In production, uncomment and implement signature verification: if (len(trim(webhookSecret)) > 0 && len(trim(sigHeader)) > 0) {
/* // Parse signature header: t=timestamp,v1=signature
if (webhookSecret != "" && sigHeader != "") { sigParts = {};
// Verify webhook signature for (part in listToArray(sigHeader, ",")) {
// This requires computing HMAC-SHA256 and comparing kv = listToArray(trim(part), "=");
// See: https://stripe.com/docs/webhooks/signatures if (arrayLen(kv) >= 2) sigParts[trim(kv[1])] = trim(kv[2]);
}
sigTimestamp = sigParts["t"] ?: "";
sigV1 = sigParts["v1"] ?: "";
if (len(sigTimestamp) == 0 || len(sigV1) == 0) {
response["ERROR"] = "invalid_signature";
writeOutput(serializeJSON(response));
abort;
}
// Check timestamp tolerance (5 minutes)
timestampAge = dateDiff("s", dateAdd("s", val(sigTimestamp), createDate(1970,1,1)), now());
if (abs(timestampAge) > 300) {
response["ERROR"] = "timestamp_expired";
writeOutput(serializeJSON(response));
abort;
}
// Compute expected signature: HMAC-SHA256(timestamp + "." + payload, secret)
signedPayload = sigTimestamp & "." & payload;
expectedSig = lcase(hmac(signedPayload, webhookSecret, "HmacSHA256"));
if (expectedSig != lcase(sigV1)) {
writeLog(file="stripe_webhooks", text="Signature mismatch! Expected=#left(expectedSig,16)#... Got=#left(sigV1,16)#...");
response["ERROR"] = "signature_mismatch";
writeOutput(serializeJSON(response));
abort;
}
} }
*/
// Parse event // Parse event
event = deserializeJSON(payload); event = deserializeJSON(payload);
@ -101,6 +129,7 @@ try {
httpTransfer.addParam(type="formfield", name="metadata[task_id]", value=qLedger.TaskID); httpTransfer.addParam(type="formfield", name="metadata[task_id]", value=qLedger.TaskID);
httpTransfer.addParam(type="formfield", name="metadata[ledger_id]", value=qLedger.ID); httpTransfer.addParam(type="formfield", name="metadata[ledger_id]", value=qLedger.ID);
httpTransfer.addParam(type="formfield", name="metadata[activation_withheld_cents]", value=0); httpTransfer.addParam(type="formfield", name="metadata[activation_withheld_cents]", value=0);
httpTransfer.addParam(type="header", name="Idempotency-Key", value="transfer-ledger-#qLedger.ID#");
transferResult = httpTransfer.send().getPrefix(); transferResult = httpTransfer.send().getPrefix();
transferData = deserializeJSON(transferResult.fileContent); transferData = deserializeJSON(transferResult.fileContent);

View file

@ -105,7 +105,7 @@
<cfset queryExecute(" <cfset queryExecute("
UPDATE Tasks UPDATE Tasks
SET CompletedOn = NOW() SET CompletedOn = NOW()
WHERE TaskID = ? WHERE ID = ?
", [ { value = TaskID, cfsqltype = "cf_sql_integer" } ], { datasource = "payfrit" })> ", [ { value = TaskID, cfsqltype = "cf_sql_integer" } ], { datasource = "payfrit" })>
<!--- If task has an associated order, mark it as Delivered/Complete (status 5) ---> <!--- If task has an associated order, mark it as Delivered/Complete (status 5) --->
@ -126,7 +126,7 @@
<cfif workerUserID_for_payout GT 0> <cfif workerUserID_for_payout GT 0>
<!--- Get PayCents from the task ---> <!--- Get PayCents from the task --->
<cfset qTaskPay = queryExecute(" <cfset qTaskPay = queryExecute("
SELECT PayCents FROM Tasks WHERE TaskID = ? SELECT PayCents FROM Tasks WHERE ID = ?
", [ { value = TaskID, cfsqltype = "cf_sql_integer" } ], { datasource = "payfrit" })> ", [ { value = TaskID, cfsqltype = "cf_sql_integer" } ], { datasource = "payfrit" })>
<cfset grossCents = val(qTaskPay.PayCents)> <cfset grossCents = val(qTaskPay.PayCents)>

View file

@ -59,8 +59,9 @@ try {
httpService.addParam(type="formfield", name="line_items[0][price_data][currency]", value="usd"); httpService.addParam(type="formfield", name="line_items[0][price_data][currency]", value="usd");
httpService.addParam(type="formfield", name="line_items[0][price_data][product_data][name]", value="Payfrit Activation"); httpService.addParam(type="formfield", name="line_items[0][price_data][product_data][name]", value="Payfrit Activation");
httpService.addParam(type="formfield", name="line_items[0][quantity]", value="1"); httpService.addParam(type="formfield", name="line_items[0][quantity]", value="1");
httpService.addParam(type="formfield", name="success_url", value="https://biz.payfrit.com/works/activation?success=1"); baseUrl = application.isDevEnvironment ? "https://dev.payfrit.com" : "https://biz.payfrit.com";
httpService.addParam(type="formfield", name="cancel_url", value="https://biz.payfrit.com/works/activation?cancel=1"); httpService.addParam(type="formfield", name="success_url", value=baseUrl & "/works/stripe-return.cfm?status=success");
httpService.addParam(type="formfield", name="cancel_url", value=baseUrl & "/works/stripe-return.cfm?status=cancel");
httpService.addParam(type="formfield", name="metadata[user_id]", value=userID); httpService.addParam(type="formfield", name="metadata[user_id]", value=userID);
httpService.addParam(type="formfield", name="metadata[type]", value="activation_unlock"); httpService.addParam(type="formfield", name="metadata[type]", value="activation_unlock");

View file

@ -53,8 +53,9 @@ try {
httpService.setPassword(""); httpService.setPassword("");
httpService.addParam(type="formfield", name="account", value=accountID); httpService.addParam(type="formfield", name="account", value=accountID);
httpService.addParam(type="formfield", name="refresh_url", value="https://biz.payfrit.com/works/tier?refresh=1"); baseUrl = application.isDevEnvironment ? "https://dev.payfrit.com" : "https://biz.payfrit.com";
httpService.addParam(type="formfield", name="return_url", value="https://biz.payfrit.com/works/tier?return=1"); httpService.addParam(type="formfield", name="refresh_url", value=baseUrl & "/works/stripe-return.cfm?status=refresh");
httpService.addParam(type="formfield", name="return_url", value=baseUrl & "/works/stripe-return.cfm?status=complete");
httpService.addParam(type="formfield", name="type", value="account_onboarding"); httpService.addParam(type="formfield", name="type", value="account_onboarding");
result = httpService.send().getPrefix(); result = httpService.send().getPrefix();