fix: validate Stripe customer before using, handle mode mismatch
If a user has a live-mode StripeCustomerId but the API is running in test mode (or vice versa), the PI creation fails. Now validates the customer with Stripe first and creates a new one if invalid. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5dd0884b8f
commit
f3a41bf01a
2 changed files with 32 additions and 4 deletions
|
|
@ -233,8 +233,23 @@ try {
|
||||||
if (orderUserID > 0) {
|
if (orderUserID > 0) {
|
||||||
stripeCustomerId = qOrder.StripeCustomerId ?: "";
|
stripeCustomerId = qOrder.StripeCustomerId ?: "";
|
||||||
|
|
||||||
// Create Stripe Customer if user doesn't have one
|
// Validate existing customer (catches live/test mode mismatch)
|
||||||
if (len(trim(stripeCustomerId)) == 0) {
|
needNewCustomer = (len(trim(stripeCustomerId)) == 0);
|
||||||
|
if (!needNewCustomer) {
|
||||||
|
validateService = new http();
|
||||||
|
validateService.setMethod("GET");
|
||||||
|
validateService.setUrl("https://api.stripe.com/v1/customers/#stripeCustomerId#");
|
||||||
|
validateService.setUsername(stripeSecretKey);
|
||||||
|
validateService.setPassword("");
|
||||||
|
validateResult = validateService.send().getPrefix();
|
||||||
|
validateData = deserializeJSON(validateResult.fileContent);
|
||||||
|
if (structKeyExists(validateData, "error") || !structKeyExists(validateData, "id")) {
|
||||||
|
needNewCustomer = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Stripe Customer if needed
|
||||||
|
if (needNewCustomer) {
|
||||||
customerService = new http();
|
customerService = new http();
|
||||||
customerService.setMethod("POST");
|
customerService.setMethod("POST");
|
||||||
customerService.setUrl("https://api.stripe.com/v1/customers");
|
customerService.setUrl("https://api.stripe.com/v1/customers");
|
||||||
|
|
|
||||||
|
|
@ -82,8 +82,21 @@ try {
|
||||||
if (qUser.recordCount == 0) apiAbort({ "OK": false, "ERROR": "user_not_found" });
|
if (qUser.recordCount == 0) apiAbort({ "OK": false, "ERROR": "user_not_found" });
|
||||||
|
|
||||||
stripeCustomerId = qUser.StripeCustomerId;
|
stripeCustomerId = qUser.StripeCustomerId;
|
||||||
if (!len(trim(stripeCustomerId))) {
|
|
||||||
// Create Stripe Customer
|
// Validate existing customer with Stripe (catches live/test mode mismatch)
|
||||||
|
needNewCustomer = true;
|
||||||
|
if (len(trim(stripeCustomerId))) {
|
||||||
|
cfhttp(method="GET", url="https://api.stripe.com/v1/customers/#stripeCustomerId#", result="checkResp") {
|
||||||
|
cfhttpparam(type="header", name="Authorization", value="Bearer #application.stripeSecretKey#");
|
||||||
|
}
|
||||||
|
checkData = deserializeJSON(checkResp.fileContent);
|
||||||
|
if (structKeyExists(checkData, "id") && !structKeyExists(checkData, "error")) {
|
||||||
|
needNewCustomer = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needNewCustomer) {
|
||||||
|
// Create Stripe Customer (or replace invalid one)
|
||||||
cfhttp(method="POST", url="https://api.stripe.com/v1/customers", result="custResp") {
|
cfhttp(method="POST", url="https://api.stripe.com/v1/customers", result="custResp") {
|
||||||
cfhttpparam(type="header", name="Authorization", value="Bearer #application.stripeSecretKey#");
|
cfhttpparam(type="header", name="Authorization", value="Bearer #application.stripeSecretKey#");
|
||||||
cfhttpparam(type="formfield", name="name", value="#qUser.FirstName# #qUser.LastName#");
|
cfhttpparam(type="formfield", name="name", value="#qUser.FirstName# #qUser.LastName#");
|
||||||
|
|
|
||||||
Reference in a new issue