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:
parent
62c61c13cd
commit
6b66d2cef8
26 changed files with 222 additions and 227 deletions
|
|
@ -37,36 +37,19 @@ try {
|
|||
apiAbort({ "OK": false, "ERROR": "missing_fields", "MESSAGE": "UUID and OTP are required" });
|
||||
}
|
||||
|
||||
// Check for magic OTP bypass (for App Store review)
|
||||
isMagicOTP = structKeyExists(application, "MAGIC_OTP_ENABLED")
|
||||
&& application.MAGIC_OTP_ENABLED
|
||||
&& structKeyExists(application, "MAGIC_OTP_CODE")
|
||||
&& otp == application.MAGIC_OTP_CODE;
|
||||
|
||||
// Find verified user with matching UUID and OTP (or magic OTP)
|
||||
if (isMagicOTP) {
|
||||
qUser = queryExecute("
|
||||
SELECT ID, FirstName, LastName
|
||||
FROM Users
|
||||
WHERE UUID = :uuid
|
||||
AND IsContactVerified = 1
|
||||
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" });
|
||||
}
|
||||
// Find verified user with matching UUID and OTP
|
||||
// Magic OTP only bypasses Twilio SMS (in loginOTP.cfm), not OTP verification
|
||||
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) {
|
||||
// Check if UUID exists but OTP is wrong
|
||||
|
|
|
|||
|
|
@ -40,36 +40,19 @@ try {
|
|||
apiAbort({ "OK": false, "ERROR": "missing_fields", "MESSAGE": "UUID and OTP are required" });
|
||||
}
|
||||
|
||||
// Check for magic OTP bypass (for App Store review)
|
||||
isMagicOTP = structKeyExists(application, "MAGIC_OTP_ENABLED")
|
||||
&& application.MAGIC_OTP_ENABLED
|
||||
&& structKeyExists(application, "MAGIC_OTP_CODE")
|
||||
&& otp == application.MAGIC_OTP_CODE;
|
||||
|
||||
// Find unverified user with matching UUID and OTP (or magic OTP)
|
||||
if (isMagicOTP) {
|
||||
qUser = queryExecute("
|
||||
SELECT ID, FirstName, LastName, EmailAddress, IsEmailVerified
|
||||
FROM Users
|
||||
WHERE UUID = :uuid
|
||||
AND IsContactVerified = 0
|
||||
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" });
|
||||
}
|
||||
// Find unverified user with matching UUID and OTP
|
||||
// Magic OTP only bypasses Twilio SMS (in sendOTP.cfm), not OTP verification
|
||||
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) {
|
||||
// Check if UUID exists but OTP is wrong
|
||||
|
|
|
|||
|
|
@ -50,11 +50,11 @@ beaconId = int(data.BeaconID);
|
|||
SELECT
|
||||
sp.BusinessID,
|
||||
sp.ID AS ServicePointID,
|
||||
biz.Name AS BusinessName,
|
||||
biz.ParentBusinessID,
|
||||
biz.BusinessName AS BusinessName,
|
||||
biz.BusinessParentBusinessID,
|
||||
sp.Name AS ServicePointName
|
||||
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#">
|
||||
AND sp.IsActive = 1
|
||||
|
||||
|
|
@ -63,18 +63,18 @@ beaconId = int(data.BeaconID);
|
|||
SELECT
|
||||
lt.BusinessID,
|
||||
0 AS ServicePointID,
|
||||
biz.Name AS BusinessName,
|
||||
biz.ParentBusinessID,
|
||||
biz.BusinessName AS BusinessName,
|
||||
biz.BusinessParentBusinessID,
|
||||
'' AS ServicePointName
|
||||
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#">
|
||||
AND lt.BusinessID NOT IN (
|
||||
SELECT sp2.BusinessID FROM ServicePoints sp2
|
||||
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>
|
||||
|
||||
<!--- Check if any assigned business is a parent (has children) --->
|
||||
|
|
@ -83,7 +83,7 @@ beaconId = int(data.BeaconID);
|
|||
<!--- Check if this business has children --->
|
||||
<cfquery name="qChildren" datasource="payfrit">
|
||||
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>
|
||||
<cfif qChildren.cnt GT 0>
|
||||
<cfset parentBusinessID = qAssignments.BusinessID>
|
||||
|
|
@ -98,24 +98,24 @@ beaconId = int(data.BeaconID);
|
|||
<cfif parentBusinessID GT 0>
|
||||
<!--- Get parent business info for header image --->
|
||||
<cfquery name="qParent" datasource="payfrit">
|
||||
SELECT Name, HeaderImageExtension
|
||||
SELECT BusinessName, BusinessHeaderImageExtension
|
||||
FROM Businesses
|
||||
WHERE ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#parentBusinessID#">
|
||||
WHERE BusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#parentBusinessID#">
|
||||
</cfquery>
|
||||
<cfquery name="qChildBusinesses" datasource="payfrit">
|
||||
SELECT
|
||||
ID,
|
||||
Name,
|
||||
ParentBusinessID,
|
||||
HeaderImageExtension
|
||||
BusinessID,
|
||||
BusinessName,
|
||||
BusinessParentBusinessID,
|
||||
BusinessHeaderImageExtension
|
||||
FROM Businesses
|
||||
WHERE ParentBusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#parentBusinessID#">
|
||||
WHERE BusinessParentBusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#parentBusinessID#">
|
||||
ORDER BY Name ASC
|
||||
</cfquery>
|
||||
<cfloop query="qChildBusinesses">
|
||||
<cfset arrayAppend(businesses, {
|
||||
"BusinessID" = qChildBusinesses.ID,
|
||||
"Name" = qChildBusinesses.Name,
|
||||
"BusinessID" = qChildBusinesses.BusinessID,
|
||||
"Name" = qChildBusinesses.BusinessName,
|
||||
"ServicePointID" = qAssignments.ServicePointID,
|
||||
"ServicePointName" = qAssignments.ServicePointName,
|
||||
"IsParent" = false,
|
||||
|
|
@ -156,8 +156,8 @@ beaconId = int(data.BeaconID);
|
|||
<cfif parentBusinessID GT 0>
|
||||
<cfset response["PARENT"] = {
|
||||
"BusinessID" = parentBusinessID,
|
||||
"Name" = qParent.Name,
|
||||
"HeaderImageExtension" = len(trim(qParent.HeaderImageExtension)) ? qParent.HeaderImageExtension : ""
|
||||
"Name" = qParent.BusinessName,
|
||||
"HeaderImageExtension" = len(trim(qParent.BusinessHeaderImageExtension)) ? qParent.BusinessHeaderImageExtension : ""
|
||||
}>
|
||||
</cfif>
|
||||
|
||||
|
|
|
|||
|
|
@ -35,17 +35,17 @@ try {
|
|||
// Get business details
|
||||
q = queryExecute("
|
||||
SELECT
|
||||
ID,
|
||||
Name,
|
||||
Phone,
|
||||
StripeAccountID,
|
||||
StripeOnboardingComplete,
|
||||
IsHiring,
|
||||
HeaderImageExtension,
|
||||
TaxRate,
|
||||
BrandColor
|
||||
BusinessID,
|
||||
BusinessName,
|
||||
BusinessPhone,
|
||||
BusinessStripeAccountID,
|
||||
BusinessStripeOnboardingComplete,
|
||||
BusinessIsHiring,
|
||||
BusinessHeaderImageExtension,
|
||||
BusinessTaxRate,
|
||||
BusinessBrandColor
|
||||
FROM Businesses
|
||||
WHERE ID = :businessID
|
||||
WHERE BusinessID = :businessID
|
||||
", { businessID: businessID }, { datasource: "payfrit" });
|
||||
|
||||
if (q.recordCount == 0) {
|
||||
|
|
@ -54,13 +54,13 @@ try {
|
|||
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("
|
||||
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
|
||||
LEFT JOIN tt_States s ON s.ID = a.StateID
|
||||
WHERE (a.BusinessID = :businessID OR a.ID = (SELECT AddressID FROM Businesses WHERE ID = :businessID))
|
||||
AND a.IsDeleted = 0
|
||||
LEFT JOIN tt_States s ON s.ID = a.AddressStateID
|
||||
WHERE (a.AddressBusinessID = :businessID OR a.AddressID = (SELECT BusinessAddressID FROM Businesses WHERE BusinessID = :businessID))
|
||||
AND a.AddressIsDeleted = 0
|
||||
LIMIT 1
|
||||
", { businessID: businessID }, { datasource: "payfrit" });
|
||||
|
||||
|
|
@ -70,29 +70,29 @@ try {
|
|||
addressState = "";
|
||||
addressZip = "";
|
||||
if (qAddr.recordCount > 0) {
|
||||
addressLine1 = qAddr.Line1;
|
||||
addressCity = qAddr.City;
|
||||
addressLine1 = qAddr.AddressLine1;
|
||||
addressCity = qAddr.AddressCity;
|
||||
addressState = qAddr.Abbreviation;
|
||||
addressZip = qAddr.ZIPCode;
|
||||
addressZip = qAddr.AddressZIPCode;
|
||||
|
||||
addressParts = [];
|
||||
if (len(qAddr.Line1)) arrayAppend(addressParts, qAddr.Line1);
|
||||
if (len(qAddr.Line2)) arrayAppend(addressParts, qAddr.Line2);
|
||||
if (len(qAddr.AddressLine1)) arrayAppend(addressParts, qAddr.AddressLine1);
|
||||
if (len(qAddr.AddressLine2)) arrayAppend(addressParts, qAddr.AddressLine2);
|
||||
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.ZIPCode)) arrayAppend(cityStateZip, qAddr.ZIPCode);
|
||||
if (len(qAddr.AddressZIPCode)) arrayAppend(cityStateZip, qAddr.AddressZIPCode);
|
||||
if (arrayLen(cityStateZip) > 0) arrayAppend(addressParts, arrayToList(cityStateZip, ", "));
|
||||
addressStr = arrayToList(addressParts, ", ");
|
||||
}
|
||||
|
||||
// Get hours from Hours table
|
||||
qHours = queryExecute("
|
||||
SELECT h.DayID, h.OpenTime, h.ClosingTime, d.Abbrev
|
||||
SELECT h.HoursDayID, h.HoursOpenTime, h.HoursClosingTime, d.Abbrev
|
||||
FROM Hours h
|
||||
JOIN tt_Days d ON d.ID = h.DayID
|
||||
WHERE h.BusinessID = :businessID
|
||||
ORDER BY h.DayID
|
||||
JOIN tt_Days d ON d.ID = h.HoursDayID
|
||||
WHERE h.HoursBusinessID = :businessID
|
||||
ORDER BY h.HoursDayID
|
||||
", { businessID: businessID }, { datasource: "payfrit" });
|
||||
|
||||
hoursArr = [];
|
||||
|
|
@ -101,13 +101,12 @@ try {
|
|||
for (h in qHours) {
|
||||
arrayAppend(hoursArr, {
|
||||
"day": h.Abbrev,
|
||||
"dayId": h.DayID,
|
||||
"open": timeFormat(h.OpenTime, "h:mm tt"),
|
||||
"close": timeFormat(h.ClosingTime, "h:mm tt")
|
||||
"dayId": h.HoursDayID,
|
||||
"open": timeFormat(h.HoursOpenTime, "h:mm tt"),
|
||||
"close": timeFormat(h.HoursClosingTime, "h:mm tt")
|
||||
});
|
||||
}
|
||||
// Build readable hours string (group similar days)
|
||||
// Mon-Thu: 11am-10pm, Fri-Sat: 11am-11pm, Sun: 11am-10pm
|
||||
hourGroups = {};
|
||||
for (h in hoursArr) {
|
||||
key = h.open & "-" & h.close;
|
||||
|
|
@ -125,28 +124,28 @@ try {
|
|||
}
|
||||
|
||||
// Build business object
|
||||
taxRate = isNumeric(q.TaxRate) ? q.TaxRate : 0;
|
||||
taxRate = isNumeric(q.BusinessTaxRate) ? q.BusinessTaxRate : 0;
|
||||
business = {
|
||||
"BusinessID": q.ID,
|
||||
"Name": q.Name,
|
||||
"BusinessID": q.BusinessID,
|
||||
"Name": q.BusinessName,
|
||||
"Address": addressStr,
|
||||
"Line1": addressLine1,
|
||||
"City": addressCity,
|
||||
"AddressState": addressState,
|
||||
"AddressZip": addressZip,
|
||||
"Phone": q.Phone,
|
||||
"Phone": q.BusinessPhone,
|
||||
"Hours": hoursStr,
|
||||
"HoursDetail": hoursArr,
|
||||
"StripeConnected": (len(q.StripeAccountID) > 0 && q.StripeOnboardingComplete == 1),
|
||||
"IsHiring": q.IsHiring == 1,
|
||||
"StripeConnected": (len(q.BusinessStripeAccountID) > 0 && q.BusinessStripeOnboardingComplete == 1),
|
||||
"IsHiring": q.BusinessIsHiring == 1,
|
||||
"TaxRate": taxRate,
|
||||
"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
|
||||
if (len(q.HeaderImageExtension)) {
|
||||
business["HeaderImageURL"] = "https://biz.payfrit.com/uploads/headers/" & q.ID & "." & q.HeaderImageExtension;
|
||||
if (len(q.BusinessHeaderImageExtension)) {
|
||||
business["HeaderImageURL"] = "https://biz.payfrit.com/uploads/headers/" & q.BusinessID & "." & q.BusinessHeaderImageExtension;
|
||||
}
|
||||
|
||||
response["OK"] = true;
|
||||
|
|
|
|||
|
|
@ -36,10 +36,10 @@ try {
|
|||
q = queryExecute(
|
||||
"
|
||||
SELECT
|
||||
ID,
|
||||
Name
|
||||
BusinessID,
|
||||
BusinessName
|
||||
FROM Businesses
|
||||
WHERE ParentBusinessID = :parentId
|
||||
WHERE BusinessParentBusinessID = :parentId
|
||||
ORDER BY Name
|
||||
",
|
||||
{ parentId = { value = parentBusinessId, cfsqltype = "cf_sql_integer" } },
|
||||
|
|
@ -49,8 +49,8 @@ try {
|
|||
rows = [];
|
||||
for (i = 1; i <= q.recordCount; i++) {
|
||||
arrayAppend(rows, {
|
||||
"BusinessID": q.ID[i],
|
||||
"Name": q.Name[i]
|
||||
"BusinessID": q.BusinessID[i],
|
||||
"Name": q.BusinessName[i]
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,17 +43,17 @@ try {
|
|||
q = queryExecute(
|
||||
"
|
||||
SELECT
|
||||
b.ID,
|
||||
b.Name,
|
||||
a.Latitude,
|
||||
a.Longitude,
|
||||
a.City,
|
||||
a.Line1
|
||||
b.BusinessID,
|
||||
b.BusinessName,
|
||||
a.AddressLat,
|
||||
a.AddressLng,
|
||||
a.AddressCity,
|
||||
a.AddressLine1
|
||||
FROM Businesses b
|
||||
LEFT JOIN Addresses a ON b.AddressID = a.ID
|
||||
WHERE (b.IsDemo = 0 OR b.IsDemo IS NULL)
|
||||
AND (b.IsPrivate = 0 OR b.IsPrivate IS NULL)
|
||||
ORDER BY b.Name
|
||||
LEFT JOIN Addresses a ON b.BusinessAddressID = a.AddressID
|
||||
WHERE (b.BusinessIsDemo = 0 OR b.BusinessIsDemo IS NULL)
|
||||
AND (b.BusinessIsPrivate = 0 OR b.BusinessIsPrivate IS NULL)
|
||||
ORDER BY b.BusinessName
|
||||
",
|
||||
[],
|
||||
{ datasource = "payfrit" }
|
||||
|
|
@ -63,15 +63,15 @@ try {
|
|||
rows = [];
|
||||
for (i = 1; i <= q.recordCount; i++) {
|
||||
row = {
|
||||
"BusinessID": q.ID[i],
|
||||
"Name": q.Name[i],
|
||||
"City": isNull(q.City[i]) ? "" : q.City[i],
|
||||
"Line1": isNull(q.Line1[i]) ? "" : q.Line1[i]
|
||||
"BusinessID": q.BusinessID[i],
|
||||
"Name": q.BusinessName[i],
|
||||
"City": isNull(q.AddressCity[i]) ? "" : q.AddressCity[i],
|
||||
"Line1": isNull(q.AddressLine1[i]) ? "" : q.AddressLine1[i]
|
||||
};
|
||||
|
||||
// Calculate distance if we have both user location and business location
|
||||
bizLat = isNull(q.Latitude[i]) ? 0 : val(q.Latitude[i]);
|
||||
bizLng = isNull(q.Longitude[i]) ? 0 : val(q.Longitude[i]);
|
||||
bizLat = isNull(q.AddressLat[i]) ? 0 : val(q.AddressLat[i]);
|
||||
bizLng = isNull(q.AddressLng[i]) ? 0 : val(q.AddressLng[i]);
|
||||
|
||||
if (hasUserLocation AND bizLat != 0 AND bizLng != 0) {
|
||||
row["DistanceMiles"] = haversineDistance(userLat, userLng, bizLat, bizLng);
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ if (isHiring == -1) {
|
|||
try {
|
||||
queryExecute("
|
||||
UPDATE Businesses
|
||||
SET IsHiring = ?
|
||||
SET BusinessIsHiring = ?
|
||||
WHERE BusinessID = ?
|
||||
", [
|
||||
{ value: isHiring, cfsqltype: "cf_sql_tinyint" },
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ try {
|
|||
if (len(bizName)) {
|
||||
if (isNumeric(taxRate)) {
|
||||
queryExecute("
|
||||
UPDATE Businesses SET Name = :name, Phone = :phone, TaxRate = :taxRate
|
||||
UPDATE Businesses SET BusinessName = :name, BusinessPhone = :phone, BusinessTaxRate = :taxRate
|
||||
WHERE BusinessID = :id
|
||||
", {
|
||||
name: bizName,
|
||||
|
|
@ -58,7 +58,7 @@ try {
|
|||
}, { datasource: "payfrit" });
|
||||
} else {
|
||||
queryExecute("
|
||||
UPDATE Businesses SET Name = :name, Phone = :phone
|
||||
UPDATE Businesses SET BusinessName = :name, BusinessPhone = :phone
|
||||
WHERE BusinessID = :id
|
||||
", {
|
||||
name: bizName,
|
||||
|
|
@ -90,8 +90,8 @@ try {
|
|||
|
||||
// Check if business has an address
|
||||
qAddr = queryExecute("
|
||||
SELECT ID FROM Addresses
|
||||
WHERE BusinessID = :bizID AND UserID = 0 AND IsDeleted = 0
|
||||
SELECT AddressID FROM Addresses
|
||||
WHERE AddressBusinessID = :bizID AND AddressUserID = 0 AND AddressIsDeleted = 0
|
||||
LIMIT 1
|
||||
", { bizID: businessId }, { datasource: "payfrit" });
|
||||
|
||||
|
|
@ -99,11 +99,11 @@ try {
|
|||
// Update existing address
|
||||
queryExecute("
|
||||
UPDATE Addresses SET
|
||||
Line1 = :line1,
|
||||
City = :city,
|
||||
StateID = :stateID,
|
||||
ZIPCode = :zip
|
||||
WHERE ID = :addrID
|
||||
AddressLine1 = :line1,
|
||||
AddressCity = :city,
|
||||
AddressStateID = :stateID,
|
||||
AddressZIPCode = :zip
|
||||
WHERE AddressID = :addrID
|
||||
", {
|
||||
line1: addressLine1,
|
||||
city: city,
|
||||
|
|
@ -114,7 +114,7 @@ try {
|
|||
} else {
|
||||
// Create new address
|
||||
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())
|
||||
", {
|
||||
line1: addressLine1,
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ try {
|
|||
|
||||
// Delete all existing hours for this business
|
||||
queryExecute("
|
||||
DELETE FROM Hours WHERE BusinessID = :bizID
|
||||
DELETE FROM Hours WHERE HoursBusinessID = :bizID
|
||||
", { bizID: businessId }, { datasource: "payfrit" });
|
||||
|
||||
// Insert new hours
|
||||
|
|
@ -55,7 +55,7 @@ try {
|
|||
if (len(closeTime) == 5) closeTime = closeTime & ":00";
|
||||
|
||||
queryExecute("
|
||||
INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime)
|
||||
INSERT INTO Hours (HoursBusinessID, HoursDayID, HoursOpenTime, HoursClosingTime)
|
||||
VALUES (:bizID, :dayID, :openTime, :closeTime)
|
||||
", {
|
||||
bizID: businessId,
|
||||
|
|
|
|||
|
|
@ -22,14 +22,14 @@ try {
|
|||
// Get counts before deletion
|
||||
qOrderLineItems = queryExecute("SELECT COUNT(*) as cnt FROM OrderLineItems", {}, { 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" });
|
||||
|
||||
// Delete in correct order (foreign key constraints)
|
||||
queryExecute("DELETE FROM Tasks", {}, { datasource: "payfrit" });
|
||||
queryExecute("DELETE FROM OrderLineItems", {}, { datasource: "payfrit" });
|
||||
queryExecute("DELETE FROM Orders", {}, { datasource: "payfrit" });
|
||||
queryExecute("DELETE FROM Addresses", {}, { datasource: "payfrit" });
|
||||
queryExecute("DELETE FROM Addresses WHERE AddressTypeID != 2", {}, { datasource: "payfrit" });
|
||||
|
||||
response = {
|
||||
"OK": true,
|
||||
|
|
|
|||
|
|
@ -442,10 +442,10 @@ try {
|
|||
brandColor = "";
|
||||
try {
|
||||
qBrand = queryExecute("
|
||||
SELECT BrandColor FROM Businesses WHERE ID = :bizId
|
||||
SELECT BusinessBrandColor FROM Businesses WHERE BusinessID = :bizId
|
||||
", { bizId: businessID }, { datasource: "payfrit" });
|
||||
if (qBrand.recordCount > 0 && len(trim(qBrand.BrandColor))) {
|
||||
brandColor = left(qBrand.BrandColor, 1) == chr(35) ? qBrand.BrandColor : chr(35) & qBrand.BrandColor;
|
||||
if (qBrand.recordCount > 0 && len(trim(qBrand.BusinessBrandColor))) {
|
||||
brandColor = left(qBrand.BusinessBrandColor, 1) == chr(35) ? qBrand.BusinessBrandColor : chr(35) & qBrand.BusinessBrandColor;
|
||||
}
|
||||
} catch (any e) {
|
||||
// Column may not exist yet, ignore
|
||||
|
|
|
|||
|
|
@ -533,12 +533,12 @@
|
|||
<cfset brandColor = "">
|
||||
<cftry>
|
||||
<cfset qBrand = queryExecute(
|
||||
"SELECT BrandColor FROM Businesses WHERE ID = ?",
|
||||
"SELECT BusinessBrandColor FROM Businesses WHERE BusinessID = ?",
|
||||
[ { value = BusinessID, cfsqltype = "cf_sql_integer" } ],
|
||||
{ datasource = "payfrit" }
|
||||
)>
|
||||
<cfif qBrand.recordCount GT 0 AND len(trim(qBrand.BrandColor))>
|
||||
<cfset brandColor = left(qBrand.BrandColor, 1) EQ chr(35) ? qBrand.BrandColor : chr(35) & qBrand.BrandColor>
|
||||
<cfif qBrand.recordCount GT 0 AND len(trim(qBrand.BusinessBrandColor))>
|
||||
<cfset brandColor = left(qBrand.BusinessBrandColor, 1) EQ chr(35) ? qBrand.BusinessBrandColor : chr(35) & qBrand.BusinessBrandColor>
|
||||
</cfif>
|
||||
<cfcatch>
|
||||
<!--- Column may not exist yet, ignore --->
|
||||
|
|
|
|||
|
|
@ -36,17 +36,17 @@ try {
|
|||
o.StatusID,
|
||||
o.ServicePointID,
|
||||
o.AddedOn,
|
||||
b.Name,
|
||||
b.OrderTypes,
|
||||
sp.Name,
|
||||
b.BusinessName,
|
||||
b.BusinessOrderTypes,
|
||||
sp.ServicePointName,
|
||||
(SELECT COUNT(*)
|
||||
FROM OrderLineItems oli
|
||||
WHERE oli.OrderID = o.ID
|
||||
AND oli.IsDeleted = 0
|
||||
AND oli.ParentOrderLineItemID = 0) as ItemCount
|
||||
FROM Orders o
|
||||
LEFT JOIN Businesses b ON b.ID = o.BusinessID
|
||||
LEFT JOIN ServicePoints sp ON sp.ID = o.ServicePointID
|
||||
LEFT JOIN Businesses b ON b.BusinessID = o.BusinessID
|
||||
LEFT JOIN ServicePoints sp ON sp.ServicePointID = o.ServicePointID
|
||||
WHERE o.UserID = :userId
|
||||
AND o.StatusID = 0
|
||||
ORDER BY o.ID DESC
|
||||
|
|
@ -65,7 +65,7 @@ try {
|
|||
}
|
||||
|
||||
// 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, ",");
|
||||
|
||||
response["OK"] = true;
|
||||
|
|
@ -74,12 +74,12 @@ try {
|
|||
"OrderID": val(qCart.OrderID),
|
||||
"UUID": qCart.UUID ?: "",
|
||||
"BusinessID": val(qCart.BusinessID),
|
||||
"Name": len(trim(qCart.Name)) ? qCart.Name : "",
|
||||
"Name": len(trim(qCart.BusinessName)) ? qCart.BusinessName : "",
|
||||
"OrderTypes": orderTypesArray,
|
||||
"OrderTypeID": val(qCart.OrderTypeID),
|
||||
"OrderTypeName": orderTypeName,
|
||||
"ServicePointID": val(qCart.ServicePointID),
|
||||
"Name": len(trim(qCart.Name)) ? qCart.Name : "",
|
||||
"ServicePointName": len(trim(qCart.ServicePointName)) ? qCart.ServicePointName : "",
|
||||
"ItemCount": val(qCart.ItemCount),
|
||||
"AddedOn": dateTimeFormat(qCart.AddedOn, "yyyy-mm-dd HH:nn:ss")
|
||||
};
|
||||
|
|
|
|||
|
|
@ -67,12 +67,12 @@
|
|||
|
||||
<!--- Get business info for display in cart --->
|
||||
<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" } ],
|
||||
{ datasource = "payfrit" }
|
||||
)>
|
||||
<cfset businessDeliveryFee = qBusiness.recordCount GT 0 ? qBusiness.DeliveryFlatFee : 0>
|
||||
<cfset businessOrderTypes = qBusiness.recordCount GT 0 AND len(trim(qBusiness.OrderTypes)) ? qBusiness.OrderTypes : "1,2,3">
|
||||
<cfset businessDeliveryFee = qBusiness.recordCount GT 0 ? qBusiness.BusinessDeliveryFlatFee : 0>
|
||||
<cfset businessOrderTypes = qBusiness.recordCount GT 0 AND len(trim(qBusiness.BusinessOrderTypes)) ? qBusiness.BusinessOrderTypes : "1,2,3">
|
||||
<cfset businessOrderTypesArray = listToArray(businessOrderTypes, ",")>
|
||||
|
||||
<cfset qLI = queryExecute(
|
||||
|
|
|
|||
|
|
@ -62,11 +62,11 @@
|
|||
|
||||
<!--- Get business delivery fee for display in cart --->
|
||||
<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" } ],
|
||||
{ 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 = {
|
||||
"OrderID": val(qOrder.ID),
|
||||
|
|
@ -229,9 +229,9 @@
|
|||
<!--- Create new cart order --->
|
||||
<cfset qBiz = queryExecute(
|
||||
"
|
||||
SELECT DeliveryMultiplier, DeliveryFlatFee
|
||||
SELECT BusinessDeliveryMultiplier, BusinessDeliveryFlatFee
|
||||
FROM Businesses
|
||||
WHERE ID = ?
|
||||
WHERE BusinessID = ?
|
||||
LIMIT 1
|
||||
",
|
||||
[ { value = BusinessID, cfsqltype = "cf_sql_integer" } ],
|
||||
|
|
@ -249,7 +249,7 @@
|
|||
OrderTypeID: 0=undecided, 1=dine-in, 2=takeaway, 3=delivery
|
||||
Only delivery (3) should have delivery fee.
|
||||
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) --->
|
||||
<cfset qNext = queryExecute(
|
||||
|
|
@ -300,7 +300,7 @@
|
|||
{ value = newUUID, cfsqltype = "cf_sql_varchar" },
|
||||
{ value = UserID, 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 = deliveryFee, cfsqltype = "cf_sql_decimal" },
|
||||
{ value = nowDt, cfsqltype = "cf_sql_timestamp" },
|
||||
|
|
|
|||
|
|
@ -72,10 +72,10 @@ try {
|
|||
o.OrderTypeID,
|
||||
o.AddedOn,
|
||||
o.LastEditedOn,
|
||||
b.Name,
|
||||
b.BusinessName,
|
||||
COALESCE(ot.Name, 'Unknown') as OrderTypeName
|
||||
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
|
||||
WHERE o.UserID = :userId
|
||||
AND o.StatusID > 0
|
||||
|
|
@ -144,7 +144,7 @@ try {
|
|||
"OrderID": val(row.ID),
|
||||
"UUID": row.UUID ?: "",
|
||||
"BusinessID": val(row.BusinessID),
|
||||
"Name": row.Name ?: "Unknown",
|
||||
"Name": row.BusinessName ?: "Unknown",
|
||||
"OrderTotal": round(val(total) * 100) / 100,
|
||||
"StatusID": val(row.StatusID),
|
||||
"StatusName": statusText,
|
||||
|
|
|
|||
|
|
@ -191,9 +191,9 @@
|
|||
o.LastEditedOn,
|
||||
o.SubmittedOn,
|
||||
o.ServicePointID,
|
||||
COALESCE(b.DeliveryFlatFee, 0) AS BusinessDeliveryFee
|
||||
COALESCE(b.BusinessDeliveryFlatFee, 0) AS BusinessDeliveryFee
|
||||
FROM Orders o
|
||||
LEFT JOIN Businesses b ON b.ID = o.BusinessID
|
||||
LEFT JOIN Businesses b ON b.BusinessID = o.BusinessID
|
||||
WHERE o.ID = ?
|
||||
LIMIT 1
|
||||
",
|
||||
|
|
|
|||
|
|
@ -62,11 +62,11 @@
|
|||
|
||||
<!--- Get business delivery fee for display in cart --->
|
||||
<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" } ],
|
||||
{ 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 = {
|
||||
"OrderID": val(qOrder.ID),
|
||||
|
|
@ -201,12 +201,12 @@
|
|||
<cfset deliveryFee = 0>
|
||||
<cfif OrderTypeID EQ 3>
|
||||
<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" } ],
|
||||
{ datasource = "payfrit" }
|
||||
)>
|
||||
<cfif qBiz.recordCount GT 0>
|
||||
<cfset deliveryFee = qBiz.DeliveryFlatFee>
|
||||
<cfset deliveryFee = qBiz.BusinessDeliveryFlatFee>
|
||||
</cfif>
|
||||
</cfif>
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ try {
|
|||
}
|
||||
|
||||
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())
|
||||
", {
|
||||
line1: len(addressLine1) ? addressLine1 : "Address pending",
|
||||
|
|
@ -103,7 +103,7 @@ try {
|
|||
|
||||
// Create new business with address link and phone
|
||||
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())
|
||||
", {
|
||||
name: bizName,
|
||||
|
|
@ -121,7 +121,7 @@ try {
|
|||
|
||||
// Update address with business ID link
|
||||
queryExecute("
|
||||
UPDATE Addresses SET BusinessID = :businessID WHERE ID = :addressID
|
||||
UPDATE Addresses SET AddressBusinessID = :businessID WHERE AddressID = :addressID
|
||||
", {
|
||||
businessID: businessId,
|
||||
addressID: addressId
|
||||
|
|
@ -188,14 +188,14 @@ try {
|
|||
} else {
|
||||
// Verify existing business exists
|
||||
qBiz = queryExecute("
|
||||
SELECT ID, Name FROM Businesses WHERE ID = :id
|
||||
SELECT BusinessID, BusinessName FROM Businesses WHERE BusinessID = :id
|
||||
", { id: businessId }, { datasource: "payfrit" });
|
||||
|
||||
if (qBiz.recordCount == 0) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -62,9 +62,9 @@ try {
|
|||
|
||||
// Get business Stripe account
|
||||
qBusiness = queryExecute("
|
||||
SELECT StripeAccountID, StripeOnboardingComplete, Name
|
||||
SELECT BusinessStripeAccountID, BusinessStripeOnboardingComplete, BusinessName
|
||||
FROM Businesses
|
||||
WHERE ID = :businessID
|
||||
WHERE BusinessID = :businessID
|
||||
", { businessID: businessID }, { datasource: "payfrit" });
|
||||
|
||||
if (qBusiness.recordCount == 0) {
|
||||
|
|
@ -75,18 +75,18 @@ try {
|
|||
|
||||
// Get order's delivery fee (if delivery order)
|
||||
qOrder = queryExecute("
|
||||
SELECT DeliveryFee, OrderTypeID
|
||||
SELECT OrderDeliveryFee, OrderTypeID
|
||||
FROM Orders
|
||||
WHERE ID = :orderID
|
||||
WHERE OrderID = :orderID
|
||||
", { orderID: orderID }, { datasource: "payfrit" });
|
||||
|
||||
deliveryFee = 0;
|
||||
if (qOrder.recordCount > 0 && qOrder.OrderTypeID == 3) {
|
||||
deliveryFee = val(qOrder.DeliveryFee);
|
||||
deliveryFee = val(qOrder.OrderDeliveryFee);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
|
@ -119,12 +119,12 @@ try {
|
|||
|
||||
if (hasStripeConnect) {
|
||||
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[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 != "") {
|
||||
httpService.addParam(type="formfield", name="receipt_email", value=customerEmail);
|
||||
|
|
|
|||
|
|
@ -32,9 +32,9 @@ try {
|
|||
|
||||
// Check if business already has a Stripe account
|
||||
qBusiness = queryExecute("
|
||||
SELECT StripeAccountID, Name, BusinessEmail
|
||||
SELECT BusinessStripeAccountID, BusinessName
|
||||
FROM Businesses
|
||||
WHERE ID = :businessID
|
||||
WHERE BusinessID = :businessID
|
||||
", { businessID: businessID });
|
||||
|
||||
if (qBusiness.recordCount == 0) {
|
||||
|
|
@ -43,7 +43,7 @@ try {
|
|||
abort;
|
||||
}
|
||||
|
||||
stripeAccountID = qBusiness.StripeAccountID;
|
||||
stripeAccountID = qBusiness.BusinessStripeAccountID;
|
||||
|
||||
// Create new connected account if none exists
|
||||
if (stripeAccountID == "" || isNull(stripeAccountID)) {
|
||||
|
|
@ -55,10 +55,9 @@ try {
|
|||
httpService.setPassword("");
|
||||
httpService.addParam(type="formfield", name="type", value="express");
|
||||
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[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();
|
||||
accountData = deserializeJSON(result.fileContent);
|
||||
|
|
@ -74,8 +73,8 @@ try {
|
|||
// Save to database
|
||||
queryExecute("
|
||||
UPDATE Businesses
|
||||
SET StripeAccountID = :stripeAccountID,
|
||||
StripeOnboardingStarted = NOW()
|
||||
SET BusinessStripeAccountID = :stripeAccountID,
|
||||
BusinessStripeOnboardingStarted = NOW()
|
||||
WHERE BusinessID = :businessID
|
||||
", {
|
||||
stripeAccountID: stripeAccountID,
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ try {
|
|||
|
||||
// Get business Stripe info
|
||||
qBusiness = queryExecute("
|
||||
SELECT StripeAccountID, StripeOnboardingComplete
|
||||
SELECT BusinessStripeAccountID, BusinessStripeOnboardingComplete
|
||||
FROM Businesses
|
||||
WHERE ID = :businessID
|
||||
WHERE BusinessID = :businessID
|
||||
", { businessID: businessID });
|
||||
|
||||
if (qBusiness.recordCount == 0) {
|
||||
|
|
@ -34,7 +34,7 @@ try {
|
|||
abort;
|
||||
}
|
||||
|
||||
stripeAccountID = qBusiness.StripeAccountID;
|
||||
stripeAccountID = qBusiness.BusinessStripeAccountID;
|
||||
|
||||
if (stripeAccountID == "" || isNull(stripeAccountID)) {
|
||||
response["OK"] = true;
|
||||
|
|
@ -73,10 +73,10 @@ try {
|
|||
accountStatus = "active";
|
||||
|
||||
// Mark as complete in database if not already
|
||||
if (!qBusiness.StripeOnboardingComplete) {
|
||||
if (!qBusiness.BusinessStripeOnboardingComplete) {
|
||||
queryExecute("
|
||||
UPDATE Businesses
|
||||
SET StripeOnboardingComplete = 1
|
||||
SET BusinessStripeOnboardingComplete = 1
|
||||
WHERE BusinessID = :businessID
|
||||
", { businessID: businessID });
|
||||
}
|
||||
|
|
@ -96,8 +96,8 @@ try {
|
|||
} else {
|
||||
// No Stripe key, just return what we have in DB
|
||||
response["OK"] = true;
|
||||
response["CONNECTED"] = qBusiness.StripeOnboardingComplete == 1;
|
||||
response["ACCOUNT_STATUS"] = qBusiness.StripeOnboardingComplete == 1 ? "active" : "unknown";
|
||||
response["CONNECTED"] = qBusiness.BusinessStripeOnboardingComplete == 1;
|
||||
response["ACCOUNT_STATUS"] = qBusiness.BusinessStripeOnboardingComplete == 1 ? "active" : "unknown";
|
||||
response["STRIPE_ACCOUNT_ID"] = stripeAccountID;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,15 +22,43 @@ try {
|
|||
// Webhook secret (set in Stripe dashboard)
|
||||
webhookSecret = application.stripeWebhookSecret ?: "";
|
||||
|
||||
// For now, skip signature verification in development
|
||||
// In production, uncomment and implement signature verification:
|
||||
/*
|
||||
if (webhookSecret != "" && sigHeader != "") {
|
||||
// Verify webhook signature
|
||||
// This requires computing HMAC-SHA256 and comparing
|
||||
// See: https://stripe.com/docs/webhooks/signatures
|
||||
// Verify webhook signature (Stripe HMAC-SHA256)
|
||||
if (len(trim(webhookSecret)) > 0 && len(trim(sigHeader)) > 0) {
|
||||
// Parse signature header: t=timestamp,v1=signature
|
||||
sigParts = {};
|
||||
for (part in listToArray(sigHeader, ",")) {
|
||||
kv = listToArray(trim(part), "=");
|
||||
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
|
||||
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[ledger_id]", value=qLedger.ID);
|
||||
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();
|
||||
transferData = deserializeJSON(transferResult.fileContent);
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@
|
|||
<cfset queryExecute("
|
||||
UPDATE Tasks
|
||||
SET CompletedOn = NOW()
|
||||
WHERE TaskID = ?
|
||||
WHERE ID = ?
|
||||
", [ { value = TaskID, cfsqltype = "cf_sql_integer" } ], { datasource = "payfrit" })>
|
||||
|
||||
<!--- If task has an associated order, mark it as Delivered/Complete (status 5) --->
|
||||
|
|
@ -126,7 +126,7 @@
|
|||
<cfif workerUserID_for_payout GT 0>
|
||||
<!--- Get PayCents from the task --->
|
||||
<cfset qTaskPay = queryExecute("
|
||||
SELECT PayCents FROM Tasks WHERE TaskID = ?
|
||||
SELECT PayCents FROM Tasks WHERE ID = ?
|
||||
", [ { value = TaskID, cfsqltype = "cf_sql_integer" } ], { datasource = "payfrit" })>
|
||||
<cfset grossCents = val(qTaskPay.PayCents)>
|
||||
|
||||
|
|
|
|||
|
|
@ -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][product_data][name]", value="Payfrit Activation");
|
||||
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");
|
||||
httpService.addParam(type="formfield", name="cancel_url", value="https://biz.payfrit.com/works/activation?cancel=1");
|
||||
baseUrl = application.isDevEnvironment ? "https://dev.payfrit.com" : "https://biz.payfrit.com";
|
||||
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[type]", value="activation_unlock");
|
||||
|
||||
|
|
|
|||
|
|
@ -53,8 +53,9 @@ try {
|
|||
httpService.setPassword("");
|
||||
|
||||
httpService.addParam(type="formfield", name="account", value=accountID);
|
||||
httpService.addParam(type="formfield", name="refresh_url", value="https://biz.payfrit.com/works/tier?refresh=1");
|
||||
httpService.addParam(type="formfield", name="return_url", value="https://biz.payfrit.com/works/tier?return=1");
|
||||
baseUrl = application.isDevEnvironment ? "https://dev.payfrit.com" : "https://biz.payfrit.com";
|
||||
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");
|
||||
|
||||
result = httpService.send().getPrefix();
|
||||
|
|
|
|||
Reference in a new issue