NodeJS 无法使用Stripe 3D Secure、React Native创建活动订阅(定期)

vdgimpew  于 2023-08-04  发布在  Node.js
关注(0)|答案(1)|浏览(218)

我无法使用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安全

cxfofazt

cxfofazt1#

您不应该在getStripeSecret中创建和使用新的PaymentIntent。您已经有一个PaymentIntent -它是subscription.latest_invoice.payment_intent中可用的一个。您应该从该服务器获取并返回client_secret,并在前端使用它。使用您当前的代码,您正在处理两个单独的付款(因此重复),并且您在前端处理的付款根本没有连接到订阅(因此它仍然处于非活动状态)。您应仔细阅读并准确执行
https://stripe.com/docs/billing/subscriptions/build-subscriptions?ui=elements但是作为一个开始,你的代码应该更像这样:

// making new subscription
const subscription = await addSubscription(customer?.id); 
// getting stripe secret
const clientSecret = subscription.latest_invoice.payment_intent.client_secret;
...

字符串

相关问题