我无法使用react-native前端和节点后端创建Stripe 3D安全的活动订阅。该订阅已创建良好,并且对于非3D Secure Stripe支付处于活动状态。对于3D安全,付款在付款 Jmeter 板上进行了验证和更新,但订阅根本没有被更新为活动。
订阅的屏幕截图(循环):x1c 0d1x的数据
付款截图:
的
我已经按照this stackoverflow的工作流程进行了回答,但仍然不起作用。
前端代码:
const createSubscription = async () => {
try {
if (!cardFormData?.complete) {
alert('Please input your card data!');
setSaving(false);
return;
}
const {firstName, lastName} = userData;
const name = `${firstName} ${lastName}`;
const billing_details = {
email,
name,
description: name,
};
// making payment method
const paymentMethod = await createPaymentMethod({
paymentMethodType: 'Card',
card: cardFormData,
billing_details,
});
const body = JSON.stringify({
paymentMethod: paymentMethod?.paymentMethod?.id,
name,
email,
});
console.log('going to make the api call');
// call the backend to create subscription / customer / client secret
const response = await fetch(`${APIURL}/pay/makePayment`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body,
});
const respJson = await response?.json();
const {
clientSecret,
error: apiError,
customerId,
subscriptionId,
subscriptionPaymentMethod,
subscriptionStart,
subscriptionEnd,
} = respJson;
if (apiError) {
alert(`Payment Error 1 ` + apiError);
setSaving(false);
} else {
// confirm the payment by the user
console.log('confirming payment');
const {paymentIntent, error} = await confirmPayment(clientSecret, {
type: 'Card',
paymentMethodType: 'Card',
paymentMethodData: {
billing_details,
payment_method: subscriptionPaymentMethod,
},
});
console.log('clientSecret', clientSecret);
console.log('Object', {
type: 'Card',
paymentMethodType: 'Card',
paymentMethodData: {
billing_details,
payment_method: subscriptionPaymentMethod,
},
});
console.log('paymentIntent', paymentIntent);
if (paymentIntent) {
createUser(
customerId,
subscriptionId,
subscriptionStart,
subscriptionEnd,
);
} else if (error) {
alert(`Payment Error`);
setSaving(false);
}
}
} catch (e) {
alert(`Payment Error 2 ` + e?.message);
setSaving(false);
}
};
字符串
后端代码:
router.post("/makePayment", async (req, res) => {
try {
const { email, name, paymentMethod } = req.body;
if (email === "" || name === "" || !email || !name || !paymentMethod)
throw "";
// making new customer
const customer = await addNewCustomer(email, name, paymentMethod);
// making new subscription
const subscription = await addSubscription(customer?.id);
// getting stripe secret
const { error, clientSecret } = await getStripeSecret(
subscription?.latest_invoice?.payment_intent?.payment_method,
customer?.id
);
// saving data in session
req.session.customerId = customer?.id;
req.session.subscriptionId = subscription?.id;
res
.send({
clientSecret,
error,
customerId: customer?.id,
subscriptionId: subscription?.id,
subscriptionPaymentMethod:
subscription?.latest_invoice?.payment_intent?.payment_method,
subscriptionStart: new Date(subscription.current_period_start * 1000),
subscriptionEnd: new Date(subscription.current_period_end * 1000),
})
.status(!error ? 200 : 500);
} catch (e) {
res.send({ error: "Internal Server Error" }).status(500);
}
});
型
后端功能:
import Stripe from "stripe";
const { STRIPE_SECRET_KEY, STRIPE_API_VERSION } = process?.env;
const stripe = Stripe(STRIPE_SECRET_KEY, { apiVersion: STRIPE_API_VERSION });
export const getStripeSecret = async (paymentMethod, customerId) => {
try {
const paymentIntent = await stripe.paymentIntents.create({
amount: 28000, //lowest denomination of particular currency
currency: "aud",
payment_method_types: ["card"], //by default
payment_method: paymentMethod,
customer: customerId,
});
const clientSecret = paymentIntent?.client_secret;
return { clientSecret };
} catch (e) {
return { error: e?.message };
}
};
export const addNewCustomer = async (email, name, paymentMethod) => {
try {
const customer = await stripe.customers.create({
email,
description: name,
payment_method: paymentMethod,
invoice_settings: {
default_payment_method: paymentMethod,
},
});
return customer;
} catch (e) {
return { error: e?.message };
}
};
export const addSubscription = async (customerId) => {
try {
const subscription = await stripe.subscriptions.create({
customer: customerId,
items: [{ price: process.env.STRIPE_PRICE_ID }],
payment_settings: {
payment_method_options: {
card: {
request_three_d_secure: "automatic",
},
},
payment_method_types: ["card"],
save_default_payment_method: "on_subscription",
},
expand: ["latest_invoice.payment_intent"],
});
return subscription;
} catch (e) {
return { error: e?.message };
}
};
型
我试着遵循上面的代码。我想让我的订阅活动,就像没有3D安全。
没有3D安全:
的
带3D安全
1条答案
按热度按时间cxfofazt1#
您不应该在getStripeSecret中创建和使用新的PaymentIntent。您已经有一个PaymentIntent -它是
subscription.latest_invoice.payment_intent
中可用的一个。您应该从该服务器获取并返回client_secret,并在前端使用它。使用您当前的代码,您正在处理两个单独的付款(因此重复),并且您在前端处理的付款根本没有连接到订阅(因此它仍然处于非活动状态)。您应仔细阅读并准确执行https://stripe.com/docs/billing/subscriptions/build-subscriptions?ui=elements但是作为一个开始,你的代码应该更像这样:
字符串