This repository has been archived on 2026-03-21. You can view files and clone it, but cannot push or open issues or pull requests.
payfrit-biz/api/grants/accept.cfm
John Mizerek f52d14bb7e Add Service Point Sharing infrastructure
Grant-based system allowing businesses to share service points with
other businesses. Includes grant CRUD API, time/eligibility/economics
policies, enforcement at cart creation and order submit, Stripe payment
routing for owner fees, and portal UI for managing grants.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 21:34:03 -08:00

93 lines
2.8 KiB
Text

<cfsetting showdebugoutput="false">
<cfsetting enablecfoutputonly="true">
<cfcontent type="application/json; charset=utf-8" reset="true">
<cfheader name="Cache-Control" value="no-store">
<cfinclude template="_grantUtils.cfm">
<cfscript>
data = {};
try {
raw = toString(getHttpRequestData().content);
if (len(trim(raw))) {
data = deserializeJSON(raw);
if (!isStruct(data)) data = {};
}
} catch (any e) { data = {}; }
grantID = val(data.GrantID ?: 0);
inviteToken = trim(data.InviteToken ?: "");
if (grantID LTE 0 && len(inviteToken) == 0) {
apiAbort({ "OK": false, "ERROR": "missing_params", "MESSAGE": "GrantID or InviteToken is required." });
}
callerUserID = val(structKeyExists(request, "UserID") ? request.UserID : 0);
if (callerUserID LTE 0) {
apiAbort({ "OK": false, "ERROR": "not_authenticated" });
}
// Load grant by ID or token
if (grantID GT 0) {
qGrant = queryExecute(
"SELECT g.*, b.UserID AS GuestOwnerUserID
FROM ServicePointGrants g
JOIN Businesses b ON b.ID = g.GuestBusinessID
WHERE g.ID = ?
LIMIT 1",
[{ value = grantID, cfsqltype = "cf_sql_integer" }],
{ datasource = "payfrit" }
);
} else {
qGrant = queryExecute(
"SELECT g.*, b.UserID AS GuestOwnerUserID
FROM ServicePointGrants g
JOIN Businesses b ON b.ID = g.GuestBusinessID
WHERE g.InviteToken = ?
LIMIT 1",
[{ value = inviteToken, cfsqltype = "cf_sql_varchar" }],
{ datasource = "payfrit" }
);
}
if (qGrant.recordCount == 0) {
apiAbort({ "OK": false, "ERROR": "not_found", "MESSAGE": "Grant not found." });
}
if (qGrant.GuestOwnerUserID != callerUserID) {
apiAbort({ "OK": false, "ERROR": "not_guest_owner", "MESSAGE": "Only the guest business owner can accept this invite." });
}
if (qGrant.StatusID != 0) {
statusLabels = { 1: "already active", 2: "declined", 3: "revoked" };
label = structKeyExists(statusLabels, qGrant.StatusID) ? statusLabels[qGrant.StatusID] : "not pending";
apiAbort({ "OK": false, "ERROR": "bad_state", "MESSAGE": "This grant is #label# and cannot be accepted." });
}
// Accept: activate grant
queryExecute(
"UPDATE ServicePointGrants
SET StatusID = 1, AcceptedOn = NOW(), AcceptedByUserID = ?, InviteToken = NULL
WHERE ID = ?",
[
{ value = callerUserID, cfsqltype = "cf_sql_integer" },
{ value = qGrant.ID, cfsqltype = "cf_sql_integer" }
],
{ datasource = "payfrit" }
);
recordGrantHistory(
grantID = qGrant.ID,
action = "accepted",
actorUserID = callerUserID,
actorBusinessID = qGrant.GuestBusinessID,
previousData = { "StatusID": 0 },
newData = { "StatusID": 1 }
);
writeOutput(serializeJSON({
"OK": true,
"GrantID": qGrant.ID,
"MESSAGE": "Grant accepted. Service point access is now active."
}));
</cfscript>