如何创建或者在哪里可以找到Stripe元素挂载的clientSecret密钥?

问题描述 投票:0回答:1

您好,我想使用 Stripe 以便用户可以创建订阅。我对客户端密钥感到困惑。我有 api 和机密的测试密钥,我也有 api 和机密的实时密钥,并且我有我创建的订阅服务的产品密钥。

另外,我还拥有安装 cli 并通过终端登录到 stripe 后创建的 CLI 密钥。

但是我没有客户端秘密,而且我很担心,因为当我获得一个客户端秘密时,我不希望将其放在客户端服务器上。

我使用离子 5 角 14 电容器 5,以 NODE.JS 和 PHP 作为后端。我的服务器上有一个名为 stripe 的文件夹,但我在那里没有看到任何密钥。

组件.ts

import { Component, AfterViewInit, ElementRef, ViewChild } from '@angular/core';
import { Router } from "@angular/router";
import { UserData } from 'src/app/services/user-data/user-data';
import {
  loadStripe,
  Stripe,
  StripeElements,
  StripeCardElement,
  StripeElementsOptions,
  StripeElement,
} from '@stripe/stripe-js';




@Component({
  selector: 'app-subscription',
  templateUrl: 'subscription.page.html',
  styleUrls: ['subscription.page.scss'],
})
export class SubscriptionPage implements AfterViewInit {
  stripe: Stripe;
  elements: StripeElements;
  paymentElement: StripeElement;
  appearance: StripeElementsOptions['appearance'] = {
    theme: 'stripe',
    variables: {
      colorPrimary: '#0570de',
      colorBackground: '#ffffff',
      colorText: '#30313d',
      colorDanger: '#df1b41',
      fontFamily: 'Ideal Sans, system-ui, sans-serif',
      spacingUnit: '2px',
      borderRadius: '4px',
      // Define other custom styling variables as needed
    },
  };

  menuOpenCopyright: boolean = false;
  user: any = {};
  email: string = '';
  uid: string = '';

  modalOpen: boolean = false;
  cardInputFocused: boolean = false;

  cardDetail: any = {
    name: '',
    cardNumber: '',
    expiryDate: '',
    securityCode: '',
  };

  constructor(
    public router: Router,
    public userData: UserData,
  ) {
    this.user = this.userData.getUserData();
    this.uid = this.user.uid;
    this.email = this.user.email;
  }

  ngAfterViewInit() {
    // Initialize Stripe with your publishable key
    this.initializeStripe().then(() => {
      // Create the card element after initializing Stripe
      this.createPaymentElement();
    });
  }

  async initializeStripe() {
    const stripePromise = loadStripe('sk_live_51HiSxxxxxxxxx'); // Replace with your actual publishable key
    this.stripe = await stripePromise;
  }

  createPaymentElement() {
    if (!this.stripe) {
      console.error('Stripe is not initialized.');
      return;
    }

    this.elements = this.stripe.elements({
      clientSecret: 'sk_live_51HiSxxxxxxxxx', // Replace with your actual client secret
    });
  
    // Create the payment element
    const paymentElementOptions = {
      // Add any specific options for the payment element
    };
    this.paymentElement = this.elements.create('payment', paymentElementOptions);
  
    // Mount the payment element to the DOM
    this.paymentElement.mount('#payment-element');

 
  }


  async subscribe() {
    try {
      event.stopPropagation();
      console.log('Card Number: ' + this.cardDetail.cardNumber);
  
      // Tokenize the card details using the new cardElement
      const { token, error } = await this.stripe.createToken(this.paymentElement, {
        name: this.cardDetail.name,
        address_line1: '', // Include any relevant address information here
        address_city: '', // Include city information here
        address_state: '', // Include state information here
        address_zip: '', // Include ZIP code here
        address_country: '', // Include country information here
      });
  
      if (!error) {
        console.log('Tokenization successful');
        const paymentData = {
          email: this.cardDetail.email,
          token: token.id,
          uid: this.uid,
          name: this.cardDetail.name,
          business: this.cardDetail.business
        };
  
        // Send the token and user's email to your server
        this.userData.createCustomer(paymentData).subscribe((customerResponse: any) => {
          if (customerResponse.success) {
            const customerId = customerResponse.customer.id;
            console.log('Customer created:', customerResponse.customer);
            this.userData.createSetupIntent(customerId).subscribe((setupIntentResponse: any) => {
              if (setupIntentResponse.success) {
                const setupIntentClientSecret = setupIntentResponse.setupIntent.client_secret;
  
                // Create a subscription with the saved payment method
                const planId = 'price_1O2VVjGozbMWFnurNiXUurH7'; // Replace with your actual pricing plan ID
                this.userData.createSubscription(customerId, planId).subscribe((subscriptionResponse: any) => {
                  if (subscriptionResponse.success) {
                    console.log('Subscription successful:', subscriptionResponse.subscription);
                  } else {
                    console.error(subscriptionResponse.error);
                  }
                });
              } else {
                console.error(setupIntentResponse.error);
              }
            });
          } else {
            console.error(customerResponse.error);
            console.error('Error creating customer:', customerResponse.error);
          }
        });
      } else {
        console.error('Tokenization error:', error);
        // Handle the error if tokenization fails
        console.error(error);
      }
    } catch (error) {
      console.error('Error in subscribe:', error);
      console.error(error);
    }
  }

在控制台上我得到

 ERROR Error: Uncaught (in promise): IntegrationError: Invalid value for elements(): clientSecret should be a client secret of the form ${id}_secret_${secret}. You specified: sk_live_51HiSUxxxxxxx.
IntegrationError: Invalid value for elements(): clientSecret should be a client secret of the form ${id}_secret_${secret}. You specified: sk_live_51HiSUxxxxx.
    at ne (v3/:1:178295)
    at re (v3/:1:178367)
    at new t (v3/:1:328546)
    at e.<anonymous> (v3/:1:382147)
    at e.<anonymous> (v3/:1:84831)
    at e.o (v3/:1:421236)
    at SubscriptionPage.createPaymentElement (subscription.page.ts:82:33)
    at subscription.page.ts:67:12
    at push.96084._ZoneDelegate.invoke (zone.js:409:1)
    at Object.onInvoke (core.mjs:25450:1)
    at resolvePromise (zone.js:1262:1)
    at zone.js:1333:1
    at push.96084._ZoneDelegate.invokeTask (zone.js:443:1)
    at Object.onInvokeTask (core.mjs:25437:1)
    at push.96084._ZoneDelegate.invokeTask (zone.js:442:1)
    at push.96084.Zone.runTask (zone.js:214:1)
    at drainMicroTaskQueue (zone.js:632:1)
    at push.96084.ZoneTask.invokeTask [as invoke] (zone.js:529:1)
    at invokeTask (zone.js:1727:1)
    at globalCallback (zone.js:1758:1)

有什么帮助吗?

angular ionic-framework stripe-payments
1个回答
0
投票

client_secret 是从通过订阅创建的 PaymentIntent 中获取的。因此,基本上,您在后端创建订阅,当您这样做时,您需要使用

payment_behavior: 'default_incomplete'
并展开
latest_invoice.payment_intent
,以便您可以访问 PaymentIntent 的 client_secret。然后,您将该 client_secret 传递到前端以初始化 Elements。有关此流程的完整文档,请参阅:https://stripe.com/docs/billing/subscriptions/build-subscriptions?ui=elements

© www.soinside.com 2019 - 2024. All rights reserved.