Add Stripe Customer creation to save payment methods

- Get user info (StripeCustomerId, email, name) when creating PaymentIntent
- Create Stripe Customer if user doesn't have one
- Add customer and setup_future_usage=off_session to PaymentIntent
- Cards are automatically saved after successful payment

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
John Mizerek 2026-02-17 17:56:13 -08:00
parent 9e2c3a8478
commit 07c2f24d67

View file

@ -73,11 +73,14 @@ try {
abort;
}
// Get order's delivery fee, grant economics, and existing PaymentIntent
// Get order's delivery fee, grant economics, existing PaymentIntent, and user info
qOrder = queryExecute("
SELECT DeliveryFee, OrderTypeID, GrantID, GrantOwnerBusinessID, GrantEconomicsType, GrantEconomicsValue, StripePaymentIntentID
FROM Orders
WHERE ID = :orderID
SELECT o.DeliveryFee, o.OrderTypeID, o.GrantID, o.GrantOwnerBusinessID,
o.GrantEconomicsType, o.GrantEconomicsValue, o.StripePaymentIntentID,
o.UserID, u.StripeCustomerId, u.EmailAddress, u.FirstName, u.LastName
FROM Orders o
LEFT JOIN Users u ON u.ID = o.UserID
WHERE o.ID = :orderID
", { orderID: orderID }, { datasource: "payfrit" });
// Check if order already has a PaymentIntent (idempotency check)
@ -137,6 +140,50 @@ try {
totalAmountCents = round(totalCustomerPays * 100);
totalPlatformFeeCents = round((payfritCustomerFee + payfritBusinessFee) * 100);
// ============================================================
// STRIPE CUSTOMER (for saving payment methods)
// ============================================================
stripeCustomerId = "";
orderUserID = val(qOrder.UserID ?: 0);
if (orderUserID > 0) {
stripeCustomerId = qOrder.StripeCustomerId ?: "";
// Create Stripe Customer if user doesn't have one
if (len(trim(stripeCustomerId)) == 0) {
customerService = new http();
customerService.setMethod("POST");
customerService.setUrl("https://api.stripe.com/v1/customers");
customerService.setUsername(stripeSecretKey);
customerService.setPassword("");
// Build customer name
customerName = trim((qOrder.FirstName ?: "") & " " & (qOrder.LastName ?: ""));
if (len(customerName) > 0) {
customerService.addParam(type="formfield", name="name", value=customerName);
}
if (len(trim(qOrder.EmailAddress ?: "")) > 0) {
customerService.addParam(type="formfield", name="email", value=qOrder.EmailAddress);
}
customerService.addParam(type="formfield", name="metadata[user_id]", value=orderUserID);
customerResult = customerService.send().getPrefix();
customerData = deserializeJSON(customerResult.fileContent);
if (!structKeyExists(customerData, "error") && structKeyExists(customerData, "id")) {
stripeCustomerId = customerData.id;
// Save to Users table
queryExecute("
UPDATE Users SET StripeCustomerId = :custId WHERE ID = :userId
", {
custId: stripeCustomerId,
userId: orderUserID
}, { datasource: "payfrit" });
writeLog(file="stripe_webhooks", text="Created Stripe Customer #stripeCustomerId# for user #orderUserID#");
}
}
}
// Create PaymentIntent
httpService = new http();
httpService.setMethod("POST");
@ -151,6 +198,12 @@ try {
httpService.addParam(type="formfield", name="currency", value="usd");
httpService.addParam(type="formfield", name="automatic_payment_methods[enabled]", value="true");
// Attach customer and save payment method for future use
if (len(trim(stripeCustomerId)) > 0) {
httpService.addParam(type="formfield", name="customer", value=stripeCustomerId);
httpService.addParam(type="formfield", name="setup_future_usage", value="off_session");
}
if (hasStripeConnect) {
// SP-SM: Add grant owner fee to platform fee (Payfrit collects, then transfers to owner)
effectivePlatformFeeCents = totalPlatformFeeCents + grantOwnerFeeCents;